@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.
@@ -0,0 +1,1941 @@
1
+ 'use strict';
2
+
3
+ var chai = require('chai');
4
+ var expect = chai.expect;
5
+
6
+ var _require = require('mongodb'),
7
+ MongoClient = _require.MongoClient,
8
+ ObjectId = _require.ObjectId;
9
+
10
+ var query = require('.');
11
+
12
+ var TESTRECORD_COUNT = 100;
13
+
14
+ var initClient = function initClient() {
15
+ return MongoClient.connect('mongodb://localhost:27017/dxtqutests', {
16
+ useNewUrlParser: true,
17
+ useUnifiedTopology: true
18
+ });
19
+ };
20
+
21
+ function testQueryValues(tdone, loadOptions, test, getTestDataPromises, contextOptions) {
22
+ function date(start, addDays) {
23
+ return new Date(start + addDays * (24 * 60 * 60 * 1000));
24
+ }
25
+
26
+ initClient().then(function (client) {
27
+ return client.db().dropDatabase().then(function () {
28
+ var values = client.db().collection('values');
29
+ var currentYear = 2017;
30
+ var currentYearStart = new Date(currentYear, 0, 1).valueOf();
31
+ var nextYearStart = new Date(currentYear + 1, 0, 1).valueOf();
32
+
33
+ return Promise.all(getTestDataPromises ? getTestDataPromises(values) : Array.from(new Array(TESTRECORD_COUNT), function (v, i) {
34
+ return i;
35
+ }).map(function (n) {
36
+ return values.insertOne({
37
+ date1: date(currentYearStart, n),
38
+ date2: date(nextYearStart, n),
39
+ int1: n % 10,
40
+ int2: n % 5,
41
+ string: 'Item ' + n
42
+ });
43
+ })).then(function () {
44
+ return query(values, loadOptions, contextOptions);
45
+ }).then(test);
46
+ }).then(function () {
47
+ return client.close();
48
+ }).then(tdone);
49
+ }).catch(function (err) {
50
+ return tdone(err);
51
+ });
52
+ }
53
+
54
+ suite('query-values', function () {
55
+ suite('#aggregateOptions', function () {
56
+ test('collation', function (tdone) {
57
+ testQueryValues(tdone, { sort: [{ selector: 'string' }], requireTotalCount: true }, function (res) {
58
+ expect(res.totalCount, 'totalCount').to.eql(2);
59
+
60
+ expect(res.data, 'res.data').to.be.instanceof(Array);
61
+ expect(res.data, 'list length').to.have.lengthOf(2);
62
+ expect(res.data[0].string).to.eql('something');
63
+ expect(res.data[1].string).to.eql('Something');
64
+ }, function (collection) {
65
+ return [collection.insertOne({
66
+ string: 'something'
67
+ }), collection.insertOne({
68
+ string: 'Something'
69
+ })];
70
+ }, {
71
+ aggregateOptions: {
72
+ collation: { locale: 'en', caseFirst: 'lower' }
73
+ }
74
+ });
75
+ });
76
+
77
+ test('collation dynamic', function (tdone) {
78
+ testQueryValues(tdone, { sort: [{ selector: 'string' }], requireTotalCount: true }, function (res) {
79
+ expect(res.totalCount, 'totalCount').to.eql(2);
80
+
81
+ expect(res.data, 'res.data').to.be.instanceof(Array);
82
+ expect(res.data, 'list length').to.have.lengthOf(2);
83
+ expect(res.data[0].string).to.eql('something');
84
+ expect(res.data[1].string).to.eql('Something');
85
+ }, function (collection) {
86
+ return [collection.insertOne({
87
+ string: 'something'
88
+ }), collection.insertOne({
89
+ string: 'Something'
90
+ })];
91
+ }, {
92
+ dynamicAggregateOptions: function dynamicAggregateOptions(identifier) {
93
+ return identifier === 'mainQueryResult' ? {
94
+ collation: { locale: 'en', caseFirst: 'lower' }
95
+ } : {};
96
+ }
97
+ });
98
+ });
99
+ });
100
+
101
+ suite('#entitiesQuery.values', function () {
102
+ test('list should retrieve all entities', function (tdone) {
103
+ testQueryValues(tdone, {
104
+ requireTotalCount: true
105
+ }, function (res) {
106
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
107
+
108
+ expect(res.data, 'res.data').to.be.instanceof(Array);
109
+ expect(res.data, 'result').to.have.lengthOf(TESTRECORD_COUNT);
110
+ });
111
+ });
112
+
113
+ test('list should accept skip', function (tdone) {
114
+ testQueryValues(tdone, {
115
+ skip: 5,
116
+ requireTotalCount: true
117
+ }, function (res) {
118
+ expect(res.totalCount).to.eql(TESTRECORD_COUNT);
119
+
120
+ expect(res.data, 'res.data').to.be.instanceof(Array);
121
+ expect(res.data, 'result').to.have.lengthOf(TESTRECORD_COUNT - 5);
122
+ });
123
+ });
124
+
125
+ test('list should accept take', function (tdone) {
126
+ testQueryValues(tdone, {
127
+ take: 5,
128
+ requireTotalCount: true
129
+ }, function (res) {
130
+ expect(res.totalCount).to.eql(TESTRECORD_COUNT);
131
+
132
+ expect(res.data, 'res.data').to.be.instanceof(Array);
133
+ expect(res.data, 'result').to.have.lengthOf(5);
134
+ });
135
+ });
136
+
137
+ test('list should sort ascending', function (tdone) {
138
+ testQueryValues(tdone, {
139
+ take: 5,
140
+ sort: [{
141
+ selector: 'int1',
142
+ desc: false
143
+ }]
144
+ }, function (res) {
145
+ expect(res.data, 'res.data').to.be.instanceof(Array);
146
+ expect(res.data, 'result').to.have.lengthOf(5);
147
+ expect(res.data[0].int1).to.eql(0);
148
+ expect(res.data[1].int1).to.eql(0);
149
+ expect(res.data[2].int1).to.eql(0);
150
+ expect(res.data[3].int1).to.eql(0);
151
+ expect(res.data[4].int1).to.eql(0);
152
+ });
153
+ });
154
+
155
+ test('list should sort descending', function (tdone) {
156
+ testQueryValues(tdone, {
157
+ take: 5,
158
+ sort: [{
159
+ selector: 'int1',
160
+ desc: true
161
+ }]
162
+ }, function (res) {
163
+ expect(res.data, 'res.data').to.be.instanceof(Array);
164
+ expect(res.data, 'result').to.have.lengthOf(5);
165
+ expect(res.data[0].int1).to.eql(9);
166
+ expect(res.data[1].int1).to.eql(9);
167
+ expect(res.data[2].int1).to.eql(9);
168
+ expect(res.data[3].int1).to.eql(9);
169
+ expect(res.data[4].int1).to.eql(9);
170
+ });
171
+ });
172
+
173
+ test('list should sort by two fields', function (tdone) {
174
+ testQueryValues(tdone, {
175
+ take: 20,
176
+ sort: [{
177
+ selector: 'int2',
178
+ desc: true
179
+ }, { selector: 'int1', desc: false }]
180
+ }, function (res) {
181
+
182
+ expect(res.data, 'res.data').to.be.instanceof(Array);
183
+ expect(res.data, 'result').to.have.lengthOf(20);
184
+ expect(res.data[0].int2).to.eql(4);
185
+ expect(res.data[1].int2).to.eql(4);
186
+ expect(res.data[2].int2).to.eql(4);
187
+ expect(res.data[3].int2).to.eql(4);
188
+ expect(res.data[4].int2).to.eql(4);
189
+ expect(res.data[5].int2).to.eql(4);
190
+ expect(res.data[6].int2).to.eql(4);
191
+ expect(res.data[7].int2).to.eql(4);
192
+ expect(res.data[8].int2).to.eql(4);
193
+ expect(res.data[9].int2).to.eql(4);
194
+ expect(res.data[10].int2).to.eql(4);
195
+ expect(res.data[11].int2).to.eql(4);
196
+ expect(res.data[12].int2).to.eql(4);
197
+ expect(res.data[13].int2).to.eql(4);
198
+ expect(res.data[14].int2).to.eql(4);
199
+ expect(res.data[15].int2).to.eql(4);
200
+ expect(res.data[16].int2).to.eql(4);
201
+ expect(res.data[17].int2).to.eql(4);
202
+ expect(res.data[18].int2).to.eql(4);
203
+ expect(res.data[19].int2).to.eql(4);
204
+
205
+ expect(res.data[0].int1).to.eql(4);
206
+ expect(res.data[1].int1).to.eql(4);
207
+ expect(res.data[2].int1).to.eql(4);
208
+ expect(res.data[3].int1).to.eql(4);
209
+ expect(res.data[4].int1).to.eql(4);
210
+ expect(res.data[5].int1).to.eql(4);
211
+ expect(res.data[6].int1).to.eql(4);
212
+ expect(res.data[7].int1).to.eql(4);
213
+ expect(res.data[8].int1).to.eql(4);
214
+ expect(res.data[9].int1).to.eql(4);
215
+ expect(res.data[10].int1).to.eql(9);
216
+ expect(res.data[11].int1).to.eql(9);
217
+ expect(res.data[12].int1).to.eql(9);
218
+ expect(res.data[13].int1).to.eql(9);
219
+ expect(res.data[14].int1).to.eql(9);
220
+ expect(res.data[15].int1).to.eql(9);
221
+ expect(res.data[16].int1).to.eql(9);
222
+ expect(res.data[17].int1).to.eql(9);
223
+ expect(res.data[18].int1).to.eql(9);
224
+ expect(res.data[19].int1).to.eql(9);
225
+ });
226
+ });
227
+
228
+ test('list should filter with =', function (tdone) {
229
+ testQueryValues(tdone, {
230
+ filter: ['int1', '=', 3],
231
+ requireTotalCount: true
232
+ }, function (res) {
233
+ expect(res.totalCount, 'totalCount').to.eql(10);
234
+
235
+ expect(res.data, 'res.data').to.be.instanceof(Array);
236
+ expect(res.data, 'list length').to.have.lengthOf(10);
237
+ });
238
+ });
239
+
240
+ test('list should filter with multiple criteria', function (tdone) {
241
+ testQueryValues(tdone, {
242
+ filter: [['int1', '=', 3], 'or', ['int1', '=', 5]],
243
+ requireTotalCount: true
244
+ }, function (res) {
245
+ expect(res.totalCount, 'totalCount').to.eql(20);
246
+
247
+ expect(res.data, 'res.data').to.be.instanceof(Array);
248
+ expect(res.data, 'list length').to.have.lengthOf(20);
249
+ });
250
+ });
251
+
252
+ test('list should search with =', function (tdone) {
253
+ testQueryValues(tdone, {
254
+ searchExpr: 'int1',
255
+ searchOperation: '=',
256
+ searchValue: 3,
257
+ requireTotalCount: true
258
+ }, function (res) {
259
+ expect(res.totalCount, 'totalCount').to.eql(10);
260
+
261
+ expect(res.data, 'res.data').to.be.instanceof(Array);
262
+ expect(res.data, 'list length').to.have.lengthOf(10);
263
+ });
264
+ });
265
+
266
+ test('list should project with select', function (tdone) {
267
+ testQueryValues(tdone, {
268
+ filter: ['int1', '=', 3],
269
+ requireTotalCount: false,
270
+ select: ['int2', 'date1']
271
+ }, function (res) {
272
+
273
+ expect(res.data[0]).to.have.ownProperty('_id');
274
+ expect(res.data[0]).to.have.ownProperty('int2');
275
+ expect(res.data[0]).to.have.ownProperty('date1');
276
+
277
+ expect(res.data[0]).to.not.have.ownProperty('int1');
278
+ expect(res.data[0]).to.not.have.ownProperty('date2');
279
+ expect(res.data[0]).to.not.have.ownProperty('string');
280
+ });
281
+ });
282
+
283
+ test('list should search with multiple fields', function (tdone) {
284
+ testQueryValues(tdone, {
285
+ searchExpr: ['int1', 'int2'],
286
+ searchOperation: '=',
287
+ searchValue: 3,
288
+ requireTotalCount: true
289
+ }, function (res) {
290
+
291
+ expect(res.totalCount, 'totalCount').to.eql(20);
292
+
293
+ expect(res.data, 'res.data').to.be.instanceof(Array);
294
+ expect(res.data, 'list length').to.have.lengthOf(20);
295
+ });
296
+ });
297
+
298
+ test('list should filter with <', function (tdone) {
299
+ testQueryValues(tdone, {
300
+ filter: ['int1', '<', 5],
301
+ requireTotalCount: true
302
+ }, function (res) {
303
+ expect(res.totalCount, 'totalCount').to.eql(50);
304
+
305
+ expect(res.data, 'res.data').to.be.instanceof(Array);
306
+ expect(res.data, 'list length').to.have.lengthOf(50);
307
+ });
308
+ });
309
+
310
+ test('list should filter with date.Month and nested array', function (tdone) {
311
+ testQueryValues(tdone, {
312
+ filter: [['date1.Month', '<=', 2]],
313
+ requireTotalCount: true
314
+ }, function (res) {
315
+ expect(res.totalCount, 'totalCount').to.eql(59);
316
+
317
+ expect(res.data, 'res.data').to.be.instanceof(Array);
318
+ expect(res.data, 'list length').to.have.lengthOf(59);
319
+ });
320
+ });
321
+
322
+ test('list should filter with date.Quarter', function (tdone) {
323
+ testQueryValues(tdone, {
324
+ filter: ['date1.quarter', '=', 2],
325
+ requireTotalCount: true
326
+ }, function (res) {
327
+ expect(res.totalCount, 'totalCount').to.eql(10);
328
+
329
+ expect(res.data, 'res.data').to.be.instanceof(Array);
330
+ expect(res.data, 'list length').to.have.lengthOf(10);
331
+
332
+ expect(res.data[0].date1, 'date1').to.be.a('date');
333
+ expect(res.data[0].date2, 'date2').to.be.a('date');
334
+ expect(res.data[0].int1, 'int1').to.be.a('number');
335
+ expect(res.data[0].int2, 'int2').to.be.a('number');
336
+ expect(res.data[0].string, 'string').to.be.a('string');
337
+ expect(res.data[0].___date1_mp2, '___date1_mp2').to.be.undefined;
338
+ expect(res.data[0].___date1_quarter, '___date1_quarter').to.be.undefined;
339
+ });
340
+ });
341
+
342
+ test('list should filter and group (sample 1)', function (tdone) {
343
+ testQueryValues(tdone, {
344
+ filter: [['date2.Month', '>=', 4], 'and', ['date2.Month', '<', 7]],
345
+ group: [{
346
+ groupInterval: 'month',
347
+ isExpanded: false,
348
+ selector: 'date1'
349
+ }],
350
+ groupSummary: [{
351
+ selector: 'int1',
352
+ summaryType: 'sum'
353
+ }],
354
+ totalSummary: [{
355
+ selector: 'int1',
356
+ summaryType: 'sum'
357
+ }],
358
+ requireTotalCount: true
359
+ }, function (res) {
360
+
361
+ expect(res.totalCount, 'totalCount').to.eql(10);
362
+
363
+ expect(res.data, 'res.data').to.be.instanceof(Array);
364
+ expect(res.data, 'list length').to.have.lengthOf(1);
365
+
366
+ expect(res.summary[0], 'summary value').to.eql(45);
367
+ });
368
+ });
369
+
370
+ test('list should group and filter by quarter without extra fields', function (tdone) {
371
+ testQueryValues(tdone, {
372
+ filter: [['date2.quarter', '=', 1]],
373
+ group: [{
374
+ groupInterval: 'month',
375
+ isExpanded: true,
376
+ selector: 'date1'
377
+ }],
378
+ requireTotalCount: true
379
+ }, function (res) {
380
+
381
+ expect(res.totalCount, 'totalCount').to.eql(90);
382
+
383
+ expect(res.data, 'res.data').to.be.instanceof(Array);
384
+ expect(res.data, 'list length').to.have.lengthOf(3);
385
+
386
+ var _iteratorNormalCompletion = true;
387
+ var _didIteratorError = false;
388
+ var _iteratorError = undefined;
389
+
390
+ try {
391
+ for (var _iterator = res.data[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
392
+ var group = _step.value;
393
+
394
+ expect(group.key, 'group.key').to.not.be.undefined;
395
+ expect(group.items, 'group(' + group.key + ').items').to.be.instanceof(Array);
396
+ expect(group.items, 'group(' + group.key + ') items list').to.have.length.of.at.least(10);
397
+ expect(group.count, 'group(' + group.key + ').count').to.eql(group.items.length);
398
+
399
+ var _iteratorNormalCompletion2 = true;
400
+ var _didIteratorError2 = false;
401
+ var _iteratorError2 = undefined;
402
+
403
+ try {
404
+ for (var _iterator2 = group.items[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
405
+ var item = _step2.value;
406
+
407
+ expect(item.___date2_mp2, 'item.___date2_mp2').to.be.undefined;
408
+ expect(item.___date2_quarter, 'item.___date2_quarter').to.be.undefined;
409
+ }
410
+ } catch (err) {
411
+ _didIteratorError2 = true;
412
+ _iteratorError2 = err;
413
+ } finally {
414
+ try {
415
+ if (!_iteratorNormalCompletion2 && _iterator2.return) {
416
+ _iterator2.return();
417
+ }
418
+ } finally {
419
+ if (_didIteratorError2) {
420
+ throw _iteratorError2;
421
+ }
422
+ }
423
+ }
424
+ }
425
+ } catch (err) {
426
+ _didIteratorError = true;
427
+ _iteratorError = err;
428
+ } finally {
429
+ try {
430
+ if (!_iteratorNormalCompletion && _iterator.return) {
431
+ _iterator.return();
432
+ }
433
+ } finally {
434
+ if (_didIteratorError) {
435
+ throw _iteratorError;
436
+ }
437
+ }
438
+ }
439
+ });
440
+ });
441
+
442
+ test('list should filter with endswith', function (tdone) {
443
+ testQueryValues(tdone, {
444
+ filter: ['string', 'endswith', '23'],
445
+ requireTotalCount: true
446
+ }, function (res) {
447
+ expect(res.totalCount, 'totalCount').to.eql(1);
448
+
449
+ expect(res.data, 'res.data').to.be.instanceof(Array);
450
+ expect(res.data, 'list length').to.have.lengthOf(1);
451
+ });
452
+ });
453
+
454
+ test('prefer metadata count with filter', function (tdone) {
455
+ testQueryValues(tdone, {
456
+ filter: ['string', 'contains', '7'],
457
+ requireTotalCount: true
458
+ }, function (res) {
459
+ expect(res.totalCount, 'totalCount').to.eql(19);
460
+
461
+ expect(res.data, 'res.data').to.be.instanceof(Array);
462
+ expect(res.data, 'list length').to.have.lengthOf(19);
463
+ }, undefined, { preferMetadataCount: true });
464
+ });
465
+
466
+ test('prefer metadata count without filter', function (tdone) {
467
+ testQueryValues(tdone, {
468
+ requireTotalCount: true
469
+ }, function (res) {
470
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
471
+ }, undefined, { preferMetadataCount: true });
472
+ });
473
+
474
+ test('list should filter with contains', function (tdone) {
475
+ testQueryValues(tdone, {
476
+ filter: ['string', 'contains', 'Item'],
477
+ requireTotalCount: true
478
+ }, function (res) {
479
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
480
+
481
+ expect(res.data, 'res.data').to.be.instanceof(Array);
482
+ expect(res.data, 'list length').to.have.lengthOf(TESTRECORD_COUNT);
483
+ });
484
+ });
485
+
486
+ test('list should filter with contains (case insensitive)', function (tdone) {
487
+ testQueryValues(tdone, {
488
+ filter: ['string', 'contains', 'item'],
489
+ requireTotalCount: true
490
+ }, function (res) {
491
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
492
+
493
+ expect(res.data, 'res.data').to.be.instanceof(Array);
494
+ expect(res.data, 'list length').to.have.lengthOf(TESTRECORD_COUNT);
495
+ });
496
+ });
497
+
498
+ test('list should filter with contains (case sensitive!)', function (tdone) {
499
+ testQueryValues(tdone, {
500
+ filter: ['string', 'contains', 'Something'],
501
+ requireTotalCount: true
502
+ }, function (res) {
503
+ expect(res.totalCount, 'totalCount').to.eql(1);
504
+
505
+ expect(res.data, 'res.data').to.be.instanceof(Array);
506
+ expect(res.data, 'list length').to.have.lengthOf(1);
507
+ }, function (collection) {
508
+ return [collection.insertOne({
509
+ string: 'something'
510
+ }), collection.insertOne({
511
+ string: 'Something'
512
+ })];
513
+ }, { caseInsensitiveRegex: false });
514
+ });
515
+
516
+ test('ids should be strings by default', function (tdone) {
517
+ testQueryValues(tdone, {
518
+ requireTotalCount: true
519
+ }, function (res) {
520
+ expect(res.totalCount, 'totalCount').to.eql(1);
521
+
522
+ expect(res.data, 'res.data').to.be.instanceof(Array);
523
+ expect(res.data, 'list length').to.have.lengthOf(1);
524
+ expect(res.data[0]._id, 'id').to.be.a('string');
525
+ }, function (collection) {
526
+ return [collection.insertOne({
527
+ data: 42
528
+ })];
529
+ }, {});
530
+ });
531
+
532
+ test('ids should not be strings if replaceId=false', function (tdone) {
533
+ testQueryValues(tdone, {
534
+ requireTotalCount: true
535
+ }, function (res) {
536
+ expect(res.totalCount, 'totalCount').to.eql(1);
537
+
538
+ expect(res.data, 'res.data').to.be.instanceof(Array);
539
+ expect(res.data, 'list length').to.have.lengthOf(1);
540
+ expect(res.data[0]._id, 'id').to.be.a('object');
541
+ }, function (collection) {
542
+ return [collection.insertOne({
543
+ data: 42
544
+ })];
545
+ }, {
546
+ replaceIds: false });
547
+ });
548
+
549
+ test('list should filter with endswith, no results', function (tdone) {
550
+ testQueryValues(tdone, {
551
+ filter: ['string', 'endswith', "something that doesn't exist"],
552
+ requireTotalCount: true
553
+ }, function (res) {
554
+ expect(res.totalCount, 'totalCount').to.eql(0);
555
+
556
+ expect(res.data, 'res.data').to.be.instanceof(Array);
557
+ expect(res.data, 'list length').to.have.lengthOf(0);
558
+ });
559
+ });
560
+
561
+ test('list should filter with endswith, no results, total summary defined', function (tdone) {
562
+ testQueryValues(tdone, {
563
+ filter: ['string', 'endswith', "something that doesn't exist"],
564
+ totalSummary: [{
565
+ selector: 'int1',
566
+ summaryType: 'sum'
567
+ }],
568
+ requireTotalCount: true
569
+ }, function (res) {
570
+ expect(res.totalCount, 'totalCount').to.eql(0);
571
+
572
+ expect(res.data, 'res.data').to.be.instanceof(Array);
573
+ expect(res.data, 'list length').to.have.lengthOf(0);
574
+
575
+ expect(res.summary, 'res.summary').to.be.undefined;
576
+ });
577
+ });
578
+
579
+ test('list should calculate total summaries for simple queries', function (tdone) {
580
+ testQueryValues(tdone, {
581
+ filter: ['int1', '<', 5],
582
+ totalSummary: [{
583
+ selector: 'int1',
584
+ summaryType: 'sum'
585
+ }, {
586
+ selector: 'int2',
587
+ summaryType: 'max'
588
+ }],
589
+ requireTotalCount: true
590
+ }, function (res) {
591
+ expect(res.totalCount, 'totalCount').to.eql(50);
592
+
593
+ expect(res.summary, 'res.summary').to.be.instanceof(Array);
594
+ expect(res.summary, 'res.summary').to.have.lengthOf(2);
595
+ expect(res.summary[0], 'sum(int1)').to.eql(100);
596
+ expect(res.summary[1], 'max(int2)').to.eql(4);
597
+ });
598
+ });
599
+
600
+ test('list should group with items', function (tdone) {
601
+ testQueryValues(tdone, {
602
+ group: [{
603
+ selector: 'int1',
604
+ desc: false,
605
+ isExpanded: true
606
+ }],
607
+ requireTotalCount: true,
608
+ requireGroupCount: true
609
+ }, function (res) {
610
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
611
+ expect(res.groupCount, 'groupCount').to.eql(10);
612
+
613
+ expect(res.data, 'res.data').to.be.instanceof(Array);
614
+ expect(res.data, 'group list length').to.have.lengthOf(10);
615
+
616
+ var _iteratorNormalCompletion3 = true;
617
+ var _didIteratorError3 = false;
618
+ var _iteratorError3 = undefined;
619
+
620
+ try {
621
+ for (var _iterator3 = res.data[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
622
+ var group = _step3.value;
623
+
624
+ expect(group.key, 'group.key').to.not.be.undefined;
625
+ expect(group.items, 'group(' + group.key + ').items').to.be.instanceof(Array);
626
+ expect(group.items, 'group(' + group.key + ') items list').to.have.lengthOf(10);
627
+ expect(group.count, 'group(' + group.key + ').count').to.eql(group.items.length);
628
+
629
+ var _iteratorNormalCompletion4 = true;
630
+ var _didIteratorError4 = false;
631
+ var _iteratorError4 = undefined;
632
+
633
+ try {
634
+ for (var _iterator4 = group.items[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
635
+ var item = _step4.value;
636
+
637
+ expect(item.int1, 'item.int1').to.eql(group.key);
638
+ }
639
+ } catch (err) {
640
+ _didIteratorError4 = true;
641
+ _iteratorError4 = err;
642
+ } finally {
643
+ try {
644
+ if (!_iteratorNormalCompletion4 && _iterator4.return) {
645
+ _iterator4.return();
646
+ }
647
+ } finally {
648
+ if (_didIteratorError4) {
649
+ throw _iteratorError4;
650
+ }
651
+ }
652
+ }
653
+ }
654
+ } catch (err) {
655
+ _didIteratorError3 = true;
656
+ _iteratorError3 = err;
657
+ } finally {
658
+ try {
659
+ if (!_iteratorNormalCompletion3 && _iterator3.return) {
660
+ _iterator3.return();
661
+ }
662
+ } finally {
663
+ if (_didIteratorError3) {
664
+ throw _iteratorError3;
665
+ }
666
+ }
667
+ }
668
+ });
669
+ });
670
+
671
+ test('group item id should be type string by default', function (tdone) {
672
+ testQueryValues(tdone, {
673
+ group: [{
674
+ selector: 'int1',
675
+ desc: false,
676
+ isExpanded: true
677
+ }],
678
+ requireTotalCount: true,
679
+ requireGroupCount: true
680
+ }, function (res) {
681
+ expect(res.data[0].items[0]._id, 'group item id').to.be.a('string');
682
+ }, undefined, {});
683
+ });
684
+
685
+ test('group item id should not be type string if replaceIds=false', function (tdone) {
686
+ testQueryValues(tdone, {
687
+ group: [{
688
+ selector: 'int1',
689
+ desc: false,
690
+ isExpanded: true
691
+ }],
692
+ requireTotalCount: true,
693
+ requireGroupCount: true
694
+ }, function (res) {
695
+ expect(res.data[0].items[0]._id, 'group item id').to.be.a('object');
696
+ }, undefined, {
697
+ replaceIds: false });
698
+ });
699
+
700
+ test('list should group with items and select', function (tdone) {
701
+ testQueryValues(tdone, {
702
+ group: [{
703
+ selector: 'int1',
704
+ desc: false,
705
+ isExpanded: true
706
+ }],
707
+ select: ['int2', 'date1']
708
+ }, function (res) {
709
+
710
+ var x = res.data[0].items[0];
711
+
712
+ expect(x).to.have.ownProperty('_id');
713
+ expect(x).to.have.ownProperty('int2');
714
+ expect(x).to.have.ownProperty('date1');
715
+
716
+ expect(x).to.not.have.ownProperty('int1');
717
+ expect(x).to.not.have.ownProperty('date2');
718
+ expect(x).to.not.have.ownProperty('string');
719
+ });
720
+ });
721
+
722
+ test('list should group with items and secondary sort', function (tdone) {
723
+ testQueryValues(tdone, {
724
+ filter: ['int2', '=', 3],
725
+ group: [{
726
+ selector: 'int2',
727
+ desc: false,
728
+ isExpanded: true
729
+ }],
730
+ sort: [{
731
+ selector: 'int1',
732
+ desc: true
733
+ }],
734
+ requireTotalCount: true,
735
+ requireGroupCount: true
736
+ }, function (res) {
737
+ expect(res.totalCount, 'totalCount').to.eql(20);
738
+ expect(res.groupCount, 'groupCount').to.eql(1);
739
+
740
+ expect(res.data, 'res.data').to.be.instanceof(Array);
741
+ expect(res.data, 'group list length').to.have.lengthOf(1);
742
+
743
+ var _iteratorNormalCompletion5 = true;
744
+ var _didIteratorError5 = false;
745
+ var _iteratorError5 = undefined;
746
+
747
+ try {
748
+ for (var _iterator5 = res.data[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
749
+ var group = _step5.value;
750
+
751
+
752
+ expect(group.key, 'group.key').to.not.be.undefined;
753
+ expect(group.items, 'group(' + group.key + ').items').to.be.instanceof(Array);
754
+ expect(group.items, 'group(' + group.key + ') items list').to.have.lengthOf(20);
755
+
756
+ for (var i = 0; i <= 9; i++) {
757
+ expect(group.items[i].int1, 'groupitem ' + i).to.eql(8);
758
+ }
759
+ for (var _i = 10; _i <= 19; _i++) {
760
+ expect(group.items[_i].int1, 'groupitem ' + _i).to.eql(3);
761
+ }
762
+ }
763
+ } catch (err) {
764
+ _didIteratorError5 = true;
765
+ _iteratorError5 = err;
766
+ } finally {
767
+ try {
768
+ if (!_iteratorNormalCompletion5 && _iterator5.return) {
769
+ _iterator5.return();
770
+ }
771
+ } finally {
772
+ if (_didIteratorError5) {
773
+ throw _iteratorError5;
774
+ }
775
+ }
776
+ }
777
+ });
778
+ });
779
+
780
+ test('list should group without items', function (tdone) {
781
+ testQueryValues(tdone, {
782
+ group: [{
783
+ selector: 'int1',
784
+ desc: false
785
+ }],
786
+ requireTotalCount: true,
787
+ requireGroupCount: true
788
+ }, function (res) {
789
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
790
+ expect(res.groupCount, 'groupCount').to.eql(10);
791
+
792
+ expect(res.data, 'res.data').to.be.instanceof(Array);
793
+ expect(res.data, 'group list length').to.have.lengthOf(10);
794
+
795
+ var _iteratorNormalCompletion6 = true;
796
+ var _didIteratorError6 = false;
797
+ var _iteratorError6 = undefined;
798
+
799
+ try {
800
+ for (var _iterator6 = res.data[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
801
+ var group = _step6.value;
802
+
803
+ expect(group.key, 'group.key').to.not.be.undefined;
804
+ expect(group.items, 'group(' + group.key + ').items').to.be.null;
805
+ expect(group.count, 'group(' + group.key + ').count').to.eql(10);
806
+ }
807
+ } catch (err) {
808
+ _didIteratorError6 = true;
809
+ _iteratorError6 = err;
810
+ } finally {
811
+ try {
812
+ if (!_iteratorNormalCompletion6 && _iterator6.return) {
813
+ _iterator6.return();
814
+ }
815
+ } finally {
816
+ if (_didIteratorError6) {
817
+ throw _iteratorError6;
818
+ }
819
+ }
820
+ }
821
+ });
822
+ });
823
+
824
+ test('list should group without items, with filter', function (tdone) {
825
+ testQueryValues(tdone, {
826
+ filter: ['int1', '=', 3],
827
+ group: [{
828
+ selector: 'int1',
829
+ desc: false
830
+ }],
831
+ requireTotalCount: true,
832
+ requireGroupCount: true
833
+ }, function (res) {
834
+ expect(res.totalCount, 'totalCount').to.eql(10);
835
+ expect(res.groupCount, 'groupCount').to.eql(1);
836
+
837
+ expect(res.data, 'res.data').to.be.instanceof(Array);
838
+ expect(res.data, 'group list length').to.have.lengthOf(1);
839
+
840
+ var _iteratorNormalCompletion7 = true;
841
+ var _didIteratorError7 = false;
842
+ var _iteratorError7 = undefined;
843
+
844
+ try {
845
+ for (var _iterator7 = res.data[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
846
+ var group = _step7.value;
847
+
848
+ expect(group.key, 'group.key').to.not.be.undefined;
849
+ expect(group.items, 'group(' + group.key + ').items').to.be.null;
850
+ expect(group.count, 'group(' + group.key + ').count').to.eql(10);
851
+ }
852
+ } catch (err) {
853
+ _didIteratorError7 = true;
854
+ _iteratorError7 = err;
855
+ } finally {
856
+ try {
857
+ if (!_iteratorNormalCompletion7 && _iterator7.return) {
858
+ _iterator7.return();
859
+ }
860
+ } finally {
861
+ if (_didIteratorError7) {
862
+ throw _iteratorError7;
863
+ }
864
+ }
865
+ }
866
+ });
867
+ });
868
+
869
+ test('list should group without items, with complex filter', function (tdone) {
870
+ testQueryValues(tdone, {
871
+ filter: [['int1', '=', 3], 'or', ['int1', '=', 5], 'or', ['int1', '=', 7]],
872
+ group: [{
873
+ selector: 'int1',
874
+ desc: false
875
+ }],
876
+ requireTotalCount: true,
877
+ requireGroupCount: true
878
+ }, function (res) {
879
+ expect(res.totalCount, 'totalCount').to.eql(30);
880
+ expect(res.groupCount, 'groupCount').to.eql(3);
881
+
882
+ expect(res.data, 'res.data').to.be.instanceof(Array);
883
+ expect(res.data, 'group list length').to.have.lengthOf(3);
884
+
885
+ var _iteratorNormalCompletion8 = true;
886
+ var _didIteratorError8 = false;
887
+ var _iteratorError8 = undefined;
888
+
889
+ try {
890
+ for (var _iterator8 = res.data[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
891
+ var group = _step8.value;
892
+
893
+ expect(group.key, 'group.key').to.not.be.undefined;
894
+ expect(group.items, 'group(' + group.key + ').items').to.be.null;
895
+ expect(group.count, 'group(' + group.key + ').count').to.eql(10);
896
+ }
897
+ } catch (err) {
898
+ _didIteratorError8 = true;
899
+ _iteratorError8 = err;
900
+ } finally {
901
+ try {
902
+ if (!_iteratorNormalCompletion8 && _iterator8.return) {
903
+ _iterator8.return();
904
+ }
905
+ } finally {
906
+ if (_didIteratorError8) {
907
+ throw _iteratorError8;
908
+ }
909
+ }
910
+ }
911
+ });
912
+ });
913
+
914
+ test('list should group with items, with complex filter', function (tdone) {
915
+ testQueryValues(tdone, {
916
+ filter: [['int1', '=', 3], 'or', ['int1', '=', 5], 'or', ['int1', '=', 7]],
917
+ group: [{
918
+ selector: 'int1',
919
+ desc: false,
920
+ isExpanded: true
921
+ }],
922
+ requireTotalCount: true,
923
+ requireGroupCount: true
924
+ }, function (res) {
925
+ expect(res.totalCount, 'totalCount').to.eql(30);
926
+ expect(res.groupCount, 'groupCount').to.eql(3);
927
+
928
+ expect(res.data, 'res.data').to.be.instanceof(Array);
929
+ expect(res.data, 'group list length').to.have.lengthOf(3);
930
+
931
+ var _iteratorNormalCompletion9 = true;
932
+ var _didIteratorError9 = false;
933
+ var _iteratorError9 = undefined;
934
+
935
+ try {
936
+ for (var _iterator9 = res.data[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
937
+ var group = _step9.value;
938
+
939
+ expect(group.key, 'group.key').to.not.be.undefined;
940
+ expect(group.items, 'group(' + group.key + ').items').to.be.instanceof(Array);
941
+
942
+ expect(group.items, 'group items list').to.have.lengthOf(10);
943
+ expect(group.count, 'group(' + group.key + ').count').to.eql(group.items.length);
944
+
945
+ var _iteratorNormalCompletion10 = true;
946
+ var _didIteratorError10 = false;
947
+ var _iteratorError10 = undefined;
948
+
949
+ try {
950
+ for (var _iterator10 = group.items[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
951
+ var item = _step10.value;
952
+
953
+ expect(item.int1, 'item.int1').to.eql(group.key);
954
+ }
955
+ } catch (err) {
956
+ _didIteratorError10 = true;
957
+ _iteratorError10 = err;
958
+ } finally {
959
+ try {
960
+ if (!_iteratorNormalCompletion10 && _iterator10.return) {
961
+ _iterator10.return();
962
+ }
963
+ } finally {
964
+ if (_didIteratorError10) {
965
+ throw _iteratorError10;
966
+ }
967
+ }
968
+ }
969
+ }
970
+ } catch (err) {
971
+ _didIteratorError9 = true;
972
+ _iteratorError9 = err;
973
+ } finally {
974
+ try {
975
+ if (!_iteratorNormalCompletion9 && _iterator9.return) {
976
+ _iterator9.return();
977
+ }
978
+ } finally {
979
+ if (_didIteratorError9) {
980
+ throw _iteratorError9;
981
+ }
982
+ }
983
+ }
984
+ });
985
+ });
986
+
987
+ test('list should group two levels with bottom-level items', function (tdone) {
988
+ testQueryValues(tdone, {
989
+ filter: [[['int1', '=', 3], 'or', ['int1', '=', 6]], 'and', [['int2', '=', 3], 'or', ['int2', '=', 1]]],
990
+ group: [{
991
+ selector: 'int1',
992
+ desc: false,
993
+ isExpanded: false
994
+ }, {
995
+ selector: 'int2',
996
+ desc: false,
997
+ isExpanded: true
998
+ }],
999
+ requireTotalCount: true,
1000
+ requireGroupCount: true
1001
+ }, function (res) {
1002
+
1003
+ expect(res.totalCount, 'totalCount').to.eql(20);
1004
+ expect(res.groupCount, 'groupCount').to.eql(2);
1005
+
1006
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1007
+ expect(res.data, 'group list length').to.have.lengthOf(2);
1008
+
1009
+ var _iteratorNormalCompletion11 = true;
1010
+ var _didIteratorError11 = false;
1011
+ var _iteratorError11 = undefined;
1012
+
1013
+ try {
1014
+ for (var _iterator11 = res.data[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
1015
+ var group1 = _step11.value;
1016
+
1017
+ expect(group1.key, 'group1.key').to.not.be.undefined;
1018
+ expect(group1.items, 'group1(' + group1.key + ').items').to.be.instanceof(Array);
1019
+
1020
+ expect(group1.items, 'group1 items list').to.have.lengthOf(1);
1021
+ expect(group1.count, 'group(' + group1.key + ').count').to.eql(group1.items.length);
1022
+
1023
+ var _iteratorNormalCompletion12 = true;
1024
+ var _didIteratorError12 = false;
1025
+ var _iteratorError12 = undefined;
1026
+
1027
+ try {
1028
+ for (var _iterator12 = group1.items[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
1029
+ var group2 = _step12.value;
1030
+
1031
+ expect(group2.key, 'group2.key').to.not.be.undefined;
1032
+ expect(group2.items, 'group2(' + group2.key + ').items').to.be.instanceof(Array);
1033
+
1034
+ expect(group2.items, 'group2 items list').to.have.lengthOf(10);
1035
+ expect(group2.count, 'group(' + group2.key + ').count').to.eql(group2.items.length);
1036
+ var _iteratorNormalCompletion13 = true;
1037
+ var _didIteratorError13 = false;
1038
+ var _iteratorError13 = undefined;
1039
+
1040
+ try {
1041
+ for (var _iterator13 = group2.items[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
1042
+ var item = _step13.value;
1043
+
1044
+ expect(item.int1, 'item.int1').to.eql(group1.key);
1045
+ expect(item.int2, 'item.int2').to.eql(group2.key);
1046
+ }
1047
+ } catch (err) {
1048
+ _didIteratorError13 = true;
1049
+ _iteratorError13 = err;
1050
+ } finally {
1051
+ try {
1052
+ if (!_iteratorNormalCompletion13 && _iterator13.return) {
1053
+ _iterator13.return();
1054
+ }
1055
+ } finally {
1056
+ if (_didIteratorError13) {
1057
+ throw _iteratorError13;
1058
+ }
1059
+ }
1060
+ }
1061
+ }
1062
+ } catch (err) {
1063
+ _didIteratorError12 = true;
1064
+ _iteratorError12 = err;
1065
+ } finally {
1066
+ try {
1067
+ if (!_iteratorNormalCompletion12 && _iterator12.return) {
1068
+ _iterator12.return();
1069
+ }
1070
+ } finally {
1071
+ if (_didIteratorError12) {
1072
+ throw _iteratorError12;
1073
+ }
1074
+ }
1075
+ }
1076
+ }
1077
+ } catch (err) {
1078
+ _didIteratorError11 = true;
1079
+ _iteratorError11 = err;
1080
+ } finally {
1081
+ try {
1082
+ if (!_iteratorNormalCompletion11 && _iterator11.return) {
1083
+ _iterator11.return();
1084
+ }
1085
+ } finally {
1086
+ if (_didIteratorError11) {
1087
+ throw _iteratorError11;
1088
+ }
1089
+ }
1090
+ }
1091
+ });
1092
+ });
1093
+
1094
+ test('list should group two levels without bottom-level items', function (tdone) {
1095
+ testQueryValues(tdone, {
1096
+ filter: [[['int1', '=', 3], 'or', ['int1', '=', 6]], 'and', [['int2', '=', 3], 'or', ['int2', '=', 1]]],
1097
+ group: [{
1098
+ selector: 'int1',
1099
+ desc: false,
1100
+ isExpanded: false
1101
+ }, {
1102
+ selector: 'int2',
1103
+ desc: false,
1104
+ isExpanded: false
1105
+ }],
1106
+ requireTotalCount: true,
1107
+ requireGroupCount: true
1108
+ }, function (res) {
1109
+
1110
+ expect(res.totalCount, 'totalCount').to.eql(20);
1111
+ expect(res.groupCount, 'groupCount').to.eql(2);
1112
+
1113
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1114
+ expect(res.data, 'group list length').to.have.lengthOf(2);
1115
+
1116
+ var _iteratorNormalCompletion14 = true;
1117
+ var _didIteratorError14 = false;
1118
+ var _iteratorError14 = undefined;
1119
+
1120
+ try {
1121
+ for (var _iterator14 = res.data[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
1122
+ var group1 = _step14.value;
1123
+
1124
+ expect(group1.key, 'group1.key').to.not.be.undefined;
1125
+ expect(group1.items, 'group1(' + group1.key + ').items').to.be.instanceof(Array);
1126
+
1127
+ expect(group1.items, 'group1 items list').to.have.lengthOf(1);
1128
+ expect(group1.count, 'group(' + group1.key + ').count').to.eql(group1.items.length);
1129
+
1130
+ var _iteratorNormalCompletion15 = true;
1131
+ var _didIteratorError15 = false;
1132
+ var _iteratorError15 = undefined;
1133
+
1134
+ try {
1135
+ for (var _iterator15 = group1.items[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
1136
+ var group2 = _step15.value;
1137
+
1138
+ expect(group2.key, 'group2.key').to.not.be.undefined;
1139
+ expect(group2.items, 'group2 items list').to.be.null;
1140
+ expect(group2.count, 'group(' + group2.key + ').count').to.eql(10);
1141
+ }
1142
+ } catch (err) {
1143
+ _didIteratorError15 = true;
1144
+ _iteratorError15 = err;
1145
+ } finally {
1146
+ try {
1147
+ if (!_iteratorNormalCompletion15 && _iterator15.return) {
1148
+ _iterator15.return();
1149
+ }
1150
+ } finally {
1151
+ if (_didIteratorError15) {
1152
+ throw _iteratorError15;
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ } catch (err) {
1158
+ _didIteratorError14 = true;
1159
+ _iteratorError14 = err;
1160
+ } finally {
1161
+ try {
1162
+ if (!_iteratorNormalCompletion14 && _iterator14.return) {
1163
+ _iterator14.return();
1164
+ }
1165
+ } finally {
1166
+ if (_didIteratorError14) {
1167
+ throw _iteratorError14;
1168
+ }
1169
+ }
1170
+ }
1171
+ });
1172
+ });
1173
+
1174
+ test('list should group three levels without items', function (tdone) {
1175
+ testQueryValues(tdone, {
1176
+ group: [{
1177
+ selector: 'int1',
1178
+ isExpanded: false
1179
+ }, {
1180
+ selector: 'int2',
1181
+ isExpanded: false
1182
+ }, {
1183
+ selector: 'string',
1184
+ isExpanded: false
1185
+ }],
1186
+ requireTotalCount: true,
1187
+ requireGroupCount: true
1188
+ }, function (res) {
1189
+ expect(res).to.deep.eql({
1190
+ data: [{
1191
+ key: 0,
1192
+ items: [{
1193
+ key: 0,
1194
+ items: [{
1195
+ count: 1,
1196
+ key: 'Item 0',
1197
+ items: null
1198
+ }, {
1199
+ count: 1,
1200
+ key: 'Item 10',
1201
+ items: null
1202
+ }, {
1203
+ count: 1,
1204
+ key: 'Item 20',
1205
+ items: null
1206
+ }, {
1207
+ count: 1,
1208
+ key: 'Item 30',
1209
+ items: null
1210
+ }, {
1211
+ count: 1,
1212
+ key: 'Item 40',
1213
+ items: null
1214
+ }, {
1215
+ count: 1,
1216
+ key: 'Item 50',
1217
+ items: null
1218
+ }, {
1219
+ count: 1,
1220
+ key: 'Item 60',
1221
+ items: null
1222
+ }, {
1223
+ count: 1,
1224
+ key: 'Item 70',
1225
+ items: null
1226
+ }, {
1227
+ count: 1,
1228
+ key: 'Item 80',
1229
+ items: null
1230
+ }, {
1231
+ count: 1,
1232
+ key: 'Item 90',
1233
+ items: null
1234
+ }],
1235
+ count: 10
1236
+ }],
1237
+ count: 1
1238
+ }, {
1239
+ key: 1,
1240
+ items: [{
1241
+ key: 1,
1242
+ items: [{
1243
+ count: 1,
1244
+ key: 'Item 1',
1245
+ items: null
1246
+ }, {
1247
+ count: 1,
1248
+ key: 'Item 11',
1249
+ items: null
1250
+ }, {
1251
+ count: 1,
1252
+ key: 'Item 21',
1253
+ items: null
1254
+ }, {
1255
+ count: 1,
1256
+ key: 'Item 31',
1257
+ items: null
1258
+ }, {
1259
+ count: 1,
1260
+ key: 'Item 41',
1261
+ items: null
1262
+ }, {
1263
+ count: 1,
1264
+ key: 'Item 51',
1265
+ items: null
1266
+ }, {
1267
+ count: 1,
1268
+ key: 'Item 61',
1269
+ items: null
1270
+ }, {
1271
+ count: 1,
1272
+ key: 'Item 71',
1273
+ items: null
1274
+ }, {
1275
+ count: 1,
1276
+ key: 'Item 81',
1277
+ items: null
1278
+ }, {
1279
+ count: 1,
1280
+ key: 'Item 91',
1281
+ items: null
1282
+ }],
1283
+ count: 10
1284
+ }],
1285
+ count: 1
1286
+ }, {
1287
+ key: 2,
1288
+ items: [{
1289
+ key: 2,
1290
+ items: [{
1291
+ count: 1,
1292
+ key: 'Item 12',
1293
+ items: null
1294
+ }, {
1295
+ count: 1,
1296
+ key: 'Item 2',
1297
+ items: null
1298
+ }, {
1299
+ count: 1,
1300
+ key: 'Item 22',
1301
+ items: null
1302
+ }, {
1303
+ count: 1,
1304
+ key: 'Item 32',
1305
+ items: null
1306
+ }, {
1307
+ count: 1,
1308
+ key: 'Item 42',
1309
+ items: null
1310
+ }, {
1311
+ count: 1,
1312
+ key: 'Item 52',
1313
+ items: null
1314
+ }, {
1315
+ count: 1,
1316
+ key: 'Item 62',
1317
+ items: null
1318
+ }, {
1319
+ count: 1,
1320
+ key: 'Item 72',
1321
+ items: null
1322
+ }, {
1323
+ count: 1,
1324
+ key: 'Item 82',
1325
+ items: null
1326
+ }, {
1327
+ count: 1,
1328
+ key: 'Item 92',
1329
+ items: null
1330
+ }],
1331
+ count: 10
1332
+ }],
1333
+ count: 1
1334
+ }, {
1335
+ key: 3,
1336
+ items: [{
1337
+ key: 3,
1338
+ items: [{
1339
+ count: 1,
1340
+ key: 'Item 13',
1341
+ items: null
1342
+ }, {
1343
+ count: 1,
1344
+ key: 'Item 23',
1345
+ items: null
1346
+ }, {
1347
+ count: 1,
1348
+ key: 'Item 3',
1349
+ items: null
1350
+ }, {
1351
+ count: 1,
1352
+ key: 'Item 33',
1353
+ items: null
1354
+ }, {
1355
+ count: 1,
1356
+ key: 'Item 43',
1357
+ items: null
1358
+ }, {
1359
+ count: 1,
1360
+ key: 'Item 53',
1361
+ items: null
1362
+ }, {
1363
+ count: 1,
1364
+ key: 'Item 63',
1365
+ items: null
1366
+ }, {
1367
+ count: 1,
1368
+ key: 'Item 73',
1369
+ items: null
1370
+ }, {
1371
+ count: 1,
1372
+ key: 'Item 83',
1373
+ items: null
1374
+ }, {
1375
+ count: 1,
1376
+ key: 'Item 93',
1377
+ items: null
1378
+ }],
1379
+ count: 10
1380
+ }],
1381
+ count: 1
1382
+ }, {
1383
+ key: 4,
1384
+ items: [{
1385
+ key: 4,
1386
+ items: [{
1387
+ count: 1,
1388
+ key: 'Item 14',
1389
+ items: null
1390
+ }, {
1391
+ count: 1,
1392
+ key: 'Item 24',
1393
+ items: null
1394
+ }, {
1395
+ count: 1,
1396
+ key: 'Item 34',
1397
+ items: null
1398
+ }, {
1399
+ count: 1,
1400
+ key: 'Item 4',
1401
+ items: null
1402
+ }, {
1403
+ count: 1,
1404
+ key: 'Item 44',
1405
+ items: null
1406
+ }, {
1407
+ count: 1,
1408
+ key: 'Item 54',
1409
+ items: null
1410
+ }, {
1411
+ count: 1,
1412
+ key: 'Item 64',
1413
+ items: null
1414
+ }, {
1415
+ count: 1,
1416
+ key: 'Item 74',
1417
+ items: null
1418
+ }, {
1419
+ count: 1,
1420
+ key: 'Item 84',
1421
+ items: null
1422
+ }, {
1423
+ count: 1,
1424
+ key: 'Item 94',
1425
+ items: null
1426
+ }],
1427
+ count: 10
1428
+ }],
1429
+ count: 1
1430
+ }, {
1431
+ key: 5,
1432
+ items: [{
1433
+ key: 0,
1434
+ items: [{
1435
+ count: 1,
1436
+ key: 'Item 15',
1437
+ items: null
1438
+ }, {
1439
+ count: 1,
1440
+ key: 'Item 25',
1441
+ items: null
1442
+ }, {
1443
+ count: 1,
1444
+ key: 'Item 35',
1445
+ items: null
1446
+ }, {
1447
+ count: 1,
1448
+ key: 'Item 45',
1449
+ items: null
1450
+ }, {
1451
+ count: 1,
1452
+ key: 'Item 5',
1453
+ items: null
1454
+ }, {
1455
+ count: 1,
1456
+ key: 'Item 55',
1457
+ items: null
1458
+ }, {
1459
+ count: 1,
1460
+ key: 'Item 65',
1461
+ items: null
1462
+ }, {
1463
+ count: 1,
1464
+ key: 'Item 75',
1465
+ items: null
1466
+ }, {
1467
+ count: 1,
1468
+ key: 'Item 85',
1469
+ items: null
1470
+ }, {
1471
+ count: 1,
1472
+ key: 'Item 95',
1473
+ items: null
1474
+ }],
1475
+ count: 10
1476
+ }],
1477
+ count: 1
1478
+ }, {
1479
+ key: 6,
1480
+ items: [{
1481
+ key: 1,
1482
+ items: [{
1483
+ count: 1,
1484
+ key: 'Item 16',
1485
+ items: null
1486
+ }, {
1487
+ count: 1,
1488
+ key: 'Item 26',
1489
+ items: null
1490
+ }, {
1491
+ count: 1,
1492
+ key: 'Item 36',
1493
+ items: null
1494
+ }, {
1495
+ count: 1,
1496
+ key: 'Item 46',
1497
+ items: null
1498
+ }, {
1499
+ count: 1,
1500
+ key: 'Item 56',
1501
+ items: null
1502
+ }, {
1503
+ count: 1,
1504
+ key: 'Item 6',
1505
+ items: null
1506
+ }, {
1507
+ count: 1,
1508
+ key: 'Item 66',
1509
+ items: null
1510
+ }, {
1511
+ count: 1,
1512
+ key: 'Item 76',
1513
+ items: null
1514
+ }, {
1515
+ count: 1,
1516
+ key: 'Item 86',
1517
+ items: null
1518
+ }, {
1519
+ count: 1,
1520
+ key: 'Item 96',
1521
+ items: null
1522
+ }],
1523
+ count: 10
1524
+ }],
1525
+ count: 1
1526
+ }, {
1527
+ key: 7,
1528
+ items: [{
1529
+ key: 2,
1530
+ items: [{
1531
+ count: 1,
1532
+ key: 'Item 17',
1533
+ items: null
1534
+ }, {
1535
+ count: 1,
1536
+ key: 'Item 27',
1537
+ items: null
1538
+ }, {
1539
+ count: 1,
1540
+ key: 'Item 37',
1541
+ items: null
1542
+ }, {
1543
+ count: 1,
1544
+ key: 'Item 47',
1545
+ items: null
1546
+ }, {
1547
+ count: 1,
1548
+ key: 'Item 57',
1549
+ items: null
1550
+ }, {
1551
+ count: 1,
1552
+ key: 'Item 67',
1553
+ items: null
1554
+ }, {
1555
+ count: 1,
1556
+ key: 'Item 7',
1557
+ items: null
1558
+ }, {
1559
+ count: 1,
1560
+ key: 'Item 77',
1561
+ items: null
1562
+ }, {
1563
+ count: 1,
1564
+ key: 'Item 87',
1565
+ items: null
1566
+ }, {
1567
+ count: 1,
1568
+ key: 'Item 97',
1569
+ items: null
1570
+ }],
1571
+ count: 10
1572
+ }],
1573
+ count: 1
1574
+ }, {
1575
+ key: 8,
1576
+ items: [{
1577
+ key: 3,
1578
+ items: [{
1579
+ count: 1,
1580
+ key: 'Item 18',
1581
+ items: null
1582
+ }, {
1583
+ count: 1,
1584
+ key: 'Item 28',
1585
+ items: null
1586
+ }, {
1587
+ count: 1,
1588
+ key: 'Item 38',
1589
+ items: null
1590
+ }, {
1591
+ count: 1,
1592
+ key: 'Item 48',
1593
+ items: null
1594
+ }, {
1595
+ count: 1,
1596
+ key: 'Item 58',
1597
+ items: null
1598
+ }, {
1599
+ count: 1,
1600
+ key: 'Item 68',
1601
+ items: null
1602
+ }, {
1603
+ count: 1,
1604
+ key: 'Item 78',
1605
+ items: null
1606
+ }, {
1607
+ count: 1,
1608
+ key: 'Item 8',
1609
+ items: null
1610
+ }, {
1611
+ count: 1,
1612
+ key: 'Item 88',
1613
+ items: null
1614
+ }, {
1615
+ count: 1,
1616
+ key: 'Item 98',
1617
+ items: null
1618
+ }],
1619
+ count: 10
1620
+ }],
1621
+ count: 1
1622
+ }, {
1623
+ key: 9,
1624
+ items: [{
1625
+ key: 4,
1626
+ items: [{
1627
+ count: 1,
1628
+ key: 'Item 19',
1629
+ items: null
1630
+ }, {
1631
+ count: 1,
1632
+ key: 'Item 29',
1633
+ items: null
1634
+ }, {
1635
+ count: 1,
1636
+ key: 'Item 39',
1637
+ items: null
1638
+ }, {
1639
+ count: 1,
1640
+ key: 'Item 49',
1641
+ items: null
1642
+ }, {
1643
+ count: 1,
1644
+ key: 'Item 59',
1645
+ items: null
1646
+ }, {
1647
+ count: 1,
1648
+ key: 'Item 69',
1649
+ items: null
1650
+ }, {
1651
+ count: 1,
1652
+ key: 'Item 79',
1653
+ items: null
1654
+ }, {
1655
+ count: 1,
1656
+ key: 'Item 89',
1657
+ items: null
1658
+ }, {
1659
+ count: 1,
1660
+ key: 'Item 9',
1661
+ items: null
1662
+ }, {
1663
+ count: 1,
1664
+ key: 'Item 99',
1665
+ items: null
1666
+ }],
1667
+ count: 10
1668
+ }],
1669
+ count: 1
1670
+ }],
1671
+ groupCount: 10,
1672
+ totalCount: 100
1673
+ });
1674
+ });
1675
+ });
1676
+
1677
+ test('list should calculate total summaries group query', function (tdone) {
1678
+ testQueryValues(tdone, {
1679
+ filter: [[['int1', '=', 3], 'or', ['int1', '=', 6]], 'and', [['int2', '=', 3], 'or', ['int2', '=', 1]]],
1680
+ group: [{
1681
+ selector: 'int1',
1682
+ desc: false,
1683
+ isExpanded: false
1684
+ }, {
1685
+ selector: 'int2',
1686
+ desc: false,
1687
+ isExpanded: false
1688
+ }],
1689
+ totalSummary: [{
1690
+ selector: 'int1',
1691
+ summaryType: 'sum'
1692
+ }, {
1693
+ selector: 'int2',
1694
+ summaryType: 'max'
1695
+ }],
1696
+ requireTotalCount: true,
1697
+ requireGroupCount: true
1698
+ }, function (res) {
1699
+
1700
+ expect(res.totalCount, 'totalCount').to.eql(20);
1701
+ expect(res.groupCount, 'groupCount').to.eql(2);
1702
+
1703
+ expect(res.summary, 'res.summary').to.be.instanceof(Array);
1704
+ expect(res.summary, 'res.summary').to.have.lengthOf(2);
1705
+ expect(res.summary[0], 'sum(int1)').to.eql(90);
1706
+ expect(res.summary[1], 'max(int2)').to.eql(3);
1707
+ });
1708
+ });
1709
+
1710
+ test('list should calculate group summaries', function (tdone) {
1711
+ testQueryValues(tdone, {
1712
+ filter: [['int1', '=', 3], 'or', ['int1', '=', 6]],
1713
+ group: [{
1714
+ selector: 'int1',
1715
+ desc: false,
1716
+ isExpanded: false
1717
+ }],
1718
+ groupSummary: [{
1719
+ selector: 'int1',
1720
+ summaryType: 'sum'
1721
+ }, {
1722
+ selector: 'int2',
1723
+ summaryType: 'max'
1724
+ }],
1725
+ requireTotalCount: true,
1726
+ requireGroupCount: true
1727
+ }, function (res) {
1728
+
1729
+ expect(res.totalCount, 'totalCount').to.eql(20);
1730
+ expect(res.groupCount, 'groupCount').to.eql(2);
1731
+
1732
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1733
+ expect(res.data, 'group list length').to.have.lengthOf(2);
1734
+
1735
+ expect(res.data[0].summary, 'group1.summary').to.be.instanceof(Array);
1736
+ expect(res.data[0].summary, 'group1.summary').to.have.lengthOf(2);
1737
+ expect(res.data[0].summary[0], 'group1.sum(int1)').to.eql(30);
1738
+ expect(res.data[0].summary[1], 'group1.max(int2)').to.eql(3);
1739
+
1740
+ expect(res.data[1].summary, 'group2.summary').to.be.instanceof(Array);
1741
+ expect(res.data[1].summary, 'group2.summary').to.have.lengthOf(2);
1742
+ expect(res.data[1].summary[0], 'group2.sum(int1)').to.eql(60);
1743
+ expect(res.data[1].summary[1], 'group2.max(int2)').to.eql(1);
1744
+ });
1745
+ });
1746
+
1747
+ test('list should group with groupInterval quarter', function (tdone) {
1748
+ testQueryValues(tdone, {
1749
+ group: [{
1750
+ selector: 'date1',
1751
+ groupInterval: 'quarter'
1752
+ }],
1753
+ requireTotalCount: true,
1754
+ requireGroupCount: true
1755
+ }, function (res) {
1756
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
1757
+ expect(res.groupCount, 'groupCount').to.eql(2);
1758
+
1759
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1760
+ expect(res.data, 'group list length').to.have.lengthOf(2);
1761
+
1762
+ expect(res.data[0].key, 'group 1.key').to.not.be.undefined;
1763
+ expect(res.data[0].items, 'group 1.items').to.be.null;
1764
+ expect(res.data[0].count, 'group 1.count').to.eql(90);
1765
+ expect(res.data[1].key, 'group 2.key').to.not.be.undefined;
1766
+ expect(res.data[1].items, 'group 2.items').to.be.null;
1767
+ expect(res.data[1].count, 'group 2.count').to.eql(10);
1768
+ });
1769
+ });
1770
+
1771
+ test('list should group with groupInterval month', function (tdone) {
1772
+ testQueryValues(tdone, {
1773
+ group: [{
1774
+ selector: 'date1',
1775
+ groupInterval: 'month'
1776
+ }],
1777
+ requireTotalCount: true,
1778
+ requireGroupCount: true
1779
+ }, function (res) {
1780
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
1781
+ expect(res.groupCount, 'groupCount').to.eql(4);
1782
+
1783
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1784
+ expect(res.data, 'group list length').to.have.lengthOf(4);
1785
+
1786
+ expect(res.data[0].key, 'group 1.key').to.eql(1);
1787
+ expect(res.data[0].items, 'group 1.items').to.be.null;
1788
+ expect(res.data[0].count, 'group 1.count').to.eql(31);
1789
+ expect(res.data[1].key, 'group 2.key').to.eql(2);
1790
+ expect(res.data[1].items, 'group 2.items').to.be.null;
1791
+ expect(res.data[1].count, 'group 2.count').to.eql(28);
1792
+ expect(res.data[2].key, 'group 3.key').to.eql(3);
1793
+ expect(res.data[2].items, 'group 3.items').to.be.null;
1794
+ expect(res.data[2].count, 'group 3.count').to.eql(31);
1795
+ expect(res.data[3].key, 'group 4.key').to.eql(4);
1796
+ expect(res.data[3].items, 'group 4.items').to.be.null;
1797
+ expect(res.data[3].count, 'group 4.count').to.eql(10);
1798
+ });
1799
+ });
1800
+
1801
+ test('list should group with groupInterval dayOfWeek', function (tdone) {
1802
+ testQueryValues(tdone, {
1803
+ group: [{
1804
+ selector: 'date1',
1805
+ groupInterval: 'dayOfWeek'
1806
+ }],
1807
+ requireTotalCount: true,
1808
+ requireGroupCount: true
1809
+ }, function (res) {
1810
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
1811
+ expect(res.groupCount, 'groupCount').to.eql(7);
1812
+
1813
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1814
+ expect(res.data, 'group list length').to.have.lengthOf(7);
1815
+ });
1816
+ });
1817
+
1818
+ test('list should group with groupInterval 2', function (tdone) {
1819
+ testQueryValues(tdone, {
1820
+ group: [{
1821
+ selector: 'int1',
1822
+ groupInterval: 2
1823
+ }],
1824
+ requireTotalCount: true,
1825
+ requireGroupCount: true
1826
+ }, function (res) {
1827
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
1828
+ expect(res.groupCount, 'groupCount').to.eql(5);
1829
+
1830
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1831
+ expect(res.data, 'group list length').to.have.lengthOf(5);
1832
+
1833
+ expect(res.data[0].key, 'group 1 key').to.eql(0);
1834
+ expect(res.data[0].count, 'group 1 count').to.eql(20);
1835
+ expect(res.data[1].key, 'group 2 key').to.eql(2);
1836
+ expect(res.data[1].count, 'group 2 count').to.eql(20);
1837
+ expect(res.data[2].key, 'group 3 key').to.eql(4);
1838
+ expect(res.data[2].count, 'group 3 count').to.eql(20);
1839
+ expect(res.data[3].key, 'group 4 key').to.eql(6);
1840
+ expect(res.data[3].count, 'group 4 count').to.eql(20);
1841
+ expect(res.data[4].key, 'group 5 key').to.eql(8);
1842
+ expect(res.data[4].count, 'group 5 count').to.eql(20);
1843
+ });
1844
+ });
1845
+
1846
+ test('list should group with groupInterval quarter and summaries', function (tdone) {
1847
+ testQueryValues(tdone, {
1848
+ group: [{
1849
+ selector: 'date1',
1850
+ groupInterval: 'quarter'
1851
+ }],
1852
+ groupSummary: [{
1853
+ selector: 'int1',
1854
+ summaryType: 'count'
1855
+ }],
1856
+ totalSummary: [{
1857
+ selector: 'int1',
1858
+ summaryType: 'count'
1859
+ }],
1860
+ requireTotalCount: true,
1861
+ requireGroupCount: true
1862
+ }, function (res) {
1863
+ expect(res.totalCount, 'totalCount').to.eql(TESTRECORD_COUNT);
1864
+ expect(res.groupCount, 'groupCount').to.eql(2);
1865
+
1866
+ expect(res.data, 'res.data').to.be.instanceof(Array);
1867
+ expect(res.data, 'group list length').to.have.lengthOf(2);
1868
+
1869
+ expect(res.summary, 'res.summary').to.be.instanceof(Array);
1870
+ expect(res.summary, 'res.summary length').to.have.lengthOf(1);
1871
+
1872
+ expect(res.data[0].key, 'group 1.key').to.not.be.undefined;
1873
+ expect(res.data[0].items, 'group 1.items').to.be.null;
1874
+ expect(res.data[0].count, 'group 1.count').to.eql(90);
1875
+ expect(res.data[0].summary, 'group 1 summary').to.be.instanceof(Array);
1876
+ expect(res.data[0].summary, 'group 1 summary length').to.have.lengthOf(1);
1877
+
1878
+ expect(res.data[1].key, 'group 2.key').to.not.be.undefined;
1879
+ expect(res.data[1].items, 'group 2.items').to.be.null;
1880
+ expect(res.data[1].count, 'group 2.count').to.eql(10);
1881
+ expect(res.data[1].summary, 'group 2 summary').to.be.instanceof(Array);
1882
+ expect(res.data[1].summary, 'group 2 summary length').to.have.lengthOf(1);
1883
+ });
1884
+ });
1885
+
1886
+ test('query should work correctly for May 1st 2017', function (tdone) {
1887
+ testQueryValues(tdone, {
1888
+ filter: ['date1', '=', new Date(2017, 4, 1)],
1889
+ requireTotalCount: true
1890
+ }, function (res) {
1891
+ expect(res.totalCount, 'totalCount').to.eql(1);
1892
+ expect(res.data).to.have.lengthOf(1);
1893
+
1894
+ expect(new Date(res.data[0].date1)).to.eql(new Date(2017, 4, 1));
1895
+ }, function (collection) {
1896
+ return [collection.insertOne({
1897
+ date1: new Date(2017, 4, 1),
1898
+ date2: new Date(2017, 4, 1),
1899
+ int1: 10,
1900
+ int2: 10,
1901
+ string: 'something'
1902
+ })];
1903
+ });
1904
+ });
1905
+
1906
+ test('equalsObjectId operator with ObjectId value', function (tdone) {
1907
+ var testId = new ObjectId('0123456789abcdef01234567');
1908
+ testQueryValues(tdone, {
1909
+ filter: ['idField', 'equalsObjectId', testId],
1910
+ requireTotalCount: true
1911
+ }, function (res) {
1912
+ expect(res.totalCount, 'totalCount').to.eql(1);
1913
+ }, function (collection) {
1914
+ return [collection.insertOne({ idField: testId })];
1915
+ });
1916
+ });
1917
+
1918
+ test('equalsObjectId operator with string value', function (tdone) {
1919
+ var testId = new ObjectId('0123456789abcdef01234567');
1920
+ testQueryValues(tdone, {
1921
+ filter: ['idField', 'equalsObjectId', testId.toString()],
1922
+ requireTotalCount: true
1923
+ }, function (res) {
1924
+ expect(res.totalCount, 'totalCount').to.eql(1);
1925
+ }, function (collection) {
1926
+ return [collection.insertOne({ idField: testId })];
1927
+ });
1928
+ });
1929
+
1930
+ test('issue #40', function (tdone) {
1931
+ testQueryValues(tdone, {
1932
+ filter: [['date1', '>=', new Date(2017, 0, 15)], 'and', ['date1', '<', new Date(2017, 0, 16)]],
1933
+ requireTotalCount: true
1934
+ }, function (res) {
1935
+ expect(res.totalCount, 'totalCount').to.eql(1);
1936
+ expect(res.data).to.have.lengthOf(1);
1937
+ expect(new Date(res.data[0].date1)).to.eql(new Date(2017, 0, 15));
1938
+ });
1939
+ });
1940
+ });
1941
+ });