@firebase/database-compat 0.1.1-2021823172527 → 0.1.2-canary.0b3ca78eb

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +19 -8
  2. package/dist/database-compat/src/index.d.ts +0 -9
  3. package/dist/database-compat/src/index.node.d.ts +0 -53
  4. package/dist/database-compat/src/index.standalone.d.ts +52 -0
  5. package/dist/index.esm2017.js +5 -6
  6. package/dist/index.esm2017.js.map +1 -1
  7. package/dist/index.esm5.js +2 -3
  8. package/dist/index.esm5.js.map +1 -1
  9. package/dist/index.js +10 -77
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.standalone.js +15150 -0
  12. package/dist/index.standalone.js.map +1 -0
  13. package/dist/node-esm/database-compat/src/api/Database.d.ts +72 -0
  14. package/dist/node-esm/database-compat/src/api/Reference.d.ts +201 -0
  15. package/{karma.conf.js → dist/node-esm/database-compat/src/api/TransactionResult.d.ts} +26 -34
  16. package/dist/node-esm/database-compat/src/api/internal.d.ts +39 -0
  17. package/dist/node-esm/database-compat/src/api/onDisconnect.d.ts +27 -0
  18. package/dist/node-esm/database-compat/src/index.d.ts +32 -0
  19. package/dist/node-esm/database-compat/src/index.node.d.ts +14 -0
  20. package/dist/node-esm/database-compat/src/index.standalone.d.ts +52 -0
  21. package/{src/util/util.ts → dist/node-esm/database-compat/src/util/util.d.ts} +17 -25
  22. package/dist/node-esm/database-compat/src/util/validation.d.ts +18 -0
  23. package/{src/api/TransactionResult.ts → dist/node-esm/database-compat/test/browser/crawler_support.test.d.ts} +17 -34
  24. package/dist/node-esm/database-compat/test/database.test.d.ts +17 -0
  25. package/dist/node-esm/database-compat/test/datasnapshot.test.d.ts +17 -0
  26. package/dist/node-esm/database-compat/test/helpers/events.d.ts +34 -0
  27. package/dist/node-esm/database-compat/test/helpers/util.d.ts +42 -0
  28. package/dist/node-esm/database-compat/test/info.test.d.ts +17 -0
  29. package/dist/node-esm/database-compat/test/order.test.d.ts +17 -0
  30. package/dist/node-esm/database-compat/test/order_by.test.d.ts +17 -0
  31. package/dist/node-esm/database-compat/test/promise.test.d.ts +17 -0
  32. package/dist/node-esm/database-compat/test/query.test.d.ts +17 -0
  33. package/dist/node-esm/database-compat/test/servervalues.test.d.ts +17 -0
  34. package/dist/node-esm/database-compat/test/transaction.test.d.ts +17 -0
  35. package/dist/node-esm/index.js +868 -0
  36. package/dist/node-esm/index.js.map +1 -0
  37. package/dist/node-esm/package.json +1 -0
  38. package/package.json +34 -9
  39. package/standalone/package.json +7 -0
  40. package/.eslintrc.js +0 -64
  41. package/rollup.config.js +0 -125
  42. package/src/api/Database.ts +0 -123
  43. package/src/api/Reference.ts +0 -790
  44. package/src/api/internal.ts +0 -91
  45. package/src/api/onDisconnect.ts +0 -112
  46. package/src/index.node.ts +0 -142
  47. package/src/index.ts +0 -88
  48. package/src/util/validation.ts +0 -59
  49. package/test/browser/crawler_support.test.ts +0 -206
  50. package/test/database.test.ts +0 -306
  51. package/test/datasnapshot.test.ts +0 -249
  52. package/test/helpers/events.ts +0 -258
  53. package/test/helpers/util.ts +0 -177
  54. package/test/info.test.ts +0 -222
  55. package/test/order.test.ts +0 -592
  56. package/test/order_by.test.ts +0 -530
  57. package/test/promise.test.ts +0 -261
  58. package/test/query.test.ts +0 -4670
  59. package/test/servervalues.test.ts +0 -152
  60. package/test/transaction.test.ts +0 -1534
  61. package/tsconfig.json +0 -11
