@cloudbase/node-sdk
Version:
tencent cloud base server sdk for node.js
999 lines (910 loc) • 29.6 kB
text/typescript
import * as assert from 'power-assert'
import tcb from '../../../src/index'
import * as Config from '../../config.local'
import * as common from '../../common/index'
const app = tcb.init(Config)
const db = app.database()
describe('test/unit/collection.test.ts', () => {
const collName = 'coll-1'
const collection = db.collection(collName)
const command = db.command
const _ = command
it('operator', async () => {
let a
a = _.gt(4)
const result = await collection.where({ a }).update({ c: { d: _.mul(3) } })
})
})
describe('stdDevPop', async () => {
let studentsCollection = null
const collectionName = 'test-students'
const data = [
{ group: 'a', score: 84 },
{ group: 'a', score: 96 },
{ group: 'b', score: 80 },
{ group: 'b', score: 100 }
]
beforeAll(async () => {
studentsCollection = await common.safeCollection(db, collectionName)
const success = await studentsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await studentsCollection.remove()
assert.strictEqual(success, true)
})
it('计算不同组的标准差', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.group({
_id: '$group',
stdDev: $.stdDevPop('$score')
})
.end()
const stdDevs = {
a: null,
b: null
}
result.data.forEach(item => (stdDevs[item._id] = item.stdDev))
// a分组标准差为: 6; b分组标准差为: 10
assert.strictEqual(stdDevs.a, 6)
assert.strictEqual(stdDevs.b, 10)
})
})
describe('stdDevSamp', async () => {
let studentsCollection = null
const collectionName = 'test-students'
const data = [{ score: 80 }, { score: 100 }]
beforeAll(async () => {
studentsCollection = await common.safeCollection(db, collectionName)
const success = await studentsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await studentsCollection.remove()
assert.strictEqual(success, true)
})
it('计算标准样本偏差', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.group({
_id: null,
ageStdDev: $.stdDevSamp('$score')
})
.end()
// data 的标准样本偏差为 14.14
assert.strictEqual(result.data[0].ageStdDev.toFixed(2), '14.14')
})
})
describe('sum', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ cost: -10, price: 100 },
{ cost: -15, price: 1 },
{ cost: -10, price: 10 }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('参数为单独字段', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.group({
_id: null,
totalPrice: $.sum('$price')
})
.end()
assert.strictEqual(result.data[0].totalPrice, 111)
})
it('参数为字段列表', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.group({
_id: null,
totalProfit: $.sum($.sum(['$price', '$cost']))
})
.end()
assert.strictEqual(result.data[0].totalProfit, 76)
})
})
describe('let', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ cost: -10, discount: 0.95, price: 100 },
{ cost: -15, discount: 0.98, price: 1 },
{ cost: -10, discount: 1, price: 10 }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('参数为单独字段', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
profit: $.let({
vars: {
priceTotal: $.multiply(['$price', '$discount'])
},
in: $.sum(['$$priceTotal', '$cost'])
})
})
.end()
assert.strictEqual(result.data.length, 3)
})
})
describe('条件操作符', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ name: 'a', amount: 100, desc: 'A' },
{ name: 'b', amount: 200, desc: null },
{ name: 'c', amount: 300 }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('cond', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
name: 1,
discount: $.cond({
if: $.gte(['$amount', 200]),
then: 0.7,
else: 0.9
})
})
.end()
assert.deepStrictEqual(result.data, [
{ name: 'a', discount: 0.9 },
{ name: 'b', discount: 0.7 },
{ name: 'c', discount: 0.7 }
])
})
it('ifNull', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
name: 1,
desc: $.ifNull(['$desc', 'Not defined'])
})
.end()
assert.deepStrictEqual(result.data, [
{ desc: 'A', name: 'a' },
{ desc: 'Not defined', name: 'b' },
{ desc: 'Not defined', name: 'c' }
])
})
it('switch', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
name: 1,
discount: $.switch({
branches: [
{ case: $.gt(['$amount', 250]), then: 0.8 },
{ case: $.gt(['$amount', 150]), then: 0.9 }
],
default: 1
})
})
.end()
assert.deepStrictEqual(result.data, [
{ name: 'a', discount: 1 },
{ name: 'b', discount: 0.9 },
{ name: 'c', discount: 0.8 }
])
})
})
describe('group操作符', async () => {
let studentsCollection = null,
passagesCollection = null
const $ = db.command.aggregate
const studentsName = 'test-students'
const studentsData = [
{ group: 'a', name: 'stu1', score: 84 },
{ group: 'a', name: 'stu2', score: 96 },
{ group: 'b', name: 'stu3', score: 80 },
{ group: 'b', name: 'stu4', score: 100 }
]
const passagesName = 'test-passages'
const passagesData = [
{ category: 'web', tags: ['JavaScript', 'CSS'], title: 'title1' },
{ category: 'System', tags: ['C++', 'C'], title: 'title2' }
]
beforeAll(async () => {
studentsCollection = await common.safeCollection(db, studentsName)
passagesCollection = await common.safeCollection(db, passagesName)
assert.strictEqual(await studentsCollection.create(studentsData), true)
assert.strictEqual(await passagesCollection.create(passagesData), true)
})
afterAll(async () => {
assert.strictEqual(await studentsCollection.remove(), true)
assert.strictEqual(await passagesCollection.remove(), true)
})
it('push', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.group({
_id: '$group',
students: $.push({
name: '$name',
score: '$score'
})
})
.end()
const valid = result.data.every(item => 'students' in item)
assert.strictEqual(valid, true)
})
it('max', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.group({
_id: '$group',
maxScore: $.max('$score')
})
.end()
assert.strictEqual(result.data.length, 2)
})
it('min', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.group({
_id: '$group',
minScore: $.min('$score')
})
.end()
assert.strictEqual(result.data.length, 2)
})
it('last', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.sort({
score: 1
})
.group({
_id: null,
max: $.last('$score')
})
.end()
assert(result.data[0].max, 100)
})
it('first', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.sort({
score: 1
})
.group({
_id: null,
min: $.first('$score')
})
.end()
assert(result.data[0].min, 80)
})
it('avg', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.group({
_id: null,
average: $.avg('$score')
})
.end()
assert(result.data[0].average, 90)
})
describe('addToSet', async () => {
it('非数组字段', async () => {
const result = await db
.collection(passagesName)
.aggregate()
.group({
_id: null,
categories: $.addToSet('$category')
})
.end()
assert(result.data[0].categories.length, 2)
})
it('数组字段', async () => {
const result = await db
.collection(passagesName)
.aggregate()
.group({
_id: null,
tagsList: $.addToSet('$tags')
})
.end()
const valid = result.data.some(item => Array.isArray(item.tagsList))
assert(valid, true)
})
})
})
describe('字面量操作符', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [{ price: '$1' }, { price: '$2.50' }, { price: '$3.60' }, { price: '$4.60' }]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('以字面量的形式使用$', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
isOneDollar: $.eq(['$price', $.literal('$1')])
})
.end()
assert.deepStrictEqual(result.data, [
{ isOneDollar: true },
{ isOneDollar: false },
{ isOneDollar: false },
{ isOneDollar: false }
])
})
it('投影一个字段,对应的值为1', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
price: 1,
amount: $.literal(1)
})
.end()
assert.deepStrictEqual(result.data, [
{ amount: 1, price: '$1' },
{ amount: 1, price: '$2.50' },
{ amount: 1, price: '$3.60' },
{ amount: 1, price: '$4.60' }
])
})
})
describe('字符串操作符', async () => {
let studentsCollection = null,
personCollection = null
const $ = db.command.aggregate
const studentsName = 'test-students'
const studentsData = [
{
birthday: '1999/12/12',
date: new Date('1999/12/12'),
firstName: 'Yuanxin',
group: 'a',
lastName: 'Dong',
score: 84
},
{
birthday: '1998/11/11',
date: new Date('1998/11/11'),
firstName: 'Weijia',
group: 'a',
lastName: 'Wang',
score: 96
},
{
birthday: '1997/10/10',
date: new Date('1997/10/10'),
firstName: 'Chengxi',
group: 'b',
lastName: 'Li',
score: 80
}
]
const personName = 'test-person'
const personData = [{ name: 'dongyuanxin', nickname: '心谭' }]
beforeAll(async () => {
studentsCollection = await common.safeCollection(db, studentsName)
personCollection = await common.safeCollection(db, personName)
assert.strictEqual(await studentsCollection.create(studentsData), true)
assert.strictEqual(await personCollection.create(personData), true)
})
afterAll(async () => {
assert.strictEqual(await studentsCollection.remove(), true)
assert.strictEqual(await personCollection.remove(), true)
})
it('concat', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
fullName: $.concat(['$firstName', ' ', '$lastName'])
})
.end()
assert.deepStrictEqual(result.data, [
{ fullName: 'Yuanxin Dong' },
{ fullName: 'Weijia Wang' },
{ fullName: 'Chengxi Li' }
])
})
describe('dateToString', async () => {
it('格式化日期', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$date',
format: '%Y-%m-%d'
})
})
.end()
assert.deepStrictEqual(result.data, [
{ formatDate: '1999-12-11' },
{ formatDate: '1998-11-10' },
{ formatDate: '1997-10-09' }
])
})
it('时区时间', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$date',
format: '%H:%M:%S',
timezone: 'Asia/Shanghai'
})
})
.end()
const valid = result.data.every(item => item.formatDate === '00:00:00')
assert.ok(valid)
})
it('缺失情况的默认值', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$empty',
onNull: 'null'
})
})
.end()
const valid = result.data.every(item => item.formatDate === 'null')
assert.ok(valid)
})
})
it('indexOfBytes', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
aStrIndex: $.indexOfBytes(['$firstName', 'a'])
})
.end()
assert.deepStrictEqual(result.data, [{ aStrIndex: 2 }, { aStrIndex: 5 }, { aStrIndex: -1 }])
})
it('indexOfCP', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
aStrIndex: $.indexOfCP(['$firstName', 'a'])
})
.end()
assert.deepStrictEqual(result.data, [{ aStrIndex: 2 }, { aStrIndex: 5 }, { aStrIndex: -1 }])
})
it('split', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
birthday: $.split(['$birthday', '/'])
})
.end()
assert.deepStrictEqual(result.data, [
{ birthday: ['1999', '12', '12'] },
{ birthday: ['1998', '11', '11'] },
{ birthday: ['1997', '10', '10'] }
])
})
it('strcasecmp', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
result: $.strcasecmp(['$firstName', '$lastName'])
})
.end()
assert.deepStrictEqual(result.data, [{ result: 1 }, { result: 1 }, { result: -1 }])
})
it.skip('strLenBytes', async () => {
const result = await db
.collection(personName)
.aggregate()
.project({
_id: 0,
nameLength: $.strLenBytes('$name'),
nicknameLength: $.strLenBytes('$nickname')
})
.end()
assert.deepStrictEqual(result.data, [{ nameLength: 11, nicknameLength: 6 }])
})
it.skip('strLenCP', async () => {
const result = await db
.collection(personName)
.aggregate()
.project({
_id: 0,
nameLength: $.strLenCP('$name'),
nicknameLength: $.strLenCP('$nickname')
})
.end()
assert.deepStrictEqual(result.data, [{ nameLength: 11, nicknameLength: 2 }])
})
it('substr', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
year: $.substr(['$birthday', 0, 4]),
month: $.substr(['$birthday', 5, 2]),
day: $.substr(['$birthday', 8, -1])
})
.end()
assert.deepStrictEqual(result.data, [
{ day: '12', month: '12', year: '1999' },
{ day: '11', month: '11', year: '1998' },
{ day: '10', month: '10', year: '1997' }
])
})
it('substrBytes', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
year: $.substrBytes(['$birthday', 0, 4]),
month: $.substrBytes(['$birthday', 5, 2]),
day: $.substrBytes(['$birthday', 8, -1])
})
.end()
assert.deepStrictEqual(result.data, [
{ day: '12', month: '12', year: '1999' },
{ day: '11', month: '11', year: '1998' },
{ day: '10', month: '10', year: '1997' }
])
})
test.skip('substrCP', async () => {
const result = await db
.collection(personName)
.aggregate()
.project({
_id: 0,
firstCh: $.substrCP(['$nickname', 0, 1])
})
.end()
assert.deepStrictEqual(result.data, [{ firstCh: '心' }])
})
test('toLower', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
result: $.toLower('$firstName')
})
.end()
assert.deepStrictEqual(result.data, [
{ result: 'yuanxin' },
{ result: 'weijia' },
{ result: 'chengxi' }
])
})
test('toUpper', async () => {
const result = await db
.collection(studentsName)
.aggregate()
.project({
_id: 0,
result: $.toUpper('$lastName')
})
.end()
assert.deepStrictEqual(result.data, [
{ result: 'DONG' },
{ result: 'WANG' },
{ result: 'LI' }
])
})
})
describe('mergeObjects', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ name: 'A', foo: { a: 1 }, bar: { b: 2 } },
{ name: 'A', foo: { c: 1 }, bar: { d: 2 } },
{ name: 'A', foo: { e: 1 }, bar: { f: 2 } }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('在group中使用', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.group({
_id: '$name',
mergedFoo: $.mergeObjects('$foo'),
mergeBar: $.mergeObjects('$bar')
})
.end()
assert.deepStrictEqual(result.data, [
{
_id: 'A',
mergedFoo: { a: 1, c: 1, e: 1 },
mergeBar: { b: 2, d: 2, f: 2 }
}
])
})
it('在group以外使用', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
foobar: $.mergeObjects(['$foo', '$bar'])
})
.end()
assert.deepStrictEqual(result.data, [
{ foobar: { a: 1, b: 2 } },
{ foobar: { c: 1, d: 2 } },
{ foobar: { e: 1, f: 2 } }
])
})
})
describe('集合操作', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ arr: [true] },
{ arr: [] },
{ arr: [true, false] },
{ arr: [1] },
{ arr: [1, 0] },
{ arr: ['stark'] }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('allElementsTrue', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
allElementsTrue: $.allElementsTrue(['$arr'])
})
.end()
assert.deepStrictEqual(result.data, [
{ allElementsTrue: true },
{ allElementsTrue: true },
{ allElementsTrue: false },
{ allElementsTrue: true },
{ allElementsTrue: false },
{ allElementsTrue: true }
])
})
it('anyElementTrue', async () => {
const $ = db.command.aggregate
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
anyElementTrue: $.anyElementTrue(['$arr'])
})
.end()
assert.deepStrictEqual(result.data, [
{ anyElementTrue: true },
{ anyElementTrue: false },
{ anyElementTrue: true },
{ anyElementTrue: true },
{ anyElementTrue: true },
{ anyElementTrue: true }
])
})
})
describe('集合操作2', async () => {
let goodsCollection = null
const $ = db.command.aggregate
const collectionName = 'test-goods'
const data = [
{ A: [1, 2], B: [1, 2] },
{ A: [1, 2], B: [2, 1, 2] },
{ A: [1, 2], B: [1, 2, 3] },
{ A: [1, 2], B: [3, 1] },
{ A: [1, 2], B: [] },
{ A: [1, 2], B: [{}, []] },
{ A: [], B: [] },
{ A: [], B: [1] }
]
beforeAll(async () => {
goodsCollection = await common.safeCollection(db, collectionName)
const success = await goodsCollection.create(data)
assert.strictEqual(success, true)
})
afterAll(async () => {
const success = await goodsCollection.remove()
assert.strictEqual(success, true)
})
it('setDifference', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
isBOnly: $.setDifference(['$B', '$A'])
})
.end()
assert.deepStrictEqual(result.data, [
{ isBOnly: [] },
{ isBOnly: [] },
{ isBOnly: [3] },
{ isBOnly: [3] },
{ isBOnly: [] },
{ isBOnly: [{}, []] },
{ isBOnly: [] },
{ isBOnly: [1] }
])
})
it('setEquals', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
sameElements: $.setEquals(['$A', '$B'])
})
.end()
assert.deepStrictEqual(result.data, [
{ sameElements: true },
{ sameElements: true },
{ sameElements: false },
{ sameElements: false },
{ sameElements: false },
{ sameElements: false },
{ sameElements: true },
{ sameElements: false }
])
})
it('setIntersection', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
setIntersection: $.setIntersection(['$A', '$B'])
})
.end()
assert.deepStrictEqual(result.data, [
{ setIntersection: [1, 2] },
{ setIntersection: [1, 2] },
{ setIntersection: [1, 2] },
{ setIntersection: [1] },
{ setIntersection: [] },
{ setIntersection: [] },
{ setIntersection: [] },
{ setIntersection: [] }
])
})
it('setIsSubset', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
setIsSubset: $.setIsSubset(['$A', '$B'])
})
.end()
assert.deepStrictEqual(result.data, [
{ setIsSubset: true },
{ setIsSubset: true },
{ setIsSubset: true },
{ setIsSubset: false },
{ setIsSubset: false },
{ setIsSubset: false },
{ setIsSubset: true },
{ setIsSubset: true }
])
})
it('setUnion', async () => {
const result = await db
.collection(collectionName)
.aggregate()
.project({
_id: 0,
setUnion: $.setUnion(['$A', '$B'])
})
.end()
assert.deepStrictEqual(result.data, [
{ setUnion: [1, 2] },
{ setUnion: [1, 2] },
{ setUnion: [1, 2, 3] },
{ setUnion: [1, 2, 3] },
{ setUnion: [1, 2] },
{ setUnion: [1, 2, {}, []] },
{ setUnion: [] },
{ setUnion: [1] }
])
})
})