@builder6/query-mongodb 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +37 -0
- package/dist/index.js +272 -0
- package/dist/index.test.js +1941 -0
- package/dist/options.js +420 -0
- package/dist/options.test.js +960 -0
- package/dist/pipelines.js +751 -0
- package/dist/pipelines.test.js +782 -0
- package/dist/utils.js +45 -0
- package/dist/utils.test.js +36 -0
- package/index.js +1 -0
- package/options.js +1 -0
- package/package.json +60 -0
- package/src/index.js +497 -0
- package/src/index.test.js +2333 -0
- package/src/options.js +573 -0
- package/src/options.test.js +1112 -0
- package/src/pipelines.js +760 -0
- package/src/pipelines.test.js +1300 -0
- package/src/utils.js +33 -0
- package/src/utils.test.js +40 -0
|
@@ -0,0 +1,2333 @@
|
|
|
1
|
+
/* global suite, test */
|
|
2
|
+
/* eslint-disable no-unused-expressions */
|
|
3
|
+
|
|
4
|
+
const chai = require('chai');
|
|
5
|
+
const expect = chai.expect;
|
|
6
|
+
const { MongoClient, ObjectId } = require('mongodb');
|
|
7
|
+
|
|
8
|
+
const query = require('.');
|
|
9
|
+
|
|
10
|
+
const TESTRECORD_COUNT = 100;
|
|
11
|
+
|
|
12
|
+
const initClient = () =>
|
|
13
|
+
MongoClient.connect('mongodb://localhost:27017/dxtqutests', {
|
|
14
|
+
useNewUrlParser: true,
|
|
15
|
+
useUnifiedTopology: true,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function testQueryValues(
|
|
19
|
+
tdone,
|
|
20
|
+
loadOptions,
|
|
21
|
+
test,
|
|
22
|
+
getTestDataPromises,
|
|
23
|
+
contextOptions
|
|
24
|
+
) {
|
|
25
|
+
function date(start, addDays) {
|
|
26
|
+
return new Date(start + addDays * (24 * 60 * 60 * 1000));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
initClient()
|
|
30
|
+
.then(
|
|
31
|
+
(client) =>
|
|
32
|
+
/* eslint-disable promise/always-return, promise/no-nesting */
|
|
33
|
+
client
|
|
34
|
+
.db()
|
|
35
|
+
.dropDatabase()
|
|
36
|
+
.then(() => {
|
|
37
|
+
const values = client.db().collection('values');
|
|
38
|
+
const currentYear = 2017;
|
|
39
|
+
const currentYearStart = new Date(currentYear, 0, 1).valueOf();
|
|
40
|
+
const nextYearStart = new Date(currentYear + 1, 0, 1).valueOf();
|
|
41
|
+
|
|
42
|
+
return Promise.all(
|
|
43
|
+
getTestDataPromises
|
|
44
|
+
? getTestDataPromises(values)
|
|
45
|
+
: Array.from(new Array(TESTRECORD_COUNT), (v, i) => i).map(
|
|
46
|
+
(n) =>
|
|
47
|
+
values.insertOne({
|
|
48
|
+
date1: date(currentYearStart, n),
|
|
49
|
+
date2: date(nextYearStart, n),
|
|
50
|
+
int1: n % 10,
|
|
51
|
+
int2: n % 5,
|
|
52
|
+
string: 'Item ' + n,
|
|
53
|
+
})
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
.then(() => query(values, loadOptions, contextOptions))
|
|
57
|
+
.then(test);
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
.then(() => client.close())
|
|
61
|
+
.then(tdone)
|
|
62
|
+
/* eslint-enable promise/always-return, promise/no-nesting */
|
|
63
|
+
)
|
|
64
|
+
.catch((err) => tdone(err));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
suite('query-values', function () {
|
|
68
|
+
suite('#aggregateOptions', function () {
|
|
69
|
+
// these tests are only to make sure that the aggregate setting
|
|
70
|
+
// are passed through correctly to the aggregate calls
|
|
71
|
+
test('collation', function (tdone) {
|
|
72
|
+
testQueryValues(
|
|
73
|
+
tdone,
|
|
74
|
+
{ sort: [{ selector: 'string' }], requireTotalCount: true },
|
|
75
|
+
function (res) {
|
|
76
|
+
expect(res.totalCount, 'totalCount').to.eql(2);
|
|
77
|
+
|
|
78
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
79
|
+
expect(res.data, 'list length').to.have.lengthOf(2);
|
|
80
|
+
expect(res.data[0].string).to.eql('something');
|
|
81
|
+
expect(res.data[1].string).to.eql('Something');
|
|
82
|
+
},
|
|
83
|
+
function (collection) {
|
|
84
|
+
return [
|
|
85
|
+
collection.insertOne({
|
|
86
|
+
string: 'something',
|
|
87
|
+
}),
|
|
88
|
+
collection.insertOne({
|
|
89
|
+
string: 'Something',
|
|
90
|
+
}),
|
|
91
|
+
];
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
aggregateOptions: {
|
|
95
|
+
collation: { locale: 'en', caseFirst: 'lower' },
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('collation dynamic', function (tdone) {
|
|
102
|
+
testQueryValues(
|
|
103
|
+
tdone,
|
|
104
|
+
{ sort: [{ selector: 'string' }], requireTotalCount: true },
|
|
105
|
+
function (res) {
|
|
106
|
+
expect(res.totalCount, 'totalCount').to.eql(2);
|
|
107
|
+
|
|
108
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
109
|
+
expect(res.data, 'list length').to.have.lengthOf(2);
|
|
110
|
+
expect(res.data[0].string).to.eql('something');
|
|
111
|
+
expect(res.data[1].string).to.eql('Something');
|
|
112
|
+
},
|
|
113
|
+
function (collection) {
|
|
114
|
+
return [
|
|
115
|
+
collection.insertOne({
|
|
116
|
+
string: 'something',
|
|
117
|
+
}),
|
|
118
|
+
collection.insertOne({
|
|
119
|
+
string: 'Something',
|
|
120
|
+
}),
|
|
121
|
+
];
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
dynamicAggregateOptions: (identifier /*, pipeline,collection*/) =>
|
|
125
|
+
identifier === 'mainQueryResult'
|
|
126
|
+
? {
|
|
127
|
+
collation: { locale: 'en', caseFirst: 'lower' },
|
|
128
|
+
}
|
|
129
|
+
: {},
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
suite('#entitiesQuery.values', function () {
|
|
136
|
+
test('list should retrieve all entities', function (tdone) {
|
|
137
|
+
testQueryValues(
|
|
138
|
+
tdone,
|
|
139
|
+
{
|
|
140
|
+
requireTotalCount: true,
|
|
141
|
+
},
|
|
142
|
+
function (res) {
|
|
143
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
144
|
+
|
|
145
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
146
|
+
expect(res.data, 'result').to.have.lengthOf(TESTRECORD_COUNT);
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('list should accept skip', function (tdone) {
|
|
152
|
+
testQueryValues(
|
|
153
|
+
tdone,
|
|
154
|
+
{
|
|
155
|
+
skip: 5,
|
|
156
|
+
requireTotalCount: true,
|
|
157
|
+
},
|
|
158
|
+
function (res) {
|
|
159
|
+
expect(res.totalCount).to.eql(TESTRECORD_COUNT);
|
|
160
|
+
|
|
161
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
162
|
+
expect(res.data, 'result').to.have.lengthOf(TESTRECORD_COUNT - 5);
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('list should accept take', function (tdone) {
|
|
168
|
+
testQueryValues(
|
|
169
|
+
tdone,
|
|
170
|
+
{
|
|
171
|
+
take: 5,
|
|
172
|
+
requireTotalCount: true,
|
|
173
|
+
},
|
|
174
|
+
function (res) {
|
|
175
|
+
expect(res.totalCount).to.eql(TESTRECORD_COUNT);
|
|
176
|
+
|
|
177
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
178
|
+
expect(res.data, 'result').to.have.lengthOf(5);
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('list should sort ascending', function (tdone) {
|
|
184
|
+
testQueryValues(
|
|
185
|
+
tdone,
|
|
186
|
+
{
|
|
187
|
+
take: 5,
|
|
188
|
+
sort: [
|
|
189
|
+
{
|
|
190
|
+
selector: 'int1',
|
|
191
|
+
desc: false,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
function (res) {
|
|
196
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
197
|
+
expect(res.data, 'result').to.have.lengthOf(5);
|
|
198
|
+
expect(res.data[0].int1).to.eql(0);
|
|
199
|
+
expect(res.data[1].int1).to.eql(0);
|
|
200
|
+
expect(res.data[2].int1).to.eql(0);
|
|
201
|
+
expect(res.data[3].int1).to.eql(0);
|
|
202
|
+
expect(res.data[4].int1).to.eql(0);
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('list should sort descending', function (tdone) {
|
|
208
|
+
testQueryValues(
|
|
209
|
+
tdone,
|
|
210
|
+
{
|
|
211
|
+
take: 5,
|
|
212
|
+
sort: [
|
|
213
|
+
{
|
|
214
|
+
selector: 'int1',
|
|
215
|
+
desc: true,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
function (res) {
|
|
220
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
221
|
+
expect(res.data, 'result').to.have.lengthOf(5);
|
|
222
|
+
expect(res.data[0].int1).to.eql(9);
|
|
223
|
+
expect(res.data[1].int1).to.eql(9);
|
|
224
|
+
expect(res.data[2].int1).to.eql(9);
|
|
225
|
+
expect(res.data[3].int1).to.eql(9);
|
|
226
|
+
expect(res.data[4].int1).to.eql(9);
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('list should sort by two fields', function (tdone) {
|
|
232
|
+
testQueryValues(
|
|
233
|
+
tdone,
|
|
234
|
+
{
|
|
235
|
+
take: 20,
|
|
236
|
+
sort: [
|
|
237
|
+
{
|
|
238
|
+
selector: 'int2',
|
|
239
|
+
desc: true,
|
|
240
|
+
},
|
|
241
|
+
{ selector: 'int1', desc: false },
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
function (res) {
|
|
245
|
+
// the highest 20 are all 4 for int2, but then
|
|
246
|
+
// there's 4 and 9 for int1. Sorting ascending on int1,
|
|
247
|
+
// we should start with the 4s and then see the 9s.
|
|
248
|
+
|
|
249
|
+
// I guess this is not a perfect sorting test because it
|
|
250
|
+
// doesn't have much variety. But I was testing just now
|
|
251
|
+
// on suspicion that something was severely out of order,
|
|
252
|
+
// and that is apparently not the case.
|
|
253
|
+
|
|
254
|
+
// console.log(JSON.stringify(res.data, null, 2));
|
|
255
|
+
|
|
256
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
257
|
+
expect(res.data, 'result').to.have.lengthOf(20);
|
|
258
|
+
expect(res.data[0].int2).to.eql(4);
|
|
259
|
+
expect(res.data[1].int2).to.eql(4);
|
|
260
|
+
expect(res.data[2].int2).to.eql(4);
|
|
261
|
+
expect(res.data[3].int2).to.eql(4);
|
|
262
|
+
expect(res.data[4].int2).to.eql(4);
|
|
263
|
+
expect(res.data[5].int2).to.eql(4);
|
|
264
|
+
expect(res.data[6].int2).to.eql(4);
|
|
265
|
+
expect(res.data[7].int2).to.eql(4);
|
|
266
|
+
expect(res.data[8].int2).to.eql(4);
|
|
267
|
+
expect(res.data[9].int2).to.eql(4);
|
|
268
|
+
expect(res.data[10].int2).to.eql(4);
|
|
269
|
+
expect(res.data[11].int2).to.eql(4);
|
|
270
|
+
expect(res.data[12].int2).to.eql(4);
|
|
271
|
+
expect(res.data[13].int2).to.eql(4);
|
|
272
|
+
expect(res.data[14].int2).to.eql(4);
|
|
273
|
+
expect(res.data[15].int2).to.eql(4);
|
|
274
|
+
expect(res.data[16].int2).to.eql(4);
|
|
275
|
+
expect(res.data[17].int2).to.eql(4);
|
|
276
|
+
expect(res.data[18].int2).to.eql(4);
|
|
277
|
+
expect(res.data[19].int2).to.eql(4);
|
|
278
|
+
|
|
279
|
+
expect(res.data[0].int1).to.eql(4);
|
|
280
|
+
expect(res.data[1].int1).to.eql(4);
|
|
281
|
+
expect(res.data[2].int1).to.eql(4);
|
|
282
|
+
expect(res.data[3].int1).to.eql(4);
|
|
283
|
+
expect(res.data[4].int1).to.eql(4);
|
|
284
|
+
expect(res.data[5].int1).to.eql(4);
|
|
285
|
+
expect(res.data[6].int1).to.eql(4);
|
|
286
|
+
expect(res.data[7].int1).to.eql(4);
|
|
287
|
+
expect(res.data[8].int1).to.eql(4);
|
|
288
|
+
expect(res.data[9].int1).to.eql(4);
|
|
289
|
+
expect(res.data[10].int1).to.eql(9);
|
|
290
|
+
expect(res.data[11].int1).to.eql(9);
|
|
291
|
+
expect(res.data[12].int1).to.eql(9);
|
|
292
|
+
expect(res.data[13].int1).to.eql(9);
|
|
293
|
+
expect(res.data[14].int1).to.eql(9);
|
|
294
|
+
expect(res.data[15].int1).to.eql(9);
|
|
295
|
+
expect(res.data[16].int1).to.eql(9);
|
|
296
|
+
expect(res.data[17].int1).to.eql(9);
|
|
297
|
+
expect(res.data[18].int1).to.eql(9);
|
|
298
|
+
expect(res.data[19].int1).to.eql(9);
|
|
299
|
+
}
|
|
300
|
+
);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test('list should filter with =', function (tdone) {
|
|
304
|
+
testQueryValues(
|
|
305
|
+
tdone,
|
|
306
|
+
{
|
|
307
|
+
filter: ['int1', '=', 3],
|
|
308
|
+
requireTotalCount: true,
|
|
309
|
+
},
|
|
310
|
+
function (res) {
|
|
311
|
+
expect(res.totalCount, 'totalCount').to.eql(10);
|
|
312
|
+
|
|
313
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
314
|
+
expect(res.data, 'list length').to.have.lengthOf(10);
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('list should filter with multiple criteria', function (tdone) {
|
|
320
|
+
testQueryValues(
|
|
321
|
+
tdone,
|
|
322
|
+
{
|
|
323
|
+
filter: [['int1', '=', 3], 'or', ['int1', '=', 5]],
|
|
324
|
+
requireTotalCount: true,
|
|
325
|
+
},
|
|
326
|
+
function (res) {
|
|
327
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
328
|
+
|
|
329
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
330
|
+
expect(res.data, 'list length').to.have.lengthOf(20);
|
|
331
|
+
}
|
|
332
|
+
);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test('list should search with =', function (tdone) {
|
|
336
|
+
testQueryValues(
|
|
337
|
+
tdone,
|
|
338
|
+
{
|
|
339
|
+
searchExpr: 'int1',
|
|
340
|
+
searchOperation: '=',
|
|
341
|
+
searchValue: 3,
|
|
342
|
+
requireTotalCount: true,
|
|
343
|
+
},
|
|
344
|
+
function (res) {
|
|
345
|
+
expect(res.totalCount, 'totalCount').to.eql(10);
|
|
346
|
+
|
|
347
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
348
|
+
expect(res.data, 'list length').to.have.lengthOf(10);
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test('list should project with select', function (tdone) {
|
|
354
|
+
testQueryValues(
|
|
355
|
+
tdone,
|
|
356
|
+
{
|
|
357
|
+
filter: ['int1', '=', 3],
|
|
358
|
+
requireTotalCount: false,
|
|
359
|
+
select: ['int2', 'date1'],
|
|
360
|
+
},
|
|
361
|
+
function (res) {
|
|
362
|
+
//console.log("Result: ", JSON.stringify(res, null, 2));
|
|
363
|
+
|
|
364
|
+
expect(res.data[0]).to.have.ownProperty('_id');
|
|
365
|
+
expect(res.data[0]).to.have.ownProperty('int2');
|
|
366
|
+
expect(res.data[0]).to.have.ownProperty('date1');
|
|
367
|
+
|
|
368
|
+
expect(res.data[0]).to.not.have.ownProperty('int1');
|
|
369
|
+
expect(res.data[0]).to.not.have.ownProperty('date2');
|
|
370
|
+
expect(res.data[0]).to.not.have.ownProperty('string');
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
test('list should search with multiple fields', function (tdone) {
|
|
376
|
+
testQueryValues(
|
|
377
|
+
tdone,
|
|
378
|
+
{
|
|
379
|
+
searchExpr: ['int1', 'int2'],
|
|
380
|
+
searchOperation: '=',
|
|
381
|
+
searchValue: 3,
|
|
382
|
+
requireTotalCount: true,
|
|
383
|
+
},
|
|
384
|
+
function (res) {
|
|
385
|
+
//console.log("Result: ", JSON.stringify(res, null, 2));
|
|
386
|
+
|
|
387
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
388
|
+
|
|
389
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
390
|
+
expect(res.data, 'list length').to.have.lengthOf(20);
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
test('list should filter with <', function (tdone) {
|
|
396
|
+
testQueryValues(
|
|
397
|
+
tdone,
|
|
398
|
+
{
|
|
399
|
+
filter: ['int1', '<', 5],
|
|
400
|
+
requireTotalCount: true,
|
|
401
|
+
},
|
|
402
|
+
function (res) {
|
|
403
|
+
expect(res.totalCount, 'totalCount').to.eql(50);
|
|
404
|
+
|
|
405
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
406
|
+
expect(res.data, 'list length').to.have.lengthOf(50);
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test('list should filter with date.Month and nested array', function (tdone) {
|
|
412
|
+
testQueryValues(
|
|
413
|
+
tdone,
|
|
414
|
+
{
|
|
415
|
+
// some pivot grid queries nest a single filter condition in an extra array
|
|
416
|
+
filter: [['date1.Month', '<=', 2]],
|
|
417
|
+
requireTotalCount: true,
|
|
418
|
+
},
|
|
419
|
+
function (res) {
|
|
420
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
421
|
+
expect(res.totalCount, 'totalCount').to.eql(59);
|
|
422
|
+
|
|
423
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
424
|
+
expect(res.data, 'list length').to.have.lengthOf(59);
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test('list should filter with date.Quarter', function (tdone) {
|
|
430
|
+
testQueryValues(
|
|
431
|
+
tdone,
|
|
432
|
+
{
|
|
433
|
+
filter: ['date1.quarter', '=', 2],
|
|
434
|
+
requireTotalCount: true,
|
|
435
|
+
},
|
|
436
|
+
function (res) {
|
|
437
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
438
|
+
expect(res.totalCount, 'totalCount').to.eql(10);
|
|
439
|
+
|
|
440
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
441
|
+
expect(res.data, 'list length').to.have.lengthOf(10);
|
|
442
|
+
|
|
443
|
+
expect(res.data[0].date1, 'date1').to.be.a('date');
|
|
444
|
+
expect(res.data[0].date2, 'date2').to.be.a('date');
|
|
445
|
+
expect(res.data[0].int1, 'int1').to.be.a('number');
|
|
446
|
+
expect(res.data[0].int2, 'int2').to.be.a('number');
|
|
447
|
+
expect(res.data[0].string, 'string').to.be.a('string');
|
|
448
|
+
expect(res.data[0].___date1_mp2, '___date1_mp2').to.be.undefined;
|
|
449
|
+
expect(res.data[0].___date1_quarter, '___date1_quarter').to.be
|
|
450
|
+
.undefined;
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
test('list should filter and group (sample 1)', function (tdone) {
|
|
456
|
+
testQueryValues(
|
|
457
|
+
tdone,
|
|
458
|
+
{
|
|
459
|
+
filter: [['date2.Month', '>=', 4], 'and', ['date2.Month', '<', 7]],
|
|
460
|
+
group: [
|
|
461
|
+
{
|
|
462
|
+
groupInterval: 'month',
|
|
463
|
+
isExpanded: false,
|
|
464
|
+
selector: 'date1',
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
groupSummary: [
|
|
468
|
+
{
|
|
469
|
+
selector: 'int1',
|
|
470
|
+
summaryType: 'sum',
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
totalSummary: [
|
|
474
|
+
{
|
|
475
|
+
selector: 'int1',
|
|
476
|
+
summaryType: 'sum',
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
requireTotalCount: true,
|
|
480
|
+
},
|
|
481
|
+
function (res) {
|
|
482
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
483
|
+
|
|
484
|
+
expect(res.totalCount, 'totalCount').to.eql(10);
|
|
485
|
+
|
|
486
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
487
|
+
expect(res.data, 'list length').to.have.lengthOf(1);
|
|
488
|
+
|
|
489
|
+
expect(res.summary[0], 'summary value').to.eql(45);
|
|
490
|
+
}
|
|
491
|
+
);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
test('list should group and filter by quarter without extra fields', function (tdone) {
|
|
495
|
+
testQueryValues(
|
|
496
|
+
tdone,
|
|
497
|
+
{
|
|
498
|
+
filter: [['date2.quarter', '=', 1]],
|
|
499
|
+
group: [
|
|
500
|
+
{
|
|
501
|
+
groupInterval: 'month',
|
|
502
|
+
isExpanded: true,
|
|
503
|
+
selector: 'date1',
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
requireTotalCount: true,
|
|
507
|
+
},
|
|
508
|
+
function (res) {
|
|
509
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
510
|
+
|
|
511
|
+
expect(res.totalCount, 'totalCount').to.eql(90);
|
|
512
|
+
|
|
513
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
514
|
+
expect(res.data, 'list length').to.have.lengthOf(3);
|
|
515
|
+
|
|
516
|
+
for (const group of res.data) {
|
|
517
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
518
|
+
expect(group.items, `group(${group.key}).items`).to.be.instanceof(
|
|
519
|
+
Array
|
|
520
|
+
);
|
|
521
|
+
expect(
|
|
522
|
+
group.items,
|
|
523
|
+
`group(${group.key}) items list`
|
|
524
|
+
).to.have.length.of.at.least(10); // arbitrary
|
|
525
|
+
expect(group.count, `group(${group.key}).count`).to.eql(
|
|
526
|
+
group.items.length
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
for (const item of group.items) {
|
|
530
|
+
expect(item.___date2_mp2, 'item.___date2_mp2').to.be.undefined;
|
|
531
|
+
expect(item.___date2_quarter, 'item.___date2_quarter').to.be
|
|
532
|
+
.undefined;
|
|
533
|
+
// leaving the group key in place for now, Mongo doesn't seem to have a
|
|
534
|
+
// very easy way to remove this while data is queried as part of the
|
|
535
|
+
// $group step with $push $$CURRENT
|
|
536
|
+
//expect(item.___group_key_0, "item.___group_key_0").to.be.undefined;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
test('list should filter with endswith', function (tdone) {
|
|
544
|
+
testQueryValues(
|
|
545
|
+
tdone,
|
|
546
|
+
{
|
|
547
|
+
filter: ['string', 'endswith', '23'],
|
|
548
|
+
requireTotalCount: true,
|
|
549
|
+
},
|
|
550
|
+
function (res) {
|
|
551
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
552
|
+
|
|
553
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
554
|
+
expect(res.data, 'list length').to.have.lengthOf(1);
|
|
555
|
+
}
|
|
556
|
+
);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
test('prefer metadata count with filter', function (tdone) {
|
|
560
|
+
testQueryValues(
|
|
561
|
+
tdone,
|
|
562
|
+
{
|
|
563
|
+
filter: ['string', 'contains', '7'],
|
|
564
|
+
requireTotalCount: true,
|
|
565
|
+
},
|
|
566
|
+
function (res) {
|
|
567
|
+
expect(res.totalCount, 'totalCount').to.eql(19);
|
|
568
|
+
|
|
569
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
570
|
+
expect(res.data, 'list length').to.have.lengthOf(19);
|
|
571
|
+
},
|
|
572
|
+
undefined,
|
|
573
|
+
{ preferMetadataCount: true }
|
|
574
|
+
);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
test('prefer metadata count without filter', function (tdone) {
|
|
578
|
+
testQueryValues(
|
|
579
|
+
tdone,
|
|
580
|
+
{
|
|
581
|
+
requireTotalCount: true,
|
|
582
|
+
},
|
|
583
|
+
function (res) {
|
|
584
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
585
|
+
},
|
|
586
|
+
undefined,
|
|
587
|
+
{ preferMetadataCount: true }
|
|
588
|
+
);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test('list should filter with contains', function (tdone) {
|
|
592
|
+
testQueryValues(
|
|
593
|
+
tdone,
|
|
594
|
+
{
|
|
595
|
+
filter: ['string', 'contains', 'Item'],
|
|
596
|
+
requireTotalCount: true,
|
|
597
|
+
},
|
|
598
|
+
function (res) {
|
|
599
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
600
|
+
|
|
601
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
602
|
+
expect(res.data, 'list length').to.have.lengthOf(TESTRECORD_COUNT);
|
|
603
|
+
}
|
|
604
|
+
);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
test('list should filter with contains (case insensitive)', function (tdone) {
|
|
608
|
+
testQueryValues(
|
|
609
|
+
tdone,
|
|
610
|
+
{
|
|
611
|
+
filter: ['string', 'contains', 'item'],
|
|
612
|
+
requireTotalCount: true,
|
|
613
|
+
},
|
|
614
|
+
function (res) {
|
|
615
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
616
|
+
|
|
617
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
618
|
+
expect(res.data, 'list length').to.have.lengthOf(TESTRECORD_COUNT);
|
|
619
|
+
}
|
|
620
|
+
);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test('list should filter with contains (case sensitive!)', function (tdone) {
|
|
624
|
+
testQueryValues(
|
|
625
|
+
tdone,
|
|
626
|
+
{
|
|
627
|
+
filter: ['string', 'contains', 'Something'],
|
|
628
|
+
requireTotalCount: true,
|
|
629
|
+
},
|
|
630
|
+
function (res) {
|
|
631
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
632
|
+
|
|
633
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
634
|
+
expect(res.data, 'list length').to.have.lengthOf(1);
|
|
635
|
+
},
|
|
636
|
+
function (collection) {
|
|
637
|
+
return [
|
|
638
|
+
collection.insertOne({
|
|
639
|
+
string: 'something',
|
|
640
|
+
}),
|
|
641
|
+
collection.insertOne({
|
|
642
|
+
string: 'Something',
|
|
643
|
+
}),
|
|
644
|
+
];
|
|
645
|
+
},
|
|
646
|
+
{ caseInsensitiveRegex: false }
|
|
647
|
+
);
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
test('ids should be strings by default', function (tdone) {
|
|
651
|
+
testQueryValues(
|
|
652
|
+
tdone,
|
|
653
|
+
{
|
|
654
|
+
requireTotalCount: true,
|
|
655
|
+
},
|
|
656
|
+
function (res) {
|
|
657
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
658
|
+
|
|
659
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
660
|
+
expect(res.data, 'list length').to.have.lengthOf(1);
|
|
661
|
+
expect(res.data[0]._id, 'id').to.be.a('string');
|
|
662
|
+
},
|
|
663
|
+
function (collection) {
|
|
664
|
+
return [
|
|
665
|
+
collection.insertOne({
|
|
666
|
+
data: 42,
|
|
667
|
+
}),
|
|
668
|
+
];
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
// replaceIds:true // default is true
|
|
672
|
+
}
|
|
673
|
+
);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
test('ids should not be strings if replaceId=false', function (tdone) {
|
|
677
|
+
testQueryValues(
|
|
678
|
+
tdone,
|
|
679
|
+
{
|
|
680
|
+
requireTotalCount: true,
|
|
681
|
+
},
|
|
682
|
+
function (res) {
|
|
683
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
684
|
+
|
|
685
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
686
|
+
expect(res.data, 'list length').to.have.lengthOf(1);
|
|
687
|
+
expect(res.data[0]._id, 'id').to.be.a('object');
|
|
688
|
+
},
|
|
689
|
+
function (collection) {
|
|
690
|
+
return [
|
|
691
|
+
collection.insertOne({
|
|
692
|
+
data: 42,
|
|
693
|
+
}),
|
|
694
|
+
];
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
replaceIds: false, // default is true
|
|
698
|
+
}
|
|
699
|
+
);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('list should filter with endswith, no results', function (tdone) {
|
|
703
|
+
testQueryValues(
|
|
704
|
+
tdone,
|
|
705
|
+
{
|
|
706
|
+
filter: ['string', 'endswith', "something that doesn't exist"],
|
|
707
|
+
requireTotalCount: true,
|
|
708
|
+
},
|
|
709
|
+
function (res) {
|
|
710
|
+
expect(res.totalCount, 'totalCount').to.eql(0);
|
|
711
|
+
|
|
712
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
713
|
+
expect(res.data, 'list length').to.have.lengthOf(0);
|
|
714
|
+
}
|
|
715
|
+
);
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
test('list should filter with endswith, no results, total summary defined', function (tdone) {
|
|
719
|
+
testQueryValues(
|
|
720
|
+
tdone,
|
|
721
|
+
{
|
|
722
|
+
filter: ['string', 'endswith', "something that doesn't exist"],
|
|
723
|
+
totalSummary: [
|
|
724
|
+
{
|
|
725
|
+
selector: 'int1',
|
|
726
|
+
summaryType: 'sum',
|
|
727
|
+
},
|
|
728
|
+
],
|
|
729
|
+
requireTotalCount: true,
|
|
730
|
+
},
|
|
731
|
+
function (res) {
|
|
732
|
+
expect(res.totalCount, 'totalCount').to.eql(0);
|
|
733
|
+
|
|
734
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
735
|
+
expect(res.data, 'list length').to.have.lengthOf(0);
|
|
736
|
+
|
|
737
|
+
expect(res.summary, 'res.summary').to.be.undefined;
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
test('list should calculate total summaries for simple queries', function (tdone) {
|
|
743
|
+
testQueryValues(
|
|
744
|
+
tdone,
|
|
745
|
+
{
|
|
746
|
+
filter: ['int1', '<', 5],
|
|
747
|
+
totalSummary: [
|
|
748
|
+
{
|
|
749
|
+
selector: 'int1',
|
|
750
|
+
summaryType: 'sum',
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
selector: 'int2',
|
|
754
|
+
summaryType: 'max',
|
|
755
|
+
},
|
|
756
|
+
],
|
|
757
|
+
requireTotalCount: true,
|
|
758
|
+
},
|
|
759
|
+
function (res) {
|
|
760
|
+
expect(res.totalCount, 'totalCount').to.eql(50);
|
|
761
|
+
|
|
762
|
+
expect(res.summary, 'res.summary').to.be.instanceof(Array);
|
|
763
|
+
expect(res.summary, 'res.summary').to.have.lengthOf(2);
|
|
764
|
+
expect(res.summary[0], 'sum(int1)').to.eql(100);
|
|
765
|
+
expect(res.summary[1], 'max(int2)').to.eql(4);
|
|
766
|
+
}
|
|
767
|
+
);
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
test('list should group with items', function (tdone) {
|
|
771
|
+
testQueryValues(
|
|
772
|
+
tdone,
|
|
773
|
+
{
|
|
774
|
+
group: [
|
|
775
|
+
{
|
|
776
|
+
selector: 'int1',
|
|
777
|
+
desc: false,
|
|
778
|
+
isExpanded: true,
|
|
779
|
+
},
|
|
780
|
+
],
|
|
781
|
+
requireTotalCount: true,
|
|
782
|
+
requireGroupCount: true,
|
|
783
|
+
},
|
|
784
|
+
function (res) {
|
|
785
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
786
|
+
expect(res.groupCount, 'groupCount').to.eql(10);
|
|
787
|
+
|
|
788
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
789
|
+
expect(res.data, 'group list length').to.have.lengthOf(10);
|
|
790
|
+
|
|
791
|
+
for (const group of res.data) {
|
|
792
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
793
|
+
expect(group.items, `group(${group.key}).items`).to.be.instanceof(
|
|
794
|
+
Array
|
|
795
|
+
);
|
|
796
|
+
expect(
|
|
797
|
+
group.items,
|
|
798
|
+
`group(${group.key}) items list`
|
|
799
|
+
).to.have.lengthOf(10);
|
|
800
|
+
expect(group.count, `group(${group.key}).count`).to.eql(
|
|
801
|
+
group.items.length
|
|
802
|
+
);
|
|
803
|
+
|
|
804
|
+
for (const item of group.items) {
|
|
805
|
+
expect(item.int1, 'item.int1').to.eql(group.key);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
test('group item id should be type string by default', function (tdone) {
|
|
813
|
+
testQueryValues(
|
|
814
|
+
tdone,
|
|
815
|
+
{
|
|
816
|
+
group: [
|
|
817
|
+
{
|
|
818
|
+
selector: 'int1',
|
|
819
|
+
desc: false,
|
|
820
|
+
isExpanded: true,
|
|
821
|
+
},
|
|
822
|
+
],
|
|
823
|
+
requireTotalCount: true,
|
|
824
|
+
requireGroupCount: true,
|
|
825
|
+
},
|
|
826
|
+
function (res) {
|
|
827
|
+
expect(res.data[0].items[0]._id, 'group item id').to.be.a('string');
|
|
828
|
+
},
|
|
829
|
+
undefined,
|
|
830
|
+
{
|
|
831
|
+
// replaceIds: true, // default is true
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
test('group item id should not be type string if replaceIds=false', function (tdone) {
|
|
837
|
+
testQueryValues(
|
|
838
|
+
tdone,
|
|
839
|
+
{
|
|
840
|
+
group: [
|
|
841
|
+
{
|
|
842
|
+
selector: 'int1',
|
|
843
|
+
desc: false,
|
|
844
|
+
isExpanded: true,
|
|
845
|
+
},
|
|
846
|
+
],
|
|
847
|
+
requireTotalCount: true,
|
|
848
|
+
requireGroupCount: true,
|
|
849
|
+
},
|
|
850
|
+
function (res) {
|
|
851
|
+
expect(res.data[0].items[0]._id, 'group item id').to.be.a('object');
|
|
852
|
+
},
|
|
853
|
+
undefined,
|
|
854
|
+
{
|
|
855
|
+
replaceIds: false, // default is true
|
|
856
|
+
}
|
|
857
|
+
);
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
test('list should group with items and select', function (tdone) {
|
|
861
|
+
testQueryValues(
|
|
862
|
+
tdone,
|
|
863
|
+
{
|
|
864
|
+
group: [
|
|
865
|
+
{
|
|
866
|
+
selector: 'int1',
|
|
867
|
+
desc: false,
|
|
868
|
+
isExpanded: true,
|
|
869
|
+
},
|
|
870
|
+
],
|
|
871
|
+
select: ['int2', 'date1'],
|
|
872
|
+
},
|
|
873
|
+
function (res) {
|
|
874
|
+
//console.log("Result: ", JSON.stringify(res, null, 2));
|
|
875
|
+
|
|
876
|
+
const x = res.data[0].items[0];
|
|
877
|
+
|
|
878
|
+
expect(x).to.have.ownProperty('_id');
|
|
879
|
+
expect(x).to.have.ownProperty('int2');
|
|
880
|
+
expect(x).to.have.ownProperty('date1');
|
|
881
|
+
|
|
882
|
+
expect(x).to.not.have.ownProperty('int1');
|
|
883
|
+
expect(x).to.not.have.ownProperty('date2');
|
|
884
|
+
expect(x).to.not.have.ownProperty('string');
|
|
885
|
+
}
|
|
886
|
+
);
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
test('list should group with items and secondary sort', function (tdone) {
|
|
890
|
+
testQueryValues(
|
|
891
|
+
tdone,
|
|
892
|
+
{
|
|
893
|
+
filter: ['int2', '=', 3],
|
|
894
|
+
group: [
|
|
895
|
+
{
|
|
896
|
+
selector: 'int2',
|
|
897
|
+
desc: false,
|
|
898
|
+
isExpanded: true,
|
|
899
|
+
},
|
|
900
|
+
],
|
|
901
|
+
sort: [
|
|
902
|
+
{
|
|
903
|
+
selector: 'int1',
|
|
904
|
+
desc: true,
|
|
905
|
+
},
|
|
906
|
+
],
|
|
907
|
+
requireTotalCount: true,
|
|
908
|
+
requireGroupCount: true,
|
|
909
|
+
},
|
|
910
|
+
function (res) {
|
|
911
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
912
|
+
expect(res.groupCount, 'groupCount').to.eql(1);
|
|
913
|
+
|
|
914
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
915
|
+
expect(res.data, 'group list length').to.have.lengthOf(1);
|
|
916
|
+
|
|
917
|
+
for (const group of res.data) {
|
|
918
|
+
//console.log("Checking group", JSON.stringify(group, null, 2));
|
|
919
|
+
|
|
920
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
921
|
+
expect(group.items, `group(${group.key}).items`).to.be.instanceof(
|
|
922
|
+
Array
|
|
923
|
+
);
|
|
924
|
+
expect(
|
|
925
|
+
group.items,
|
|
926
|
+
`group(${group.key}) items list`
|
|
927
|
+
).to.have.lengthOf(20);
|
|
928
|
+
|
|
929
|
+
for (let i = 0; i <= 9; i++) {
|
|
930
|
+
expect(group.items[i].int1, `groupitem ${i}`).to.eql(8);
|
|
931
|
+
}
|
|
932
|
+
for (let i = 10; i <= 19; i++) {
|
|
933
|
+
expect(group.items[i].int1, `groupitem ${i}`).to.eql(3);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
);
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
test('list should group without items', function (tdone) {
|
|
941
|
+
testQueryValues(
|
|
942
|
+
tdone,
|
|
943
|
+
{
|
|
944
|
+
group: [
|
|
945
|
+
{
|
|
946
|
+
selector: 'int1',
|
|
947
|
+
desc: false,
|
|
948
|
+
// , isExpanded: false
|
|
949
|
+
},
|
|
950
|
+
],
|
|
951
|
+
requireTotalCount: true,
|
|
952
|
+
requireGroupCount: true,
|
|
953
|
+
},
|
|
954
|
+
function (res) {
|
|
955
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
956
|
+
expect(res.groupCount, 'groupCount').to.eql(10);
|
|
957
|
+
|
|
958
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
959
|
+
expect(res.data, 'group list length').to.have.lengthOf(10);
|
|
960
|
+
|
|
961
|
+
for (const group of res.data) {
|
|
962
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
963
|
+
expect(group.items, `group(${group.key}).items`).to.be.null;
|
|
964
|
+
expect(group.count, `group(${group.key}).count`).to.eql(10);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
);
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
test('list should group without items, with filter', function (tdone) {
|
|
971
|
+
testQueryValues(
|
|
972
|
+
tdone,
|
|
973
|
+
{
|
|
974
|
+
filter: ['int1', '=', 3],
|
|
975
|
+
group: [
|
|
976
|
+
{
|
|
977
|
+
selector: 'int1',
|
|
978
|
+
desc: false,
|
|
979
|
+
// , isExpanded: false
|
|
980
|
+
},
|
|
981
|
+
],
|
|
982
|
+
requireTotalCount: true,
|
|
983
|
+
requireGroupCount: true,
|
|
984
|
+
},
|
|
985
|
+
function (res) {
|
|
986
|
+
expect(res.totalCount, 'totalCount').to.eql(10);
|
|
987
|
+
expect(res.groupCount, 'groupCount').to.eql(1);
|
|
988
|
+
|
|
989
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
990
|
+
expect(res.data, 'group list length').to.have.lengthOf(1);
|
|
991
|
+
|
|
992
|
+
for (const group of res.data) {
|
|
993
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
994
|
+
expect(group.items, `group(${group.key}).items`).to.be.null;
|
|
995
|
+
expect(group.count, `group(${group.key}).count`).to.eql(10);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
);
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
test('list should group without items, with complex filter', function (tdone) {
|
|
1002
|
+
testQueryValues(
|
|
1003
|
+
tdone,
|
|
1004
|
+
{
|
|
1005
|
+
filter: [
|
|
1006
|
+
['int1', '=', 3],
|
|
1007
|
+
'or',
|
|
1008
|
+
['int1', '=', 5],
|
|
1009
|
+
'or',
|
|
1010
|
+
['int1', '=', 7],
|
|
1011
|
+
],
|
|
1012
|
+
group: [
|
|
1013
|
+
{
|
|
1014
|
+
selector: 'int1',
|
|
1015
|
+
desc: false,
|
|
1016
|
+
// , isExpanded: false
|
|
1017
|
+
},
|
|
1018
|
+
],
|
|
1019
|
+
requireTotalCount: true,
|
|
1020
|
+
requireGroupCount: true,
|
|
1021
|
+
},
|
|
1022
|
+
function (res) {
|
|
1023
|
+
expect(res.totalCount, 'totalCount').to.eql(30);
|
|
1024
|
+
expect(res.groupCount, 'groupCount').to.eql(3);
|
|
1025
|
+
|
|
1026
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1027
|
+
expect(res.data, 'group list length').to.have.lengthOf(3);
|
|
1028
|
+
|
|
1029
|
+
for (const group of res.data) {
|
|
1030
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
1031
|
+
expect(group.items, `group(${group.key}).items`).to.be.null;
|
|
1032
|
+
expect(group.count, `group(${group.key}).count`).to.eql(10);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
);
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
test('list should group with items, with complex filter', function (tdone) {
|
|
1039
|
+
testQueryValues(
|
|
1040
|
+
tdone,
|
|
1041
|
+
{
|
|
1042
|
+
filter: [
|
|
1043
|
+
['int1', '=', 3],
|
|
1044
|
+
'or',
|
|
1045
|
+
['int1', '=', 5],
|
|
1046
|
+
'or',
|
|
1047
|
+
['int1', '=', 7],
|
|
1048
|
+
],
|
|
1049
|
+
group: [
|
|
1050
|
+
{
|
|
1051
|
+
selector: 'int1',
|
|
1052
|
+
desc: false,
|
|
1053
|
+
isExpanded: true,
|
|
1054
|
+
},
|
|
1055
|
+
],
|
|
1056
|
+
requireTotalCount: true,
|
|
1057
|
+
requireGroupCount: true,
|
|
1058
|
+
},
|
|
1059
|
+
function (res) {
|
|
1060
|
+
expect(res.totalCount, 'totalCount').to.eql(30);
|
|
1061
|
+
expect(res.groupCount, 'groupCount').to.eql(3);
|
|
1062
|
+
|
|
1063
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1064
|
+
expect(res.data, 'group list length').to.have.lengthOf(3);
|
|
1065
|
+
|
|
1066
|
+
for (const group of res.data) {
|
|
1067
|
+
expect(group.key, 'group.key').to.not.be.undefined;
|
|
1068
|
+
expect(group.items, `group(${group.key}).items`).to.be.instanceof(
|
|
1069
|
+
Array
|
|
1070
|
+
);
|
|
1071
|
+
|
|
1072
|
+
expect(group.items, 'group items list').to.have.lengthOf(10);
|
|
1073
|
+
expect(group.count, `group(${group.key}).count`).to.eql(
|
|
1074
|
+
group.items.length
|
|
1075
|
+
);
|
|
1076
|
+
|
|
1077
|
+
for (const item of group.items) {
|
|
1078
|
+
expect(item.int1, 'item.int1').to.eql(group.key);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
);
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
test('list should group two levels with bottom-level items', function (tdone) {
|
|
1086
|
+
testQueryValues(
|
|
1087
|
+
tdone,
|
|
1088
|
+
{
|
|
1089
|
+
filter: [
|
|
1090
|
+
[['int1', '=', 3], 'or', ['int1', '=', 6]],
|
|
1091
|
+
'and',
|
|
1092
|
+
[['int2', '=', 3], 'or', ['int2', '=', 1]],
|
|
1093
|
+
],
|
|
1094
|
+
group: [
|
|
1095
|
+
{
|
|
1096
|
+
selector: 'int1',
|
|
1097
|
+
desc: false,
|
|
1098
|
+
isExpanded: false,
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
selector: 'int2',
|
|
1102
|
+
desc: false,
|
|
1103
|
+
isExpanded: true,
|
|
1104
|
+
},
|
|
1105
|
+
],
|
|
1106
|
+
requireTotalCount: true,
|
|
1107
|
+
requireGroupCount: true,
|
|
1108
|
+
},
|
|
1109
|
+
function (res) {
|
|
1110
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
1111
|
+
|
|
1112
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
1113
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
1114
|
+
|
|
1115
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1116
|
+
expect(res.data, 'group list length').to.have.lengthOf(2);
|
|
1117
|
+
|
|
1118
|
+
for (const group1 of res.data) {
|
|
1119
|
+
expect(group1.key, 'group1.key').to.not.be.undefined;
|
|
1120
|
+
expect(
|
|
1121
|
+
group1.items,
|
|
1122
|
+
`group1(${group1.key}).items`
|
|
1123
|
+
).to.be.instanceof(Array);
|
|
1124
|
+
|
|
1125
|
+
expect(group1.items, 'group1 items list').to.have.lengthOf(1);
|
|
1126
|
+
expect(group1.count, `group(${group1.key}).count`).to.eql(
|
|
1127
|
+
group1.items.length
|
|
1128
|
+
);
|
|
1129
|
+
|
|
1130
|
+
for (const group2 of group1.items) {
|
|
1131
|
+
expect(group2.key, 'group2.key').to.not.be.undefined;
|
|
1132
|
+
expect(
|
|
1133
|
+
group2.items,
|
|
1134
|
+
`group2(${group2.key}).items`
|
|
1135
|
+
).to.be.instanceof(Array);
|
|
1136
|
+
|
|
1137
|
+
expect(group2.items, 'group2 items list').to.have.lengthOf(10);
|
|
1138
|
+
expect(group2.count, `group(${group2.key}).count`).to.eql(
|
|
1139
|
+
group2.items.length
|
|
1140
|
+
);
|
|
1141
|
+
for (const item of group2.items) {
|
|
1142
|
+
expect(item.int1, 'item.int1').to.eql(group1.key);
|
|
1143
|
+
expect(item.int2, 'item.int2').to.eql(group2.key);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
);
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
test('list should group two levels without bottom-level items', function (tdone) {
|
|
1152
|
+
testQueryValues(
|
|
1153
|
+
tdone,
|
|
1154
|
+
{
|
|
1155
|
+
filter: [
|
|
1156
|
+
[['int1', '=', 3], 'or', ['int1', '=', 6]],
|
|
1157
|
+
'and',
|
|
1158
|
+
[['int2', '=', 3], 'or', ['int2', '=', 1]],
|
|
1159
|
+
],
|
|
1160
|
+
group: [
|
|
1161
|
+
{
|
|
1162
|
+
selector: 'int1',
|
|
1163
|
+
desc: false,
|
|
1164
|
+
isExpanded: false,
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
selector: 'int2',
|
|
1168
|
+
desc: false,
|
|
1169
|
+
isExpanded: false,
|
|
1170
|
+
},
|
|
1171
|
+
],
|
|
1172
|
+
requireTotalCount: true,
|
|
1173
|
+
requireGroupCount: true,
|
|
1174
|
+
},
|
|
1175
|
+
function (res) {
|
|
1176
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
1177
|
+
|
|
1178
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
1179
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
1180
|
+
|
|
1181
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1182
|
+
expect(res.data, 'group list length').to.have.lengthOf(2);
|
|
1183
|
+
|
|
1184
|
+
for (const group1 of res.data) {
|
|
1185
|
+
expect(group1.key, 'group1.key').to.not.be.undefined;
|
|
1186
|
+
expect(
|
|
1187
|
+
group1.items,
|
|
1188
|
+
`group1(${group1.key}).items`
|
|
1189
|
+
).to.be.instanceof(Array);
|
|
1190
|
+
|
|
1191
|
+
expect(group1.items, 'group1 items list').to.have.lengthOf(1);
|
|
1192
|
+
expect(group1.count, `group(${group1.key}).count`).to.eql(
|
|
1193
|
+
group1.items.length
|
|
1194
|
+
);
|
|
1195
|
+
|
|
1196
|
+
for (const group2 of group1.items) {
|
|
1197
|
+
expect(group2.key, 'group2.key').to.not.be.undefined;
|
|
1198
|
+
expect(group2.items, 'group2 items list').to.be.null;
|
|
1199
|
+
expect(group2.count, `group(${group2.key}).count`).to.eql(10);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
test('list should group three levels without items', function (tdone) {
|
|
1207
|
+
testQueryValues(
|
|
1208
|
+
tdone,
|
|
1209
|
+
{
|
|
1210
|
+
group: [
|
|
1211
|
+
{
|
|
1212
|
+
selector: 'int1',
|
|
1213
|
+
isExpanded: false,
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
selector: 'int2',
|
|
1217
|
+
isExpanded: false,
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
selector: 'string',
|
|
1221
|
+
isExpanded: false,
|
|
1222
|
+
},
|
|
1223
|
+
],
|
|
1224
|
+
requireTotalCount: true,
|
|
1225
|
+
requireGroupCount: true,
|
|
1226
|
+
},
|
|
1227
|
+
function (res) {
|
|
1228
|
+
//console.log('Result is ', JSON.stringify(res, null, 2));
|
|
1229
|
+
expect(res).to.deep.eql({
|
|
1230
|
+
data: [
|
|
1231
|
+
{
|
|
1232
|
+
key: 0,
|
|
1233
|
+
items: [
|
|
1234
|
+
{
|
|
1235
|
+
key: 0,
|
|
1236
|
+
items: [
|
|
1237
|
+
{
|
|
1238
|
+
count: 1,
|
|
1239
|
+
key: 'Item 0',
|
|
1240
|
+
items: null,
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
count: 1,
|
|
1244
|
+
key: 'Item 10',
|
|
1245
|
+
items: null,
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
count: 1,
|
|
1249
|
+
key: 'Item 20',
|
|
1250
|
+
items: null,
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
count: 1,
|
|
1254
|
+
key: 'Item 30',
|
|
1255
|
+
items: null,
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
count: 1,
|
|
1259
|
+
key: 'Item 40',
|
|
1260
|
+
items: null,
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
count: 1,
|
|
1264
|
+
key: 'Item 50',
|
|
1265
|
+
items: null,
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
count: 1,
|
|
1269
|
+
key: 'Item 60',
|
|
1270
|
+
items: null,
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
count: 1,
|
|
1274
|
+
key: 'Item 70',
|
|
1275
|
+
items: null,
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
count: 1,
|
|
1279
|
+
key: 'Item 80',
|
|
1280
|
+
items: null,
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
count: 1,
|
|
1284
|
+
key: 'Item 90',
|
|
1285
|
+
items: null,
|
|
1286
|
+
},
|
|
1287
|
+
],
|
|
1288
|
+
count: 10,
|
|
1289
|
+
},
|
|
1290
|
+
],
|
|
1291
|
+
count: 1,
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
key: 1,
|
|
1295
|
+
items: [
|
|
1296
|
+
{
|
|
1297
|
+
key: 1,
|
|
1298
|
+
items: [
|
|
1299
|
+
{
|
|
1300
|
+
count: 1,
|
|
1301
|
+
key: 'Item 1',
|
|
1302
|
+
items: null,
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
count: 1,
|
|
1306
|
+
key: 'Item 11',
|
|
1307
|
+
items: null,
|
|
1308
|
+
},
|
|
1309
|
+
{
|
|
1310
|
+
count: 1,
|
|
1311
|
+
key: 'Item 21',
|
|
1312
|
+
items: null,
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
count: 1,
|
|
1316
|
+
key: 'Item 31',
|
|
1317
|
+
items: null,
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
count: 1,
|
|
1321
|
+
key: 'Item 41',
|
|
1322
|
+
items: null,
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
count: 1,
|
|
1326
|
+
key: 'Item 51',
|
|
1327
|
+
items: null,
|
|
1328
|
+
},
|
|
1329
|
+
{
|
|
1330
|
+
count: 1,
|
|
1331
|
+
key: 'Item 61',
|
|
1332
|
+
items: null,
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
count: 1,
|
|
1336
|
+
key: 'Item 71',
|
|
1337
|
+
items: null,
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
count: 1,
|
|
1341
|
+
key: 'Item 81',
|
|
1342
|
+
items: null,
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
count: 1,
|
|
1346
|
+
key: 'Item 91',
|
|
1347
|
+
items: null,
|
|
1348
|
+
},
|
|
1349
|
+
],
|
|
1350
|
+
count: 10,
|
|
1351
|
+
},
|
|
1352
|
+
],
|
|
1353
|
+
count: 1,
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
key: 2,
|
|
1357
|
+
items: [
|
|
1358
|
+
{
|
|
1359
|
+
key: 2,
|
|
1360
|
+
items: [
|
|
1361
|
+
{
|
|
1362
|
+
count: 1,
|
|
1363
|
+
key: 'Item 12',
|
|
1364
|
+
items: null,
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
count: 1,
|
|
1368
|
+
key: 'Item 2',
|
|
1369
|
+
items: null,
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
count: 1,
|
|
1373
|
+
key: 'Item 22',
|
|
1374
|
+
items: null,
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
count: 1,
|
|
1378
|
+
key: 'Item 32',
|
|
1379
|
+
items: null,
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
count: 1,
|
|
1383
|
+
key: 'Item 42',
|
|
1384
|
+
items: null,
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
count: 1,
|
|
1388
|
+
key: 'Item 52',
|
|
1389
|
+
items: null,
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
count: 1,
|
|
1393
|
+
key: 'Item 62',
|
|
1394
|
+
items: null,
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
count: 1,
|
|
1398
|
+
key: 'Item 72',
|
|
1399
|
+
items: null,
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
count: 1,
|
|
1403
|
+
key: 'Item 82',
|
|
1404
|
+
items: null,
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
count: 1,
|
|
1408
|
+
key: 'Item 92',
|
|
1409
|
+
items: null,
|
|
1410
|
+
},
|
|
1411
|
+
],
|
|
1412
|
+
count: 10,
|
|
1413
|
+
},
|
|
1414
|
+
],
|
|
1415
|
+
count: 1,
|
|
1416
|
+
},
|
|
1417
|
+
{
|
|
1418
|
+
key: 3,
|
|
1419
|
+
items: [
|
|
1420
|
+
{
|
|
1421
|
+
key: 3,
|
|
1422
|
+
items: [
|
|
1423
|
+
{
|
|
1424
|
+
count: 1,
|
|
1425
|
+
key: 'Item 13',
|
|
1426
|
+
items: null,
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
count: 1,
|
|
1430
|
+
key: 'Item 23',
|
|
1431
|
+
items: null,
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
count: 1,
|
|
1435
|
+
key: 'Item 3',
|
|
1436
|
+
items: null,
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
count: 1,
|
|
1440
|
+
key: 'Item 33',
|
|
1441
|
+
items: null,
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
count: 1,
|
|
1445
|
+
key: 'Item 43',
|
|
1446
|
+
items: null,
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
count: 1,
|
|
1450
|
+
key: 'Item 53',
|
|
1451
|
+
items: null,
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
count: 1,
|
|
1455
|
+
key: 'Item 63',
|
|
1456
|
+
items: null,
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
count: 1,
|
|
1460
|
+
key: 'Item 73',
|
|
1461
|
+
items: null,
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
count: 1,
|
|
1465
|
+
key: 'Item 83',
|
|
1466
|
+
items: null,
|
|
1467
|
+
},
|
|
1468
|
+
{
|
|
1469
|
+
count: 1,
|
|
1470
|
+
key: 'Item 93',
|
|
1471
|
+
items: null,
|
|
1472
|
+
},
|
|
1473
|
+
],
|
|
1474
|
+
count: 10,
|
|
1475
|
+
},
|
|
1476
|
+
],
|
|
1477
|
+
count: 1,
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
key: 4,
|
|
1481
|
+
items: [
|
|
1482
|
+
{
|
|
1483
|
+
key: 4,
|
|
1484
|
+
items: [
|
|
1485
|
+
{
|
|
1486
|
+
count: 1,
|
|
1487
|
+
key: 'Item 14',
|
|
1488
|
+
items: null,
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
count: 1,
|
|
1492
|
+
key: 'Item 24',
|
|
1493
|
+
items: null,
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
count: 1,
|
|
1497
|
+
key: 'Item 34',
|
|
1498
|
+
items: null,
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
count: 1,
|
|
1502
|
+
key: 'Item 4',
|
|
1503
|
+
items: null,
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
count: 1,
|
|
1507
|
+
key: 'Item 44',
|
|
1508
|
+
items: null,
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
count: 1,
|
|
1512
|
+
key: 'Item 54',
|
|
1513
|
+
items: null,
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
count: 1,
|
|
1517
|
+
key: 'Item 64',
|
|
1518
|
+
items: null,
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
count: 1,
|
|
1522
|
+
key: 'Item 74',
|
|
1523
|
+
items: null,
|
|
1524
|
+
},
|
|
1525
|
+
{
|
|
1526
|
+
count: 1,
|
|
1527
|
+
key: 'Item 84',
|
|
1528
|
+
items: null,
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
count: 1,
|
|
1532
|
+
key: 'Item 94',
|
|
1533
|
+
items: null,
|
|
1534
|
+
},
|
|
1535
|
+
],
|
|
1536
|
+
count: 10,
|
|
1537
|
+
},
|
|
1538
|
+
],
|
|
1539
|
+
count: 1,
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
key: 5,
|
|
1543
|
+
items: [
|
|
1544
|
+
{
|
|
1545
|
+
key: 0,
|
|
1546
|
+
items: [
|
|
1547
|
+
{
|
|
1548
|
+
count: 1,
|
|
1549
|
+
key: 'Item 15',
|
|
1550
|
+
items: null,
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
count: 1,
|
|
1554
|
+
key: 'Item 25',
|
|
1555
|
+
items: null,
|
|
1556
|
+
},
|
|
1557
|
+
{
|
|
1558
|
+
count: 1,
|
|
1559
|
+
key: 'Item 35',
|
|
1560
|
+
items: null,
|
|
1561
|
+
},
|
|
1562
|
+
{
|
|
1563
|
+
count: 1,
|
|
1564
|
+
key: 'Item 45',
|
|
1565
|
+
items: null,
|
|
1566
|
+
},
|
|
1567
|
+
{
|
|
1568
|
+
count: 1,
|
|
1569
|
+
key: 'Item 5',
|
|
1570
|
+
items: null,
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
count: 1,
|
|
1574
|
+
key: 'Item 55',
|
|
1575
|
+
items: null,
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
count: 1,
|
|
1579
|
+
key: 'Item 65',
|
|
1580
|
+
items: null,
|
|
1581
|
+
},
|
|
1582
|
+
{
|
|
1583
|
+
count: 1,
|
|
1584
|
+
key: 'Item 75',
|
|
1585
|
+
items: null,
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
count: 1,
|
|
1589
|
+
key: 'Item 85',
|
|
1590
|
+
items: null,
|
|
1591
|
+
},
|
|
1592
|
+
{
|
|
1593
|
+
count: 1,
|
|
1594
|
+
key: 'Item 95',
|
|
1595
|
+
items: null,
|
|
1596
|
+
},
|
|
1597
|
+
],
|
|
1598
|
+
count: 10,
|
|
1599
|
+
},
|
|
1600
|
+
],
|
|
1601
|
+
count: 1,
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
key: 6,
|
|
1605
|
+
items: [
|
|
1606
|
+
{
|
|
1607
|
+
key: 1,
|
|
1608
|
+
items: [
|
|
1609
|
+
{
|
|
1610
|
+
count: 1,
|
|
1611
|
+
key: 'Item 16',
|
|
1612
|
+
items: null,
|
|
1613
|
+
},
|
|
1614
|
+
{
|
|
1615
|
+
count: 1,
|
|
1616
|
+
key: 'Item 26',
|
|
1617
|
+
items: null,
|
|
1618
|
+
},
|
|
1619
|
+
{
|
|
1620
|
+
count: 1,
|
|
1621
|
+
key: 'Item 36',
|
|
1622
|
+
items: null,
|
|
1623
|
+
},
|
|
1624
|
+
{
|
|
1625
|
+
count: 1,
|
|
1626
|
+
key: 'Item 46',
|
|
1627
|
+
items: null,
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
count: 1,
|
|
1631
|
+
key: 'Item 56',
|
|
1632
|
+
items: null,
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
count: 1,
|
|
1636
|
+
key: 'Item 6',
|
|
1637
|
+
items: null,
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
count: 1,
|
|
1641
|
+
key: 'Item 66',
|
|
1642
|
+
items: null,
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
count: 1,
|
|
1646
|
+
key: 'Item 76',
|
|
1647
|
+
items: null,
|
|
1648
|
+
},
|
|
1649
|
+
{
|
|
1650
|
+
count: 1,
|
|
1651
|
+
key: 'Item 86',
|
|
1652
|
+
items: null,
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
count: 1,
|
|
1656
|
+
key: 'Item 96',
|
|
1657
|
+
items: null,
|
|
1658
|
+
},
|
|
1659
|
+
],
|
|
1660
|
+
count: 10,
|
|
1661
|
+
},
|
|
1662
|
+
],
|
|
1663
|
+
count: 1,
|
|
1664
|
+
},
|
|
1665
|
+
{
|
|
1666
|
+
key: 7,
|
|
1667
|
+
items: [
|
|
1668
|
+
{
|
|
1669
|
+
key: 2,
|
|
1670
|
+
items: [
|
|
1671
|
+
{
|
|
1672
|
+
count: 1,
|
|
1673
|
+
key: 'Item 17',
|
|
1674
|
+
items: null,
|
|
1675
|
+
},
|
|
1676
|
+
{
|
|
1677
|
+
count: 1,
|
|
1678
|
+
key: 'Item 27',
|
|
1679
|
+
items: null,
|
|
1680
|
+
},
|
|
1681
|
+
{
|
|
1682
|
+
count: 1,
|
|
1683
|
+
key: 'Item 37',
|
|
1684
|
+
items: null,
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
count: 1,
|
|
1688
|
+
key: 'Item 47',
|
|
1689
|
+
items: null,
|
|
1690
|
+
},
|
|
1691
|
+
{
|
|
1692
|
+
count: 1,
|
|
1693
|
+
key: 'Item 57',
|
|
1694
|
+
items: null,
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
count: 1,
|
|
1698
|
+
key: 'Item 67',
|
|
1699
|
+
items: null,
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
count: 1,
|
|
1703
|
+
key: 'Item 7',
|
|
1704
|
+
items: null,
|
|
1705
|
+
},
|
|
1706
|
+
{
|
|
1707
|
+
count: 1,
|
|
1708
|
+
key: 'Item 77',
|
|
1709
|
+
items: null,
|
|
1710
|
+
},
|
|
1711
|
+
{
|
|
1712
|
+
count: 1,
|
|
1713
|
+
key: 'Item 87',
|
|
1714
|
+
items: null,
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
count: 1,
|
|
1718
|
+
key: 'Item 97',
|
|
1719
|
+
items: null,
|
|
1720
|
+
},
|
|
1721
|
+
],
|
|
1722
|
+
count: 10,
|
|
1723
|
+
},
|
|
1724
|
+
],
|
|
1725
|
+
count: 1,
|
|
1726
|
+
},
|
|
1727
|
+
{
|
|
1728
|
+
key: 8,
|
|
1729
|
+
items: [
|
|
1730
|
+
{
|
|
1731
|
+
key: 3,
|
|
1732
|
+
items: [
|
|
1733
|
+
{
|
|
1734
|
+
count: 1,
|
|
1735
|
+
key: 'Item 18',
|
|
1736
|
+
items: null,
|
|
1737
|
+
},
|
|
1738
|
+
{
|
|
1739
|
+
count: 1,
|
|
1740
|
+
key: 'Item 28',
|
|
1741
|
+
items: null,
|
|
1742
|
+
},
|
|
1743
|
+
{
|
|
1744
|
+
count: 1,
|
|
1745
|
+
key: 'Item 38',
|
|
1746
|
+
items: null,
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
count: 1,
|
|
1750
|
+
key: 'Item 48',
|
|
1751
|
+
items: null,
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
count: 1,
|
|
1755
|
+
key: 'Item 58',
|
|
1756
|
+
items: null,
|
|
1757
|
+
},
|
|
1758
|
+
{
|
|
1759
|
+
count: 1,
|
|
1760
|
+
key: 'Item 68',
|
|
1761
|
+
items: null,
|
|
1762
|
+
},
|
|
1763
|
+
{
|
|
1764
|
+
count: 1,
|
|
1765
|
+
key: 'Item 78',
|
|
1766
|
+
items: null,
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
count: 1,
|
|
1770
|
+
key: 'Item 8',
|
|
1771
|
+
items: null,
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
count: 1,
|
|
1775
|
+
key: 'Item 88',
|
|
1776
|
+
items: null,
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
count: 1,
|
|
1780
|
+
key: 'Item 98',
|
|
1781
|
+
items: null,
|
|
1782
|
+
},
|
|
1783
|
+
],
|
|
1784
|
+
count: 10,
|
|
1785
|
+
},
|
|
1786
|
+
],
|
|
1787
|
+
count: 1,
|
|
1788
|
+
},
|
|
1789
|
+
{
|
|
1790
|
+
key: 9,
|
|
1791
|
+
items: [
|
|
1792
|
+
{
|
|
1793
|
+
key: 4,
|
|
1794
|
+
items: [
|
|
1795
|
+
{
|
|
1796
|
+
count: 1,
|
|
1797
|
+
key: 'Item 19',
|
|
1798
|
+
items: null,
|
|
1799
|
+
},
|
|
1800
|
+
{
|
|
1801
|
+
count: 1,
|
|
1802
|
+
key: 'Item 29',
|
|
1803
|
+
items: null,
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
count: 1,
|
|
1807
|
+
key: 'Item 39',
|
|
1808
|
+
items: null,
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
count: 1,
|
|
1812
|
+
key: 'Item 49',
|
|
1813
|
+
items: null,
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
count: 1,
|
|
1817
|
+
key: 'Item 59',
|
|
1818
|
+
items: null,
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
count: 1,
|
|
1822
|
+
key: 'Item 69',
|
|
1823
|
+
items: null,
|
|
1824
|
+
},
|
|
1825
|
+
{
|
|
1826
|
+
count: 1,
|
|
1827
|
+
key: 'Item 79',
|
|
1828
|
+
items: null,
|
|
1829
|
+
},
|
|
1830
|
+
{
|
|
1831
|
+
count: 1,
|
|
1832
|
+
key: 'Item 89',
|
|
1833
|
+
items: null,
|
|
1834
|
+
},
|
|
1835
|
+
{
|
|
1836
|
+
count: 1,
|
|
1837
|
+
key: 'Item 9',
|
|
1838
|
+
items: null,
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
count: 1,
|
|
1842
|
+
key: 'Item 99',
|
|
1843
|
+
items: null,
|
|
1844
|
+
},
|
|
1845
|
+
],
|
|
1846
|
+
count: 10,
|
|
1847
|
+
},
|
|
1848
|
+
],
|
|
1849
|
+
count: 1,
|
|
1850
|
+
},
|
|
1851
|
+
],
|
|
1852
|
+
groupCount: 10,
|
|
1853
|
+
totalCount: 100,
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1856
|
+
);
|
|
1857
|
+
});
|
|
1858
|
+
|
|
1859
|
+
test('list should calculate total summaries group query', function (tdone) {
|
|
1860
|
+
testQueryValues(
|
|
1861
|
+
tdone,
|
|
1862
|
+
{
|
|
1863
|
+
filter: [
|
|
1864
|
+
[['int1', '=', 3], 'or', ['int1', '=', 6]],
|
|
1865
|
+
'and',
|
|
1866
|
+
[['int2', '=', 3], 'or', ['int2', '=', 1]],
|
|
1867
|
+
],
|
|
1868
|
+
group: [
|
|
1869
|
+
{
|
|
1870
|
+
selector: 'int1',
|
|
1871
|
+
desc: false,
|
|
1872
|
+
isExpanded: false,
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
selector: 'int2',
|
|
1876
|
+
desc: false,
|
|
1877
|
+
isExpanded: false,
|
|
1878
|
+
},
|
|
1879
|
+
],
|
|
1880
|
+
totalSummary: [
|
|
1881
|
+
{
|
|
1882
|
+
selector: 'int1',
|
|
1883
|
+
summaryType: 'sum',
|
|
1884
|
+
},
|
|
1885
|
+
{
|
|
1886
|
+
selector: 'int2',
|
|
1887
|
+
summaryType: 'max',
|
|
1888
|
+
},
|
|
1889
|
+
],
|
|
1890
|
+
requireTotalCount: true,
|
|
1891
|
+
requireGroupCount: true,
|
|
1892
|
+
},
|
|
1893
|
+
function (res) {
|
|
1894
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
1895
|
+
|
|
1896
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
1897
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
1898
|
+
|
|
1899
|
+
expect(res.summary, 'res.summary').to.be.instanceof(Array);
|
|
1900
|
+
expect(res.summary, 'res.summary').to.have.lengthOf(2);
|
|
1901
|
+
expect(res.summary[0], 'sum(int1)').to.eql(90);
|
|
1902
|
+
expect(res.summary[1], 'max(int2)').to.eql(3);
|
|
1903
|
+
}
|
|
1904
|
+
);
|
|
1905
|
+
});
|
|
1906
|
+
|
|
1907
|
+
test('list should calculate group summaries', function (tdone) {
|
|
1908
|
+
testQueryValues(
|
|
1909
|
+
tdone,
|
|
1910
|
+
{
|
|
1911
|
+
filter: [['int1', '=', 3], 'or', ['int1', '=', 6]],
|
|
1912
|
+
group: [
|
|
1913
|
+
{
|
|
1914
|
+
selector: 'int1',
|
|
1915
|
+
desc: false,
|
|
1916
|
+
isExpanded: false,
|
|
1917
|
+
},
|
|
1918
|
+
],
|
|
1919
|
+
groupSummary: [
|
|
1920
|
+
{
|
|
1921
|
+
selector: 'int1',
|
|
1922
|
+
summaryType: 'sum',
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
selector: 'int2',
|
|
1926
|
+
summaryType: 'max',
|
|
1927
|
+
},
|
|
1928
|
+
],
|
|
1929
|
+
requireTotalCount: true,
|
|
1930
|
+
requireGroupCount: true,
|
|
1931
|
+
},
|
|
1932
|
+
function (res) {
|
|
1933
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
1934
|
+
|
|
1935
|
+
expect(res.totalCount, 'totalCount').to.eql(20);
|
|
1936
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
1937
|
+
|
|
1938
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1939
|
+
expect(res.data, 'group list length').to.have.lengthOf(2);
|
|
1940
|
+
|
|
1941
|
+
expect(res.data[0].summary, 'group1.summary').to.be.instanceof(Array);
|
|
1942
|
+
expect(res.data[0].summary, 'group1.summary').to.have.lengthOf(2);
|
|
1943
|
+
expect(res.data[0].summary[0], 'group1.sum(int1)').to.eql(30);
|
|
1944
|
+
expect(res.data[0].summary[1], 'group1.max(int2)').to.eql(3);
|
|
1945
|
+
|
|
1946
|
+
expect(res.data[1].summary, 'group2.summary').to.be.instanceof(Array);
|
|
1947
|
+
expect(res.data[1].summary, 'group2.summary').to.have.lengthOf(2);
|
|
1948
|
+
expect(res.data[1].summary[0], 'group2.sum(int1)').to.eql(60);
|
|
1949
|
+
expect(res.data[1].summary[1], 'group2.max(int2)').to.eql(1);
|
|
1950
|
+
}
|
|
1951
|
+
);
|
|
1952
|
+
});
|
|
1953
|
+
|
|
1954
|
+
test('list should group with groupInterval quarter', function (tdone) {
|
|
1955
|
+
testQueryValues(
|
|
1956
|
+
tdone,
|
|
1957
|
+
{
|
|
1958
|
+
group: [
|
|
1959
|
+
{
|
|
1960
|
+
selector: 'date1',
|
|
1961
|
+
groupInterval: 'quarter',
|
|
1962
|
+
},
|
|
1963
|
+
],
|
|
1964
|
+
requireTotalCount: true,
|
|
1965
|
+
requireGroupCount: true,
|
|
1966
|
+
},
|
|
1967
|
+
function (res) {
|
|
1968
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
1969
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
1970
|
+
|
|
1971
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
1972
|
+
expect(res.data, 'group list length').to.have.lengthOf(2);
|
|
1973
|
+
|
|
1974
|
+
expect(res.data[0].key, 'group 1.key').to.not.be.undefined;
|
|
1975
|
+
expect(res.data[0].items, `group 1.items`).to.be.null;
|
|
1976
|
+
expect(res.data[0].count, `group 1.count`).to.eql(90);
|
|
1977
|
+
expect(res.data[1].key, 'group 2.key').to.not.be.undefined;
|
|
1978
|
+
expect(res.data[1].items, `group 2.items`).to.be.null;
|
|
1979
|
+
expect(res.data[1].count, `group 2.count`).to.eql(10);
|
|
1980
|
+
}
|
|
1981
|
+
);
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
test('list should group with groupInterval month', function (tdone) {
|
|
1985
|
+
testQueryValues(
|
|
1986
|
+
tdone,
|
|
1987
|
+
{
|
|
1988
|
+
group: [
|
|
1989
|
+
{
|
|
1990
|
+
selector: 'date1',
|
|
1991
|
+
groupInterval: 'month',
|
|
1992
|
+
},
|
|
1993
|
+
],
|
|
1994
|
+
requireTotalCount: true,
|
|
1995
|
+
requireGroupCount: true,
|
|
1996
|
+
},
|
|
1997
|
+
function (res) {
|
|
1998
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
1999
|
+
expect(res.groupCount, 'groupCount').to.eql(4);
|
|
2000
|
+
|
|
2001
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
2002
|
+
expect(res.data, 'group list length').to.have.lengthOf(4);
|
|
2003
|
+
|
|
2004
|
+
expect(res.data[0].key, 'group 1.key').to.eql(1);
|
|
2005
|
+
expect(res.data[0].items, `group 1.items`).to.be.null;
|
|
2006
|
+
expect(res.data[0].count, `group 1.count`).to.eql(31);
|
|
2007
|
+
expect(res.data[1].key, 'group 2.key').to.eql(2);
|
|
2008
|
+
expect(res.data[1].items, `group 2.items`).to.be.null;
|
|
2009
|
+
expect(res.data[1].count, `group 2.count`).to.eql(28);
|
|
2010
|
+
expect(res.data[2].key, 'group 3.key').to.eql(3);
|
|
2011
|
+
expect(res.data[2].items, `group 3.items`).to.be.null;
|
|
2012
|
+
expect(res.data[2].count, `group 3.count`).to.eql(31);
|
|
2013
|
+
expect(res.data[3].key, 'group 4.key').to.eql(4);
|
|
2014
|
+
expect(res.data[3].items, `group 4.items`).to.be.null;
|
|
2015
|
+
expect(res.data[3].count, `group 4.count`).to.eql(10);
|
|
2016
|
+
}
|
|
2017
|
+
);
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
test('list should group with groupInterval dayOfWeek', function (tdone) {
|
|
2021
|
+
testQueryValues(
|
|
2022
|
+
tdone,
|
|
2023
|
+
{
|
|
2024
|
+
group: [
|
|
2025
|
+
{
|
|
2026
|
+
selector: 'date1',
|
|
2027
|
+
groupInterval: 'dayOfWeek',
|
|
2028
|
+
},
|
|
2029
|
+
],
|
|
2030
|
+
requireTotalCount: true,
|
|
2031
|
+
requireGroupCount: true,
|
|
2032
|
+
},
|
|
2033
|
+
function (res) {
|
|
2034
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
2035
|
+
expect(res.groupCount, 'groupCount').to.eql(7);
|
|
2036
|
+
|
|
2037
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
2038
|
+
expect(res.data, 'group list length').to.have.lengthOf(7);
|
|
2039
|
+
}
|
|
2040
|
+
);
|
|
2041
|
+
});
|
|
2042
|
+
|
|
2043
|
+
test('list should group with groupInterval 2', function (tdone) {
|
|
2044
|
+
testQueryValues(
|
|
2045
|
+
tdone,
|
|
2046
|
+
{
|
|
2047
|
+
group: [
|
|
2048
|
+
{
|
|
2049
|
+
selector: 'int1',
|
|
2050
|
+
groupInterval: 2,
|
|
2051
|
+
},
|
|
2052
|
+
],
|
|
2053
|
+
requireTotalCount: true,
|
|
2054
|
+
requireGroupCount: true,
|
|
2055
|
+
},
|
|
2056
|
+
function (res) {
|
|
2057
|
+
//console.log("Result is ", JSON.stringify(res, null, 2));
|
|
2058
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
2059
|
+
expect(res.groupCount, 'groupCount').to.eql(5);
|
|
2060
|
+
|
|
2061
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
2062
|
+
expect(res.data, 'group list length').to.have.lengthOf(5);
|
|
2063
|
+
|
|
2064
|
+
expect(res.data[0].key, 'group 1 key').to.eql(0);
|
|
2065
|
+
expect(res.data[0].count, 'group 1 count').to.eql(20);
|
|
2066
|
+
expect(res.data[1].key, 'group 2 key').to.eql(2);
|
|
2067
|
+
expect(res.data[1].count, 'group 2 count').to.eql(20);
|
|
2068
|
+
expect(res.data[2].key, 'group 3 key').to.eql(4);
|
|
2069
|
+
expect(res.data[2].count, 'group 3 count').to.eql(20);
|
|
2070
|
+
expect(res.data[3].key, 'group 4 key').to.eql(6);
|
|
2071
|
+
expect(res.data[3].count, 'group 4 count').to.eql(20);
|
|
2072
|
+
expect(res.data[4].key, 'group 5 key').to.eql(8);
|
|
2073
|
+
expect(res.data[4].count, 'group 5 count').to.eql(20);
|
|
2074
|
+
}
|
|
2075
|
+
);
|
|
2076
|
+
});
|
|
2077
|
+
|
|
2078
|
+
test('list should group with groupInterval quarter and summaries', function (tdone) {
|
|
2079
|
+
testQueryValues(
|
|
2080
|
+
tdone,
|
|
2081
|
+
{
|
|
2082
|
+
group: [
|
|
2083
|
+
{
|
|
2084
|
+
selector: 'date1',
|
|
2085
|
+
groupInterval: 'quarter',
|
|
2086
|
+
},
|
|
2087
|
+
],
|
|
2088
|
+
groupSummary: [
|
|
2089
|
+
{
|
|
2090
|
+
selector: 'int1',
|
|
2091
|
+
summaryType: 'count',
|
|
2092
|
+
},
|
|
2093
|
+
],
|
|
2094
|
+
totalSummary: [
|
|
2095
|
+
{
|
|
2096
|
+
selector: 'int1',
|
|
2097
|
+
summaryType: 'count',
|
|
2098
|
+
},
|
|
2099
|
+
],
|
|
2100
|
+
requireTotalCount: true,
|
|
2101
|
+
requireGroupCount: true,
|
|
2102
|
+
},
|
|
2103
|
+
function (res) {
|
|
2104
|
+
expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
|
|
2105
|
+
expect(res.groupCount, 'groupCount').to.eql(2);
|
|
2106
|
+
|
|
2107
|
+
expect(res.data, 'res.data').to.be.instanceof(Array);
|
|
2108
|
+
expect(res.data, 'group list length').to.have.lengthOf(2);
|
|
2109
|
+
|
|
2110
|
+
expect(res.summary, 'res.summary').to.be.instanceof(Array);
|
|
2111
|
+
expect(res.summary, 'res.summary length').to.have.lengthOf(1);
|
|
2112
|
+
|
|
2113
|
+
expect(res.data[0].key, 'group 1.key').to.not.be.undefined;
|
|
2114
|
+
expect(res.data[0].items, `group 1.items`).to.be.null;
|
|
2115
|
+
expect(res.data[0].count, `group 1.count`).to.eql(90);
|
|
2116
|
+
expect(res.data[0].summary, 'group 1 summary').to.be.instanceof(
|
|
2117
|
+
Array
|
|
2118
|
+
);
|
|
2119
|
+
expect(
|
|
2120
|
+
res.data[0].summary,
|
|
2121
|
+
'group 1 summary length'
|
|
2122
|
+
).to.have.lengthOf(1);
|
|
2123
|
+
|
|
2124
|
+
expect(res.data[1].key, 'group 2.key').to.not.be.undefined;
|
|
2125
|
+
expect(res.data[1].items, `group 2.items`).to.be.null;
|
|
2126
|
+
expect(res.data[1].count, `group 2.count`).to.eql(10);
|
|
2127
|
+
expect(res.data[1].summary, 'group 2 summary').to.be.instanceof(
|
|
2128
|
+
Array
|
|
2129
|
+
);
|
|
2130
|
+
expect(
|
|
2131
|
+
res.data[1].summary,
|
|
2132
|
+
'group 2 summary length'
|
|
2133
|
+
).to.have.lengthOf(1);
|
|
2134
|
+
}
|
|
2135
|
+
);
|
|
2136
|
+
});
|
|
2137
|
+
|
|
2138
|
+
// The following two tests are meant to test the timezoneOffset correction.
|
|
2139
|
+
// However, since the mechanism depends on the server to use the correct
|
|
2140
|
+
// time, it's hard to remote-control this so that the tests don't fail
|
|
2141
|
+
// on occasion. I'm commenting them - as far as I'm aware, the mechanism
|
|
2142
|
+
// works correctly in reality and I'll debug if necessary.
|
|
2143
|
+
|
|
2144
|
+
// test('month and dow should work correctly for May 1st 2017', function (tdone) {
|
|
2145
|
+
// // mongodb aggregation operators that extract Date details work on
|
|
2146
|
+
// // UTC only - so they need to have a timezone offset to work with
|
|
2147
|
+
// // in order to deliver the correct results if the local timezone
|
|
2148
|
+
// // is not UTC.
|
|
2149
|
+
// // The test is only meaningful if there's a difference between local timezone
|
|
2150
|
+
// // and UTC. Unfortunately mongodb seems to use the server time to handle
|
|
2151
|
+
// // its persistence, so mocking a timezone from JS doesn't make any
|
|
2152
|
+
// // difference.
|
|
2153
|
+
|
|
2154
|
+
// // I have noticed that this test fails right now (2017-12-11) because the Docker
|
|
2155
|
+
// // image I run for Mongo doesn't seem to know what the correct time zone is...
|
|
2156
|
+
// // This wouldn't be an issue in real life since we can assume that server
|
|
2157
|
+
// // time zones and dst are going to change according to the real world, but it
|
|
2158
|
+
// // does make it clear that it's not easy passing the "correct" timezoneOffset
|
|
2159
|
+
// // from the client.
|
|
2160
|
+
|
|
2161
|
+
// testQueryValues(
|
|
2162
|
+
// tdone,
|
|
2163
|
+
// {
|
|
2164
|
+
// filter: [['date1.Month', '=', 5], 'and', ['date1.DayOfWeek', '=', 1]],
|
|
2165
|
+
// requireTotalCount: true,
|
|
2166
|
+
// },
|
|
2167
|
+
// function (res) {
|
|
2168
|
+
// //console.log('Result is ', JSON.stringify(res, null, 2));
|
|
2169
|
+
// expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2170
|
+
// expect(res.data).to.have.lengthOf(1);
|
|
2171
|
+
// },
|
|
2172
|
+
// function (collection) {
|
|
2173
|
+
// return [
|
|
2174
|
+
// collection.insertOne({
|
|
2175
|
+
// // forgive JavaScript - this is the 1st of May
|
|
2176
|
+
// date1: new Date(2017, 4, 1),
|
|
2177
|
+
// date2: new Date(2017, 4, 1),
|
|
2178
|
+
// int1: 10,
|
|
2179
|
+
// int2: 10,
|
|
2180
|
+
// string: 'something',
|
|
2181
|
+
// }),
|
|
2182
|
+
// ];
|
|
2183
|
+
// },
|
|
2184
|
+
// {
|
|
2185
|
+
// timezoneOffset: new Date().getTimezoneOffset(),
|
|
2186
|
+
// }
|
|
2187
|
+
// );
|
|
2188
|
+
// });
|
|
2189
|
+
|
|
2190
|
+
// test('month grouping should work correctly for May 1st 2017', function (tdone) {
|
|
2191
|
+
// // mongodb aggregation operators that extract Date details work on
|
|
2192
|
+
// // UTC only - so they need to have a timezone offset to work with
|
|
2193
|
+
// // in order to deliver the correct results if the local timezone
|
|
2194
|
+
// // is not UTC.
|
|
2195
|
+
// // The test is only meaningful if there's a difference between local timezone
|
|
2196
|
+
// // and UTC. Unfortunately mongodb seems to use the server time to handle
|
|
2197
|
+
// // its persistence, so mocking a timezone from JS doesn't make any
|
|
2198
|
+
// // difference.
|
|
2199
|
+
|
|
2200
|
+
// // I have noticed that this test fails right now (2017-12-11) because the Docker
|
|
2201
|
+
// // image I run for Mongo doesn't seem to know what the correct time zone is...
|
|
2202
|
+
// // This wouldn't be an issue in real life since we can assume that server
|
|
2203
|
+
// // time zones and dst are going to change according to the real world, but it
|
|
2204
|
+
// // does make it clear that it's not easy passing the "correct" timezoneOffset
|
|
2205
|
+
// // from the client.
|
|
2206
|
+
|
|
2207
|
+
// testQueryValues(
|
|
2208
|
+
// tdone,
|
|
2209
|
+
// {
|
|
2210
|
+
// group: [
|
|
2211
|
+
// {
|
|
2212
|
+
// selector: 'date1',
|
|
2213
|
+
// groupInterval: 'month',
|
|
2214
|
+
// },
|
|
2215
|
+
// ],
|
|
2216
|
+
// requireGroupCount: true,
|
|
2217
|
+
// requireTotalCount: true,
|
|
2218
|
+
// },
|
|
2219
|
+
// function (res) {
|
|
2220
|
+
// //console.log('Result is ', JSON.stringify(res, null, 2));
|
|
2221
|
+
// expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2222
|
+
// expect(res.groupCount).to.eql(1);
|
|
2223
|
+
// expect(res.data).to.have.lengthOf(1);
|
|
2224
|
+
// expect(res.data[0].key).to.eql(5); // month May after mongo $month
|
|
2225
|
+
// },
|
|
2226
|
+
// function (collection) {
|
|
2227
|
+
// return [
|
|
2228
|
+
// collection.insertOne({
|
|
2229
|
+
// // forgive JavaScript - this is the 1st of May
|
|
2230
|
+
// date1: new Date(2017, 4, 1),
|
|
2231
|
+
// date2: new Date(2017, 4, 1),
|
|
2232
|
+
// int1: 10,
|
|
2233
|
+
// int2: 10,
|
|
2234
|
+
// string: 'something',
|
|
2235
|
+
// }),
|
|
2236
|
+
// ];
|
|
2237
|
+
// },
|
|
2238
|
+
// {
|
|
2239
|
+
// timezoneOffset: new Date().getTimezoneOffset(),
|
|
2240
|
+
// }
|
|
2241
|
+
// );
|
|
2242
|
+
// });
|
|
2243
|
+
|
|
2244
|
+
test('query should work correctly for May 1st 2017', function (tdone) {
|
|
2245
|
+
// see comment above - this test is meaningless if there's no difference
|
|
2246
|
+
// between local timezone and UTC. If there is a difference, the test
|
|
2247
|
+
// makes sure that data persistence and querying work together the way
|
|
2248
|
+
// they should, even if the mongodb level date is stored in UTC.
|
|
2249
|
+
// This is mainly for documentation purposes, it happens automatically.
|
|
2250
|
+
testQueryValues(
|
|
2251
|
+
tdone,
|
|
2252
|
+
{
|
|
2253
|
+
filter: ['date1', '=', new Date(2017, 4, 1)],
|
|
2254
|
+
requireTotalCount: true,
|
|
2255
|
+
},
|
|
2256
|
+
function (res) {
|
|
2257
|
+
//console.log('Result is ', JSON.stringify(res, null, 2));
|
|
2258
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2259
|
+
expect(res.data).to.have.lengthOf(1);
|
|
2260
|
+
|
|
2261
|
+
expect(new Date(res.data[0].date1)).to.eql(new Date(2017, 4, 1));
|
|
2262
|
+
},
|
|
2263
|
+
function (collection) {
|
|
2264
|
+
return [
|
|
2265
|
+
collection.insertOne({
|
|
2266
|
+
// forgive JavaScript - this is the 1st of May
|
|
2267
|
+
date1: new Date(2017, 4, 1),
|
|
2268
|
+
date2: new Date(2017, 4, 1),
|
|
2269
|
+
int1: 10,
|
|
2270
|
+
int2: 10,
|
|
2271
|
+
string: 'something',
|
|
2272
|
+
}),
|
|
2273
|
+
];
|
|
2274
|
+
}
|
|
2275
|
+
);
|
|
2276
|
+
});
|
|
2277
|
+
|
|
2278
|
+
test('equalsObjectId operator with ObjectId value', function (tdone) {
|
|
2279
|
+
// this query also works with the standard '=' operator
|
|
2280
|
+
const testId = new ObjectId('0123456789abcdef01234567');
|
|
2281
|
+
testQueryValues(
|
|
2282
|
+
tdone,
|
|
2283
|
+
{
|
|
2284
|
+
filter: ['idField', 'equalsObjectId', testId],
|
|
2285
|
+
requireTotalCount: true,
|
|
2286
|
+
},
|
|
2287
|
+
function (res) {
|
|
2288
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2289
|
+
},
|
|
2290
|
+
function (collection) {
|
|
2291
|
+
return [collection.insertOne({ idField: testId })];
|
|
2292
|
+
}
|
|
2293
|
+
);
|
|
2294
|
+
});
|
|
2295
|
+
|
|
2296
|
+
test('equalsObjectId operator with string value', function (tdone) {
|
|
2297
|
+
// this query works only with the equalsObjectId operator
|
|
2298
|
+
const testId = new ObjectId('0123456789abcdef01234567');
|
|
2299
|
+
testQueryValues(
|
|
2300
|
+
tdone,
|
|
2301
|
+
{
|
|
2302
|
+
filter: ['idField', 'equalsObjectId', testId.toString()],
|
|
2303
|
+
requireTotalCount: true,
|
|
2304
|
+
},
|
|
2305
|
+
function (res) {
|
|
2306
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2307
|
+
},
|
|
2308
|
+
function (collection) {
|
|
2309
|
+
return [collection.insertOne({ idField: testId })];
|
|
2310
|
+
}
|
|
2311
|
+
);
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2314
|
+
test('issue #40', function (tdone) {
|
|
2315
|
+
testQueryValues(
|
|
2316
|
+
tdone,
|
|
2317
|
+
{
|
|
2318
|
+
filter: [
|
|
2319
|
+
['date1', '>=', new Date(2017, 0, 15)],
|
|
2320
|
+
'and',
|
|
2321
|
+
['date1', '<', new Date(2017, 0, 16)],
|
|
2322
|
+
],
|
|
2323
|
+
requireTotalCount: true,
|
|
2324
|
+
},
|
|
2325
|
+
function (res) {
|
|
2326
|
+
expect(res.totalCount, 'totalCount').to.eql(1);
|
|
2327
|
+
expect(res.data).to.have.lengthOf(1);
|
|
2328
|
+
expect(new Date(res.data[0].date1)).to.eql(new Date(2017, 0, 15));
|
|
2329
|
+
}
|
|
2330
|
+
);
|
|
2331
|
+
});
|
|
2332
|
+
});
|
|
2333
|
+
});
|