@@ -1,4670 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2017 Google LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- import { expect, use } from 'chai';
19
- import * as chaiAsPromised from 'chai-as-promised';
20
- import * as _ from 'lodash';
21
-
22
- import {
23
- INTEGER_32_MAX,
24
- INTEGER_32_MIN
25
- } from '../../database/src/core/util/util';
26
- import {
27
- EventAccumulator,
28
- EventAccumulatorFactory
29
- } from '../../database/test/helpers/EventAccumulator';
30
- import { DataSnapshot, Query, Reference } from '../src/api/Reference';
31
-
32
- import { getFreshRepo, getPath, getRandomNode, pause } from './helpers/util';
33
-
34
- use(chaiAsPromised);
35
-
36
- type TaskList = Array<[Query, any]>;
37
-
38
- describe('Query Tests', () => {
39
- // Little helper class for testing event callbacks w/ contexts.
40
- const EventReceiver = function () {
41
- this.gotValue = false;
42
- this.gotChildAdded = false;
43
- };
44
- EventReceiver.prototype.onValue = function () {
45
- this.gotValue = true;
46
- };
47
- EventReceiver.prototype.onChildAdded = function () {
48
- this.gotChildAdded = true;
49
- };
50
-
51
- it('Can create basic queries.', () => {
52
- const path = getRandomNode() as Reference;
53
-
54
- path.limitToLast(10);
55
- path.startAt('199').limitToFirst(10);
56
- path.startAfter('199').limitToFirst(10);
57
- path.startAt('199', 'test').limitToFirst(10);
58
- path.startAfter('199', 'test').limitToFirst(10);
59
- path.endAt('199').limitToLast(1);
60
- path.endBefore('199').limitToLast(1);
61
- path.startAt('50', 'test').endAt('100', 'tree');
62
- path.startAfter('50', 'test').endAt('100', 'tree');
63
- path.startAt('4').endAt('10');
64
- path.startAfter('4').endAt('10');
65
- path.startAt().limitToFirst(10);
66
- path.startAfter().limitToFirst(10);
67
- path.endAt().limitToLast(10);
68
- path.orderByKey().startAt('foo');
69
- path.orderByKey().startAfter('foo');
70
- path.orderByKey().endAt('foo');
71
- path.orderByKey().equalTo('foo');
72
- path.orderByChild('child');
73
- path.orderByChild('child/deep/path');
74
- path.orderByValue();
75
- path.orderByPriority();
76
- });
77
-
78
- it('Exposes database as read-only property', () => {
79
- const path = getRandomNode() as Reference;
80
- const child = path.child('child');
81
-
82
- const db = path.database;
83
- const dbChild = child.database;
84
-
85
- expect(db).to.equal(dbChild);
86
- expect(path.database).to.equal(db);
87
- });
88
-
89
- it('Invalid queries throw', () => {
90
- const path = getRandomNode() as Reference;
91
-
92
- /**
93
- * Because we are testing invalid queries, I am casting
94
- * to `any` to avoid the typechecking error. This can
95
- * occur when a user uses the SDK through a pure JS
96
- * client, rather than typescript
97
- */
98
- expect(() => {
99
- (path as any).limitToLast();
100
- }).to.throw();
101
- expect(() => {
102
- (path as any).limitToLast('100');
103
- }).to.throw();
104
- expect(() => {
105
- (path as any).limitToLast({ x: 5 });
106
- }).to.throw();
107
- expect(() => {
108
- path.limitToLast(100).limitToLast(100);
109
- }).to.throw();
110
- expect(() => {
111
- path.limitToLast(100).limitToFirst(100);
112
- }).to.throw();
113
- expect(() => {
114
- path.limitToLast(100).limitToLast(100);
115
- }).to.throw();
116
- expect(() => {
117
- path.limitToFirst(100).limitToLast(100);
118
- }).to.throw();
119
- expect(() => {
120
- path.limitToFirst(100).limitToFirst(100);
121
- }).to.throw();
122
- expect(() => {
123
- path.limitToFirst(100).limitToLast(100);
124
- }).to.throw();
125
- expect(() => {
126
- path.limitToLast(100).limitToLast(100);
127
- }).to.throw();
128
- expect(() => {
129
- path.limitToLast(100).limitToFirst(100);
130
- }).to.throw();
131
- expect(() => {
132
- path.limitToLast(100).limitToLast(100);
133
- }).to.throw();
134
- expect(() => {
135
- path.orderByPriority().orderByPriority();
136
- }).to.throw();
137
- expect(() => {
138
- path.orderByPriority().orderByKey();
139
- }).to.throw();
140
- expect(() => {
141
- path.orderByPriority().orderByChild('foo');
142
- }).to.throw();
143
- expect(() => {
144
- path.orderByPriority().startAt(true);
145
- }).to.throw();
146
- expect(() => {
147
- path.orderByPriority().startAfter(true);
148
- }).to.throw();
149
- expect(() => {
150
- path.orderByPriority().endAt(false);
151
- }).to.throw();
152
- expect(() => {
153
- path.orderByPriority().equalTo(true);
154
- }).to.throw();
155
- expect(() => {
156
- path.orderByKey().orderByPriority();
157
- }).to.throw();
158
- expect(() => {
159
- path.orderByKey().orderByKey();
160
- }).to.throw();
161
- expect(() => {
162
- path.orderByKey().orderByChild('foo');
163
- }).to.throw();
164
- expect(() => {
165
- path.orderByChild('foo').orderByPriority();
166
- }).to.throw();
167
- expect(() => {
168
- path.orderByChild('foo').orderByKey();
169
- }).to.throw();
170
- expect(() => {
171
- path.orderByChild('foo').orderByChild('foo');
172
- }).to.throw();
173
- expect(() => {
174
- (path as any).orderByChild('foo').startAt({ a: 1 });
175
- }).to.throw();
176
- expect(() => {
177
- (path as any).orderByChild('foo').startAfter({ a: 1 });
178
- }).to.throw();
179
- expect(() => {
180
- (path as any).orderByChild('foo').endAt({ a: 1 });
181
- }).to.throw();
182
- expect(() => {
183
- (path as any).orderByChild('foo').equalTo({ a: 1 });
184
- }).to.throw();
185
- expect(() => {
186
- path.startAt('foo').startAt('foo');
187
- }).to.throw();
188
- expect(() => {
189
- path.startAfter('foo').startAfter('foo');
190
- }).to.throw();
191
- expect(() => {
192
- path.startAt('foo').startAfter('foo');
193
- }).to.throw();
194
- expect(() => {
195
- path.startAfter('foo').startAt('foo');
196
- }).to.throw();
197
- expect(() => {
198
- path.startAt('foo').equalTo('foo');
199
- }).to.throw();
200
- expect(() => {
201
- path.startAfter('foo').equalTo('foo');
202
- }).to.throw();
203
- expect(() => {
204
- path.endAt('foo').endAt('foo');
205
- }).to.throw();
206
- expect(() => {
207
- path.endAt('foo').equalTo('foo');
208
- }).to.throw();
209
- expect(() => {
210
- path.equalTo('foo').startAt('foo');
211
- }).to.throw();
212
- expect(() => {
213
- path.equalTo('foo').startAfter('foo');
214
- }).to.throw();
215
- expect(() => {
216
- path.equalTo('foo').endAt('foo');
217
- }).to.throw();
218
- expect(() => {
219
- path.equalTo('foo').equalTo('foo');
220
- }).to.throw();
221
- expect(() => {
222
- path.orderByKey().startAt('foo', 'foo');
223
- }).to.throw();
224
- expect(() => {
225
- path.orderByKey().startAfter('foo', 'foo');
226
- }).to.throw();
227
- expect(() => {
228
- path.orderByKey().endAt('foo', 'foo');
229
- }).to.throw();
230
- expect(() => {
231
- path.orderByKey().equalTo('foo', 'foo');
232
- }).to.throw();
233
- expect(() => {
234
- path.orderByKey().startAt(1);
235
- }).to.throw();
236
- expect(() => {
237
- path.orderByKey().startAfter(1);
238
- }).to.throw();
239
- expect(() => {
240
- path.orderByKey().startAt(true);
241
- }).to.throw();
242
- expect(() => {
243
- path.orderByKey().startAfter(true);
244
- }).to.throw();
245
- expect(() => {
246
- path.orderByKey().startAt(null);
247
- }).to.throw();
248
- expect(() => {
249
- path.orderByKey().startAfter(null);
250
- }).to.throw();
251
- expect(() => {
252
- path.orderByKey().endAt(1);
253
- }).to.throw();
254
- expect(() => {
255
- path.orderByKey().endAt(true);
256
- }).to.throw();
257
- expect(() => {
258
- path.orderByKey().endAt(null);
259
- }).to.throw();
260
- expect(() => {
261
- path.orderByKey().equalTo(1);
262
- }).to.throw();
263
- expect(() => {
264
- path.orderByKey().equalTo(true);
265
- }).to.throw();
266
- expect(() => {
267
- path.orderByKey().equalTo(null);
268
- }).to.throw();
269
- expect(() => {
270
- path.startAt('foo', 'foo').orderByKey();
271
- }).to.throw();
272
- expect(() => {
273
- path.startAfter('foo', 'foo').orderByKey();
274
- }).to.throw();
275
- expect(() => {
276
- path.endAt('foo', 'foo').orderByKey();
277
- }).to.throw();
278
- expect(() => {
279
- path.equalTo('foo', 'foo').orderByKey();
280
- }).to.throw();
281
- expect(() => {
282
- path.startAt(1).orderByKey();
283
- }).to.throw();
284
- expect(() => {
285
- path.startAfter(1).orderByKey();
286
- }).to.throw();
287
- expect(() => {
288
- path.startAt(true).orderByKey();
289
- }).to.throw();
290
- expect(() => {
291
- path.startAfter(true).orderByKey();
292
- }).to.throw();
293
- expect(() => {
294
- path.endAt(1).orderByKey();
295
- }).to.throw();
296
- expect(() => {
297
- path.endAt(true).orderByKey();
298
- }).to.throw();
299
- });
300
-
301
- it('can produce a valid ref', () => {
302
- const path = getRandomNode() as Reference;
303
-
304
- const query = path.limitToLast(1);
305
- const ref = query.ref;
306
-
307
- expect(ref.toString()).to.equal(path.toString());
308
- });
309
-
310
- it('Passing invalidKeys to startAt / endAt throws.', () => {
311
- const f = getRandomNode() as Reference;
312
- const badKeys = [
313
- '.test',
314
- 'test.',
315
- 'fo$o',
316
- '[what',
317
- 'ever]',
318
- 'ha#sh',
319
- '/thing',
320
- 'th/ing',
321
- 'thing/'
322
- ];
323
- // Changed from basic array iteration to avoid closure issues accessing mutable state
324
- _.each(badKeys, badKey => {
325
- expect(() => {
326
- f.startAt(null, badKey);
327
- }).to.throw();
328
- expect(() => {
329
- f.endAt(null, badKey);
330
- }).to.throw();
331
- });
332
- });
333
-
334
- it('Passing invalidKeys to startAfter throws.', () => {
335
- const f = getRandomNode() as Reference;
336
- const badKeys = [
337
- '.test',
338
- 'test.',
339
- 'fo$o',
340
- '[what',
341
- 'ever]',
342
- 'ha#sh',
343
- '/thing',
344
- 'th/ing',
345
- 'thing/'
346
- ];
347
- // Changed from basic array iteration to avoid closure issues accessing mutable state
348
- _.each(badKeys, badKey => {
349
- expect(() => {
350
- f.startAfter(null, badKey);
351
- }).to.throw();
352
- });
353
- });
354
-
355
- it('Passing invalid paths to orderBy throws', () => {
356
- const ref = getRandomNode() as Reference;
357
- expect(() => {
358
- ref.orderByChild('$child/foo');
359
- }).to.throw();
360
- expect(() => {
361
- ref.orderByChild('$key');
362
- }).to.throw();
363
- expect(() => {
364
- ref.orderByChild('$priority');
365
- }).to.throw();
366
- });
367
-
368
- it('Query.queryIdentifier works.', () => {
369
- const path = getRandomNode() as Reference;
370
- const queryId = function (query) {
371
- return query._delegate._queryIdentifier;
372
- };
373
-
374
- expect(queryId(path)).to.equal('default');
375
-
376
- expect(queryId(path.startAt('pri', 'name'))).to.equal(
377
- '{"sn":"name","sp":"pri"}'
378
- );
379
- expect(queryId(path.startAfter('pri', 'name'))).to.equal(
380
- '{"sn":"name-","sp":"pri"}'
381
- );
382
- expect(queryId(path.startAt('spri').endAt('epri'))).to.equal(
383
- '{"ep":"epri","sp":"spri"}'
384
- );
385
- expect(queryId(path.startAfter('spri').endAt('epri'))).to.equal(
386
- '{"ep":"epri","sn":"[MAX_NAME]","sp":"spri"}'
387
- );
388
- expect(
389
- queryId(path.startAt('spri', 'sname').endAt('epri', 'ename'))
390
- ).to.equal('{"en":"ename","ep":"epri","sn":"sname","sp":"spri"}');
391
- expect(
392
- queryId(path.startAfter('spri', 'sname').endAt('epri', 'ename'))
393
- ).to.equal('{"en":"ename","ep":"epri","sn":"sname-","sp":"spri"}');
394
- expect(queryId(path.startAt('pri').limitToFirst(100))).to.equal(
395
- '{"l":100,"sp":"pri","vf":"l"}'
396
- );
397
- expect(queryId(path.startAfter('pri').limitToFirst(100))).to.equal(
398
- '{"l":100,"sn":"[MAX_NAME]","sp":"pri","vf":"l"}'
399
- );
400
- expect(queryId(path.startAt('bar').orderByChild('foo'))).to.equal(
401
- '{"i":"foo","sp":"bar"}'
402
- );
403
- expect(queryId(path.startAfter('bar').orderByChild('foo'))).to.equal(
404
- '{"i":"foo","sn":"[MAX_NAME]","sp":"bar"}'
405
- );
406
- });
407
-
408
- it('Passing invalid queries to isEqual throws', () => {
409
- const ref = getRandomNode() as Reference;
410
- expect(() => {
411
- (ref as any).isEqual();
412
- }).to.throw();
413
- expect(() => {
414
- (ref as any).isEqual('');
415
- }).to.throw();
416
- expect(() => {
417
- (ref as any).isEqual('foo');
418
- }).to.throw();
419
- expect(() => {
420
- (ref as any).isEqual({});
421
- }).to.throw();
422
- expect(() => {
423
- (ref as any).isEqual([]);
424
- }).to.throw();
425
- expect(() => {
426
- (ref as any).isEqual(0);
427
- }).to.throw();
428
- expect(() => {
429
- (ref as any).isEqual(1);
430
- }).to.throw();
431
- expect(() => {
432
- (ref as any).isEqual(NaN);
433
- }).to.throw();
434
- expect(() => {
435
- ref.isEqual(null);
436
- }).to.throw();
437
- expect(() => {
438
- (ref as any).isEqual({ a: 1 });
439
- }).to.throw();
440
- expect(() => {
441
- (ref as any).isEqual(ref, 'extra');
442
- }).to.throw();
443
- });
444
-
445
- it('Query.isEqual works.', () => {
446
- const path = getRandomNode() as Reference;
447
- const rootRef = path.root;
448
- const childRef = rootRef.child('child');
449
-
450
- // Equivalent refs
451
- expect(path.isEqual(path), 'Query.isEqual - 1').to.be.true;
452
- expect(rootRef.isEqual(rootRef), 'Query.isEqual - 2').to.be.true;
453
- expect(rootRef.isEqual(childRef.parent), 'Query.isEqual - 3').to.be.true;
454
- expect(rootRef.child('child').isEqual(childRef), 'Query.isEqual - 4').to.be
455
- .true;
456
-
457
- // Refs with different repos
458
- // NOTE: getFreshRepo() no longer takes a hostname, so this test needs to be reworked.
459
- // Same in info.test.ts.
460
- // var rootRefDifferentRepo = TESTS.getFreshRepo(TEST_ALT_NAMESPACE);
461
- // rootRefDifferentRepo.database.goOffline();
462
-
463
- // expect(rootRef.isEqual(rootRefDifferentRepo), 'Query.isEqual - 5').to.be.false;
464
- // expect(childRef.isEqual(rootRefDifferentRepo.child('child')), 'Query.isEqual - 6').to.be.false;
465
-
466
- // Refs with different paths
467
- expect(rootRef.isEqual(childRef), 'Query.isEqual - 7').to.be.false;
468
- expect(childRef.isEqual(rootRef.child('otherChild')), 'Query.isEqual - 8')
469
- .to.be.false;
470
-
471
- const childQueryLast25 = childRef.limitToLast(25);
472
- const childQueryOrderedByKey = childRef.orderByKey();
473
- const childQueryOrderedByPriority = childRef.orderByPriority();
474
- const childQueryOrderedByTimestamp = childRef.orderByChild('timestamp');
475
- const childQueryStartAt1 = childQueryOrderedByTimestamp.startAt(1);
476
- const childQueryStartAt2 = childQueryOrderedByTimestamp.startAt(2);
477
- const childQueryStartAfter1 = childQueryOrderedByTimestamp.startAfter(1);
478
- const childQueryStartAfter2 = childQueryOrderedByTimestamp.startAfter(2);
479
- const childQueryEndAt2 = childQueryOrderedByTimestamp.endAt(2);
480
- const childQueryStartAt1EndAt2 = childQueryOrderedByTimestamp
481
- .startAt(1)
482
- .endAt(2);
483
- const childQueryStartAfter1EndAt2 = childQueryOrderedByTimestamp
484
- .startAfter(1)
485
- .endAt(2);
486
-
487
- // Equivalent queries
488
- expect(childRef.isEqual(childQueryLast25.ref), 'Query.isEqual - 9').to.be
489
- .true;
490
- expect(
491
- childQueryLast25.isEqual(childRef.limitToLast(25)),
492
- 'Query.isEqual - 10'
493
- ).to.be.true;
494
- expect(
495
- childQueryStartAt1EndAt2.isEqual(
496
- childQueryOrderedByTimestamp.startAt(1).endAt(2)
497
- ),
498
- 'Query.isEqual - 11'
499
- ).to.be.true;
500
-
501
- // Non-equivalent queries
502
- expect(childQueryLast25.isEqual(childRef), 'Query.isEqual - 12').to.be
503
- .false;
504
- expect(
505
- childQueryLast25.isEqual(childQueryOrderedByKey),
506
- 'Query.isEqual - 13'
507
- ).to.be.false;
508
- expect(
509
- childQueryLast25.isEqual(childQueryOrderedByPriority),
510
- 'Query.isEqual - 14'
511
- ).to.be.false;
512
- expect(
513
- childQueryLast25.isEqual(childQueryOrderedByTimestamp),
514
- 'Query.isEqual - 15'
515
- ).to.be.false;
516
- expect(
517
- childQueryOrderedByKey.isEqual(childQueryOrderedByPriority),
518
- 'Query.isEqual - 16'
519
- ).to.be.false;
520
- expect(
521
- childQueryOrderedByKey.isEqual(childQueryOrderedByTimestamp),
522
- 'Query.isEqual - 17'
523
- ).to.be.false;
524
- expect(childQueryStartAt1.isEqual(childQueryStartAt2), 'Query.isEqual - 18')
525
- .to.be.false;
526
- expect(
527
- childQueryStartAfter1.isEqual(childQueryStartAfter2),
528
- 'Query.isEqual - 19'
529
- ).to.be.false;
530
- expect(
531
- childQueryStartAt1.isEqual(childQueryStartAt1EndAt2),
532
- 'Query.isEqual - 20'
533
- ).to.be.false;
534
- expect(
535
- childQueryStartAfter1.isEqual(childQueryStartAfter1EndAt2),
536
- 'Query.isEqual - 21'
537
- ).to.be.false;
538
- expect(childQueryEndAt2.isEqual(childQueryStartAt2), 'Query.isEqual - 22')
539
- .to.be.false;
540
- expect(
541
- childQueryEndAt2.isEqual(childQueryStartAt1EndAt2),
542
- 'Query.isEqual - 23'
543
- ).to.be.false;
544
- });
545
-
546
- it('Query.off can be called on the default query.', () => {
547
- const path = getRandomNode() as Reference;
548
- let eventFired = false;
549
-
550
- const callback = function () {
551
- eventFired = true;
552
- };
553
- path.limitToLast(5).on('value', callback);
554
-
555
- path.set({ a: 5, b: 6 });
556
- expect(eventFired).to.be.true;
557
- eventFired = false;
558
-
559
- path.off('value', callback);
560
- path.set({ a: 6, b: 5 });
561
- expect(eventFired).to.be.false;
562
- });
563
-
564
- it('Query.off can be called on the specific query.', () => {
565
- const path = getRandomNode() as Reference;
566
- let eventFired = false;
567
-
568
- const callback = function () {
569
- eventFired = true;
570
- };
571
- path.limitToLast(5).on('value', callback);
572
-
573
- path.set({ a: 5, b: 6 });
574
- expect(eventFired).to.be.true;
575
- eventFired = false;
576
-
577
- path.limitToLast(5).off('value', callback);
578
- path.set({ a: 6, b: 5 });
579
- expect(eventFired).to.be.false;
580
- });
581
-
582
- it('Query.off can be called without a callback specified.', () => {
583
- const path = getRandomNode() as Reference;
584
- let eventFired = false;
585
-
586
- const callback1 = function () {
587
- eventFired = true;
588
- };
589
- const callback2 = function () {
590
- eventFired = true;
591
- };
592
- path.on('value', callback1);
593
- path.limitToLast(5).on('value', callback2);
594
-
595
- path.set({ a: 5, b: 6 });
596
- expect(eventFired).to.be.true;
597
- eventFired = false;
598
-
599
- path.off('value');
600
- path.set({ a: 6, b: 5 });
601
- expect(eventFired).to.be.false;
602
- });
603
-
604
- it('Query.off can be called without an event type or callback specified.', () => {
605
- const path = getRandomNode() as Reference;
606
- let eventFired = false;
607
-
608
- const callback1 = function () {
609
- eventFired = true;
610
- };
611
- const callback2 = function () {
612
- eventFired = true;
613
- };
614
- path.on('value', callback1);
615
- path.limitToLast(5).on('value', callback2);
616
-
617
- path.set({ a: 5, b: 6 });
618
- expect(eventFired).to.be.true;
619
- eventFired = false;
620
-
621
- path.off();
622
- path.set({ a: 6, b: 5 });
623
- expect(eventFired).to.be.false;
624
- });
625
-
626
- it('Query.off respects provided context (for value events).', () => {
627
- const ref = getRandomNode() as Reference;
628
-
629
- const a = new EventReceiver(),
630
- b = new EventReceiver();
631
-
632
- ref.on('value', a.onValue, a);
633
- ref.on('value', b.onValue, b);
634
-
635
- ref.set('hello!');
636
- expect(a.gotValue).to.be.true;
637
- expect(b.gotValue).to.be.true;
638
- a.gotValue = b.gotValue = false;
639
-
640
- // unsubscribe b
641
- ref.off('value', b.onValue, b);
642
-
643
- // Only a should get this event.
644
- ref.set(42);
645
- expect(a.gotValue).to.be.true;
646
- expect(b.gotValue).to.be.false;
647
-
648
- ref.off('value', a.onValue, a);
649
- });
650
-
651
- it('Query.off respects provided context (for child events).', () => {
652
- const ref = getRandomNode() as Reference;
653
-
654
- const a = new EventReceiver(),
655
- b = new EventReceiver();
656
-
657
- ref.on('child_added', a.onChildAdded, a);
658
- ref.on('child_added', b.onChildAdded, b);
659
-
660
- ref.push('hello!');
661
- expect(a.gotChildAdded).to.be.true;
662
- expect(b.gotChildAdded).to.be.true;
663
- a.gotChildAdded = b.gotChildAdded = false;
664
-
665
- // unsubscribe b.
666
- ref.off('child_added', b.onChildAdded, b);
667
-
668
- // Only a should get this event.
669
- ref.push(42);
670
- expect(a.gotChildAdded).to.be.true;
671
- expect(b.gotChildAdded).to.be.false;
672
-
673
- ref.off('child_added', a.onChildAdded, a);
674
- });
675
-
676
- it('Query.off with no callback/context removes all callbacks, even with contexts (for value events).', () => {
677
- const ref = getRandomNode() as Reference;
678
-
679
- const a = new EventReceiver(),
680
- b = new EventReceiver();
681
-
682
- ref.on('value', a.onValue, a);
683
- ref.on('value', b.onValue, b);
684
-
685
- ref.set('hello!');
686
- expect(a.gotValue).to.be.true;
687
- expect(b.gotValue).to.be.true;
688
- a.gotValue = b.gotValue = false;
689
-
690
- // unsubscribe value events.
691
- ref.off('value');
692
-
693
- // Should get no events.
694
- ref.set(42);
695
- expect(a.gotValue).to.be.false;
696
- expect(b.gotValue).to.be.false;
697
- });
698
-
699
- it('Query.off with no callback/context removes all callbacks, even with contexts (for child events).', () => {
700
- const ref = getRandomNode() as Reference;
701
-
702
- const a = new EventReceiver(),
703
- b = new EventReceiver();
704
-
705
- ref.on('child_added', a.onChildAdded, a);
706
- ref.on('child_added', b.onChildAdded, b);
707
-
708
- ref.push('hello!');
709
- expect(a.gotChildAdded).to.be.true;
710
- expect(b.gotChildAdded).to.be.true;
711
- a.gotChildAdded = b.gotChildAdded = false;
712
-
713
- // unsubscribe child_added.
714
- ref.off('child_added');
715
-
716
- // Should get no events.
717
- ref.push(42);
718
- expect(a.gotChildAdded).to.be.false;
719
- expect(b.gotChildAdded).to.be.false;
720
- });
721
-
722
- it('Query.off with no event type / callback removes all callbacks (even those with contexts).', () => {
723
- const ref = getRandomNode() as Reference;
724
-
725
- const a = new EventReceiver(),
726
- b = new EventReceiver();
727
-
728
- ref.on('value', a.onValue, a);
729
- ref.on('value', b.onValue, b);
730
- ref.on('child_added', a.onChildAdded, a);
731
- ref.on('child_added', b.onChildAdded, b);
732
-
733
- ref.set(null);
734
- ref.push('hello!');
735
- expect(a.gotChildAdded).to.be.true;
736
- expect(a.gotValue).to.be.true;
737
- expect(b.gotChildAdded).to.be.true;
738
- expect(b.gotValue).to.be.true;
739
- a.gotValue = b.gotValue = a.gotChildAdded = b.gotChildAdded = false;
740
-
741
- // unsubscribe all events.
742
- ref.off();
743
-
744
- // We should get no events.
745
- ref.push(42);
746
- expect(a.gotChildAdded).to.be.false;
747
- expect(b.gotChildAdded).to.be.false;
748
- expect(a.gotValue).to.be.false;
749
- expect(b.gotValue).to.be.false;
750
- });
751
-
752
- it('Set a limit of 5, add a bunch of nodes, ensure only last 5 items are kept.', () => {
753
- const node = getRandomNode() as Reference;
754
- let snap = null;
755
- node.limitToLast(5).on('value', s => {
756
- snap = s;
757
- });
758
-
759
- node.set({});
760
- for (let i = 0; i < 10; i++) {
761
- node.push().set(i);
762
- }
763
-
764
- let expected = 5;
765
- snap.forEach(child => {
766
- expect(child.val()).to.equal(expected);
767
- expected++;
768
- });
769
-
770
- expect(expected).to.equal(10);
771
- });
772
-
773
- it('Raises snapshots synchronously', () => {
774
- const node = getRandomNode() as Reference;
775
- let newValue;
776
- node.on('value', v => {
777
- newValue = v.val();
778
- });
779
- node.set('foo');
780
- expect(newValue).to.equal('foo');
781
- });
782
-
783
- it('Set a limit of 5, add a bunch of nodes, ensure only last 5 items are sent from server.', async () => {
784
- const node = getRandomNode() as Reference;
785
- await node.set({});
786
-
787
- const pushPromises = [];
788
-
789
- for (let i = 0; i < 10; i++) {
790
- const promise = node.push().set(i);
791
- pushPromises.push(promise);
792
- }
793
-
794
- await Promise.all(pushPromises);
795
-
796
- const ea = EventAccumulatorFactory.waitsForCount(1);
797
-
798
- node.limitToLast(5).on('value', snap => {
799
- ea.addEvent(snap);
800
- });
801
-
802
- const [snap] = await ea.promise;
803
-
804
- let expected = 5;
805
-
806
- snap.forEach(child => {
807
- expect(child.val()).to.equal(expected);
808
- expected++;
809
- });
810
-
811
- expect(expected).to.equal(10);
812
- });
813
-
814
- it('Set various limits, ensure resulting data is correct.', async () => {
815
- const node = getRandomNode() as Reference;
816
-
817
- await node.set({ a: 1, b: 2, c: 3 });
818
-
819
- const tasks: TaskList = [
820
- [node.limitToLast(1), { c: 3 }],
821
- [node.endAt().limitToLast(1), { c: 3 }],
822
- [node.limitToLast(2), { b: 2, c: 3 }],
823
- [node.limitToLast(3), { a: 1, b: 2, c: 3 }],
824
- [node.limitToLast(4), { a: 1, b: 2, c: 3 }]
825
- ];
826
-
827
- return Promise.all(
828
- tasks.map(async task => {
829
- const [query, val] = task;
830
- const ea = EventAccumulatorFactory.waitsForCount(1);
831
- query.on('value', snap => {
832
- ea.addEvent(snap.val());
833
- });
834
- const [newVal] = await ea.promise;
835
- expect(newVal).to.deep.equal(val);
836
- })
837
- );
838
- });
839
-
840
- it('Set various limits with a startAt name, ensure resulting data is correct.', async () => {
841
- const node = getRandomNode() as Reference;
842
-
843
- await node.set({ a: 1, b: 2, c: 3 });
844
-
845
- const tasks: TaskList = [
846
- [node.startAt().limitToFirst(1), { a: 1 }],
847
- [node.startAt(null, 'c').limitToFirst(1), { c: 3 }],
848
- [node.startAt(null, 'b').limitToFirst(1), { b: 2 }],
849
- [node.startAt(null, 'b').limitToFirst(2), { b: 2, c: 3 }],
850
- [node.startAt(null, 'b').limitToFirst(3), { b: 2, c: 3 }],
851
- [node.startAt(null, 'b').limitToLast(1), { c: 3 }],
852
- [node.startAt(null, 'b').limitToLast(1), { c: 3 }],
853
- [node.startAt(null, 'b').limitToLast(2), { b: 2, c: 3 }],
854
- [node.startAt(null, 'b').limitToLast(3), { b: 2, c: 3 }],
855
- [node.limitToFirst(1).startAt(null, 'c'), { c: 3 }],
856
- [node.limitToFirst(1).startAt(null, 'b'), { b: 2 }],
857
- [node.limitToFirst(2).startAt(null, 'b'), { b: 2, c: 3 }],
858
- [node.limitToFirst(3).startAt(null, 'b'), { b: 2, c: 3 }],
859
- [node.limitToLast(1).startAt(null, 'b'), { c: 3 }],
860
- [node.limitToLast(1).startAt(null, 'b'), { c: 3 }],
861
- [node.limitToLast(2).startAt(null, 'b'), { b: 2, c: 3 }],
862
- [node.limitToLast(3).startAt(null, 'b'), { b: 2, c: 3 }]
863
- ];
864
-
865
- return Promise.all(
866
- tasks.map(async task => {
867
- const [query, val] = task;
868
- const ea = EventAccumulatorFactory.waitsForCount(1);
869
- query.on('value', snap => {
870
- ea.addEvent(snap.val());
871
- });
872
- const [newVal] = await ea.promise;
873
- expect(newVal).to.deep.equal(val);
874
- })
875
- );
876
- });
877
-
878
- it('Set various limits with a startAfter name, ensure resulting data is correct.', async () => {
879
- const node = getRandomNode() as Reference;
880
-
881
- await node.set({ a: 1, b: 2, c: 3, d: 4 });
882
-
883
- const tasks: TaskList = [
884
- // Using the priority index here, so startAfter() skips everything.
885
- [node.startAfter().limitToFirst(1), null],
886
- [node.startAfter(null, 'c').limitToFirst(1), { d: 4 }],
887
- [node.startAfter(null, 'b').limitToFirst(1), { c: 3 }],
888
- [node.startAfter(null, 'b').limitToFirst(2), { c: 3, d: 4 }],
889
- [node.startAfter(null, 'b').limitToFirst(3), { c: 3, d: 4 }],
890
- [node.startAfter(null, 'b').limitToLast(1), { d: 4 }],
891
- [node.startAfter(null, 'b').limitToLast(1), { d: 4 }],
892
- [node.startAfter(null, 'b').limitToLast(2), { c: 3, d: 4 }],
893
- [node.startAfter(null, 'b').limitToLast(3), { c: 3, d: 4 }],
894
- [node.limitToFirst(1).startAfter(null, 'c'), { d: 4 }],
895
- [node.limitToFirst(1).startAfter(null, 'b'), { c: 3 }],
896
- [node.limitToFirst(2).startAfter(null, 'b'), { c: 3, d: 4 }],
897
- [node.limitToFirst(3).startAfter(null, 'b'), { c: 3, d: 4 }],
898
- [node.limitToLast(1).startAfter(null, 'b'), { d: 4 }],
899
- [node.limitToLast(1).startAfter(null, 'b'), { d: 4 }],
900
- [node.limitToLast(2).startAfter(null, 'b'), { c: 3, d: 4 }],
901
- [node.limitToLast(3).startAfter(null, 'b'), { c: 3, d: 4 }]
902
- ];
903
-
904
- return Promise.all(
905
- tasks.map(async task => {
906
- const [query, val] = task;
907
- const ea = EventAccumulatorFactory.waitsForCount(1);
908
- query.on('value', snap => {
909
- ea.addEvent(snap.val());
910
- });
911
- const [newVal] = await ea.promise;
912
- expect(newVal).to.deep.equal(val);
913
- })
914
- );
915
- });
916
-
917
- it('Set various limits with a endAt name, ensure resulting data is correct.', async () => {
918
- const node = getRandomNode() as Reference;
919
-
920
- await node.set({ a: 1, b: 2, c: 3 });
921
-
922
- const tasks: TaskList = [
923
- [node.endAt().limitToFirst(1), { a: 1 }],
924
- [node.endAt(null, 'c').limitToFirst(1), { a: 1 }],
925
- [node.endAt(null, 'b').limitToFirst(1), { a: 1 }],
926
- [node.endAt(null, 'b').limitToFirst(2), { a: 1, b: 2 }],
927
- [node.endAt(null, 'b').limitToFirst(3), { a: 1, b: 2 }],
928
- [node.endAt(null, 'c').limitToLast(1), { c: 3 }],
929
- [node.endAt(null, 'b').limitToLast(1), { b: 2 }],
930
- [node.endAt(null, 'b').limitToLast(2), { a: 1, b: 2 }],
931
- [node.endAt(null, 'b').limitToLast(3), { a: 1, b: 2 }],
932
- [node.limitToFirst(1).endAt(null, 'c'), { a: 1 }],
933
- [node.limitToFirst(1).endAt(null, 'b'), { a: 1 }],
934
- [node.limitToFirst(2).endAt(null, 'b'), { a: 1, b: 2 }],
935
- [node.limitToFirst(3).endAt(null, 'b'), { a: 1, b: 2 }],
936
- [node.limitToLast(1).endAt(null, 'c'), { c: 3 }],
937
- [node.limitToLast(1).endAt(null, 'b'), { b: 2 }],
938
- [node.limitToLast(2).endAt(null, 'b'), { a: 1, b: 2 }],
939
- [node.limitToLast(3).endAt(null, 'b'), { a: 1, b: 2 }]
940
- ];
941
-
942
- return Promise.all(
943
- tasks.map(async task => {
944
- const [query, val] = task;
945
- const ea = EventAccumulatorFactory.waitsForCount(1);
946
- query.on('value', snap => {
947
- ea.addEvent(snap.val());
948
- });
949
- const [newVal] = await ea.promise;
950
- expect(newVal).to.deep.equal(val);
951
- })
952
- );
953
- });
954
-
955
- it('Set various limits with a startAt name, ensure resulting data is correct from the server.', async () => {
956
- const node = getRandomNode() as Reference;
957
-
958
- await node.set({ a: 1, b: 2, c: 3 });
959
-
960
- const tasks: TaskList = [
961
- [node.startAt().limitToFirst(1), { a: 1 }],
962
- [node.startAt(null, 'c').limitToFirst(1), { c: 3 }],
963
- [node.startAt(null, 'b').limitToFirst(1), { b: 2 }],
964
- // NOTE: technically there is a race condition here. The limitToFirst(1) query will return a single value, which will be
965
- // raised for the limitToFirst(2) callback as well, if it exists already. However, once the server gets the limitToFirst(2)
966
- // query, it will send more data and the correct state will be returned.
967
- [node.startAt(null, 'b').limitToFirst(2), { b: 2, c: 3 }],
968
- [node.startAt(null, 'b').limitToFirst(3), { b: 2, c: 3 }]
969
- ];
970
-
971
- return Promise.all(
972
- tasks.map(async task => {
973
- const [query, val] = task;
974
- const ea = EventAccumulatorFactory.waitsForCount(1);
975
- query.on('value', snap => {
976
- ea.addEvent(snap.val());
977
- });
978
- const [newVal] = await ea.promise;
979
- expect(newVal).to.deep.equal(val);
980
- })
981
- );
982
- });
983
-
984
- it('Set limit, ensure child_removed and child_added events are fired when limit is hit.', () => {
985
- const node = getRandomNode() as Reference;
986
- let added = '',
987
- removed = '';
988
- node.limitToLast(2).on('child_added', snap => {
989
- added += snap.key + ' ';
990
- });
991
- node.limitToLast(2).on('child_removed', snap => {
992
- removed += snap.key + ' ';
993
- });
994
- node.set({ a: 1, b: 2, c: 3 });
995
-
996
- expect(added).to.equal('b c ');
997
- expect(removed).to.equal('');
998
-
999
- added = '';
1000
- node.child('d').set(4);
1001
- expect(added).to.equal('d ');
1002
- expect(removed).to.equal('b ');
1003
- });
1004
-
1005
- it('Set limit, ensure child_removed and child_added events are fired when limit is hit, using server data', async () => {
1006
- const node = getRandomNode() as Reference;
1007
-
1008
- await node.set({ a: 1, b: 2, c: 3 });
1009
-
1010
- const ea = EventAccumulatorFactory.waitsForCount(2);
1011
-
1012
- let added = '',
1013
- removed = '';
1014
- node.limitToLast(2).on('child_added', snap => {
1015
- added += snap.key + ' ';
1016
- ea.addEvent();
1017
- });
1018
- node.limitToLast(2).on('child_removed', snap => {
1019
- removed += snap.key + ' ';
1020
- });
1021
-
1022
- await ea.promise;
1023
-
1024
- expect(added).to.equal('b c ');
1025
- expect(removed).to.equal('');
1026
-
1027
- added = '';
1028
- await node.child('d').set(4);
1029
-
1030
- expect(added).to.equal('d ');
1031
- expect(removed).to.equal('b ');
1032
- });
1033
-
1034
- it('Set start and limit, ensure child_removed and child_added events are fired when limit is hit.', () => {
1035
- const node = getRandomNode() as Reference;
1036
-
1037
- let added = '',
1038
- removed = '';
1039
- node
1040
- .startAt(null, 'a')
1041
- .limitToFirst(2)
1042
- .on('child_added', snap => {
1043
- added += snap.key + ' ';
1044
- });
1045
- node
1046
- .startAt(null, 'a')
1047
- .limitToFirst(2)
1048
- .on('child_removed', snap => {
1049
- removed += snap.key + ' ';
1050
- });
1051
- node.set({ a: 1, b: 2, c: 3 });
1052
- expect(added).to.equal('a b ');
1053
- expect(removed).to.equal('');
1054
-
1055
- added = '';
1056
- node.child('aa').set(4);
1057
- expect(added).to.equal('aa ');
1058
- expect(removed).to.equal('b ');
1059
- });
1060
-
1061
- it('Set startAfter and limit, ensure child_removed and child_added events are fired when limit is hit.', () => {
1062
- const node = getRandomNode() as Reference;
1063
-
1064
- let added = '',
1065
- removed = '';
1066
- node
1067
- .startAfter(null, 'a')
1068
- .limitToFirst(2)
1069
- .on('child_added', snap => {
1070
- added += snap.key + ' ';
1071
- });
1072
- node
1073
- .startAfter(null, 'a')
1074
- .limitToFirst(2)
1075
- .on('child_removed', snap => {
1076
- removed += snap.key + ' ';
1077
- });
1078
- node.set({ a: 1, b: 2, c: 3 });
1079
- expect(added).to.equal('b c ');
1080
- expect(removed).to.equal('');
1081
-
1082
- added = '';
1083
- node.child('aa').set(4);
1084
- expect(added).to.equal('aa ');
1085
- expect(removed).to.equal('c ');
1086
- });
1087
-
1088
- it('Set start and limit, ensure child_removed and child_added events are fired when limit is hit, using server data', async () => {
1089
- const node = getRandomNode() as Reference;
1090
-
1091
- await node.set({ a: 1, b: 2, c: 3 });
1092
- const ea = EventAccumulatorFactory.waitsForCount(2);
1093
-
1094
- let added = '',
1095
- removed = '';
1096
- node
1097
- .startAt(null, 'a')
1098
- .limitToFirst(2)
1099
- .on('child_added', snap => {
1100
- added += snap.key + ' ';
1101
- ea.addEvent();
1102
- });
1103
- node
1104
- .startAt(null, 'a')
1105
- .limitToFirst(2)
1106
- .on('child_removed', snap => {
1107
- removed += snap.key + ' ';
1108
- });
1109
-
1110
- await ea.promise;
1111
-
1112
- expect(added).to.equal('a b ');
1113
- expect(removed).to.equal('');
1114
-
1115
- added = '';
1116
- await node.child('aa').set(4);
1117
-
1118
- expect(added).to.equal('aa ');
1119
- expect(removed).to.equal('b ');
1120
- });
1121
-
1122
- it('Set start and limit, ensure child_removed and child_added events are fired when limit is hit, using server data', async () => {
1123
- const node = getRandomNode() as Reference;
1124
-
1125
- await node.set({ a: 1, b: 2, c: 3 });
1126
- const ea = EventAccumulatorFactory.waitsForCount(2);
1127
-
1128
- let added = '',
1129
- removed = '';
1130
- node
1131
- .startAfter(null, 'a')
1132
- .limitToFirst(2)
1133
- .on('child_added', snap => {
1134
- added += snap.key + ' ';
1135
- ea.addEvent();
1136
- });
1137
- node
1138
- .startAfter(null, 'a')
1139
- .limitToFirst(2)
1140
- .on('child_removed', snap => {
1141
- removed += snap.key + ' ';
1142
- });
1143
-
1144
- await ea.promise;
1145
-
1146
- expect(added).to.equal('b c ');
1147
- expect(removed).to.equal('');
1148
-
1149
- added = '';
1150
- await node.child('bb').set(4);
1151
-
1152
- expect(added).to.equal('bb ');
1153
- expect(removed).to.equal('c ');
1154
- });
1155
-
1156
- it("Set start and limit, ensure child_added events are fired when limit isn't hit yet.", () => {
1157
- const node = getRandomNode() as Reference;
1158
-
1159
- let added = '',
1160
- removed = '';
1161
- node
1162
- .startAt(null, 'a')
1163
- .limitToFirst(2)
1164
- .on('child_added', snap => {
1165
- added += snap.key + ' ';
1166
- });
1167
- node
1168
- .startAt(null, 'a')
1169
- .limitToFirst(2)
1170
- .on('child_removed', snap => {
1171
- removed += snap.key + ' ';
1172
- });
1173
- node.set({ c: 3 });
1174
- expect(added).to.equal('c ');
1175
- expect(removed).to.equal('');
1176
-
1177
- added = '';
1178
- node.child('b').set(4);
1179
- expect(added).to.equal('b ');
1180
- expect(removed).to.equal('');
1181
- });
1182
-
1183
- it("Set startAfter and limit, ensure child_added events are fired when limit isn't hit yet.", () => {
1184
- const node = getRandomNode() as Reference;
1185
-
1186
- let added = '',
1187
- removed = '';
1188
- node
1189
- .startAfter(null, 'a')
1190
- .limitToFirst(2)
1191
- .on('child_added', snap => {
1192
- added += snap.key + ' ';
1193
- });
1194
- node
1195
- .startAfter(null, 'a')
1196
- .limitToFirst(2)
1197
- .on('child_removed', snap => {
1198
- removed += snap.key + ' ';
1199
- });
1200
- node.set({ c: 3 });
1201
- expect(added).to.equal('c ');
1202
- expect(removed).to.equal('');
1203
-
1204
- added = '';
1205
- node.child('b').set(4);
1206
- expect(added).to.equal('b ');
1207
- expect(removed).to.equal('');
1208
- });
1209
-
1210
- it("Set start and limit, ensure child_added events are fired when limit isn't hit yet, using server data", async () => {
1211
- const node = getRandomNode() as Reference;
1212
-
1213
- await node.set({ c: 3 });
1214
-
1215
- const ea = EventAccumulatorFactory.waitsForCount(1);
1216
-
1217
- let added = '';
1218
- let removed = '';
1219
- node
1220
- .startAt(null, 'a')
1221
- .limitToFirst(2)
1222
- .on('child_added', snap => {
1223
- added += snap.key + ' ';
1224
- ea.addEvent();
1225
- });
1226
- node
1227
- .startAt(null, 'a')
1228
- .limitToFirst(2)
1229
- .on('child_removed', snap => {
1230
- removed += snap.key + ' ';
1231
- });
1232
-
1233
- await ea.promise;
1234
-
1235
- expect(added).to.equal('c ');
1236
- expect(removed).to.equal('');
1237
-
1238
- added = '';
1239
- await node.child('b').set(4);
1240
-
1241
- expect(added).to.equal('b ');
1242
- expect(removed).to.equal('');
1243
- });
1244
-
1245
- it("Set startAfter and limit, ensure child_added events are fired when limit isn't hit yet, using server data", async () => {
1246
- const node = getRandomNode() as Reference;
1247
-
1248
- await node.set({ c: 3 });
1249
-
1250
- const ea = EventAccumulatorFactory.waitsForCount(1);
1251
-
1252
- let added = '';
1253
- let removed = '';
1254
- node
1255
- .startAfter(null, 'a')
1256
- .limitToFirst(2)
1257
- .on('child_added', snap => {
1258
- added += snap.key + ' ';
1259
- ea.addEvent();
1260
- });
1261
- node
1262
- .startAfter(null, 'a')
1263
- .limitToFirst(2)
1264
- .on('child_removed', snap => {
1265
- removed += snap.key + ' ';
1266
- });
1267
-
1268
- await ea.promise;
1269
-
1270
- expect(added).to.equal('c ');
1271
- expect(removed).to.equal('');
1272
-
1273
- added = '';
1274
- await node.child('b').set(4);
1275
-
1276
- expect(added).to.equal('b ');
1277
- expect(removed).to.equal('');
1278
- });
1279
-
1280
- it('Set a limit, ensure child_removed and child_added events are fired when limit is satisfied and you remove an item.', async () => {
1281
- const node = getRandomNode() as Reference;
1282
- const ea = EventAccumulatorFactory.waitsForCount(1);
1283
-
1284
- let added = '',
1285
- removed = '';
1286
- node.limitToLast(2).on('child_added', snap => {
1287
- added += snap.key + ' ';
1288
- ea.addEvent();
1289
- });
1290
- node.limitToLast(2).on('child_removed', snap => {
1291
- removed += snap.key + ' ';
1292
- });
1293
- node.set({ a: 1, b: 2, c: 3 });
1294
- expect(added).to.equal('b c ');
1295
- expect(removed).to.equal('');
1296
-
1297
- added = '';
1298
- node.child('b').remove();
1299
- expect(removed).to.equal('b ');
1300
-
1301
- await ea.promise;
1302
- });
1303
-
1304
- it('Set a limit, ensure child_removed and child_added events are fired when limit is satisfied and you remove an item. Using server data', async () => {
1305
- const node = getRandomNode() as Reference;
1306
-
1307
- await node.set({ a: 1, b: 2, c: 3 });
1308
-
1309
- let ea = EventAccumulatorFactory.waitsForCount(2);
1310
- let added = '',
1311
- removed = '';
1312
- node.limitToLast(2).on('child_added', snap => {
1313
- added += snap.key + ' ';
1314
- ea.addEvent();
1315
- });
1316
- node.limitToLast(2).on('child_removed', snap => {
1317
- removed += snap.key + ' ';
1318
- });
1319
-
1320
- await ea.promise;
1321
-
1322
- expect(added).to.equal('b c ');
1323
- expect(removed).to.equal('');
1324
-
1325
- // We are going to wait for one more event before closing
1326
- ea = EventAccumulatorFactory.waitsForCount(1);
1327
- added = '';
1328
- await node.child('b').remove();
1329
-
1330
- expect(removed).to.equal('b ');
1331
-
1332
- await ea.promise;
1333
- expect(added).to.equal('a ');
1334
- });
1335
-
1336
- it('Set a limit, ensure child_removed events are fired when limit is satisfied, you remove an item, and there are no more.', () => {
1337
- const node = getRandomNode() as Reference;
1338
-
1339
- let added = '',
1340
- removed = '';
1341
- node.limitToLast(2).on('child_added', snap => {
1342
- added += snap.key + ' ';
1343
- });
1344
- node.limitToLast(2).on('child_removed', snap => {
1345
- removed += snap.key + ' ';
1346
- });
1347
- node.set({ b: 2, c: 3 });
1348
- expect(added).to.equal('b c ');
1349
- expect(removed).to.equal('');
1350
-
1351
- added = '';
1352
- node.child('b').remove();
1353
- expect(added).to.equal('');
1354
- expect(removed).to.equal('b ');
1355
- node.child('c').remove();
1356
- expect(removed).to.equal('b c ');
1357
- });
1358
-
1359
- it('Set a limit, ensure child_removed events are fired when limit is satisfied, you remove an item, and there are no more. Using server data', async () => {
1360
- const node = getRandomNode() as Reference;
1361
- const ea = EventAccumulatorFactory.waitsForCount(2);
1362
- let added = '';
1363
- let removed = '';
1364
- await node.set({ b: 2, c: 3 });
1365
-
1366
- node.limitToLast(2).on('child_added', snap => {
1367
- added += snap.key + ' ';
1368
- ea.addEvent();
1369
- });
1370
- node.limitToLast(2).on('child_removed', snap => {
1371
- removed += snap.key + ' ';
1372
- });
1373
-
1374
- await ea.promise;
1375
-
1376
- expect(added).to.equal('b c ');
1377
- expect(removed).to.equal('');
1378
-
1379
- added = '';
1380
-
1381
- await node.child('b').remove();
1382
-
1383
- expect(added).to.equal('');
1384
- expect(removed).to.equal('b ');
1385
- });
1386
-
1387
- it('Ensure startAfter on key index works', async () => {
1388
- const node = getRandomNode() as Reference;
1389
- const childOne = node.push();
1390
- const childTwo = node.push();
1391
- await childOne.set(1);
1392
- await childTwo.set(2);
1393
- const snap = await node.orderByKey().startAfter(childOne.key).get();
1394
- expect(Object.keys(snap.val())).to.deep.equal([childTwo.key]);
1395
- expect(Object.values(snap.val())).to.deep.equal([snap.val()[childTwo.key]]);
1396
- });
1397
-
1398
- it('Ensure endBefore on key index works', async () => {
1399
- const node = getRandomNode() as Reference;
1400
- const childOne = node.push();
1401
- const childTwo = node.push();
1402
- await childOne.set(1);
1403
- await childTwo.set(2);
1404
- const snap = await node.orderByKey().endBefore(childTwo.key).get();
1405
- expect(Object.keys(snap.val())).to.deep.equal([childOne.key]);
1406
- expect(Object.values(snap.val())).to.deep.equal([snap.val()[childOne.key]]);
1407
- });
1408
-
1409
- it('Ensure startAfter on key index works with overlapping listener', async () => {
1410
- const node = getRandomNode() as Reference;
1411
- const childOne = node.push();
1412
- const childTwo = node.push();
1413
- // Create a server synced and a latency-compensated write
1414
- await childOne.set(1);
1415
- childTwo.set(2);
1416
- const ea = EventAccumulatorFactory.waitsForCount(1);
1417
- node.on('value', snap => {
1418
- ea.addEvent(snap.val());
1419
- });
1420
- await ea.promise;
1421
- const snap = await node.orderByKey().startAfter(childOne.key).get();
1422
- expect(Object.keys(snap.val())).to.deep.equal([childTwo.key]);
1423
- expect(Object.values(snap.val())).to.deep.equal([snap.val()[childTwo.key]]);
1424
- });
1425
-
1426
- it('Ensure endBefore on key index works with overlapping listener', async () => {
1427
- const node = getRandomNode() as Reference;
1428
- const childOne = node.push();
1429
- const childTwo = node.push();
1430
- // Create a server synced and a latency-compensated write
1431
- await childOne.set(1);
1432
- childTwo.set(2);
1433
- const ea = EventAccumulatorFactory.waitsForCount(1);
1434
- node.on('value', snap => {
1435
- ea.addEvent(snap.val());
1436
- });
1437
- await ea.promise;
1438
- const snap = await node.orderByKey().endBefore(childTwo.key).get();
1439
- expect(Object.keys(snap.val())).to.deep.equal([childOne.key]);
1440
- expect(Object.values(snap.val())).to.deep.equal([snap.val()[childOne.key]]);
1441
- });
1442
-
1443
- it('Ensure startAt / endAt with priority works.', async () => {
1444
- const node = getRandomNode() as Reference;
1445
-
1446
- const tasks: TaskList = [
1447
- [node.startAt('w').endAt('y'), { b: 2, c: 3, d: 4 }],
1448
- [node.startAt('w').endAt('w'), { d: 4 }],
1449
- [node.startAt('a').endAt('c'), null]
1450
- ];
1451
-
1452
- await node.set({
1453
- a: { '.value': 1, '.priority': 'z' },
1454
- b: { '.value': 2, '.priority': 'y' },
1455
- c: { '.value': 3, '.priority': 'x' },
1456
- d: { '.value': 4, '.priority': 'w' }
1457
- });
1458
-
1459
- return Promise.all(
1460
- tasks.map(async task => {
1461
- const [query, val] = task;
1462
- const ea = EventAccumulatorFactory.waitsForCount(1);
1463
- query.on('value', snap => {
1464
- ea.addEvent(snap.val());
1465
- });
1466
- const [newVal] = await ea.promise;
1467
- expect(newVal).to.deep.equal(val);
1468
- })
1469
- );
1470
- });
1471
-
1472
- it('Ensure startAfter / endAt with priority works.', async () => {
1473
- const node = getRandomNode() as Reference;
1474
-
1475
- const tasks: TaskList = [
1476
- [node.startAfter('w').endAt('y'), { b: 2, c: 3 }],
1477
- [node.startAfter('w').endAt('x'), { c: 3 }],
1478
- [node.startAfter('a').endAt('c'), null]
1479
- ];
1480
-
1481
- await node.set({
1482
- a: { '.value': 1, '.priority': 'z' },
1483
- b: { '.value': 2, '.priority': 'y' },
1484
- c: { '.value': 3, '.priority': 'x' },
1485
- d: { '.value': 4, '.priority': 'w' }
1486
- });
1487
-
1488
- return Promise.all(
1489
- tasks.map(async task => {
1490
- const [query, val] = task;
1491
- const ea = EventAccumulatorFactory.waitsForCount(1);
1492
- query.on('value', snap => {
1493
- ea.addEvent(snap.val());
1494
- });
1495
- const [newVal] = await ea.promise;
1496
- expect(newVal).to.deep.equal(val);
1497
- })
1498
- );
1499
- });
1500
-
1501
- it('Ensure startAt / endBefore with priority works.', async () => {
1502
- const node = getRandomNode() as Reference;
1503
-
1504
- const tasks: TaskList = [
1505
- [node.startAt('w').endBefore('y'), { c: 3, d: 4 }],
1506
- [node.startAt('w').endBefore('x'), { d: 4 }],
1507
- [node.startAt('a').endBefore('c'), null]
1508
- ];
1509
-
1510
- await node.set({
1511
- a: { '.value': 1, '.priority': 'z' },
1512
- b: { '.value': 2, '.priority': 'y' },
1513
- c: { '.value': 3, '.priority': 'x' },
1514
- d: { '.value': 4, '.priority': 'w' }
1515
- });
1516
-
1517
- return Promise.all(
1518
- tasks.map(async task => {
1519
- const [query, val] = task;
1520
- const ea = EventAccumulatorFactory.waitsForCount(1);
1521
- query.on('value', snap => {
1522
- ea.addEvent(snap.val());
1523
- });
1524
- const [newVal] = await ea.promise;
1525
- expect(newVal).to.deep.equal(val);
1526
- })
1527
- );
1528
- });
1529
-
1530
- it('Ensure startAfter / endBefore with priority works.', async () => {
1531
- const node = getRandomNode() as Reference;
1532
-
1533
- const tasks: TaskList = [
1534
- [node.startAfter('w').endBefore('z'), { b: 2, c: 3 }],
1535
- [node.startAfter('w').endBefore('y'), { c: 3 }],
1536
- [node.startAfter('w').endBefore('w'), null]
1537
- ];
1538
-
1539
- await node.set({
1540
- a: { '.value': 1, '.priority': 'z' },
1541
- b: { '.value': 2, '.priority': 'y' },
1542
- c: { '.value': 3, '.priority': 'x' },
1543
- d: { '.value': 4, '.priority': 'w' }
1544
- });
1545
-
1546
- return Promise.all(
1547
- tasks.map(async task => {
1548
- const [query, val] = task;
1549
- const ea = EventAccumulatorFactory.waitsForCount(1);
1550
- query.on('value', snap => {
1551
- ea.addEvent(snap.val());
1552
- });
1553
- const [newVal] = await ea.promise;
1554
- expect(newVal).to.deep.equal(val);
1555
- })
1556
- );
1557
- });
1558
-
1559
- it('Ensure startAt / endAt with priority work with server data.', async () => {
1560
- const node = getRandomNode() as Reference;
1561
-
1562
- await node.set({
1563
- a: { '.value': 1, '.priority': 'z' },
1564
- b: { '.value': 2, '.priority': 'y' },
1565
- c: { '.value': 3, '.priority': 'x' },
1566
- d: { '.value': 4, '.priority': 'w' }
1567
- });
1568
-
1569
- const tasks: TaskList = [
1570
- [node.startAt('w').endAt('y'), { b: 2, c: 3, d: 4 }],
1571
- [node.startAt('w').endAt('w'), { d: 4 }],
1572
- [node.startAt('a').endAt('c'), null]
1573
- ];
1574
-
1575
- return Promise.all(
1576
- tasks.map(async task => {
1577
- const [query, val] = task;
1578
- const ea = EventAccumulatorFactory.waitsForCount(1);
1579
- query.on('value', snap => {
1580
- ea.addEvent(snap.val());
1581
- });
1582
- const [newVal] = await ea.promise;
1583
- expect(newVal).to.deep.equal(val);
1584
- })
1585
- );
1586
- });
1587
-
1588
- it('Ensure startAfter / endAt with priority work with server data.', async () => {
1589
- const node = getRandomNode() as Reference;
1590
-
1591
- await node.set({
1592
- a: { '.value': 1, '.priority': 'z' },
1593
- b: { '.value': 2, '.priority': 'y' },
1594
- c: { '.value': 3, '.priority': 'x' },
1595
- d: { '.value': 4, '.priority': 'w' }
1596
- });
1597
-
1598
- const tasks: TaskList = [
1599
- [node.startAfter('w').endAt('y'), { b: 2, c: 3 }],
1600
- [node.startAfter('w').endAt('x'), { c: 3 }],
1601
- [node.startAfter('a').endAt('c'), null]
1602
- ];
1603
-
1604
- return Promise.all(
1605
- tasks.map(async task => {
1606
- const [query, val] = task;
1607
- const ea = EventAccumulatorFactory.waitsForCount(1);
1608
- query.on('value', snap => {
1609
- ea.addEvent(snap.val());
1610
- });
1611
- const [newVal] = await ea.promise;
1612
- expect(newVal).to.deep.equal(val);
1613
- })
1614
- );
1615
- });
1616
-
1617
- it('Ensure startAt / endBefore with priority work with server data.', async () => {
1618
- const node = getRandomNode() as Reference;
1619
-
1620
- await node.set({
1621
- a: { '.value': 1, '.priority': 'z' },
1622
- b: { '.value': 2, '.priority': 'y' },
1623
- c: { '.value': 3, '.priority': 'x' },
1624
- d: { '.value': 4, '.priority': 'w' }
1625
- });
1626
-
1627
- const tasks: TaskList = [
1628
- [node.startAt('w').endBefore('y'), { c: 3, d: 4 }],
1629
- [node.startAt('w').endBefore('x'), { d: 4 }],
1630
- [node.startAt('a').endBefore('c'), null]
1631
- ];
1632
-
1633
- return Promise.all(
1634
- tasks.map(async task => {
1635
- const [query, val] = task;
1636
- const ea = EventAccumulatorFactory.waitsForCount(1);
1637
- query.on('value', snap => {
1638
- ea.addEvent(snap.val());
1639
- });
1640
- const [newVal] = await ea.promise;
1641
- expect(newVal).to.deep.equal(val);
1642
- })
1643
- );
1644
- });
1645
-
1646
- it('Ensure startAfter / endBefore with priority work with server data.', async () => {
1647
- const node = getRandomNode() as Reference;
1648
-
1649
- await node.set({
1650
- a: { '.value': 1, '.priority': 'z' },
1651
- b: { '.value': 2, '.priority': 'y' },
1652
- c: { '.value': 3, '.priority': 'x' },
1653
- d: { '.value': 4, '.priority': 'w' }
1654
- });
1655
-
1656
- const tasks: TaskList = [
1657
- [node.startAfter('w').endBefore('z'), { b: 2, c: 3 }],
1658
- [node.startAfter('w').endBefore('y'), { c: 3 }],
1659
- [node.startAfter('w').endBefore('w'), null]
1660
- ];
1661
-
1662
- return Promise.all(
1663
- tasks.map(async task => {
1664
- const [query, val] = task;
1665
- const ea = EventAccumulatorFactory.waitsForCount(1);
1666
- query.on('value', snap => {
1667
- ea.addEvent(snap.val());
1668
- });
1669
- const [newVal] = await ea.promise;
1670
- expect(newVal).to.deep.equal(val);
1671
- })
1672
- );
1673
- });
1674
-
1675
- it('Ensure startAt / endAt with priority and name works.', async () => {
1676
- const node = getRandomNode() as Reference;
1677
-
1678
- await node.set({
1679
- a: { '.value': 1, '.priority': 1 },
1680
- b: { '.value': 2, '.priority': 1 },
1681
- c: { '.value': 3, '.priority': 2 },
1682
- d: { '.value': 4, '.priority': 2 }
1683
- });
1684
-
1685
- const tasks: TaskList = [
1686
- [node.startAt(1, 'a').endAt(2, 'd'), { a: 1, b: 2, c: 3, d: 4 }],
1687
- [node.startAt(1, 'b').endAt(2, 'c'), { b: 2, c: 3 }],
1688
- [node.startAt(1, 'c').endAt(2), { c: 3, d: 4 }]
1689
- ];
1690
-
1691
- return Promise.all(
1692
- tasks.map(async task => {
1693
- const [query, val] = task;
1694
- const ea = EventAccumulatorFactory.waitsForCount(1);
1695
- query.on('value', snap => {
1696
- ea.addEvent(snap.val());
1697
- });
1698
- const [newVal] = await ea.promise;
1699
- expect(newVal).to.deep.equal(val);
1700
- })
1701
- );
1702
- });
1703
-
1704
- it('Ensure startAfter / endAt with priority and name works.', async () => {
1705
- const node = getRandomNode() as Reference;
1706
-
1707
- await node.set({
1708
- a: { '.value': 1, '.priority': 1 },
1709
- b: { '.value': 2, '.priority': 1 },
1710
- c: { '.value': 3, '.priority': 2 },
1711
- d: { '.value': 4, '.priority': 2 }
1712
- });
1713
-
1714
- const tasks: TaskList = [
1715
- [node.startAfter(1, 'a').endAt(2, 'd'), { b: 2, c: 3, d: 4 }],
1716
- [node.startAfter(1, 'b').endAt(2, 'c'), { c: 3 }],
1717
- [node.startAfter(1, 'c').endAt(2), { c: 3, d: 4 }]
1718
- ];
1719
-
1720
- return Promise.all(
1721
- tasks.map(async task => {
1722
- const [query, val] = task;
1723
- const ea = EventAccumulatorFactory.waitsForCount(1);
1724
- query.on('value', snap => {
1725
- ea.addEvent(snap.val());
1726
- });
1727
- const [newVal] = await ea.promise;
1728
- expect(newVal).to.deep.equal(val);
1729
- })
1730
- );
1731
- });
1732
-
1733
- it('Ensure startAt / endBefore with priority and name works.', async () => {
1734
- const node = getRandomNode() as Reference;
1735
-
1736
- await node.set({
1737
- a: { '.value': 1, '.priority': 1 },
1738
- b: { '.value': 2, '.priority': 1 },
1739
- c: { '.value': 3, '.priority': 2 },
1740
- d: { '.value': 4, '.priority': 2 }
1741
- });
1742
-
1743
- const tasks: TaskList = [
1744
- [node.startAt(1, 'a').endBefore(2, 'd'), { a: 1, b: 2, c: 3 }],
1745
- [node.startAt(1, 'b').endBefore(2, 'c'), { b: 2 }],
1746
- [node.startAt(1, 'c').endBefore(2), null]
1747
- ];
1748
-
1749
- return Promise.all(
1750
- tasks.map(async task => {
1751
- const [query, val] = task;
1752
- const ea = EventAccumulatorFactory.waitsForCount(1);
1753
- query.on('value', snap => {
1754
- ea.addEvent(snap.val());
1755
- });
1756
- const [newVal] = await ea.promise;
1757
- expect(newVal).to.deep.equal(val);
1758
- })
1759
- );
1760
- });
1761
-
1762
- it('Ensure startAfter / endBefore with priority and name works.', async () => {
1763
- const node = getRandomNode() as Reference;
1764
-
1765
- await node.set({
1766
- a: { '.value': 1, '.priority': 1 },
1767
- b: { '.value': 2, '.priority': 1 },
1768
- c: { '.value': 3, '.priority': 2 },
1769
- d: { '.value': 4, '.priority': 2 }
1770
- });
1771
-
1772
- const tasks: TaskList = [
1773
- [node.startAfter(1, 'a').endBefore(2, 'd'), { b: 2, c: 3 }],
1774
- [node.startAfter(1, 'b').endBefore(2, 'c'), null],
1775
- [node.startAfter(1, 'c').endBefore(2), null]
1776
- ];
1777
-
1778
- return Promise.all(
1779
- tasks.map(async task => {
1780
- const [query, val] = task;
1781
- const ea = EventAccumulatorFactory.waitsForCount(1);
1782
- query.on('value', snap => {
1783
- ea.addEvent(snap.val());
1784
- });
1785
- const [newVal] = await ea.promise;
1786
- expect(newVal).to.deep.equal(val);
1787
- })
1788
- );
1789
- });
1790
-
1791
- it('Ensure startAt / endAt with priority and name work with server data', async () => {
1792
- const node = getRandomNode() as Reference;
1793
-
1794
- await node.set({
1795
- a: { '.value': 1, '.priority': 1 },
1796
- b: { '.value': 2, '.priority': 1 },
1797
- c: { '.value': 3, '.priority': 2 },
1798
- d: { '.value': 4, '.priority': 2 }
1799
- });
1800
- const tasks: TaskList = [
1801
- [node.startAt(1, 'a').endAt(2, 'd'), { a: 1, b: 2, c: 3, d: 4 }],
1802
- [node.startAt(1, 'b').endAt(2, 'c'), { b: 2, c: 3 }],
1803
- [node.startAt(1, 'c').endAt(2), { c: 3, d: 4 }]
1804
- ];
1805
- return Promise.all(
1806
- tasks.map(async task => {
1807
- const [query, val] = task;
1808
- const ea = EventAccumulatorFactory.waitsForCount(1);
1809
- query.on('value', snap => {
1810
- ea.addEvent(snap.val());
1811
- });
1812
- const [newVal] = await ea.promise;
1813
- expect(newVal).to.deep.equal(val);
1814
- })
1815
- );
1816
- });
1817
-
1818
- it('Ensure startAfter / endAt with priority and name work with server data', async () => {
1819
- const node = getRandomNode() as Reference;
1820
-
1821
- await node.set({
1822
- a: { '.value': 1, '.priority': 1 },
1823
- b: { '.value': 2, '.priority': 1 },
1824
- c: { '.value': 3, '.priority': 2 },
1825
- d: { '.value': 4, '.priority': 2 }
1826
- });
1827
- const tasks: TaskList = [
1828
- [node.startAfter(1, 'a').endAt(2, 'd'), { b: 2, c: 3, d: 4 }],
1829
- [node.startAfter(1, 'b').endAt(2, 'c'), { c: 3 }],
1830
- [node.startAfter(1, 'c').endAt(2), { c: 3, d: 4 }]
1831
- ];
1832
- return Promise.all(
1833
- tasks.map(async task => {
1834
- const [query, val] = task;
1835
- const ea = EventAccumulatorFactory.waitsForCount(1);
1836
- query.on('value', snap => {
1837
- ea.addEvent(snap.val());
1838
- });
1839
- const [newVal] = await ea.promise;
1840
- expect(newVal).to.deep.equal(val);
1841
- })
1842
- );
1843
- });
1844
-
1845
- it('Ensure startAt / endBefore with priority and name work with server data', async () => {
1846
- const node = getRandomNode() as Reference;
1847
-
1848
- await node.set({
1849
- a: { '.value': 1, '.priority': 1 },
1850
- b: { '.value': 2, '.priority': 1 },
1851
- c: { '.value': 3, '.priority': 2 },
1852
- d: { '.value': 4, '.priority': 2 }
1853
- });
1854
- const tasks: TaskList = [
1855
- [node.startAt(1, 'a').endBefore(2, 'd'), { a: 1, b: 2, c: 3 }],
1856
- [node.startAt(1, 'b').endBefore(2, 'c'), { b: 2 }],
1857
- [node.startAt(1, 'c').endBefore(2), null]
1858
- ];
1859
- return Promise.all(
1860
- tasks.map(async task => {
1861
- const [query, val] = task;
1862
- const ea = EventAccumulatorFactory.waitsForCount(1);
1863
- query.on('value', snap => {
1864
- ea.addEvent(snap.val());
1865
- });
1866
- const [newVal] = await ea.promise;
1867
- expect(newVal).to.deep.equal(val);
1868
- })
1869
- );
1870
- });
1871
-
1872
- it('Ensure startAfter / endBefore with priority and name work with server data', async () => {
1873
- const node = getRandomNode() as Reference;
1874
-
1875
- await node.set({
1876
- a: { '.value': 1, '.priority': 1 },
1877
- b: { '.value': 2, '.priority': 1 },
1878
- c: { '.value': 3, '.priority': 2 },
1879
- d: { '.value': 4, '.priority': 2 }
1880
- });
1881
- const tasks: TaskList = [
1882
- [node.startAfter(1, 'a').endBefore(2, 'd'), { b: 2, c: 3 }],
1883
- [node.startAfter(1, 'b').endBefore(2, 'c'), null],
1884
- [node.startAfter(1, 'c').endBefore(2), null]
1885
- ];
1886
- return Promise.all(
1887
- tasks.map(async task => {
1888
- const [query, val] = task;
1889
- const ea = EventAccumulatorFactory.waitsForCount(1);
1890
- query.on('value', snap => {
1891
- ea.addEvent(snap.val());
1892
- });
1893
- const [newVal] = await ea.promise;
1894
- expect(newVal).to.deep.equal(val);
1895
- })
1896
- );
1897
- });
1898
-
1899
- it('Ensure startAt / endAt with priority and name works (2).', () => {
1900
- const node = getRandomNode() as Reference;
1901
-
1902
- const tasks: TaskList = [
1903
- [node.startAt(1, 'c').endAt(2, 'b'), { a: 1, b: 2, c: 3, d: 4 }],
1904
- [node.startAt(1, 'd').endAt(2, 'a'), { d: 4, a: 1 }],
1905
- [node.startAt(1, 'e').endAt(2), { a: 1, b: 2 }]
1906
- ];
1907
-
1908
- node.set({
1909
- c: { '.value': 3, '.priority': 1 },
1910
- d: { '.value': 4, '.priority': 1 },
1911
- a: { '.value': 1, '.priority': 2 },
1912
- b: { '.value': 2, '.priority': 2 }
1913
- });
1914
-
1915
- return Promise.all(
1916
- tasks.map(async task => {
1917
- const [query, val] = task;
1918
- const ea = EventAccumulatorFactory.waitsForCount(1);
1919
- query.on('value', snap => {
1920
- ea.addEvent(snap.val());
1921
- });
1922
- const [newVal] = await ea.promise;
1923
- expect(newVal).to.deep.equal(val);
1924
- })
1925
- );
1926
- });
1927
-
1928
- it('Ensure startAfter / endAt with priority and name works (2).', () => {
1929
- const node = getRandomNode() as Reference;
1930
-
1931
- const tasks: TaskList = [
1932
- [node.startAfter(1, 'c').endAt(2, 'b'), { a: 1, b: 2, d: 4 }],
1933
- [node.startAfter(1, 'd').endAt(2, 'a'), { a: 1 }],
1934
- [node.startAfter(1, 'e').endAt(2), { a: 1, b: 2 }]
1935
- ];
1936
-
1937
- node.set({
1938
- c: { '.value': 3, '.priority': 1 },
1939
- d: { '.value': 4, '.priority': 1 },
1940
- a: { '.value': 1, '.priority': 2 },
1941
- b: { '.value': 2, '.priority': 2 }
1942
- });
1943
-
1944
- return Promise.all(
1945
- tasks.map(async task => {
1946
- const [query, val] = task;
1947
- const ea = EventAccumulatorFactory.waitsForCount(1);
1948
- query.on('value', snap => {
1949
- ea.addEvent(snap.val());
1950
- });
1951
- const [newVal] = await ea.promise;
1952
- expect(newVal).to.deep.equal(val);
1953
- })
1954
- );
1955
- });
1956
-
1957
- it('Ensure startAt / endBefore with priority and name works with queries before set.', () => {
1958
- const node = getRandomNode() as Reference;
1959
-
1960
- const tasks: TaskList = [
1961
- [node.startAt(1, 'c').endBefore(2, 'b'), { a: 1, c: 3, d: 4 }],
1962
- [node.startAt(1, 'd').endBefore(2, 'a'), { d: 4 }],
1963
- [node.startAt(1, 'e').endBefore(2), null]
1964
- ];
1965
-
1966
- node.set({
1967
- c: { '.value': 3, '.priority': 1 },
1968
- d: { '.value': 4, '.priority': 1 },
1969
- a: { '.value': 1, '.priority': 2 },
1970
- b: { '.value': 2, '.priority': 2 }
1971
- });
1972
-
1973
- return Promise.all(
1974
- tasks.map(async task => {
1975
- const [query, val] = task;
1976
- const ea = EventAccumulatorFactory.waitsForCount(1);
1977
- query.on('value', snap => {
1978
- ea.addEvent(snap.val());
1979
- });
1980
- const [newVal] = await ea.promise;
1981
- expect(newVal).to.deep.equal(val);
1982
- })
1983
- );
1984
- });
1985
-
1986
- it('Ensure startAfter / endBefore with priority and name works (2).', () => {
1987
- const node = getRandomNode() as Reference;
1988
-
1989
- const tasks: TaskList = [
1990
- [node.startAfter(1, 'c').endBefore(2, 'b'), { a: 1, d: 4 }],
1991
- [node.startAfter(1, 'd').endBefore(2, 'a'), null],
1992
- [node.startAfter(1, 'e').endBefore(2), null]
1993
- ];
1994
-
1995
- node.set({
1996
- c: { '.value': 3, '.priority': 1 },
1997
- d: { '.value': 4, '.priority': 1 },
1998
- a: { '.value': 1, '.priority': 2 },
1999
- b: { '.value': 2, '.priority': 2 }
2000
- });
2001
-
2002
- return Promise.all(
2003
- tasks.map(async task => {
2004
- const [query, val] = task;
2005
- const ea = EventAccumulatorFactory.waitsForCount(1);
2006
- query.on('value', snap => {
2007
- ea.addEvent(snap.val());
2008
- });
2009
- const [newVal] = await ea.promise;
2010
- expect(newVal).to.deep.equal(val);
2011
- })
2012
- );
2013
- });
2014
-
2015
- it('Ensure startAt / endAt with priority and name works (2). With server data', async () => {
2016
- const node = getRandomNode() as Reference;
2017
-
2018
- await node.set({
2019
- c: { '.value': 3, '.priority': 1 },
2020
- d: { '.value': 4, '.priority': 1 },
2021
- a: { '.value': 1, '.priority': 2 },
2022
- b: { '.value': 2, '.priority': 2 }
2023
- });
2024
-
2025
- const tasks: TaskList = [
2026
- [node.startAt(1, 'c').endAt(2, 'b'), { a: 1, b: 2, c: 3, d: 4 }],
2027
- [node.startAt(1, 'd').endAt(2, 'a'), { d: 4, a: 1 }],
2028
- [node.startAt(1, 'e').endAt(2), { a: 1, b: 2 }]
2029
- ];
2030
-
2031
- return Promise.all(
2032
- tasks.map(async task => {
2033
- const [query, val] = task;
2034
- const ea = EventAccumulatorFactory.waitsForCount(1);
2035
- query.on('value', snap => {
2036
- ea.addEvent(snap.val());
2037
- });
2038
- const [newVal] = await ea.promise;
2039
- expect(newVal).to.deep.equal(val);
2040
- })
2041
- );
2042
- });
2043
-
2044
- it('Ensure startAfter / endAt with priority and name works (2). With server data', async () => {
2045
- const node = getRandomNode() as Reference;
2046
-
2047
- await node.set({
2048
- c: { '.value': 3, '.priority': 1 },
2049
- d: { '.value': 4, '.priority': 1 },
2050
- a: { '.value': 1, '.priority': 2 },
2051
- b: { '.value': 2, '.priority': 2 }
2052
- });
2053
-
2054
- const tasks: TaskList = [
2055
- [node.startAfter(1, 'c').endAt(2, 'b'), { a: 1, b: 2, d: 4 }],
2056
- [node.startAfter(1, 'd').endAt(2, 'a'), { a: 1 }],
2057
- [node.startAfter(1, 'e').endAt(2), { a: 1, b: 2 }]
2058
- ];
2059
-
2060
- return Promise.all(
2061
- tasks.map(async task => {
2062
- const [query, val] = task;
2063
- const ea = EventAccumulatorFactory.waitsForCount(1);
2064
- query.on('value', snap => {
2065
- ea.addEvent(snap.val());
2066
- });
2067
- const [newVal] = await ea.promise;
2068
- expect(newVal).to.deep.equal(val);
2069
- })
2070
- );
2071
- });
2072
-
2073
- it('Ensure startAt / endBefore with priority and name works (2). With server data.', () => {
2074
- const node = getRandomNode() as Reference;
2075
-
2076
- node.set({
2077
- c: { '.value': 3, '.priority': 1 },
2078
- d: { '.value': 4, '.priority': 1 },
2079
- a: { '.value': 1, '.priority': 2 },
2080
- b: { '.value': 2, '.priority': 2 }
2081
- });
2082
-
2083
- const tasks: TaskList = [
2084
- [node.startAt(1, 'c').endBefore(2, 'b'), { a: 1, c: 3, d: 4 }],
2085
- [node.startAt(1, 'd').endBefore(2, 'a'), { d: 4 }],
2086
- [node.startAt(1, 'e').endBefore(2), null]
2087
- ];
2088
-
2089
- return Promise.all(
2090
- tasks.map(async task => {
2091
- const [query, val] = task;
2092
- const ea = EventAccumulatorFactory.waitsForCount(1);
2093
- query.on('value', snap => {
2094
- ea.addEvent(snap.val());
2095
- });
2096
- const [newVal] = await ea.promise;
2097
- expect(newVal).to.deep.equal(val);
2098
- })
2099
- );
2100
- });
2101
-
2102
- it('Ensure startAfter / endBefore with priority and name works (2). With server data.', () => {
2103
- const node = getRandomNode() as Reference;
2104
-
2105
- node.set({
2106
- c: { '.value': 3, '.priority': 1 },
2107
- d: { '.value': 4, '.priority': 1 },
2108
- a: { '.value': 1, '.priority': 2 },
2109
- b: { '.value': 2, '.priority': 2 }
2110
- });
2111
-
2112
- const tasks: TaskList = [
2113
- [node.startAfter(1, 'c').endBefore(2, 'b'), { a: 1, d: 4 }],
2114
- [node.startAfter(1, 'd').endBefore(2, 'a'), null],
2115
- [node.startAfter(1, 'e').endBefore(2), null]
2116
- ];
2117
-
2118
- return Promise.all(
2119
- tasks.map(async task => {
2120
- const [query, val] = task;
2121
- const ea = EventAccumulatorFactory.waitsForCount(1);
2122
- query.on('value', snap => {
2123
- ea.addEvent(snap.val());
2124
- });
2125
- const [newVal] = await ea.promise;
2126
- expect(newVal).to.deep.equal(val);
2127
- })
2128
- );
2129
- });
2130
-
2131
- it('Set a limit, add some nodes, ensure prevName works correctly.', () => {
2132
- const node = getRandomNode() as Reference;
2133
-
2134
- let added = '';
2135
- node.limitToLast(2).on('child_added', (snap, prevName) => {
2136
- added += snap.key + ' ' + prevName + ', ';
2137
- });
2138
-
2139
- node.child('a').set(1);
2140
- expect(added).to.equal('a null, ');
2141
-
2142
- added = '';
2143
- node.child('c').set(3);
2144
- expect(added).to.equal('c a, ');
2145
-
2146
- added = '';
2147
- node.child('b').set(2);
2148
- expect(added).to.equal('b null, ');
2149
-
2150
- added = '';
2151
- node.child('d').set(4);
2152
- expect(added).to.equal('d c, ');
2153
- });
2154
-
2155
- it('Set a limit, add some nodes, ensure prevName works correctly. With server data', async () => {
2156
- const node = getRandomNode() as Reference;
2157
-
2158
- let added = '';
2159
- await node.child('a').set(1);
2160
-
2161
- const ea = EventAccumulatorFactory.waitsForCount(1);
2162
- node.limitToLast(2).on('child_added', (snap, prevName) => {
2163
- added += snap.key + ' ' + prevName + ', ';
2164
- ea.addEvent();
2165
- });
2166
-
2167
- await ea.promise;
2168
-
2169
- expect(added).to.equal('a null, ');
2170
-
2171
- added = '';
2172
- await node.child('c').set(3);
2173
-
2174
- expect(added).to.equal('c a, ');
2175
-
2176
- added = '';
2177
- await node.child('b').set(2);
2178
-
2179
- expect(added).to.equal('b null, ');
2180
-
2181
- added = '';
2182
- await node.child('d').set(4);
2183
-
2184
- expect(added).to.equal('d c, ');
2185
- });
2186
-
2187
- it('Set a limit, move some nodes, ensure prevName works correctly.', () => {
2188
- const node = getRandomNode() as Reference;
2189
- let moved = '';
2190
- node.limitToLast(2).on('child_moved', (snap, prevName) => {
2191
- moved += snap.key + ' ' + prevName + ', ';
2192
- });
2193
-
2194
- node.child('a').setWithPriority('a', 10);
2195
- node.child('b').setWithPriority('b', 20);
2196
- node.child('c').setWithPriority('c', 30);
2197
- node.child('d').setWithPriority('d', 40);
2198
-
2199
- node.child('c').setPriority(50);
2200
- expect(moved).to.equal('c d, ');
2201
-
2202
- moved = '';
2203
- node.child('c').setPriority(35);
2204
- expect(moved).to.equal('c null, ');
2205
-
2206
- moved = '';
2207
- node.child('b').setPriority(33);
2208
- expect(moved).to.equal('');
2209
- });
2210
-
2211
- it('Set a limit, move some nodes, ensure prevName works correctly, with server data', async () => {
2212
- const node = getRandomNode() as Reference;
2213
- let moved = '';
2214
-
2215
- node.child('a').setWithPriority('a', 10);
2216
- node.child('b').setWithPriority('b', 20);
2217
- node.child('c').setWithPriority('c', 30);
2218
- await node.child('d').setWithPriority('d', 40);
2219
-
2220
- node.limitToLast(2).on('child_moved', async (snap, prevName) => {
2221
- moved += snap.key + ' ' + prevName + ', ';
2222
- });
2223
- // Need to load the data before the set so we'll see the move
2224
- await node.limitToLast(2).once('value');
2225
-
2226
- await node.child('c').setPriority(50);
2227
-
2228
- expect(moved).to.equal('c d, ');
2229
-
2230
- moved = '';
2231
- await node.child('c').setPriority(35);
2232
-
2233
- expect(moved).to.equal('c null, ');
2234
- moved = '';
2235
- await node.child('b').setPriority(33);
2236
-
2237
- expect(moved).to.equal('');
2238
- });
2239
-
2240
- it('Numeric priorities: Set a limit, move some nodes, ensure prevName works correctly.', () => {
2241
- const node = getRandomNode() as Reference;
2242
-
2243
- let moved = '';
2244
- node.limitToLast(2).on('child_moved', (snap, prevName) => {
2245
- moved += snap.key + ' ' + prevName + ', ';
2246
- });
2247
-
2248
- node.child('a').setWithPriority('a', 1);
2249
- node.child('b').setWithPriority('b', 2);
2250
- node.child('c').setWithPriority('c', 3);
2251
- node.child('d').setWithPriority('d', 4);
2252
-
2253
- node.child('c').setPriority(10);
2254
- expect(moved).to.equal('c d, ');
2255
- });
2256
-
2257
- it('Numeric priorities: Set a limit, move some nodes, ensure prevName works correctly. With server data', async () => {
2258
- const node = getRandomNode() as Reference;
2259
- let moved = '';
2260
-
2261
- node.child('a').setWithPriority('a', 1);
2262
- node.child('b').setWithPriority('b', 2);
2263
- node.child('c').setWithPriority('c', 3);
2264
- await node.child('d').setWithPriority('d', 4);
2265
-
2266
- node.limitToLast(2).on('child_moved', (snap, prevName) => {
2267
- moved += snap.key + ' ' + prevName + ', ';
2268
- });
2269
- // Need to load the data before the set so we'll see the move
2270
- await node.limitToLast(2).once('value');
2271
-
2272
- await node.child('c').setPriority(10);
2273
-
2274
- expect(moved).to.equal('c d, ');
2275
- });
2276
-
2277
- it('Set a limit, add a bunch of nodes, ensure local events are correct.', () => {
2278
- const node = getRandomNode() as Reference;
2279
- node.set({});
2280
- let eventHistory = '';
2281
-
2282
- node.limitToLast(2).on('child_added', snap => {
2283
- eventHistory = eventHistory + snap.val() + ' added, ';
2284
- });
2285
- node.limitToLast(2).on('child_removed', snap => {
2286
- eventHistory = eventHistory + snap.val() + ' removed, ';
2287
- });
2288
-
2289
- for (let i = 0; i < 5; i++) {
2290
- const n = node.push();
2291
- n.set(i);
2292
- }
2293
-
2294
- expect(eventHistory).to.equal(
2295
- '0 added, 1 added, 0 removed, 2 added, 1 removed, 3 added, 2 removed, 4 added, '
2296
- );
2297
- });
2298
-
2299
- it('Set a limit, add a bunch of nodes, ensure remote events are correct.', async () => {
2300
- const nodePair = getRandomNode(2);
2301
- const writeNode = nodePair[0];
2302
- const readNode = nodePair[1];
2303
- const ea = new EventAccumulator(() => {
2304
- try {
2305
- expect(eventHistory).to.equal('3 added, 4 added, ');
2306
- return true;
2307
- } catch (err) {
2308
- return false;
2309
- }
2310
- });
2311
- let eventHistory = '';
2312
-
2313
- readNode.limitToLast(2).on('child_added', snap => {
2314
- eventHistory = eventHistory + snap.val() + ' added, ';
2315
- ea.addEvent();
2316
- });
2317
- readNode.limitToLast(2).on('child_removed', snap => {
2318
- eventHistory = eventHistory.replace(snap.val() + ' added, ', '');
2319
- /**
2320
- * This test expects this code NOT to fire, so by adding this
2321
- * I trigger the resolve early if it happens to fire and fail
2322
- * the expect at the end
2323
- */
2324
- ea.addEvent();
2325
- });
2326
-
2327
- const promises = [];
2328
- for (let i = 0; i < 5; i++) {
2329
- const n = writeNode.push();
2330
- n.set(i);
2331
- }
2332
-
2333
- await ea.promise;
2334
- });
2335
-
2336
- it('Query.once() only fires once', async () => {
2337
- const node = getRandomNode() as Reference;
2338
-
2339
- let count = 1;
2340
- node.set(count);
2341
-
2342
- const valueEvent = EventAccumulatorFactory.waitsForCount(3);
2343
- node.on('value', () => {
2344
- if (count < 3) {
2345
- ++count;
2346
- node.set(count);
2347
- }
2348
- valueEvent.addEvent();
2349
- });
2350
-
2351
- const onceEvent = EventAccumulatorFactory.waitsForExactCount(1);
2352
- node.once('value', () => {
2353
- ++count;
2354
- node.set(count);
2355
- onceEvent.addEvent();
2356
- });
2357
-
2358
- await valueEvent.promise;
2359
- await onceEvent.promise;
2360
- });
2361
-
2362
- it('Ensure on() returns callback function.', () => {
2363
- const node = getRandomNode() as Reference;
2364
- const callback = function () {};
2365
- const ret = node.on('value', callback);
2366
- expect(ret).to.equal(callback);
2367
- });
2368
-
2369
- it("Limit on unsynced node fires 'value'.", done => {
2370
- const f = getRandomNode() as Reference;
2371
- f.limitToLast(1).on('value', () => {
2372
- done();
2373
- });
2374
- });
2375
-
2376
- it('Filtering to only null priorities works.', async () => {
2377
- const f = getRandomNode() as Reference;
2378
-
2379
- const ea = EventAccumulatorFactory.waitsForCount(1);
2380
- f.root.child('.info/connected').on('value', snap => {
2381
- ea.addEvent();
2382
- });
2383
-
2384
- await ea.promise;
2385
-
2386
- f.set({
2387
- a: { '.priority': null, '.value': 0 },
2388
- b: { '.priority': null, '.value': 1 },
2389
- c: { '.priority': '2', '.value': 2 },
2390
- d: { '.priority': 3, '.value': 3 },
2391
- e: { '.priority': 'hi', '.value': 4 }
2392
- });
2393
-
2394
- const snapAcc = EventAccumulatorFactory.waitsForCount(1);
2395
- f.startAt(null)
2396
- .endAt(null)
2397
- .on('value', snap => {
2398
- snapAcc.addEvent(snap.val());
2399
- });
2400
-
2401
- const [val] = await snapAcc.promise;
2402
- expect(val).to.deep.equal({ a: 0, b: 1 });
2403
- });
2404
-
2405
- it('Null priorities not included in startAfter().', async () => {
2406
- const f = getRandomNode() as Reference;
2407
-
2408
- const ea = EventAccumulatorFactory.waitsForCount(1);
2409
- f.root.child('.info/connected').on('value', snap => {
2410
- ea.addEvent();
2411
- });
2412
-
2413
- await ea.promise;
2414
-
2415
- f.set({
2416
- a: { '.priority': null, '.value': 0 },
2417
- b: { '.priority': null, '.value': 1 },
2418
- c: { '.priority': '2', '.value': 2 },
2419
- d: { '.priority': 3, '.value': 3 },
2420
- e: { '.priority': 'hi', '.value': 4 }
2421
- });
2422
-
2423
- const snapAcc = EventAccumulatorFactory.waitsForCount(1);
2424
- f.startAfter(null)
2425
- .endAt(null)
2426
- .on('value', snap => {
2427
- snapAcc.addEvent(snap.val());
2428
- });
2429
-
2430
- const [val] = await snapAcc.promise;
2431
- expect(val).to.deep.equal(null);
2432
- });
2433
-
2434
- it('null priorities included in endAt(2).', async () => {
2435
- const f = getRandomNode() as Reference;
2436
-
2437
- f.set({
2438
- a: { '.priority': null, '.value': 0 },
2439
- b: { '.priority': null, '.value': 1 },
2440
- c: { '.priority': 2, '.value': 2 },
2441
- d: { '.priority': 3, '.value': 3 },
2442
- e: { '.priority': 'hi', '.value': 4 }
2443
- });
2444
-
2445
- const ea = EventAccumulatorFactory.waitsForCount(1);
2446
- f.endAt(2).on('value', snap => {
2447
- ea.addEvent(snap.val());
2448
- });
2449
-
2450
- const [val] = await ea.promise;
2451
- expect(val).to.deep.equal({ a: 0, b: 1, c: 2 });
2452
- });
2453
-
2454
- it('null priorities included in endBefore.', async () => {
2455
- const f = getRandomNode() as Reference;
2456
-
2457
- f.set({
2458
- a: { '.priority': null, '.value': 0 },
2459
- b: { '.priority': null, '.value': 1 },
2460
- c: { '.priority': 2, '.value': 2 },
2461
- d: { '.priority': 3, '.value': 3 },
2462
- e: { '.priority': 'hi', '.value': 4 }
2463
- });
2464
-
2465
- const ea = EventAccumulatorFactory.waitsForCount(1);
2466
- f.endBefore(2).on('value', snap => {
2467
- ea.addEvent(snap.val());
2468
- });
2469
-
2470
- const [val] = await ea.promise;
2471
- expect(val).to.deep.equal({ a: 0, b: 1 });
2472
- });
2473
-
2474
- it('null priorities not included in startAt(2).', async () => {
2475
- const f = getRandomNode() as Reference;
2476
-
2477
- f.set({
2478
- a: { '.priority': null, '.value': 0 },
2479
- b: { '.priority': null, '.value': 1 },
2480
- c: { '.priority': 2, '.value': 2 },
2481
- d: { '.priority': 3, '.value': 3 },
2482
- e: { '.priority': 'hi', '.value': 4 }
2483
- });
2484
-
2485
- const ea = EventAccumulatorFactory.waitsForCount(1);
2486
-
2487
- f.startAt(2).on('value', snap => {
2488
- ea.addEvent(snap.val());
2489
- });
2490
-
2491
- const [val] = await ea.promise;
2492
- expect(val).to.deep.equal({ c: 2, d: 3, e: 4 });
2493
- });
2494
-
2495
- it('null priorities not included in startAfter(2).', async () => {
2496
- const f = getRandomNode() as Reference;
2497
-
2498
- f.set({
2499
- a: { '.priority': null, '.value': 0 },
2500
- b: { '.priority': null, '.value': 1 },
2501
- c: { '.priority': 2, '.value': 2 },
2502
- d: { '.priority': 3, '.value': 3 },
2503
- e: { '.priority': 'hi', '.value': 4 }
2504
- });
2505
-
2506
- const ea = EventAccumulatorFactory.waitsForCount(1);
2507
-
2508
- f.startAfter(2).on('value', snap => {
2509
- ea.addEvent(snap.val());
2510
- });
2511
-
2512
- const [val] = await ea.promise;
2513
- expect(val).to.deep.equal({ d: 3, e: 4 });
2514
- });
2515
-
2516
- function dumpListens(node: Query) {
2517
- const listens: Map<string, Map<string, unknown>> = (
2518
- node._delegate._repo.persistentConnection_ as any
2519
- ).listens;
2520
- const nodePath = getPath(node);
2521
- const listenPaths = [];
2522
- for (const path of listens.keys()) {
2523
- if (path.substring(0, nodePath.length) === nodePath) {
2524
- listenPaths.push(path);
2525
- }
2526
- }
2527
-
2528
- listenPaths.sort();
2529
- const dumpPieces = [];
2530
- for (let i = 0; i < listenPaths.length; i++) {
2531
- const queryIds = [];
2532
- for (const queryId of listens.get(listenPaths[i]).keys()) {
2533
- queryIds.push(queryId);
2534
- }
2535
- queryIds.sort();
2536
- if (queryIds.length > 0) {
2537
- dumpPieces.push(
2538
- listenPaths[i].substring(nodePath.length) + ':' + queryIds.join(',')
2539
- );
2540
- }
2541
- }
2542
-
2543
- return dumpPieces.join(';');
2544
- }
2545
-
2546
- it('Dedupe listens: listen on parent.', () => {
2547
- const node = getRandomNode() as Reference;
2548
- expect(dumpListens(node)).to.equal('');
2549
-
2550
- const aOn = node.child('a').on('value', () => {});
2551
- expect(dumpListens(node)).to.equal('/a:default');
2552
-
2553
- const rootOn = node.on('value', () => {});
2554
- expect(dumpListens(node)).to.equal(':default');
2555
-
2556
- node.off('value', rootOn);
2557
- expect(dumpListens(node)).to.equal('/a:default');
2558
-
2559
- node.child('a').off('value', aOn);
2560
- expect(dumpListens(node)).to.equal('');
2561
- });
2562
-
2563
- it('Dedupe listens: listen on grandchild.', () => {
2564
- const node = getRandomNode() as Reference;
2565
-
2566
- const rootOn = node.on('value', () => {});
2567
- expect(dumpListens(node)).to.equal(':default');
2568
-
2569
- const aaOn = node.child('a/aa').on('value', () => {});
2570
- expect(dumpListens(node)).to.equal(':default');
2571
-
2572
- node.off('value', rootOn);
2573
- node.child('a/aa').off('value', aaOn);
2574
- expect(dumpListens(node)).to.equal('');
2575
- });
2576
-
2577
- it('Dedupe listens: listen on grandparent of two children.', () => {
2578
- const node = getRandomNode() as Reference;
2579
- expect(dumpListens(node)).to.equal('');
2580
-
2581
- const aaOn = node.child('a/aa').on('value', () => {});
2582
- expect(dumpListens(node)).to.equal('/a/aa:default');
2583
-
2584
- const bbOn = node.child('a/bb').on('value', () => {});
2585
- expect(dumpListens(node)).to.equal('/a/aa:default;/a/bb:default');
2586
-
2587
- const rootOn = node.on('value', () => {});
2588
- expect(dumpListens(node)).to.equal(':default');
2589
-
2590
- node.off('value', rootOn);
2591
- expect(dumpListens(node)).to.equal('/a/aa:default;/a/bb:default');
2592
-
2593
- node.child('a/aa').off('value', aaOn);
2594
- expect(dumpListens(node)).to.equal('/a/bb:default');
2595
-
2596
- node.child('a/bb').off('value', bbOn);
2597
- expect(dumpListens(node)).to.equal('');
2598
- });
2599
-
2600
- it('Dedupe queried listens: multiple queried listens; no dupes', () => {
2601
- const node = getRandomNode() as Reference;
2602
- expect(dumpListens(node)).to.equal('');
2603
-
2604
- const aLim1On = node
2605
- .child('a')
2606
- .limitToLast(1)
2607
- .on('value', () => {});
2608
- expect(dumpListens(node)).to.equal('/a:{"l":1,"vf":"r"}');
2609
-
2610
- const rootLim1On = node.limitToLast(1).on('value', () => {});
2611
- expect(dumpListens(node)).to.equal(':{"l":1,"vf":"r"};/a:{"l":1,"vf":"r"}');
2612
-
2613
- const aLim5On = node
2614
- .child('a')
2615
- .limitToLast(5)
2616
- .on('value', () => {});
2617
- expect(dumpListens(node)).to.equal(
2618
- ':{"l":1,"vf":"r"};/a:{"l":1,"vf":"r"},{"l":5,"vf":"r"}'
2619
- );
2620
-
2621
- node.limitToLast(1).off('value', rootLim1On);
2622
- expect(dumpListens(node)).to.equal('/a:{"l":1,"vf":"r"},{"l":5,"vf":"r"}');
2623
-
2624
- node.child('a').limitToLast(1).off('value', aLim1On);
2625
- node.child('a').limitToLast(5).off('value', aLim5On);
2626
- expect(dumpListens(node)).to.equal('');
2627
- });
2628
-
2629
- it('Dedupe queried listens: listen on parent of queried children.', () => {
2630
- const node = getRandomNode() as Reference;
2631
-
2632
- const aLim1On = node
2633
- .child('a')
2634
- .limitToLast(1)
2635
- .on('value', () => {});
2636
- expect(dumpListens(node)).to.equal('/a:{"l":1,"vf":"r"}');
2637
-
2638
- const bLim1On = node
2639
- .child('b')
2640
- .limitToLast(1)
2641
- .on('value', () => {});
2642
- expect(dumpListens(node)).to.equal(
2643
- '/a:{"l":1,"vf":"r"};/b:{"l":1,"vf":"r"}'
2644
- );
2645
-
2646
- const rootOn = node.on('value', () => {});
2647
- expect(dumpListens(node)).to.equal(':default');
2648
-
2649
- // remove in slightly random order.
2650
- node.child('a').limitToLast(1).off('value', aLim1On);
2651
- expect(dumpListens(node)).to.equal(':default');
2652
-
2653
- node.off('value', rootOn);
2654
- expect(dumpListens(node)).to.equal('/b:{"l":1,"vf":"r"}');
2655
-
2656
- node.child('b').limitToLast(1).off('value', bLim1On);
2657
- expect(dumpListens(node)).to.equal('');
2658
- });
2659
-
2660
- it('Limit with mix of null and non-null priorities.', () => {
2661
- const node = getRandomNode() as Reference;
2662
-
2663
- const children = [];
2664
- node.limitToLast(5).on('child_added', childSnap => {
2665
- children.push(childSnap.key);
2666
- });
2667
-
2668
- node.set({
2669
- Vikrum: { '.priority': 1000, score: 1000, name: 'Vikrum' },
2670
- Mike: { '.priority': 500, score: 500, name: 'Mike' },
2671
- Andrew: { '.priority': 50, score: 50, name: 'Andrew' },
2672
- James: { '.priority': 7, score: 7, name: 'James' },
2673
- Sally: { '.priority': -7, score: -7, name: 'Sally' },
2674
- Fred: { score: 0, name: 'Fred' }
2675
- });
2676
-
2677
- expect(children.join(',')).to.equal('Sally,James,Andrew,Mike,Vikrum');
2678
- });
2679
-
2680
- it('Limit with mix of null and non-null priorities using server data', async () => {
2681
- const node = getRandomNode() as Reference;
2682
-
2683
- const children = [];
2684
- await node.set({
2685
- Vikrum: { '.priority': 1000, score: 1000, name: 'Vikrum' },
2686
- Mike: { '.priority': 500, score: 500, name: 'Mike' },
2687
- Andrew: { '.priority': 50, score: 50, name: 'Andrew' },
2688
- James: { '.priority': 7, score: 7, name: 'James' },
2689
- Sally: { '.priority': -7, score: -7, name: 'Sally' },
2690
- Fred: { score: 0, name: 'Fred' }
2691
- });
2692
-
2693
- const ea = EventAccumulatorFactory.waitsForCount(5);
2694
- node.limitToLast(5).on('child_added', childSnap => {
2695
- children.push(childSnap.key);
2696
- ea.addEvent();
2697
- });
2698
-
2699
- await ea.promise;
2700
-
2701
- expect(children.join(',')).to.equal('Sally,James,Andrew,Mike,Vikrum');
2702
- });
2703
-
2704
- it('.on() with a context works.', () => {
2705
- const ref = getRandomNode() as Reference;
2706
-
2707
- const ListenerDoohickey = function () {
2708
- this.snap = null;
2709
- };
2710
- ListenerDoohickey.prototype.onEvent = function (snap) {
2711
- this.snap = snap;
2712
- };
2713
-
2714
- const l = new ListenerDoohickey();
2715
- ref.on('value', l.onEvent, l);
2716
-
2717
- ref.set('test');
2718
- expect(l.snap.val()).to.equal('test');
2719
-
2720
- ref.off('value', l.onEvent, l);
2721
-
2722
- // Ensure we don't get any more events.
2723
- ref.set('blah');
2724
- expect(l.snap.val()).to.equal('test');
2725
- });
2726
-
2727
- it('.once() with a context works.', () => {
2728
- const ref = getRandomNode() as Reference;
2729
-
2730
- const ListenerDoohickey = function () {
2731
- this.snap = null;
2732
- };
2733
- ListenerDoohickey.prototype.onEvent = function (snap) {
2734
- this.snap = snap;
2735
- };
2736
-
2737
- const l = new ListenerDoohickey();
2738
- ref.once('value', l.onEvent, l);
2739
-
2740
- ref.set('test');
2741
- expect(l.snap.val()).to.equal('test');
2742
-
2743
- // Shouldn't get any more events.
2744
- ref.set('blah');
2745
- expect(l.snap.val()).to.equal('test');
2746
- });
2747
-
2748
- it('handles an update that deletes the entire window in a query', () => {
2749
- const ref = getRandomNode() as Reference;
2750
-
2751
- const snaps = [];
2752
- ref.limitToLast(2).on('value', snap => {
2753
- snaps.push(snap.val());
2754
- });
2755
-
2756
- ref.set({
2757
- a: { '.value': 1, '.priority': 1 },
2758
- b: { '.value': 2, '.priority': 2 },
2759
- c: { '.value': 3, '.priority': 3 }
2760
- });
2761
- ref.update({
2762
- b: null,
2763
- c: null
2764
- });
2765
-
2766
- expect(snaps.length).to.equal(2);
2767
- expect(snaps[0]).to.deep.equal({ b: 2, c: 3 });
2768
- // The original set is still outstanding (synchronous API), so we have a full cache to re-window against
2769
- expect(snaps[1]).to.deep.equal({ a: 1 });
2770
- });
2771
-
2772
- it('handles an out-of-view query on a child', () => {
2773
- const ref = getRandomNode() as Reference;
2774
-
2775
- let parent = null;
2776
- ref.limitToLast(1).on('value', snap => {
2777
- parent = snap.val();
2778
- });
2779
-
2780
- let child = null;
2781
- ref.child('a').on('value', snap => {
2782
- child = snap.val();
2783
- });
2784
-
2785
- ref.set({ a: 1, b: 2 });
2786
- expect(parent).to.deep.equal({ b: 2 });
2787
- expect(child).to.equal(1);
2788
-
2789
- ref.update({ c: 3 });
2790
- expect(parent).to.deep.equal({ c: 3 });
2791
- expect(child).to.equal(1);
2792
- });
2793
-
2794
- it('handles a child query going out of view of the parent', () => {
2795
- const ref = getRandomNode() as Reference;
2796
-
2797
- let parent = null;
2798
- ref.limitToLast(1).on('value', snap => {
2799
- parent = snap.val();
2800
- });
2801
-
2802
- let child = null;
2803
- ref.child('a').on('value', snap => {
2804
- child = snap.val();
2805
- });
2806
-
2807
- ref.set({ a: 1 });
2808
- expect(parent).to.deep.equal({ a: 1 });
2809
- expect(child).to.equal(1);
2810
- ref.child('b').set(2);
2811
- expect(parent).to.deep.equal({ b: 2 });
2812
- expect(child).to.equal(1);
2813
- ref.child('b').remove();
2814
- expect(parent).to.deep.equal({ a: 1 });
2815
- expect(child).to.equal(1);
2816
- });
2817
-
2818
- it('handles diverging views', () => {
2819
- const ref = getRandomNode() as Reference;
2820
-
2821
- let c = null;
2822
- ref
2823
- .limitToLast(1)
2824
- .endAt(null, 'c')
2825
- .on('value', snap => {
2826
- c = snap.val();
2827
- });
2828
-
2829
- let d = null;
2830
- ref
2831
- .limitToLast(1)
2832
- .endAt(null, 'd')
2833
- .on('value', snap => {
2834
- d = snap.val();
2835
- });
2836
-
2837
- ref.set({ a: 1, b: 2, c: 3 });
2838
- expect(c).to.deep.equal({ c: 3 });
2839
- expect(d).to.deep.equal({ c: 3 });
2840
- ref.child('d').set(4);
2841
- expect(c).to.deep.equal({ c: 3 });
2842
- expect(d).to.deep.equal({ d: 4 });
2843
- });
2844
-
2845
- it('handles removing a queried element', async () => {
2846
- const ref = getRandomNode() as Reference;
2847
-
2848
- let val;
2849
- const ea = EventAccumulatorFactory.waitsForCount(1);
2850
- ref.limitToLast(1).on('child_added', snap => {
2851
- val = snap.val();
2852
- ea.addEvent();
2853
- });
2854
-
2855
- ref.set({ a: 1, b: 2 });
2856
- expect(val).to.equal(2);
2857
-
2858
- ref.child('b').remove();
2859
-
2860
- await ea.promise;
2861
-
2862
- expect(val).to.equal(1);
2863
- });
2864
-
2865
- it('.startAt().limitToFirst(1) works.', done => {
2866
- const ref = getRandomNode() as Reference;
2867
- ref.set({ a: 1, b: 2 });
2868
-
2869
- let val;
2870
- ref
2871
- .startAt()
2872
- .limitToFirst(1)
2873
- .on('child_added', snap => {
2874
- val = snap.val();
2875
- if (val === 1) {
2876
- done();
2877
- }
2878
- });
2879
- });
2880
-
2881
- it('.startAt().limitToFirst(1) and then remove first child (case 1664).', async () => {
2882
- const ref = getRandomNode() as Reference;
2883
- ref.set({ a: 1, b: 2 });
2884
-
2885
- const ea = EventAccumulatorFactory.waitsForCount(1);
2886
- let val;
2887
- ref
2888
- .startAt()
2889
- .limitToFirst(1)
2890
- .on('child_added', snap => {
2891
- val = snap.val();
2892
- ea.addEvent();
2893
- });
2894
-
2895
- await ea.promise;
2896
- expect(val).to.equal(1);
2897
-
2898
- ea.reset();
2899
- ref.child('a').remove();
2900
-
2901
- await ea.promise;
2902
- expect(val).to.equal(2);
2903
- });
2904
-
2905
- it('.startAt() with two arguments works properly (case 1169).', done => {
2906
- const ref = getRandomNode() as Reference;
2907
- const data = {
2908
- Walker: {
2909
- name: 'Walker',
2910
- score: 20,
2911
- '.priority': 20
2912
- },
2913
- Michael: {
2914
- name: 'Michael',
2915
- score: 100,
2916
- '.priority': 100
2917
- }
2918
- };
2919
- ref.set(data, () => {
2920
- ref
2921
- .startAt(20, 'Walker')
2922
- .limitToFirst(2)
2923
- .on('value', s => {
2924
- const childNames = [];
2925
- s.forEach(node => {
2926
- childNames.push(node.key);
2927
- });
2928
- expect(childNames).to.deep.equal(['Walker', 'Michael']);
2929
- done();
2930
- });
2931
- });
2932
- });
2933
-
2934
- it('.startAfter() with two arguments works properly (case 1169).', done => {
2935
- const ref = getRandomNode() as Reference;
2936
- const data = {
2937
- Walker: {
2938
- name: 'Walker',
2939
- score: 20,
2940
- '.priority': 20
2941
- },
2942
- Michael: {
2943
- name: 'Michael',
2944
- score: 100,
2945
- '.priority': 100
2946
- }
2947
- };
2948
- ref.set(data, () => {
2949
- ref
2950
- .startAfter(20, 'Walker')
2951
- .limitToFirst(2)
2952
- .on('value', s => {
2953
- const childNames = [];
2954
- s.forEach(node => {
2955
- childNames.push(node.key);
2956
- });
2957
- expect(childNames).to.deep.equal(['Michael']);
2958
- done();
2959
- });
2960
- });
2961
- });
2962
-
2963
- it('handles multiple queries on the same node', async () => {
2964
- const ref = getRandomNode() as Reference;
2965
-
2966
- await ref.set({
2967
- a: 1,
2968
- b: 2,
2969
- c: 3,
2970
- d: 4,
2971
- e: 5,
2972
- f: 6
2973
- });
2974
-
2975
- const ea = EventAccumulatorFactory.waitsForCount(1);
2976
-
2977
- let firstListen = false;
2978
- ref.limitToLast(2).on('value', snap => {
2979
- // This shouldn't get called twice, we don't update the values here
2980
- expect(firstListen).to.be.false;
2981
- firstListen = true;
2982
- ea.addEvent();
2983
- });
2984
-
2985
- await ea.promise;
2986
-
2987
- // now do consecutive once calls
2988
- await ref.limitToLast(1).once('value');
2989
- const snap = await ref.limitToLast(1).once('value');
2990
- const val = snap.val();
2991
- expect(val).to.deep.equal({ f: 6 });
2992
- });
2993
-
2994
- it('handles once called on a node with a default listener', async () => {
2995
- const ref = getRandomNode() as Reference;
2996
-
2997
- await ref.set({
2998
- a: 1,
2999
- b: 2,
3000
- c: 3,
3001
- d: 4,
3002
- e: 5,
3003
- f: 6
3004
- });
3005
-
3006
- const ea = EventAccumulatorFactory.waitsForCount(1);
3007
- // Setup value listener
3008
- ref.on('value', snap => {
3009
- ea.addEvent();
3010
- });
3011
-
3012
- await ea.promise;
3013
-
3014
- // now do the once call
3015
- const snap = await ref.limitToLast(1).once('child_added');
3016
- const val = snap.val();
3017
- expect(val).to.equal(6);
3018
- });
3019
-
3020
- it('handles once called on a node with a default listener and non-complete limit', async () => {
3021
- const ref = getRandomNode() as Reference;
3022
-
3023
- await ref.set({
3024
- a: 1,
3025
- b: 2,
3026
- c: 3
3027
- });
3028
-
3029
- const ea = EventAccumulatorFactory.waitsForCount(1);
3030
- // Setup value listener
3031
- ref.on('value', snap => {
3032
- ea.addEvent();
3033
- });
3034
-
3035
- await ea.promise;
3036
-
3037
- // now do the once call
3038
- const snap = await ref.limitToLast(5).once('value');
3039
- const val = snap.val();
3040
- expect(val).to.deep.equal({ a: 1, b: 2, c: 3 });
3041
- });
3042
-
3043
- it('Remote remove triggers events.', done => {
3044
- const refPair = getRandomNode(2),
3045
- writeRef = refPair[0],
3046
- readRef = refPair[1];
3047
-
3048
- writeRef.set({ a: 'a', b: 'b', c: 'c', d: 'd', e: 'e' }, () => {
3049
- // Wait to get the initial data, and then remove 'c' remotely and wait for new data.
3050
- let count = 0;
3051
- readRef.limitToLast(5).on('value', s => {
3052
- count++;
3053
- if (count === 1) {
3054
- expect(s.val()).to.deep.equal({
3055
- a: 'a',
3056
- b: 'b',
3057
- c: 'c',
3058
- d: 'd',
3059
- e: 'e'
3060
- });
3061
- writeRef.child('c').remove();
3062
- } else {
3063
- expect(count).to.equal(2);
3064
- expect(s.val()).to.deep.equal({ a: 'a', b: 'b', d: 'd', e: 'e' });
3065
- done();
3066
- }
3067
- });
3068
- });
3069
- });
3070
-
3071
- it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", done => {
3072
- const ref = getRandomNode() as Reference;
3073
- ref.set(
3074
- { a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f', g: 'g', h: 'h' },
3075
- () => {
3076
- ref
3077
- .endAt(null, 'f')
3078
- .limitToLast(5)
3079
- .on('value', s => {
3080
- expect(s.val()).to.deep.equal({
3081
- b: 'b',
3082
- c: 'c',
3083
- d: 'd',
3084
- e: 'e',
3085
- f: 'f'
3086
- });
3087
- done();
3088
- });
3089
- }
3090
- );
3091
- });
3092
-
3093
- it(".endBefore(null, 'f').limitToLast(5) returns the right set of children.", done => {
3094
- const ref = getRandomNode() as Reference;
3095
- ref.set(
3096
- { a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f', g: 'g', h: 'h' },
3097
- () => {
3098
- ref
3099
- .endBefore(null, 'f')
3100
- .limitToLast(5)
3101
- .on('value', s => {
3102
- expect(s.val()).to.deep.equal({
3103
- a: 'a',
3104
- b: 'b',
3105
- c: 'c',
3106
- d: 'd',
3107
- e: 'e'
3108
- });
3109
- done();
3110
- });
3111
- }
3112
- );
3113
- });
3114
-
3115
- it('complex update() at query root raises correct value event', done => {
3116
- const nodePair = getRandomNode(2);
3117
- const writer = nodePair[0];
3118
- const reader = nodePair[1];
3119
-
3120
- let readerLoaded = false;
3121
- writer
3122
- .child('foo')
3123
- .set({ a: 1, b: 2, c: 3, d: 4, e: 5 }, (error, dummy) => {
3124
- reader
3125
- .child('foo')
3126
- .startAt()
3127
- .limitToFirst(4)
3128
- .on('value', snapshot => {
3129
- const val = snapshot.val();
3130
- if (!readerLoaded) {
3131
- readerLoaded = true;
3132
- expect(val).to.deep.equal({ a: 1, b: 2, c: 3, d: 4 });
3133
-
3134
- // This update causes the following to happen:
3135
- // 1. An in-view child is set to null (b)
3136
- // 2. An in-view child has its value changed (c)
3137
- // 3. An in-view child is changed and bumped out-of-view (d)
3138
- // We expect to get null values for b and d, along with the new children and updated value for c
3139
- writer
3140
- .child('foo')
3141
- .update({ b: null, c: 'a', cc: 'new', cd: 'new2', d: 'gone' });
3142
- } else {
3143
- done();
3144
- expect(val).to.deep.equal({
3145
- a: 1,
3146
- c: 'a',
3147
- cc: 'new',
3148
- cd: 'new2'
3149
- });
3150
- }
3151
- });
3152
- });
3153
- });
3154
-
3155
- it('update() at query root raises correct value event', done => {
3156
- const nodePair = getRandomNode(2);
3157
- const writer = nodePair[0];
3158
- const reader = nodePair[1];
3159
-
3160
- let readerLoaded = false;
3161
- writer
3162
- .child('foo')
3163
- .set({ bar: 'a', baz: 'b', bam: 'c' }, (error, dummy) => {
3164
- reader
3165
- .child('foo')
3166
- .limitToLast(10)
3167
- .on('value', snapshot => {
3168
- const val = snapshot.val();
3169
- if (!readerLoaded) {
3170
- readerLoaded = true;
3171
- expect(val.bar).to.equal('a');
3172
- expect(val.baz).to.equal('b');
3173
- expect(val.bam).to.equal('c');
3174
- writer.child('foo').update({ bar: 'd', bam: null, bat: 'e' });
3175
- } else {
3176
- expect(val.bar).to.equal('d');
3177
- expect(val.baz).to.equal('b');
3178
- expect(val.bat).to.equal('e');
3179
- expect(val.bam).to.equal(undefined);
3180
- done();
3181
- }
3182
- });
3183
- });
3184
- });
3185
-
3186
- it('get at empty node is null', async () => {
3187
- const node = getRandomNode() as Reference;
3188
- expect((await node.get()).val()).to.equal(null);
3189
- });
3190
-
3191
- it('get at node returns correct value', async () => {
3192
- const node = getRandomNode() as Reference;
3193
- const expected = { foo: 'a', bar: 'b' };
3194
- await node.set(expected);
3195
- const snapshot = await node.get();
3196
- expect(snapshot.val()).to.deep.equal(expected);
3197
- });
3198
-
3199
- it('get for child returns correct value', async () => {
3200
- const node = getRandomNode() as Reference;
3201
- await node.set({ foo: 'a', bar: 'b', baz: 'c' });
3202
- const snapshot = await node.child('baz').get();
3203
- expect(snapshot.val()).to.deep.equal('c');
3204
- });
3205
-
3206
- it('get for parent returns correct value', async () => {
3207
- const node = getRandomNode() as Reference;
3208
- const child = node.child('child');
3209
- await child.set(1);
3210
- expect((await node.get()).val()).to.deep.equal({ child: 1 });
3211
- });
3212
-
3213
- it('get for removed node returns correct value', async () => {
3214
- const node = getRandomNode() as Reference;
3215
- const expected = { foo: 'a', bar: 'b' };
3216
- await node.set(expected);
3217
- let snapshot = await node.get();
3218
- const val = snapshot.val();
3219
- expect(val).to.deep.equal(expected);
3220
- await node.remove();
3221
- snapshot = await node.get();
3222
- expect(snapshot.val()).to.be.null;
3223
- });
3224
-
3225
- it('get for missing node while offline is rejected', async () => {
3226
- const node = getRandomNode() as Reference;
3227
- node.database.goOffline();
3228
- try {
3229
- await expect(node.get()).to.eventually.be.rejected;
3230
- } finally {
3231
- node.database.goOnline();
3232
- }
3233
- });
3234
-
3235
- it('get reads node from cache when not connected', async () => {
3236
- const node = getRandomNode() as Reference;
3237
- const node2 = getFreshRepo(node._delegate._path);
3238
- try {
3239
- await node2.set({ foo: 'bar' });
3240
- const onSnapshot = await new Promise((resolve, _) => {
3241
- node.on('value', snap => {
3242
- resolve(snap);
3243
- });
3244
- });
3245
- node.database.goOffline();
3246
- const getSnapshot = await node.get();
3247
- // node's cache dropped here.
3248
- node.off();
3249
- expect(getSnapshot.val()).to.deep.equal(
3250
- (onSnapshot as DataSnapshot).val()
3251
- );
3252
- } finally {
3253
- node.database.goOnline();
3254
- }
3255
- });
3256
-
3257
- it('get reads child node from cache when not connected', async () => {
3258
- const node = getRandomNode() as Reference;
3259
- const node2 = getFreshRepo(node._delegate._path);
3260
- try {
3261
- await node2.set({ foo: 'bar' });
3262
- const onSnapshot = await new Promise((resolve, _) => {
3263
- node.on('value', snap => {
3264
- resolve(snap);
3265
- });
3266
- });
3267
- node.database.goOffline();
3268
- const getSnapshot = await node.child('foo').get();
3269
- // node's cache dropped here.
3270
- node.off();
3271
- expect(getSnapshot.val()).to.deep.equal('bar');
3272
- } finally {
3273
- node.database.goOnline();
3274
- }
3275
- });
3276
-
3277
- it('get reads parent node from cache when not connected', async () => {
3278
- const node = getRandomNode() as Reference;
3279
- const node2 = getFreshRepo(node._delegate._path);
3280
- try {
3281
- await node2.set({ foo: 'bar' });
3282
- await node2.child('baz').set(1);
3283
- const onSnapshot = await new Promise((resolve, _) => {
3284
- node.on('value', snap => {
3285
- resolve(snap);
3286
- });
3287
- });
3288
- node.database.goOffline();
3289
- const getSnapshot = await node.get();
3290
- // node's cache dropped here.
3291
- node.off();
3292
- expect(getSnapshot.val()).to.deep.equal({ foo: 'bar', baz: 1 });
3293
- } finally {
3294
- node.database.goOnline();
3295
- }
3296
- });
3297
-
3298
- it('get with pending node writes when not connected', async () => {
3299
- const node = getRandomNode() as Reference;
3300
- const node2 = getFreshRepo(node._delegate._path);
3301
- try {
3302
- await node2.set({ foo: 'bar' });
3303
- const onSnapshot = await new Promise((resolve, _) => {
3304
- node.on('value', snap => {
3305
- resolve(snap);
3306
- });
3307
- });
3308
- node.database.goOffline();
3309
- node.set({ foo: 'baz' });
3310
- const getSnapshot = await node.get();
3311
- // node's cache dropped here.
3312
- node.off();
3313
- expect(getSnapshot.val()).to.deep.equal({ foo: 'baz' });
3314
- } finally {
3315
- node.database.goOnline();
3316
- }
3317
- });
3318
-
3319
- it('get with pending child writes when not connected', async () => {
3320
- const node = getRandomNode() as Reference;
3321
- const node2 = getFreshRepo(node._delegate._path);
3322
- try {
3323
- await node2.set({ foo: 'bar' });
3324
- const onSnapshot = await new Promise((resolve, _) => {
3325
- node.on('value', snap => {
3326
- resolve(snap);
3327
- });
3328
- });
3329
- node.database.goOffline();
3330
- node.child('baz').set(true);
3331
- const getSnapshot = await node.get();
3332
- // node's cache dropped here.
3333
- node.off();
3334
- expect(getSnapshot.val()).to.deep.equal({ foo: 'bar', baz: true });
3335
- } finally {
3336
- node.database.goOnline();
3337
- }
3338
- });
3339
-
3340
- it('get with pending parent writes when not connected', async () => {
3341
- const node = getRandomNode() as Reference;
3342
- const node2 = getFreshRepo(node._delegate._path);
3343
- try {
3344
- await node2.set({ foo: 'bar' });
3345
- const onSnapshot = await new Promise((resolve, _) => {
3346
- node.on('value', snap => {
3347
- resolve(snap);
3348
- });
3349
- });
3350
- node.database.goOffline();
3351
- node.set({ foo: 'baz' });
3352
- const getSnapshot = await node.child('foo').get();
3353
- // node's cache dropped here.
3354
- node.off();
3355
- expect(getSnapshot.val()).to.deep.equal('baz');
3356
- } finally {
3357
- node.database.goOnline();
3358
- }
3359
- });
3360
-
3361
- it('get with pending writes', async () => {
3362
- const node = getRandomNode() as Reference;
3363
- node.database.goOffline();
3364
- try {
3365
- node.set({ foo: 'bar' });
3366
- const snap = await node.get();
3367
- expect(snap.val()).to.deep.equal({ foo: 'bar' });
3368
- } finally {
3369
- node.database.goOnline();
3370
- }
3371
- });
3372
-
3373
- it('get child of pending writes', async () => {
3374
- const node = getRandomNode() as Reference;
3375
- node.database.goOffline();
3376
- try {
3377
- node.set({ foo: 'bar' });
3378
- const snap = await node.child('foo').get();
3379
- expect(snap.val()).to.deep.equal('bar');
3380
- } finally {
3381
- node.database.goOnline();
3382
- }
3383
- });
3384
-
3385
- it('get does not cache sibling data', async () => {
3386
- const reader = getRandomNode() as Reference;
3387
- const writer = getFreshRepo(reader._delegate._path);
3388
- await writer.set({
3389
- foo: { cached: { data: '1' }, notCached: { data: '2' } }
3390
- });
3391
- const snapshot = await reader.child('foo/cached').get();
3392
- expect(snapshot.val()).to.deep.equal({ data: '1' });
3393
- reader.database.goOffline();
3394
- try {
3395
- await expect(reader.child('foo/notCached').get()).to.eventually.be
3396
- .rejected;
3397
- } finally {
3398
- reader.database.goOnline();
3399
- }
3400
- });
3401
-
3402
- it('set() at query root raises correct value event', done => {
3403
- const nodePair = getRandomNode(2);
3404
- const writer = nodePair[0];
3405
- const reader = nodePair[1];
3406
-
3407
- let readerLoaded = false;
3408
- writer
3409
- .child('foo')
3410
- .set({ bar: 'a', baz: 'b', bam: 'c' }, (error, dummy) => {
3411
- reader
3412
- .child('foo')
3413
- .limitToLast(10)
3414
- .on('value', snapshot => {
3415
- const val = snapshot.val();
3416
- if (!readerLoaded) {
3417
- readerLoaded = true;
3418
- expect(val.bar).to.equal('a');
3419
- expect(val.baz).to.equal('b');
3420
- expect(val.bam).to.equal('c');
3421
- writer.child('foo').set({ bar: 'd', baz: 'b', bat: 'e' });
3422
- } else {
3423
- expect(val.bar).to.equal('d');
3424
- expect(val.baz).to.equal('b');
3425
- expect(val.bat).to.equal('e');
3426
- expect(val.bam).to.equal(undefined);
3427
- done();
3428
- }
3429
- });
3430
- });
3431
- });
3432
-
3433
- it('listen for child_added events with limit and different types fires properly', done => {
3434
- const nodePair = getRandomNode(2);
3435
- const writer = nodePair[0];
3436
- const reader = nodePair[1];
3437
-
3438
- let numEventsReceived = 0,
3439
- gotA = false,
3440
- gotB = false,
3441
- gotC = false;
3442
- writer.child('a').set(1, (error, dummy) => {
3443
- writer.child('b').set('b', (error, dummy) => {
3444
- writer
3445
- .child('c')
3446
- .set({ deep: 'path', of: { stuff: true } }, (error, dummy) => {
3447
- reader.limitToLast(3).on('child_added', snap => {
3448
- const val = snap.val();
3449
- switch (snap.key) {
3450
- case 'a':
3451
- gotA = true;
3452
- expect(val).to.equal(1);
3453
- break;
3454
- case 'b':
3455
- gotB = true;
3456
- expect(val).to.equal('b');
3457
- break;
3458
- case 'c':
3459
- gotC = true;
3460
- expect(val.deep).to.equal('path');
3461
- expect(val.of.stuff).to.be.true;
3462
- break;
3463
- default:
3464
- expect(false).to.be.true;
3465
- }
3466
- numEventsReceived += 1;
3467
- expect(numEventsReceived).to.be.lessThan(4);
3468
- if (gotA && gotB && gotC) {
3469
- done();
3470
- }
3471
- });
3472
- });
3473
- });
3474
- });
3475
- });
3476
-
3477
- it('listen for child_changed events with limit and different types fires properly', done => {
3478
- const nodePair = getRandomNode(2);
3479
- const writer = nodePair[0];
3480
- const reader = nodePair[1];
3481
-
3482
- let numEventsReceived = 0,
3483
- gotA = false,
3484
- gotB = false,
3485
- gotC = false,
3486
- readerLoaded = false;
3487
- writer.set(
3488
- { a: 'something', b: "we'll", c: 'overwrite ' },
3489
- (error, dummy) => {
3490
- reader.limitToLast(3).on('value', snapshot => {
3491
- if (!readerLoaded) {
3492
- readerLoaded = true;
3493
- // Set up listener for upcoming change events
3494
- reader.limitToLast(3).on('child_changed', snap => {
3495
- const val = snap.val();
3496
- switch (snap.key) {
3497
- case 'a':
3498
- gotA = true;
3499
- expect(val).to.equal(1);
3500
- break;
3501
- case 'b':
3502
- gotB = true;
3503
- expect(val).to.equal('b');
3504
- break;
3505
- case 'c':
3506
- gotC = true;
3507
- expect(val.deep).to.equal('path');
3508
- expect(val.of.stuff).to.be.true;
3509
- break;
3510
- default:
3511
- expect(false).to.be.true;
3512
- }
3513
- numEventsReceived += 1;
3514
- expect(numEventsReceived).to.be.lessThan(4);
3515
- if (gotA && gotB && gotC) {
3516
- done();
3517
- }
3518
- });
3519
-
3520
- // Begin changing every key
3521
- writer.child('a').set(1);
3522
- writer.child('b').set('b');
3523
- writer.child('c').set({ deep: 'path', of: { stuff: true } });
3524
- }
3525
- });
3526
- }
3527
- );
3528
- });
3529
-
3530
- it('listen for child_remove events with limit and different types fires properly', done => {
3531
- const nodePair = getRandomNode(2);
3532
- const writer = nodePair[0];
3533
- const reader = nodePair[1];
3534
-
3535
- let numEventsReceived = 0,
3536
- gotA = false,
3537
- gotB = false,
3538
- gotC = false,
3539
- readerLoaded = false;
3540
- writer.set(
3541
- { a: 1, b: 'b', c: { deep: 'path', of: { stuff: true } } },
3542
- (error, dummy) => {
3543
- reader.limitToLast(3).on('value', snapshot => {
3544
- if (!readerLoaded) {
3545
- readerLoaded = true;
3546
-
3547
- // Set up listener for upcoming change events
3548
- reader.limitToLast(3).on('child_removed', snap => {
3549
- const val = snap.val();
3550
- switch (snap.key) {
3551
- case 'a':
3552
- gotA = true;
3553
- expect(val).to.equal(1);
3554
- break;
3555
- case 'b':
3556
- gotB = true;
3557
- expect(val).to.equal('b');
3558
- break;
3559
- case 'c':
3560
- gotC = true;
3561
- expect(val.deep).to.equal('path');
3562
- expect(val.of.stuff).to.be.true;
3563
- break;
3564
- default:
3565
- expect(false).to.be.true;
3566
- }
3567
- numEventsReceived += 1;
3568
- expect(numEventsReceived).to.be.lessThan(4);
3569
- if (gotA && gotB && gotC) {
3570
- done();
3571
- }
3572
- });
3573
-
3574
- // Begin removing every key
3575
- writer.child('a').remove();
3576
- writer.child('b').remove();
3577
- writer.child('c').remove();
3578
- }
3579
- });
3580
- }
3581
- );
3582
- });
3583
-
3584
- it('listen for child_remove events when parent removed', done => {
3585
- const nodePair = getRandomNode(2);
3586
- const writer = nodePair[0];
3587
- const reader = nodePair[1];
3588
-
3589
- let numEventsReceived = 0,
3590
- gotA = false,
3591
- gotB = false,
3592
- gotC = false,
3593
- readerLoaded = false;
3594
- writer.set(
3595
- { a: 1, b: 'b', c: { deep: 'path', of: { stuff: true } } },
3596
- (error, dummy) => {
3597
- reader.limitToLast(3).on('value', snapshot => {
3598
- if (!readerLoaded) {
3599
- readerLoaded = true;
3600
-
3601
- // Set up listener for upcoming change events
3602
- reader.limitToLast(3).on('child_removed', snap => {
3603
- const val = snap.val();
3604
- switch (snap.key) {
3605
- case 'a':
3606
- gotA = true;
3607
- expect(val).to.equal(1);
3608
- break;
3609
- case 'b':
3610
- gotB = true;
3611
- expect(val).to.equal('b');
3612
- break;
3613
- case 'c':
3614
- gotC = true;
3615
- expect(val.deep).to.equal('path');
3616
- expect(val.of.stuff).to.be.true;
3617
- break;
3618
- default:
3619
- expect(false).to.be.true;
3620
- }
3621
- numEventsReceived += 1;
3622
- expect(numEventsReceived).to.be.lessThan(4);
3623
- if (gotA && gotB && gotC) {
3624
- done();
3625
- }
3626
- });
3627
-
3628
- // Remove the query parent
3629
- writer.remove();
3630
- }
3631
- });
3632
- }
3633
- );
3634
- });
3635
-
3636
- it('listen for child_remove events when parent set to scalar', done => {
3637
- const nodePair = getRandomNode(2);
3638
- const writer = nodePair[0];
3639
- const reader = nodePair[1];
3640
-
3641
- let numEventsReceived = 0,
3642
- gotA = false,
3643
- gotB = false,
3644
- gotC = false,
3645
- readerLoaded = false;
3646
- writer.set(
3647
- { a: 1, b: 'b', c: { deep: 'path', of: { stuff: true } } },
3648
- (error, dummy) => {
3649
- reader.limitToLast(3).on('value', snapshot => {
3650
- if (!readerLoaded) {
3651
- readerLoaded = true;
3652
-
3653
- // Set up listener for upcoming change events
3654
- reader.limitToLast(3).on('child_removed', snap => {
3655
- const val = snap.val();
3656
- switch (snap.key) {
3657
- case 'a':
3658
- gotA = true;
3659
- expect(val).to.equal(1);
3660
- break;
3661
- case 'b':
3662
- gotB = true;
3663
- expect(val).to.equal('b');
3664
- break;
3665
- case 'c':
3666
- gotC = true;
3667
- expect(val.deep).to.equal('path');
3668
- expect(val.of.stuff).to.be.true;
3669
- break;
3670
- default:
3671
- expect(false).to.be.true;
3672
- }
3673
- numEventsReceived += 1;
3674
- expect(numEventsReceived).to.be.lessThan(4);
3675
- if (gotA && gotB && gotC) {
3676
- done();
3677
- }
3678
- });
3679
-
3680
- // Set the parent to a scalar
3681
- writer.set('scalar');
3682
- }
3683
- });
3684
- }
3685
- );
3686
- });
3687
-
3688
- it('Queries behave wrong after .once().', async () => {
3689
- const refPair = getRandomNode(2),
3690
- writeRef = refPair[0],
3691
- readRef = refPair[1];
3692
- let startAtCount, defaultCount;
3693
-
3694
- await writeRef.set({ a: 1, b: 2, c: 3, d: 4 });
3695
-
3696
- await readRef.once('value');
3697
-
3698
- const ea = EventAccumulatorFactory.waitsForCount(5);
3699
- startAtCount = 0;
3700
- readRef.startAt(null, 'd').on('child_added', () => {
3701
- startAtCount++;
3702
- ea.addEvent();
3703
- });
3704
- expect(startAtCount).to.equal(0);
3705
-
3706
- defaultCount = 0;
3707
- readRef.on('child_added', () => {
3708
- defaultCount++;
3709
- ea.addEvent();
3710
- });
3711
- expect(defaultCount).to.equal(0);
3712
-
3713
- readRef.on('child_removed', () => {
3714
- expect(false).to.be.true;
3715
- });
3716
-
3717
- return ea.promise;
3718
- });
3719
-
3720
- it('Case 2003: Correctly get events for startAt/endAt queries when priority changes.', () => {
3721
- const ref = getRandomNode() as Reference;
3722
- const addedFirst = [],
3723
- removedFirst = [],
3724
- addedSecond = [],
3725
- removedSecond = [];
3726
- ref
3727
- .startAt(0)
3728
- .endAt(10)
3729
- .on('child_added', snap => {
3730
- addedFirst.push(snap.key);
3731
- });
3732
- ref
3733
- .startAt(0)
3734
- .endAt(10)
3735
- .on('child_removed', snap => {
3736
- removedFirst.push(snap.key);
3737
- });
3738
- ref
3739
- .startAt(10)
3740
- .endAt(20)
3741
- .on('child_added', snap => {
3742
- addedSecond.push(snap.key);
3743
- });
3744
- ref
3745
- .startAt(10)
3746
- .endAt(20)
3747
- .on('child_removed', snap => {
3748
- removedSecond.push(snap.key);
3749
- });
3750
-
3751
- ref.child('a').setWithPriority('a', 5);
3752
- expect(addedFirst).to.deep.equal(['a']);
3753
- ref.child('a').setWithPriority('a', 15);
3754
- expect(removedFirst).to.deep.equal(['a']);
3755
- expect(addedSecond).to.deep.equal(['a']);
3756
-
3757
- ref.child('a').setWithPriority('a', 10);
3758
- expect(addedFirst).to.deep.equal(['a', 'a']);
3759
- expect(removedSecond).to.deep.equal([]);
3760
-
3761
- ref.child('a').setWithPriority('a', 5);
3762
- expect(removedSecond).to.deep.equal(['a']);
3763
- });
3764
-
3765
- it('Case 2003: Correctly get events for startAtfter/endAt queries when priority changes.', () => {
3766
- const ref = getRandomNode() as Reference;
3767
- const addedFirst = [],
3768
- removedFirst = [],
3769
- addedSecond = [],
3770
- removedSecond = [];
3771
- ref
3772
- .startAfter(0)
3773
- .endAt(10)
3774
- .on('child_added', snap => {
3775
- addedFirst.push(snap.key);
3776
- });
3777
- ref
3778
- .startAfter(0)
3779
- .endAt(10)
3780
- .on('child_removed', snap => {
3781
- removedFirst.push(snap.key);
3782
- });
3783
- ref
3784
- .startAfter(10)
3785
- .endAt(20)
3786
- .on('child_added', snap => {
3787
- addedSecond.push(snap.key);
3788
- });
3789
- ref
3790
- .startAfter(10)
3791
- .endAt(20)
3792
- .on('child_removed', snap => {
3793
- removedSecond.push(snap.key);
3794
- });
3795
-
3796
- ref.child('a').setWithPriority('a', 5);
3797
- expect(addedFirst).to.deep.equal(['a']);
3798
- ref.child('a').setWithPriority('a', 15);
3799
- expect(removedFirst).to.deep.equal(['a']);
3800
- expect(addedSecond).to.deep.equal(['a']);
3801
-
3802
- ref.child('a').setWithPriority('a', 10);
3803
- ref.child('a').setWithPriority('a', 0);
3804
- expect(addedFirst).to.deep.equal(['a', 'a']);
3805
- expect(removedSecond).to.deep.equal(['a']);
3806
-
3807
- ref.child('a').setWithPriority('a', 5);
3808
- expect(removedSecond).to.deep.equal(['a']);
3809
- });
3810
-
3811
- it('Correctly get events for startAt/endBefore queries when priority changes.', () => {
3812
- const ref = getRandomNode() as Reference;
3813
- const addedFirst = [],
3814
- removedFirst = [],
3815
- addedSecond = [],
3816
- removedSecond = [];
3817
- ref
3818
- .startAt(0)
3819
- .endBefore(10)
3820
- .on('child_added', snap => {
3821
- addedFirst.push(snap.key);
3822
- });
3823
- ref
3824
- .startAt(0)
3825
- .endBefore(10)
3826
- .on('child_removed', snap => {
3827
- removedFirst.push(snap.key);
3828
- });
3829
- ref
3830
- .startAt(10)
3831
- .endBefore(20)
3832
- .on('child_added', snap => {
3833
- addedSecond.push(snap.key);
3834
- });
3835
- ref
3836
- .startAt(10)
3837
- .endBefore(20)
3838
- .on('child_removed', snap => {
3839
- removedSecond.push(snap.key);
3840
- });
3841
-
3842
- ref.child('a').setWithPriority('a', 5);
3843
- expect(addedFirst).to.deep.equal(['a']);
3844
- ref.child('a').setWithPriority('a', 15);
3845
- expect(removedFirst).to.deep.equal(['a']);
3846
- expect(addedSecond).to.deep.equal(['a']);
3847
-
3848
- ref.child('a').setWithPriority('a', 10);
3849
- ref.child('a').setWithPriority('a', 0);
3850
- expect(addedFirst).to.deep.equal(['a', 'a']);
3851
- expect(removedSecond).to.deep.equal(['a']);
3852
-
3853
- ref.child('a').setWithPriority('a', 5);
3854
- expect(removedSecond).to.deep.equal(['a']);
3855
- });
3856
-
3857
- it('Behaves with diverging queries', async () => {
3858
- const refs = getRandomNode(2);
3859
- const writer = refs[0];
3860
- const reader = refs[1];
3861
-
3862
- await writer.set({
3863
- a: { b: 1, c: 2 },
3864
- e: 3
3865
- });
3866
-
3867
- let childCount = 0;
3868
-
3869
- reader.child('a/b').on('value', snap => {
3870
- const val = snap.val();
3871
- childCount++;
3872
- if (childCount === 1) {
3873
- expect(val).to.equal(1);
3874
- } else {
3875
- // fail this, nothing should have changed
3876
- expect(true).to.be.false;
3877
- }
3878
- });
3879
-
3880
- const ea = EventAccumulatorFactory.waitsForCount(1);
3881
- let count = 0;
3882
- reader.limitToLast(2).on('value', snap => {
3883
- ea.addEvent();
3884
- const val = snap.val();
3885
- count++;
3886
- if (count === 1) {
3887
- expect(val).to.deep.equal({ a: { b: 1, c: 2 }, e: 3 });
3888
- } else if (count === 2) {
3889
- expect(val).to.deep.equal({ d: 4, e: 3 });
3890
- }
3891
- });
3892
-
3893
- await ea.promise;
3894
-
3895
- ea.reset();
3896
- writer.child('d').set(4);
3897
-
3898
- return ea.promise;
3899
- });
3900
-
3901
- it('Priority-only updates are processed correctly by server.', async () => {
3902
- const refPair = getRandomNode(2) as Reference[],
3903
- readRef = refPair[0],
3904
- writeRef = refPair[1];
3905
-
3906
- const ea = EventAccumulatorFactory.waitsForCount(1);
3907
- let readVal;
3908
- readRef.limitToLast(2).on('value', s => {
3909
- readVal = s.val();
3910
- if (readVal) {
3911
- ea.addEvent();
3912
- }
3913
- });
3914
- writeRef.set({
3915
- a: { '.priority': 10, '.value': 1 },
3916
- b: { '.priority': 20, '.value': 2 },
3917
- c: { '.priority': 30, '.value': 3 }
3918
- });
3919
-
3920
- await ea.promise;
3921
- expect(readVal).to.deep.equal({ b: 2, c: 3 });
3922
-
3923
- ea.reset();
3924
- writeRef.child('a').setPriority(25);
3925
-
3926
- await ea.promise;
3927
- expect(readVal).to.deep.equal({ a: 1, c: 3 });
3928
- });
3929
-
3930
- it('Server: Test re-listen', done => {
3931
- const refPair = getRandomNode(2) as Reference[],
3932
- ref = refPair[0],
3933
- ref2 = refPair[1];
3934
- ref.set({
3935
- a: 'a',
3936
- b: 'b',
3937
- c: 'c',
3938
- d: 'd',
3939
- e: 'e',
3940
- f: 'f',
3941
- g: 'g'
3942
- });
3943
-
3944
- let before;
3945
- ref
3946
- .startAt(null, 'a')
3947
- .endAt(null, 'b')
3948
- .on('value', b => {
3949
- before = b.val();
3950
- });
3951
-
3952
- ref.child('aa').set('aa', () => {
3953
- ref2
3954
- .startAt(null, 'a')
3955
- .endAt(null, 'b')
3956
- .on('value', b => {
3957
- expect(b.val()).to.deep.equal(before);
3958
- done();
3959
- });
3960
- });
3961
- });
3962
-
3963
- it('Server: Test re-listen 2', done => {
3964
- const refPair = getRandomNode(2),
3965
- ref = refPair[0],
3966
- ref2 = refPair[1];
3967
- ref.set({
3968
- a: 'a',
3969
- b: 'b',
3970
- c: 'c',
3971
- d: 'd',
3972
- e: 'e',
3973
- f: 'f',
3974
- g: 'g'
3975
- });
3976
-
3977
- let before;
3978
- ref
3979
- .startAt(null, 'b')
3980
- .limitToFirst(3)
3981
- .on('value', b => {
3982
- before = b.val();
3983
- });
3984
-
3985
- ref.child('aa').update({ a: 5, aa: 4, b: 7, c: 4, d: 4, dd: 3 }, () => {
3986
- ref2
3987
- .startAt(null, 'b')
3988
- .limitToFirst(3)
3989
- .on('value', b => {
3990
- expect(b.val()).to.deep.equal(before);
3991
- done();
3992
- });
3993
- });
3994
- });
3995
-
3996
- it('Server: Test re-listen 3', done => {
3997
- const refPair = getRandomNode(2),
3998
- ref = refPair[0],
3999
- ref2 = refPair[1];
4000
- ref.set({
4001
- a: 'a',
4002
- b: 'b',
4003
- c: 'c',
4004
- d: 'd',
4005
- e: 'e',
4006
- f: 'f',
4007
- g: 'g'
4008
- });
4009
-
4010
- let before;
4011
- ref.limitToLast(3).on('value', b => {
4012
- before = b.val();
4013
- });
4014
-
4015
- ref.child('h').set('h', () => {
4016
- ref2.limitToLast(3).on('value', b => {
4017
- expect(b.val()).to.deep.equal(before);
4018
- done();
4019
- });
4020
- });
4021
- });
4022
-
4023
- it('Server limit below limit works properly.', async () => {
4024
- const refPair = getRandomNode(2) as Reference[],
4025
- readRef = refPair[0],
4026
- writeRef = refPair[1];
4027
- let childData;
4028
-
4029
- await writeRef.set({
4030
- a: {
4031
- aa: { '.priority': 1, '.value': 1 },
4032
- ab: { '.priority': 1, '.value': 1 }
4033
- }
4034
- });
4035
-
4036
- readRef.limitToLast(1).on('value', s => {
4037
- expect(s.val()).to.deep.equal({ a: { aa: 1, ab: 1 } });
4038
- });
4039
-
4040
- const ea = EventAccumulatorFactory.waitsForCount(1);
4041
- readRef
4042
- .child('a')
4043
- .startAt(1)
4044
- .endAt(1)
4045
- .on('value', s => {
4046
- childData = s.val();
4047
- if (childData) {
4048
- ea.addEvent();
4049
- }
4050
- });
4051
-
4052
- await ea.promise;
4053
- expect(childData).to.deep.equal({ aa: 1, ab: 1 });
4054
-
4055
- // This should remove an item from the child query, but *not* the parent query.
4056
- ea.reset();
4057
- writeRef.child('a/ab').setWithPriority(1, 2);
4058
-
4059
- await ea.promise;
4060
-
4061
- expect(childData).to.deep.equal({ aa: 1 });
4062
- });
4063
-
4064
- it('Server: Setting grandchild of item in limit works.', async () => {
4065
- const refPair = getRandomNode(2),
4066
- ref = refPair[0],
4067
- ref2 = refPair[1];
4068
-
4069
- ref.set({
4070
- a: {
4071
- name: 'Mike'
4072
- }
4073
- });
4074
-
4075
- const ea = EventAccumulatorFactory.waitsForCount(1);
4076
- const snaps = [];
4077
- ref2.limitToLast(1).on('value', s => {
4078
- const val = s.val();
4079
- if (val !== null) {
4080
- snaps.push(val);
4081
- ea.addEvent();
4082
- }
4083
- });
4084
-
4085
- await ea.promise;
4086
- expect(snaps).to.deep.equal([{ a: { name: 'Mike' } }]);
4087
-
4088
- ea.reset();
4089
- ref.child('a/name').set('Fred');
4090
-
4091
- await ea.promise;
4092
- expect(snaps).to.deep.equal([
4093
- { a: { name: 'Mike' } },
4094
- { a: { name: 'Fred' } }
4095
- ]);
4096
- });
4097
-
4098
- it('Server: Updating grandchildren of item in limit works.', async () => {
4099
- const refPair = getRandomNode(2),
4100
- ref = refPair[0],
4101
- ref2 = refPair[1];
4102
-
4103
- ref.set({
4104
- a: {
4105
- name: 'Mike'
4106
- }
4107
- });
4108
-
4109
- const ea = EventAccumulatorFactory.waitsForCount(1);
4110
- const snaps = [];
4111
- ref2.limitToLast(1).on('value', s => {
4112
- const val = s.val();
4113
- if (val !== null) {
4114
- snaps.push(val);
4115
- ea.addEvent();
4116
- }
4117
- });
4118
-
4119
- /**
4120
- * If I put this artificial pause here, this test works however
4121
- * something about the timing is broken
4122
- */
4123
- await ea.promise;
4124
- expect(snaps).to.deep.equal([{ a: { name: 'Mike' } }]);
4125
-
4126
- ea.reset();
4127
- ref.child('a').update({ name: null, Name: 'Fred' });
4128
- await ea.promise;
4129
-
4130
- expect(snaps).to.deep.equal([
4131
- { a: { name: 'Mike' } },
4132
- { a: { Name: 'Fred' } }
4133
- ]);
4134
- });
4135
-
4136
- it('Server: New child at end of limit shows up.', async () => {
4137
- const refPair = getRandomNode(2),
4138
- ref = refPair[0],
4139
- ref2 = refPair[1];
4140
-
4141
- const ea = EventAccumulatorFactory.waitsForCount(1);
4142
- let snap;
4143
- ref2.limitToLast(1).on('value', s => {
4144
- snap = s.val();
4145
- ea.addEvent();
4146
- });
4147
-
4148
- await ea.promise;
4149
- expect(snap).to.be.null;
4150
- ea.reset();
4151
-
4152
- ref.child('a').set('new child');
4153
-
4154
- /**
4155
- * If I put this artificial pause here, this test works however
4156
- * something about the timing is broken
4157
- */
4158
- await ea.promise;
4159
- expect(snap).to.deep.equal({ a: 'new child' });
4160
- });
4161
-
4162
- it('Server: Priority-only updates are processed correctly by server (1).', async () => {
4163
- const refPair = getRandomNode(2),
4164
- readRef = refPair[0],
4165
- writeRef = refPair[1];
4166
-
4167
- const ea = EventAccumulatorFactory.waitsForCount(1);
4168
- let readVal;
4169
- readRef.limitToLast(2).on('value', s => {
4170
- readVal = s.val();
4171
- if (readVal) {
4172
- ea.addEvent();
4173
- }
4174
- });
4175
- writeRef.set({
4176
- a: { '.priority': 10, '.value': 1 },
4177
- b: { '.priority': 20, '.value': 2 },
4178
- c: { '.priority': 30, '.value': 3 }
4179
- });
4180
-
4181
- await ea.promise;
4182
- expect(readVal).to.deep.equal({ b: 2, c: 3 });
4183
-
4184
- ea.reset();
4185
- writeRef.child('a').setPriority(25);
4186
-
4187
- await ea.promise;
4188
- expect(readVal).to.deep.equal({ a: 1, c: 3 });
4189
- });
4190
-
4191
- // Same as above but with an endAt() so we hit CompoundQueryView instead of SimpleLimitView.
4192
- it('Server: Priority-only updates are processed correctly by server (2).', async () => {
4193
- const refPair = getRandomNode(2),
4194
- readRef = refPair[0],
4195
- writeRef = refPair[1];
4196
-
4197
- const ea = EventAccumulatorFactory.waitsForCount(1);
4198
- let readVal;
4199
- readRef
4200
- .endAt(50)
4201
- .limitToLast(2)
4202
- .on('value', s => {
4203
- readVal = s.val();
4204
- if (readVal) {
4205
- ea.addEvent();
4206
- }
4207
- });
4208
-
4209
- writeRef.set({
4210
- a: { '.priority': 10, '.value': 1 },
4211
- b: { '.priority': 20, '.value': 2 },
4212
- c: { '.priority': 30, '.value': 3 }
4213
- });
4214
-
4215
- await ea.promise;
4216
- expect(readVal).to.deep.equal({ b: 2, c: 3 });
4217
-
4218
- ea.reset();
4219
- writeRef.child('a').setPriority(25);
4220
-
4221
- await ea.promise;
4222
- expect(readVal).to.deep.equal({ a: 1, c: 3 });
4223
- });
4224
-
4225
- it('Latency compensation works with limit and pushed object.', () => {
4226
- const ref = getRandomNode() as Reference;
4227
- const events = [];
4228
- ref.limitToLast(3).on('child_added', s => {
4229
- events.push(s.val());
4230
- });
4231
-
4232
- // If you change this to ref.push('foo') it works.
4233
- ref.push({ a: 'foo' });
4234
-
4235
- // Should have synchronously gotten an event.
4236
- expect(events.length).to.equal(1);
4237
- });
4238
-
4239
- it("Cache doesn't remove items that have fallen out of view.", async () => {
4240
- const refPair = getRandomNode(2),
4241
- readRef = refPair[0],
4242
- writeRef = refPair[1];
4243
-
4244
- let ea = EventAccumulatorFactory.waitsForCount(1);
4245
- let readVal;
4246
- readRef.limitToLast(2).on('value', s => {
4247
- readVal = s.val();
4248
- ea.addEvent();
4249
- });
4250
-
4251
- await ea.promise;
4252
- expect(readVal).to.be.null;
4253
-
4254
- ea = EventAccumulatorFactory.waitsForCount(4);
4255
- for (let i = 0; i < 4; i++) {
4256
- writeRef.child('k' + i).set(i);
4257
- }
4258
-
4259
- await ea.promise;
4260
-
4261
- await pause(500);
4262
- expect(readVal).to.deep.equal({ k2: 2, k3: 3 });
4263
-
4264
- ea = EventAccumulatorFactory.waitsForCount(1);
4265
- writeRef.remove();
4266
-
4267
- await ea.promise;
4268
- expect(readVal).to.be.null;
4269
- });
4270
-
4271
- it('handles an update that moves another child that has a deeper listener out of view', async () => {
4272
- const refs = getRandomNode(2);
4273
- const reader = refs[0];
4274
- const writer = refs[1];
4275
-
4276
- await writer.set({
4277
- a: { '.priority': 10, '.value': 1 },
4278
- b: { '.priority': 20, d: 4 },
4279
- c: { '.priority': 30, '.value': 3 }
4280
- });
4281
-
4282
- reader.child('b/d').on('value', snap => {
4283
- expect(snap.val()).to.equal(4);
4284
- });
4285
-
4286
- const ea = EventAccumulatorFactory.waitsForCount(1);
4287
- let val;
4288
- reader.limitToLast(2).on('value', snap => {
4289
- val = snap.val();
4290
- if (val) {
4291
- ea.addEvent();
4292
- }
4293
- });
4294
-
4295
- await ea.promise;
4296
- expect(val).to.deep.equal({ b: { d: 4 }, c: 3 });
4297
-
4298
- ea.reset();
4299
- writer.child('a').setWithPriority(1, 40);
4300
-
4301
- await ea.promise;
4302
- expect(val).to.deep.equal({ c: 3, a: 1 });
4303
- });
4304
-
4305
- it('Integer keys behave numerically 1.', done => {
4306
- const ref = getRandomNode() as Reference;
4307
- ref.set(
4308
- {
4309
- 1: true,
4310
- 50: true,
4311
- 550: true,
4312
- 6: true,
4313
- 600: true,
4314
- 70: true,
4315
- 8: true,
4316
- 80: true
4317
- },
4318
- () => {
4319
- ref.startAt(null, '80').once('value', s => {
4320
- expect(s.val()).to.deep.equal({ 80: true, 550: true, 600: true });
4321
- done();
4322
- });
4323
- }
4324
- );
4325
- });
4326
-
4327
- it('Integer keys behave numerically 2.', done => {
4328
- const ref = getRandomNode() as Reference;
4329
- ref.set(
4330
- {
4331
- 1: true,
4332
- 50: true,
4333
- 550: true,
4334
- 6: true,
4335
- 600: true,
4336
- 70: true,
4337
- 8: true,
4338
- 80: true
4339
- },
4340
- () => {
4341
- ref.endAt(null, '50').once('value', s => {
4342
- expect(s.val()).to.deep.equal({
4343
- 1: true,
4344
- 6: true,
4345
- 8: true,
4346
- 50: true
4347
- });
4348
- done();
4349
- });
4350
- }
4351
- );
4352
- });
4353
-
4354
- it('Integer keys behave numerically 3.', done => {
4355
- const ref = getRandomNode() as Reference;
4356
- ref.set(
4357
- {
4358
- 1: true,
4359
- 50: true,
4360
- 550: true,
4361
- 6: true,
4362
- 600: true,
4363
- 70: true,
4364
- 8: true,
4365
- 80: true
4366
- },
4367
- () => {
4368
- ref
4369
- .startAt(null, '50')
4370
- .endAt(null, '80')
4371
- .once('value', s => {
4372
- expect(s.val()).to.deep.equal({ 50: true, 70: true, 80: true });
4373
- done();
4374
- });
4375
- }
4376
- );
4377
- });
4378
-
4379
- it('Integer keys behave numerically with startAfter.', done => {
4380
- const ref = getRandomNode() as Reference;
4381
- ref.set(
4382
- {
4383
- 1: true,
4384
- 50: true,
4385
- 550: true,
4386
- 6: true,
4387
- 600: true,
4388
- 70: true,
4389
- 8: true,
4390
- 80: true
4391
- },
4392
- () => {
4393
- ref
4394
- .startAfter(null, '50')
4395
- .endAt(null, '80')
4396
- .once('value', s => {
4397
- expect(s.val()).to.deep.equal({ 70: true, 80: true });
4398
- done();
4399
- });
4400
- }
4401
- );
4402
- });
4403
-
4404
- it('Integer keys behave numerically with startAfter with overflow.', done => {
4405
- const ref = getRandomNode() as Reference;
4406
- ref.set(
4407
- {
4408
- 1: true,
4409
- 50: true,
4410
- 550: true,
4411
- 6: true,
4412
- 600: true,
4413
- 70: true,
4414
- 8: true,
4415
- 80: true,
4416
- 'a': true
4417
- },
4418
- () => {
4419
- ref.startAfter(null, '' + INTEGER_32_MAX).once('value', s => {
4420
- expect(s.val()).to.deep.equal({ 'a': true });
4421
- done();
4422
- });
4423
- }
4424
- );
4425
- });
4426
-
4427
- it('Integer keys behave numerically with endBefore.', done => {
4428
- const ref = getRandomNode() as Reference;
4429
- ref.set(
4430
- {
4431
- 1: true,
4432
- 50: true,
4433
- 550: true,
4434
- 6: true,
4435
- 600: true,
4436
- 70: true,
4437
- 8: true,
4438
- 80: true
4439
- },
4440
- () => {
4441
- ref.endBefore(null, '50').once('value', s => {
4442
- expect(s.val()).to.deep.equal({
4443
- 1: true,
4444
- 6: true,
4445
- 8: true
4446
- });
4447
- done();
4448
- });
4449
- }
4450
- );
4451
- });
4452
-
4453
- it('Integer keys behave numerically with endBefore with underflow.', done => {
4454
- const ref = getRandomNode() as Reference;
4455
- ref.set(
4456
- {
4457
- 1: true
4458
- },
4459
- () => {
4460
- ref.endBefore(null, '' + INTEGER_32_MIN).once('value', s => {
4461
- expect(s.val()).to.deep.equal(null);
4462
- done();
4463
- });
4464
- }
4465
- );
4466
- });
4467
-
4468
- it('Integer keys behave numerically with endBefore at boundary.', done => {
4469
- const ref = getRandomNode() as Reference;
4470
- const integerData = {
4471
- 1: true,
4472
- 50: true,
4473
- 550: true,
4474
- 6: true,
4475
- 600: true,
4476
- 70: true,
4477
- 8: true,
4478
- 80: true
4479
- };
4480
- const data = Object.assign({}, integerData);
4481
- data['a'] = true;
4482
- ref.set(data, () => {
4483
- ref.endBefore(null, '' + INTEGER_32_MAX).once('value', s => {
4484
- expect(s.val()).to.deep.equal(integerData),
4485
- ref.startAfter(null, '' + INTEGER_32_MAX).once('value', s => {
4486
- expect(s.val()).to.deep.equal({ 'a': true });
4487
- done();
4488
- });
4489
- });
4490
- });
4491
- });
4492
-
4493
- it('.limitToLast() on node with priority.', done => {
4494
- const ref = getRandomNode() as Reference;
4495
- ref.set({ a: 'blah', '.priority': 'priority' }, () => {
4496
- ref.limitToLast(2).once('value', s => {
4497
- expect(s.exportVal()).to.deep.equal({ a: 'blah' });
4498
- done();
4499
- });
4500
- });
4501
- });
4502
-
4503
- it('.equalTo works', async () => {
4504
- const ref = getRandomNode() as Reference;
4505
- const done = false;
4506
-
4507
- await ref.set({
4508
- a: 1,
4509
- b: { '.priority': 2, '.value': 2 },
4510
- c: { '.priority': '3', '.value': 3 }
4511
- });
4512
-
4513
- const snap1 = await ref.equalTo(2).once('value');
4514
- const val1 = snap1.exportVal();
4515
- expect(val1).to.deep.equal({ b: { '.priority': 2, '.value': 2 } });
4516
-
4517
- const snap2 = await ref.equalTo('3', 'c').once('value');
4518
-
4519
- const val2 = snap2.exportVal();
4520
- expect(val2).to.deep.equal({ c: { '.priority': '3', '.value': 3 } });
4521
-
4522
- const snap3 = await ref.equalTo(null, 'c').once('value');
4523
- const val3 = snap3.exportVal();
4524
- expect(val3).to.be.null;
4525
- });
4526
-
4527
- it('Handles fallback for orderBy', async () => {
4528
- const ref = getRandomNode() as Reference;
4529
-
4530
- const children = [];
4531
-
4532
- ref.orderByChild('foo').on('child_added', snap => {
4533
- children.push(snap.key);
4534
- });
4535
-
4536
- // Set initial data
4537
- await ref.set({
4538
- a: { foo: 3 },
4539
- b: { foo: 1 },
4540
- c: { foo: 2 }
4541
- });
4542
-
4543
- expect(children).to.deep.equal(['b', 'c', 'a']);
4544
- });
4545
-
4546
- it('Get notified of deletes that happen while offline.', async () => {
4547
- const refPair = getRandomNode(2);
4548
- const queryRef = refPair[0];
4549
- const writerRef = refPair[1];
4550
- let readSnapshot = null;
4551
-
4552
- // Write 3 children and then start our limit query.
4553
- await writerRef.set({ a: 1, b: 2, c: 3 });
4554
-
4555
- const ea = EventAccumulatorFactory.waitsForCount(1);
4556
- queryRef.limitToLast(3).on('value', s => {
4557
- readSnapshot = s;
4558
- if (readSnapshot) {
4559
- ea.addEvent();
4560
- }
4561
- });
4562
-
4563
- // Wait for us to read the 3 children.
4564
- await ea.promise;
4565
-
4566
- expect(readSnapshot.val()).to.deep.equal({ a: 1, b: 2, c: 3 });
4567
-
4568
- queryRef.database.goOffline();
4569
-
4570
- // Delete an item in the query and then bring our connection back up.
4571
- ea.reset();
4572
- await writerRef.child('b').remove();
4573
- queryRef.database.goOnline();
4574
-
4575
- await ea.promise;
4576
- expect(readSnapshot.child('b').val()).to.be.null;
4577
- });
4578
-
4579
- it('Snapshot children respect default ordering', done => {
4580
- const refPair = getRandomNode(2);
4581
- const queryRef = refPair[0],
4582
- writerRef = refPair[1];
4583
-
4584
- const list = {
4585
- a: {
4586
- thisvaluefirst: { '.value': true, '.priority': 1 },
4587
- name: { '.value': 'Michael', '.priority': 2 },
4588
- thisvaluelast: { '.value': true, '.priority': 3 }
4589
- },
4590
- b: {
4591
- thisvaluefirst: { '.value': true, '.priority': null },
4592
- name: { '.value': 'Rob', '.priority': 2 },
4593
- thisvaluelast: { '.value': true, '.priority': 3 }
4594
- },
4595
- c: {
4596
- thisvaluefirst: { '.value': true, '.priority': 1 },
4597
- name: { '.value': 'Jonny', '.priority': 2 },
4598
- thisvaluelast: { '.value': true, '.priority': 'somestring' }
4599
- }
4600
- };
4601
-
4602
- writerRef.set(list, () => {
4603
- queryRef.orderByChild('name').once('value', snap => {
4604
- const expectedKeys = ['thisvaluefirst', 'name', 'thisvaluelast'];
4605
- const expectedNames = ['Jonny', 'Michael', 'Rob'];
4606
-
4607
- // Validate that snap.child() resets order to default for child snaps
4608
- const orderedKeys = [];
4609
- snap.child('b').forEach(childSnap => {
4610
- orderedKeys.push(childSnap.key);
4611
- });
4612
- expect(orderedKeys).to.deep.equal(expectedKeys);
4613
-
4614
- // Validate that snap.forEach() resets ordering to default for child snaps
4615
- const orderedNames = [];
4616
- snap.forEach(childSnap => {
4617
- orderedNames.push(childSnap.child('name').val());
4618
- const orderedKeys = [];
4619
- childSnap.forEach(grandchildSnap => {
4620
- orderedKeys.push(grandchildSnap.key);
4621
- });
4622
- expect(orderedKeys).to.deep.equal([
4623
- 'thisvaluefirst',
4624
- 'name',
4625
- 'thisvaluelast'
4626
- ]);
4627
- });
4628
- expect(orderedNames).to.deep.equal(expectedNames);
4629
- done();
4630
- });
4631
- });
4632
- });
4633
-
4634
- it('Adding listens for the same paths does not check fail', done => {
4635
- // This bug manifests itself if there's a hierarchy of query listener, default listener and one-time listener
4636
- // underneath. During one-time listener registration, sync-tree traversal stopped as soon as it found a complete
4637
- // server cache (this is the case for not indexed query view). The problem is that the same traversal was
4638
- // looking for a ancestor default view, and the early exit prevented from finding the default listener above the
4639
- // one-time listener. Event removal code path wasn't removing the listener because it stopped as soon as it
4640
- // found the default view. This left the zombie one-time listener and check failed on the second attempt to
4641
- // create a listener for the same path (asana#61028598952586).
4642
- const ref = getRandomNode(1)[0];
4643
-
4644
- ref.child('child').set({ name: 'John' }, () => {
4645
- ref
4646
- .orderByChild('name')
4647
- .equalTo('John')
4648
- .on('value', snap => {
4649
- ref.child('child').on('value', snap => {
4650
- ref
4651
- .child('child')
4652
- .child('favoriteToy')
4653
- .once('value', snap => {
4654
- ref
4655
- .child('child')
4656
- .child('favoriteToy')
4657
- .once('value', snap => {
4658
- done();
4659
- });
4660
- });
4661
- });
4662
- });
4663
- });
4664
- });
4665
-
4666
- it('Can JSON serialize refs', () => {
4667
- const ref = getRandomNode() as Reference;
4668
- expect(JSON.stringify(ref)).to.equal('"' + ref.toString() + '"');
4669
- });
4670
- });