@angular-wave/angular.ts 0.4.3 → 0.4.4

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 (128) hide show
  1. package/dist/angular-ts.umd.js +10 -0
  2. package/index.html +74 -3
  3. package/package.json +1 -1
  4. package/src/angular.spec.js +0 -5
  5. package/src/animations/animate-css.js +5 -13
  6. package/src/animations/animate-queue.js +22 -21
  7. package/src/animations/animate-runner.js +4 -8
  8. package/src/animations/animate.md +1 -1
  9. package/src/animations/animate.spec.js +0 -21
  10. package/src/animations/animation.js +1 -1
  11. package/src/binding.spec.js +0 -1
  12. package/src/core/cache/cache.js +2 -29
  13. package/src/core/compile/compile.js +26 -27
  14. package/src/core/compile/compile.spec.js +17 -266
  15. package/src/core/compile/compile.test.js +1 -1
  16. package/src/core/controller/controller.js +2 -0
  17. package/src/core/di/injector.md +1 -1
  18. package/src/core/di/injector.spec.js +0 -2
  19. package/src/core/di/internal-injector.js +2 -1
  20. package/src/core/interpolate/interpolate.js +16 -3
  21. package/src/core/interpolate/interpolate.spec.js +70 -16
  22. package/src/core/interval/interval.test.js +1 -1
  23. package/src/core/location/location.js +0 -2
  24. package/src/core/location/location.spec.js +27 -27
  25. package/src/core/{scope/scope.html → model/model.html} +1 -1
  26. package/src/core/model/model.js +944 -0
  27. package/src/core/model/model.spec.js +3012 -0
  28. package/src/core/on.spec.js +0 -7
  29. package/src/core/parse/interpreter.js +10 -7
  30. package/src/core/parse/parse.js +26 -5
  31. package/src/core/parse/parse.spec.js +95 -91
  32. package/src/core/prop.spec.js +4 -60
  33. package/src/core/sce/sce.spec.js +0 -8
  34. package/src/core/scope/scope.js +61 -30
  35. package/src/core/scope/scope.spec.js +25 -1960
  36. package/src/directive/aria/aria.js +3 -6
  37. package/src/directive/aria/aria.spec.js +0 -87
  38. package/src/directive/attrs/attrs.spec.js +0 -5
  39. package/src/directive/attrs/boolean.spec.js +0 -15
  40. package/src/directive/attrs/element-style.spec.js +0 -8
  41. package/src/directive/attrs/src.spec.js +0 -7
  42. package/src/directive/bind/bind.spec.js +0 -33
  43. package/src/directive/bind/bing-html.spec.js +0 -3
  44. package/src/{core/q/q.html → directive/channel/channel.html} +1 -1
  45. package/src/directive/channel/channel.js +29 -0
  46. package/src/directive/channel/channel.spec.js +52 -0
  47. package/src/directive/{list/list.test.js → channel/channel.test.js} +2 -4
  48. package/src/directive/class/class.js +3 -3
  49. package/src/directive/class/class.spec.js +9 -75
  50. package/src/directive/controller/controller.spec.js +0 -13
  51. package/src/directive/events/click.spec.js +0 -3
  52. package/src/directive/events/event.spec.js +0 -6
  53. package/src/directive/form/form.js +2 -3
  54. package/src/directive/form/form.spec.js +0 -65
  55. package/src/directive/if/if.spec.js +0 -4
  56. package/src/directive/include/include.spec.js +8 -59
  57. package/src/directive/init/init.js +6 -2
  58. package/src/directive/init/init.spec.js +0 -2
  59. package/src/directive/input/input.spec.js +0 -136
  60. package/src/directive/messages/messages.spec.js +4 -35
  61. package/src/directive/model/model.js +18 -25
  62. package/src/directive/model/model.spec.js +2 -49
  63. package/src/directive/model-options/model-options.spec.js +0 -6
  64. package/src/directive/non-bindable/non-bindable.spec.js +0 -1
  65. package/src/directive/observe/observe.js +0 -1
  66. package/src/directive/observe/observe.spec.js +0 -1
  67. package/src/directive/options/options.spec.js +0 -34
  68. package/src/directive/ref/href.spec.js +0 -15
  69. package/src/directive/repeat/repeat.spec.js +8 -135
  70. package/src/directive/script/script.spec.js +0 -2
  71. package/src/directive/select/select.js +3 -3
  72. package/src/directive/select/select.spec.js +0 -96
  73. package/src/directive/show-hide/show-hide.js +2 -2
  74. package/src/directive/show-hide/show-hide.spec.js +8 -19
  75. package/src/directive/style/style.spec.js +0 -7
  76. package/src/directive/switch/switch.spec.js +5 -5
  77. package/src/directive/validators/validators.spec.js +0 -1
  78. package/src/loader.js +0 -1
  79. package/src/public.js +75 -80
  80. package/src/router/common/coreservices.js +0 -2
  81. package/src/router/directives/state-directives.js +6 -14
  82. package/src/router/directives/state-directives.spec.js +0 -83
  83. package/src/router/directives/view-directive.js +4 -13
  84. package/src/router/directives/view-directive.spec.js +25 -71
  85. package/src/router/hooks/lazy-load.js +2 -2
  86. package/src/router/hooks/views.js +3 -5
  87. package/src/router/resolve/resolvable.js +3 -6
  88. package/src/router/resolve/resolve-context.js +2 -2
  89. package/src/router/state/state-service.js +4 -4
  90. package/src/router/state/state.spec.js +2 -5
  91. package/src/router/state/views.js +7 -10
  92. package/src/router/template-factory.js +3 -6
  93. package/src/router/template-factory.spec.js +0 -4
  94. package/src/router/transition/transition-hook.js +1 -1
  95. package/src/router/transition/transition.js +1 -1
  96. package/src/router/view-hook.spec.js +2 -2
  97. package/src/router/view-scroll.js +4 -6
  98. package/src/services/http/http.js +6 -9
  99. package/src/services/http/http.spec.js +30 -31
  100. package/src/services/http/template-request.spec.js +0 -10
  101. package/src/services/http-backend/http-backend.spec.js +3 -3
  102. package/src/services/template-request.js +2 -4
  103. package/src/shared/common.js +1 -2
  104. package/src/shared/jqlite/jqlite.js +0 -3
  105. package/types/core/cache/cache.d.ts +1 -1
  106. package/types/core/model/model.d.ts +204 -0
  107. package/types/core/parse/parse.d.ts +26 -0
  108. package/types/core/scope/scope.d.ts +22 -21
  109. package/types/directive/channel/channel.d.ts +11 -0
  110. package/src/core/interval/interval-factory.js +0 -50
  111. package/src/core/interval/interval.html +0 -18
  112. package/src/core/interval/interval.js +0 -77
  113. package/src/core/interval/interval.md +0 -123
  114. package/src/core/interval/interval.spec.js +0 -280
  115. package/src/core/q/q.js +0 -472
  116. package/src/core/q/q.md +0 -211
  117. package/src/core/q/q.spec.js +0 -2748
  118. package/src/core/q/q.test.js +0 -12
  119. package/src/core/scope/scope.test.js +0 -12
  120. package/src/core/timeout/timeout.html +0 -18
  121. package/src/core/timeout/timeout.js +0 -109
  122. package/src/core/timeout/timeout.spec.js +0 -354
  123. package/src/core/timeout/timout.test.js +0 -12
  124. package/src/directive/list/list.html +0 -18
  125. package/src/directive/list/list.js +0 -46
  126. package/src/directive/list/list.md +0 -22
  127. package/src/directive/list/list.spec.js +0 -172
  128. package/types/directive/list/list.d.ts +0 -4
@@ -1,4 +1,4 @@
1
- import { $$asyncQueue, Scope } from "./scope";
1
+ import { $$asyncQueue, Scope, ScopePhase } from "./scope";
2
2
  import { extend, sliceArgs } from "../../shared/utils";
3
3
  import { Angular } from "../../loader";
4
4
  import { createInjector } from "../di/injector";
@@ -9,6 +9,7 @@ describe("Scope", function () {
9
9
  let $browser;
10
10
  let logs;
11
11
  let scope;
12
+ let injector;
12
13
 
13
14
  beforeEach(() => {
14
15
  logs = [];
@@ -23,7 +24,7 @@ describe("Scope", function () {
23
24
  };
24
25
  });
25
26
 
26
- let injector = createInjector(["myModule"]);
27
+ injector = createInjector(["myModule"]);
27
28
  $parse = injector.get("$parse");
28
29
  $browser = injector.get("$browser");
29
30
 
@@ -135,7 +136,7 @@ describe("Scope", function () {
135
136
 
136
137
  it("should attach the child scope to a specified parent", () => {
137
138
  const isolated = $rootScope.$new(true);
138
- const trans = $rootScope.$new(false, isolated);
139
+ const trans = $rootScope.$transcluded(isolated);
139
140
  $rootScope.a = 123;
140
141
  expect(isolated.a).toBeUndefined();
141
142
  expect(trans.a).toEqual(123);
@@ -196,822 +197,6 @@ describe("Scope", function () {
196
197
  });
197
198
 
198
199
  describe("$watch/$digest", () => {
199
- it("calls the listener function of a watch on first $digest", function () {
200
- var watchFn = function () {
201
- return "wat";
202
- };
203
- var listenerFn = jasmine.createSpy();
204
- $rootScope.$watch(watchFn, listenerFn);
205
- $rootScope.$digest();
206
- expect(listenerFn).toHaveBeenCalled();
207
- });
208
-
209
- it("calls the watch function with the scope as the argument", function () {
210
- var watchFn = jasmine.createSpy();
211
- var listenerFn = function () {};
212
- $rootScope.$watch(watchFn, listenerFn);
213
- $rootScope.$digest();
214
- expect(watchFn).toHaveBeenCalledWith($rootScope);
215
- });
216
-
217
- it("calls the listener function when the watched value changes", function () {
218
- scope.someValue = "a";
219
- scope.counter = 0;
220
- scope.$watch(
221
- function (scope) {
222
- return scope.someValue;
223
- },
224
- function (newValue, oldValue, scope) {
225
- scope.counter++;
226
- },
227
- );
228
- expect(scope.counter).toBe(0);
229
- scope.$digest();
230
- expect(scope.counter).toBe(1);
231
- scope.$digest();
232
- expect(scope.counter).toBe(1);
233
- scope.someValue = "b";
234
- expect(scope.counter).toBe(1);
235
- scope.$digest();
236
- expect(scope.counter).toBe(2);
237
- });
238
-
239
- it("should watch and fire on simple property change", () => {
240
- const spy = jasmine.createSpy();
241
- $rootScope.$watch("name", spy);
242
- $rootScope.$digest();
243
- spy.calls.reset();
244
-
245
- expect(spy).not.toHaveBeenCalled();
246
- $rootScope.$digest();
247
- expect(spy).not.toHaveBeenCalled();
248
- $rootScope.name = "misko";
249
- $rootScope.$digest();
250
- expect(spy).toHaveBeenCalledWith("misko", undefined, $rootScope);
251
- });
252
-
253
- it("should not expose the `inner working of watch", () => {
254
- function Getter() {
255
- expect(this).toBeUndefined();
256
- return "foo";
257
- }
258
- function Listener() {
259
- expect(this).toBeUndefined();
260
- }
261
-
262
- $rootScope.$watch(Getter, Listener);
263
- $rootScope.$digest();
264
- });
265
-
266
- it("should watch and fire on expression change", () => {
267
- const spy = jasmine.createSpy();
268
- $rootScope.$watch("name.first", spy);
269
- $rootScope.$digest();
270
- spy.calls.reset();
271
-
272
- $rootScope.name = {};
273
- expect(spy).not.toHaveBeenCalled();
274
- $rootScope.$digest();
275
- expect(spy).not.toHaveBeenCalled();
276
- $rootScope.name.first = "misko";
277
- $rootScope.$digest();
278
- expect(spy).toHaveBeenCalled();
279
- });
280
-
281
- it("should decrement the watcherCount when destroying a child scope", () => {
282
- const child1 = $rootScope.$new();
283
- const child2 = $rootScope.$new();
284
- const grandChild1 = child1.$new();
285
- const grandChild2 = child2.$new();
286
- child1.$watch("a", () => {});
287
- child2.$watch("a", () => {});
288
- grandChild1.$watch("a", () => {});
289
- grandChild2.$watch("a", () => {});
290
-
291
- expect($rootScope.$$watchersCount).toBe(4);
292
- expect(child1.$$watchersCount).toBe(2);
293
- expect(child2.$$watchersCount).toBe(2);
294
- expect(grandChild1.$$watchersCount).toBe(1);
295
- expect(grandChild2.$$watchersCount).toBe(1);
296
-
297
- grandChild2.$destroy();
298
- expect(child2.$$watchersCount).toBe(1);
299
- expect($rootScope.$$watchersCount).toBe(3);
300
- child1.$destroy();
301
- expect($rootScope.$$watchersCount).toBe(1);
302
- });
303
-
304
- it("should decrement the watcherCount when calling the remove function", () => {
305
- const child1 = $rootScope.$new();
306
- const child2 = $rootScope.$new();
307
- const grandChild1 = child1.$new();
308
- const grandChild2 = child2.$new();
309
- let remove1;
310
- let remove2;
311
-
312
- remove1 = child1.$watch("a", () => {});
313
- child2.$watch("a", () => {});
314
- grandChild1.$watch("a", () => {});
315
- remove2 = grandChild2.$watch("a", () => {});
316
-
317
- remove2();
318
- expect(grandChild2.$$watchersCount).toBe(0);
319
- expect(child2.$$watchersCount).toBe(1);
320
- expect($rootScope.$$watchersCount).toBe(3);
321
- remove1();
322
- expect(grandChild1.$$watchersCount).toBe(1);
323
- expect(child1.$$watchersCount).toBe(1);
324
- expect($rootScope.$$watchersCount).toBe(2);
325
-
326
- // Execute everything a second time to be sure that calling the remove function
327
- // several times, it only decrements the counter once
328
- remove2();
329
- expect(child2.$$watchersCount).toBe(1);
330
- expect($rootScope.$$watchersCount).toBe(2);
331
- remove1();
332
- expect(child1.$$watchersCount).toBe(1);
333
- expect($rootScope.$$watchersCount).toBe(2);
334
- });
335
-
336
- describe("constants cleanup", () => {
337
- beforeEach(() => (logs = []));
338
- it("should remove $watch of constant literals after initial digest", () => {
339
- $rootScope.$watch("[]", () => {});
340
- $rootScope.$watch("{}", () => {});
341
- $rootScope.$watch("1", () => {});
342
- $rootScope.$watch('"foo"', () => {});
343
- expect($rootScope.$$watchers.length).not.toEqual(0);
344
- $rootScope.$digest();
345
-
346
- expect($rootScope.$$watchers.length).toEqual(0);
347
- });
348
-
349
- it("should remove $watchCollection of constant literals after initial digest", () => {
350
- $rootScope.$watchCollection("[]", () => {});
351
- $rootScope.$watchCollection("{}", () => {});
352
- $rootScope.$watchCollection("1", () => {});
353
- $rootScope.$watchCollection('"foo"', () => {});
354
- expect($rootScope.$$watchers.length).not.toEqual(0);
355
- $rootScope.$digest();
356
-
357
- expect($rootScope.$$watchers.length).toEqual(0);
358
- });
359
-
360
- it("should remove $watchGroup of constant literals after initial digest", () => {
361
- $rootScope.$watchGroup(["[]", "{}", "1", '"foo"'], () => {});
362
- expect($rootScope.$$watchers.length).not.toEqual(0);
363
- $rootScope.$digest();
364
-
365
- expect($rootScope.$$watchers.length).toEqual(0);
366
- });
367
-
368
- it("should remove $watch of filtered constant literals after initial digest", () => {
369
- $rootScope.$watch('[1] | filter:"x"', () => {});
370
- $rootScope.$watch("1 | limitTo:2", () => {});
371
- expect($rootScope.$$watchers.length).not.toEqual(0);
372
- $rootScope.$digest();
373
-
374
- expect($rootScope.$$watchers.length).toEqual(0);
375
- });
376
-
377
- it("should remove $watchCollection of filtered constant literals after initial digest", () => {
378
- $rootScope.$watchCollection('[1] | filter:"x"', () => {});
379
- expect($rootScope.$$watchers.length).not.toEqual(0);
380
- $rootScope.$digest();
381
-
382
- expect($rootScope.$$watchers.length).toEqual(0);
383
- });
384
-
385
- it("should remove $watchGroup of filtered constant literals after initial digest", () => {
386
- $rootScope.$watchGroup(['[1] | filter:"x"', "1 | limitTo:2"], () => {});
387
- expect($rootScope.$$watchers.length).not.toEqual(0);
388
- $rootScope.$digest();
389
-
390
- expect($rootScope.$$watchers.length).toEqual(0);
391
- });
392
-
393
- it("should remove $watch of constant expressions after initial digest", () => {
394
- $rootScope.$watch("1 + 1", () => {});
395
- $rootScope.$watch('"a" + "b"', () => {});
396
- $rootScope.$watch('"ab".length', () => {});
397
- $rootScope.$watch("[].length", () => {});
398
- $rootScope.$watch("(1 + 1) | limitTo:2", () => {});
399
- expect($rootScope.$$watchers.length).not.toEqual(0);
400
- $rootScope.$digest();
401
-
402
- expect($rootScope.$$watchers.length).toEqual(0);
403
- });
404
- });
405
-
406
- describe("onetime cleanup", () => {
407
- it("should clean up stable watches on the watch queue", () => {
408
- $rootScope.$watch("::foo", () => {});
409
- expect($rootScope.$$watchers.length).toEqual(1);
410
- $rootScope.$digest();
411
- expect($rootScope.$$watchers.length).toEqual(1);
412
-
413
- $rootScope.foo = "foo";
414
- $rootScope.$digest();
415
- expect($rootScope.$$watchers.length).toEqual(0);
416
- });
417
-
418
- it("should clean up stable watches from $watchCollection", () => {
419
- $rootScope.$watchCollection("::foo", () => {});
420
- expect($rootScope.$$watchers.length).toEqual(1);
421
-
422
- $rootScope.$digest();
423
- expect($rootScope.$$watchers.length).toEqual(1);
424
-
425
- $rootScope.foo = [];
426
- $rootScope.$digest();
427
- expect($rootScope.$$watchers.length).toEqual(0);
428
- });
429
-
430
- it("should clean up stable watches from $watchCollection literals", () => {
431
- $rootScope.$watchCollection("::[foo, bar]", () => {});
432
- expect($rootScope.$$watchers.length).toEqual(1);
433
-
434
- $rootScope.$digest();
435
- expect($rootScope.$$watchers.length).toEqual(1);
436
-
437
- $rootScope.foo = 1;
438
- $rootScope.$digest();
439
- expect($rootScope.$$watchers.length).toEqual(1);
440
-
441
- $rootScope.foo = 2;
442
- $rootScope.$digest();
443
- expect($rootScope.$$watchers.length).toEqual(1);
444
-
445
- $rootScope.bar = 3;
446
- $rootScope.$digest();
447
- expect($rootScope.$$watchers.length).toEqual(0);
448
- });
449
-
450
- it("should clean up stable watches from $watchGroup", () => {
451
- $rootScope.$watchGroup(["::foo", "::bar"], () => {});
452
- expect($rootScope.$$watchers.length).toEqual(2);
453
-
454
- $rootScope.$digest();
455
- expect($rootScope.$$watchers.length).toEqual(2);
456
-
457
- $rootScope.foo = "foo";
458
- $rootScope.$digest();
459
- expect($rootScope.$$watchers.length).toEqual(1);
460
-
461
- $rootScope.bar = "bar";
462
- $rootScope.$digest();
463
- expect($rootScope.$$watchers.length).toEqual(0);
464
- });
465
- });
466
-
467
- it("should delegate exceptions", () => {
468
- $rootScope.$watch("a", () => {
469
- throw new Error("abc");
470
- });
471
- $rootScope.a = 1;
472
- $rootScope.$digest();
473
- expect(logs[0]).toMatch(/abc/);
474
- });
475
-
476
- it("should fire watches in order of addition", () => {
477
- // this is not an external guarantee, just our own sanity
478
- logs = "";
479
- $rootScope.$watch("a", () => {
480
- logs += "a";
481
- });
482
- $rootScope.$watch("b", () => {
483
- logs += "b";
484
- });
485
- // constant expressions have slightly different handling,
486
- // let's ensure they are kept in the same list as others
487
- $rootScope.$watch("1", () => {
488
- logs += "1";
489
- });
490
- $rootScope.$watch("c", () => {
491
- logs += "c";
492
- });
493
- $rootScope.$watch("2", () => {
494
- logs += "2";
495
- });
496
- $rootScope.a = $rootScope.b = $rootScope.c = 1;
497
- $rootScope.$digest();
498
- expect(logs).toEqual("ab1c2");
499
- });
500
-
501
- it("should call child $watchers in addition order", () => {
502
- // this is not an external guarantee, just our own sanity
503
- logs = "";
504
- const childA = $rootScope.$new();
505
- const childB = $rootScope.$new();
506
- const childC = $rootScope.$new();
507
- childA.$watch("a", () => {
508
- logs += "a";
509
- });
510
- childB.$watch("b", () => {
511
- logs += "b";
512
- });
513
- childC.$watch("c", () => {
514
- logs += "c";
515
- });
516
- childA.a = childB.b = childC.c = 1;
517
- $rootScope.$digest();
518
- expect(logs).toEqual("abc");
519
- });
520
-
521
- it("should allow $digest on a child scope with and without a right sibling", () => {
522
- // tests a traversal edge case which we originally missed
523
- logs = "";
524
- const childA = $rootScope.$new();
525
- const childB = $rootScope.$new();
526
-
527
- $rootScope.$watch(() => {
528
- logs += "r";
529
- });
530
- childA.$watch(() => {
531
- logs += "a";
532
- });
533
- childB.$watch(() => {
534
- logs += "b";
535
- });
536
-
537
- // init
538
- $rootScope.$digest();
539
- expect(logs).toBe("rabrab");
540
-
541
- logs = "";
542
- childA.$digest();
543
- expect(logs).toBe("a");
544
-
545
- logs = "";
546
- childB.$digest();
547
- expect(logs).toBe("b");
548
- });
549
-
550
- it("should repeat watch cycle while model changes are identified", () => {
551
- logs = "";
552
- $rootScope.$watch("c", (v) => {
553
- $rootScope.d = v;
554
- logs += "c";
555
- });
556
- $rootScope.$watch("b", (v) => {
557
- $rootScope.c = v;
558
- logs += "b";
559
- });
560
- $rootScope.$watch("a", (v) => {
561
- $rootScope.b = v;
562
- logs += "a";
563
- });
564
- $rootScope.$digest();
565
- logs = "";
566
- $rootScope.a = 1;
567
- $rootScope.$digest();
568
- expect($rootScope.b).toEqual(1);
569
- expect($rootScope.c).toEqual(1);
570
- expect($rootScope.d).toEqual(1);
571
- expect(logs).toEqual("abc");
572
- });
573
-
574
- it("should repeat watch cycle from the root element", () => {
575
- logs = "";
576
- const child = $rootScope.$new();
577
- $rootScope.$watch(() => {
578
- logs += "a";
579
- });
580
- child.$watch(() => {
581
- logs += "b";
582
- });
583
- $rootScope.$digest();
584
- expect(logs).toEqual("abab");
585
- });
586
-
587
- it("should prevent infinite recursion and print watcher expression", () => {
588
- $rootScope.$watch("a", function () {
589
- $rootScope.b++;
590
- });
591
- $rootScope.$watch("b", function () {
592
- $rootScope.a++;
593
- });
594
- $rootScope.a = $rootScope.b = 0;
595
- expect(function () {
596
- $rootScope.$digest();
597
- }).toThrow();
598
-
599
- expect($rootScope.$$phase).toBe(0);
600
- });
601
-
602
- it("should prevent infinite recursion and print watcher function name or body", () => {
603
- $rootScope.$watch(
604
- () => $rootScope.a,
605
- () => {
606
- $rootScope.b++;
607
- },
608
- );
609
- $rootScope.$watch(
610
- () => $rootScope.b,
611
- () => {
612
- $rootScope.a++;
613
- },
614
- );
615
- $rootScope.a = $rootScope.b = 0;
616
-
617
- try {
618
- $rootScope.$digest();
619
- throw new Error("Should have thrown exception");
620
- } catch (e) {
621
- console.error(e);
622
- expect(e.message.match(/rootScope.a/g).length).toBeTruthy();
623
- expect(e.message.match(/rootScope.b/g).length).toBeTruthy();
624
- }
625
- });
626
-
627
- // it("should prevent infinite loop when creating and resolving a promise in a watched expression", () => {
628
- // module(($rootScopeProvider) => {
629
- // $rootScopeProvider.digestTtl(10);
630
- // });
631
- // () => {
632
- // const d = $q.defer();
633
-
634
- // d.resolve("Hello, world.");
635
- // $rootScope.$watch(
636
- // () => {
637
- // const $d2 = $q.defer();
638
- // $d2.resolve("Goodbye.");
639
- // $d2.promise.then(() => {});
640
- // return d.promise;
641
- // },
642
- // () => 0,
643
- // );
644
-
645
- // expect(() => {
646
- // $rootScope.$digest();
647
- // }).toThrow(
648
- // "$rootScope",
649
- // "infdig",
650
- // "10 $digest() iterations reached. Aborting!\n" +
651
- // "Watchers fired in the last 5 iterations: []",
652
- // );
653
-
654
- // expect($rootScope.$$phase).toBeNull();
655
- // });
656
- // });
657
-
658
- it("should not fire upon $watch registration on initial $digest", () => {
659
- logs = "";
660
- $rootScope.a = 1;
661
- $rootScope.$watch("a", () => {
662
- logs += "a";
663
- });
664
- $rootScope.$watch("b", () => {
665
- logs += "b";
666
- });
667
- $rootScope.$digest();
668
- logs = "";
669
- $rootScope.$digest();
670
- expect(logs).toEqual("");
671
- });
672
-
673
- it("should watch objects", () => {
674
- logs = "";
675
- $rootScope.a = [];
676
- $rootScope.b = {};
677
- $rootScope.$watch(
678
- "a",
679
- (value) => {
680
- logs += ".";
681
- expect(value).toBe($rootScope.a);
682
- },
683
- true,
684
- );
685
- $rootScope.$watch(
686
- "b",
687
- (value) => {
688
- logs += "!";
689
- expect(value).toBe($rootScope.b);
690
- },
691
- true,
692
- );
693
- $rootScope.$digest();
694
- logs = "";
695
-
696
- $rootScope.a.push({});
697
- $rootScope.b.name = "";
698
-
699
- $rootScope.$digest();
700
- expect(logs).toEqual(".!");
701
- });
702
-
703
- it("should watch functions", () => {
704
- $rootScope.fn = function () {
705
- return "a";
706
- };
707
- $rootScope.$watch("fn", (fn) => {
708
- logs.push(fn());
709
- });
710
- $rootScope.$digest();
711
- expect(logs).toEqual(["a"]);
712
- $rootScope.fn = function () {
713
- return "b";
714
- };
715
- $rootScope.$digest();
716
- expect(logs).toEqual(["a", "b"]);
717
- });
718
-
719
- it("should prevent $digest recursion", () => {
720
- let callCount = 0;
721
- $rootScope.$watch("name", () => {
722
- expect(() => {
723
- $rootScope.$digest();
724
- }).toThrowError(/digest already in progress/);
725
- callCount++;
726
- });
727
- $rootScope.name = "a";
728
- $rootScope.$digest();
729
- expect(callCount).toEqual(1);
730
- });
731
-
732
- it("should allow a watch to be added while in a digest", () => {
733
- const watch1 = jasmine.createSpy("watch1");
734
- const watch2 = jasmine.createSpy("watch2");
735
- $rootScope.$watch("foo", () => {
736
- $rootScope.$watch("foo", watch1);
737
- $rootScope.$watch("foo", watch2);
738
- });
739
- $rootScope.$apply("foo = true");
740
- expect(watch1).toHaveBeenCalled();
741
- expect(watch2).toHaveBeenCalled();
742
- });
743
-
744
- it("should not skip watchers when adding new watchers during digest", () => {
745
- const watchFn1 = function () {
746
- logs.push(1);
747
- };
748
- const watchFn2 = function () {
749
- logs.push(2);
750
- };
751
- const watchFn3 = function () {
752
- logs.push(3);
753
- };
754
- const addWatcherOnce = function (newValue, oldValue) {
755
- if (newValue === oldValue) {
756
- $rootScope.$watch(watchFn3);
757
- }
758
- };
759
-
760
- $rootScope.$watch(watchFn1, addWatcherOnce);
761
- $rootScope.$watch(watchFn2);
762
-
763
- $rootScope.$digest();
764
-
765
- expect(logs).toEqual([1, 2, 3, 1, 2, 3]);
766
- });
767
-
768
- it("should not run the current watcher twice when removing a watcher during digest", () => {
769
- let removeWatcher3;
770
-
771
- const watchFn3 = function () {
772
- logs.push(3);
773
- };
774
- const watchFn2 = function () {
775
- logs.push(2);
776
- };
777
- const watchFn1 = function () {
778
- logs.push(1);
779
- };
780
- const removeWatcherOnce = function (newValue, oldValue) {
781
- if (newValue === oldValue) {
782
- removeWatcher3();
783
- }
784
- };
785
-
786
- $rootScope.$watch(watchFn1, removeWatcherOnce);
787
- $rootScope.$watch(watchFn2);
788
- removeWatcher3 = $rootScope.$watch(watchFn3);
789
-
790
- $rootScope.$digest();
791
-
792
- expect(logs).toEqual([1, 2, 1, 2]);
793
- });
794
-
795
- it("should not skip watchers when removing itself during digest", () => {
796
- let removeWatcher1;
797
-
798
- const watchFn3 = function () {
799
- logs.push(3);
800
- };
801
- const watchFn2 = function () {
802
- logs.push(2);
803
- };
804
- const watchFn1 = function () {
805
- logs.push(1);
806
- };
807
- const removeItself = function () {
808
- removeWatcher1();
809
- };
810
-
811
- removeWatcher1 = $rootScope.$watch(watchFn1, removeItself);
812
- $rootScope.$watch(watchFn2);
813
- $rootScope.$watch(watchFn3);
814
-
815
- $rootScope.$digest();
816
-
817
- expect(logs).toEqual([1, 2, 3, 2, 3]);
818
- });
819
-
820
- it("should not infinitely digest when current value is NaN", () => {
821
- $rootScope.$watch(() => NaN);
822
-
823
- expect(() => {
824
- $rootScope.$digest();
825
- }).not.toThrow();
826
- });
827
-
828
- it("should always call the watcher with newVal and oldVal equal on the first run", () => {
829
- function logger(scope, newVal, oldVal) {
830
- const val =
831
- newVal === oldVal || (newVal !== oldVal && oldVal !== newVal)
832
- ? newVal
833
- : "xxx";
834
- logs.push(val);
835
- }
836
-
837
- $rootScope.$watch(() => NaN, logger);
838
- $rootScope.$watch(() => undefined, logger);
839
- $rootScope.$watch(() => "", logger);
840
- $rootScope.$watch(() => false, logger);
841
- $rootScope.$watch(() => ({}), logger, true);
842
- $rootScope.$watch(() => 23, logger);
843
-
844
- $rootScope.$digest();
845
- expect(isNaN(logs.shift())).toBe(true); // jasmine's toBe and toEqual don't work well with NaNs
846
- expect(logs).toEqual([undefined, "", false, {}, 23]);
847
- logs = [];
848
- $rootScope.$digest();
849
- expect(logs).toEqual([]);
850
- });
851
-
852
- describe("$watch deregistration", () => {
853
- beforeEach(() => (logs = []));
854
- it("should return a function that allows listeners to be deregistered", () => {
855
- const listener = jasmine.createSpy("watch listener");
856
- let listenerRemove;
857
-
858
- listenerRemove = $rootScope.$watch("foo", listener);
859
- $rootScope.$digest(); // init
860
- expect(listener).toHaveBeenCalled();
861
- expect(listenerRemove).toBeDefined();
862
-
863
- listener.calls.reset();
864
- $rootScope.foo = "bar";
865
- $rootScope.$digest(); // trigger
866
- expect(listener).toHaveBeenCalled();
867
-
868
- listener.calls.reset();
869
- $rootScope.foo = "baz";
870
- listenerRemove();
871
- $rootScope.$digest(); // trigger
872
- expect(listener).not.toHaveBeenCalled();
873
- });
874
-
875
- it("should allow a watch to be deregistered while in a digest", () => {
876
- let remove1;
877
- let remove2;
878
- $rootScope.$watch("remove", () => {
879
- remove1();
880
- remove2();
881
- });
882
- remove1 = $rootScope.$watch("thing", () => {});
883
- remove2 = $rootScope.$watch("thing", () => {});
884
- expect(() => {
885
- $rootScope.$apply("remove = true");
886
- }).not.toThrow();
887
- });
888
-
889
- it("should not mess up the digest loop if deregistration happens during digest", () => {
890
- // we are testing this due to regression #5525 which is related to how the digest loops lastDirtyWatch short-circuiting optimization works
891
- // scenario: watch1 deregistering watch1
892
- let scope = $rootScope.$new();
893
- let deregWatch1 = scope.$watch(
894
- () => {
895
- logs.push("watch1");
896
- return "watch1";
897
- },
898
- () => {
899
- deregWatch1();
900
- logs.push("watchAction1");
901
- },
902
- );
903
- scope.$watch(
904
- () => {
905
- logs.push("watch2");
906
- return "watch2";
907
- },
908
- () => logs.push("watchAction2"),
909
- );
910
- scope.$watch(
911
- () => {
912
- logs.push("watch3");
913
- return "watch3";
914
- },
915
- () => logs.push("watchAction3"),
916
- );
917
-
918
- $rootScope.$digest();
919
-
920
- expect(logs).toEqual([
921
- "watch1",
922
- "watchAction1",
923
- "watch2",
924
- "watchAction2",
925
- "watch3",
926
- "watchAction3",
927
- "watch2",
928
- "watch3",
929
- ]);
930
- scope.$destroy();
931
- logs = [];
932
-
933
- // scenario: watch1 deregistering watch2
934
- scope = $rootScope.$new();
935
- scope.$watch(
936
- () => {
937
- logs.push("watch1");
938
- return "watch1";
939
- },
940
- () => {
941
- deregWatch2();
942
- logs.push("watchAction1");
943
- },
944
- );
945
- let deregWatch2 = scope.$watch(
946
- () => {
947
- logs.push("watch2");
948
- return "watch2";
949
- },
950
- () => logs.push("watchAction2"),
951
- );
952
- scope.$watch(
953
- () => {
954
- logs.push("watch3");
955
- return "watch3";
956
- },
957
- () => logs.push("watchAction3"),
958
- );
959
-
960
- $rootScope.$digest();
961
-
962
- expect(logs).toEqual([
963
- "watch1",
964
- "watchAction1",
965
- "watch3",
966
- "watchAction3",
967
- "watch1",
968
- "watch3",
969
- ]);
970
- scope.$destroy();
971
- logs = [];
972
-
973
- // scenario: watch2 deregistering watch1
974
- scope = $rootScope.$new();
975
- deregWatch1 = scope.$watch(
976
- () => {
977
- logs.push("watch1");
978
- return "watch1";
979
- },
980
- () => logs.push("watchAction1"),
981
- );
982
- scope.$watch(
983
- () => {
984
- logs.push("watch2");
985
- return "watch2";
986
- },
987
- () => {
988
- deregWatch1();
989
- logs.push("watchAction2");
990
- },
991
- );
992
- scope.$watch(
993
- () => {
994
- logs.push("watch3");
995
- return "watch3";
996
- },
997
- () => logs.push("watchAction3"),
998
- );
999
-
1000
- $rootScope.$digest();
1001
-
1002
- expect(logs).toEqual([
1003
- "watch1",
1004
- "watchAction1",
1005
- "watch2",
1006
- "watchAction2",
1007
- "watch3",
1008
- "watchAction3",
1009
- "watch2",
1010
- "watch3",
1011
- ]);
1012
- });
1013
- });
1014
-
1015
200
  describe("$watchCollection", () => {
1016
201
  describe("constiable", () => {
1017
202
  let deregister;
@@ -1029,25 +214,21 @@ describe("Scope", function () {
1029
214
  });
1030
215
 
1031
216
  it("should not trigger if nothing change", () => {
1032
- $rootScope.$digest();
1033
217
  expect(logs).toEqual([
1034
218
  { newVal: undefined, oldVal: undefined, identical: true },
1035
219
  ]);
1036
220
  logs = [];
1037
- $rootScope.$digest();
1038
221
  expect(logs).toEqual([]);
1039
222
  });
1040
223
 
1041
224
  it("should allow deregistration", () => {
1042
225
  $rootScope.obj = [];
1043
- $rootScope.$digest();
1044
226
  expect(logs.length).toBe(1);
1045
227
  logs = [];
1046
228
 
1047
229
  $rootScope.obj.push("a");
1048
230
  deregister();
1049
231
 
1050
- $rootScope.$digest();
1051
232
  expect(logs).toEqual([]);
1052
233
  });
1053
234
 
@@ -1055,7 +236,6 @@ describe("Scope", function () {
1055
236
  it("should return oldCollection === newCollection only on the first listener call", () => {
1056
237
  // first time should be identical
1057
238
  $rootScope.obj = ["a", "b"];
1058
- $rootScope.$digest();
1059
239
  expect(logs).toEqual([
1060
240
  { newVal: ["a", "b"], oldVal: ["a", "b"], identical: true },
1061
241
  ]);
@@ -1063,99 +243,58 @@ describe("Scope", function () {
1063
243
 
1064
244
  // second time should be different
1065
245
  $rootScope.obj[1] = "c";
1066
- $rootScope.$digest();
1067
246
  expect(logs).toEqual([{ newVal: ["a", "c"], oldVal: ["a", "b"] }]);
1068
247
  });
1069
248
 
1070
- it("should trigger when property changes into array", () => {
1071
- $rootScope.obj = "test";
1072
- $rootScope.$digest();
1073
- expect(logs).toEqual([
1074
- { newVal: "test", oldVal: "test", identical: true },
1075
- ]);
1076
-
1077
- logs = [];
1078
- $rootScope.obj = [];
1079
- $rootScope.$digest();
1080
- expect(logs).toEqual([{ newVal: [], oldVal: "test" }]);
1081
-
1082
- logs = [];
1083
- $rootScope.obj = {};
1084
- $rootScope.$digest();
1085
- expect(logs).toEqual([{ newVal: {}, oldVal: [] }]);
1086
-
1087
- logs = [];
1088
- $rootScope.obj = [];
1089
- $rootScope.$digest();
1090
- expect(logs).toEqual([{ newVal: [], oldVal: {} }]);
1091
-
1092
- logs = [];
1093
- $rootScope.obj = undefined;
1094
- $rootScope.$digest();
1095
- expect(logs).toEqual([{ newVal: undefined, oldVal: [] }]);
1096
- });
1097
-
1098
249
  it("should not trigger change when object in collection changes", () => {
1099
250
  $rootScope.obj = [{}];
1100
- $rootScope.$digest();
1101
251
  expect(logs).toEqual([
1102
252
  { newVal: [{}], oldVal: [{}], identical: true },
1103
253
  ]);
1104
254
 
1105
255
  logs = [];
1106
256
  $rootScope.obj[0].name = "foo";
1107
- $rootScope.$digest();
1108
257
  expect(logs).toEqual([]);
1109
258
  });
1110
259
 
1111
260
  it("should watch array properties", () => {
1112
261
  $rootScope.obj = [];
1113
- $rootScope.$digest();
1114
262
  expect(logs).toEqual([{ newVal: [], oldVal: [], identical: true }]);
1115
263
 
1116
264
  logs = [];
1117
265
  $rootScope.obj.push("a");
1118
- $rootScope.$digest();
1119
266
  expect(logs).toEqual([{ newVal: ["a"], oldVal: [] }]);
1120
267
 
1121
268
  logs = [];
1122
269
  $rootScope.obj[0] = "b";
1123
- $rootScope.$digest();
1124
270
  expect(logs).toEqual([{ newVal: ["b"], oldVal: ["a"] }]);
1125
271
 
1126
272
  logs = [];
1127
273
  $rootScope.obj.push([]);
1128
274
  $rootScope.obj.push({});
1129
- $rootScope.$digest();
1130
275
  expect(logs).toEqual([{ newVal: ["b", [], {}], oldVal: ["b"] }]);
1131
276
 
1132
277
  logs = [];
1133
278
  const temp = $rootScope.obj[1];
1134
279
  $rootScope.obj[1] = $rootScope.obj[2];
1135
280
  $rootScope.obj[2] = temp;
1136
- $rootScope.$digest();
1137
281
  expect(logs).toEqual([
1138
282
  { newVal: ["b", {}, []], oldVal: ["b", [], {}] },
1139
283
  ]);
1140
284
 
1141
285
  logs = [];
1142
286
  $rootScope.obj.shift();
1143
- $rootScope.$digest();
1144
287
  expect(logs).toEqual([{ newVal: [{}, []], oldVal: ["b", {}, []] }]);
1145
288
  });
1146
289
 
1147
290
  it("should not infinitely digest when current value is NaN", () => {
1148
291
  $rootScope.obj = [NaN];
1149
- expect(() => {
1150
- $rootScope.$digest();
1151
- }).not.toThrow();
292
+ expect(() => {}).not.toThrow();
1152
293
  });
1153
294
 
1154
295
  it("should watch array-like objects like arrays", () => {
1155
296
  logs = [];
1156
297
  $rootScope.obj = document.getElementsByTagName("src");
1157
- $rootScope.$digest();
1158
-
1159
298
  expect(logs.length).toBeTruthy();
1160
299
  });
1161
300
  });
@@ -1164,7 +303,6 @@ describe("Scope", function () {
1164
303
  it("should return oldCollection === newCollection only on the first listener call", () => {
1165
304
  $rootScope.obj = { a: "b" };
1166
305
  // first time should be identical
1167
- $rootScope.$digest();
1168
306
  expect(logs).toEqual([
1169
307
  { newVal: { a: "b" }, oldVal: { a: "b" }, identical: true },
1170
308
  ]);
@@ -1172,54 +310,45 @@ describe("Scope", function () {
1172
310
 
1173
311
  // second time not identical
1174
312
  $rootScope.obj.a = "c";
1175
- $rootScope.$digest();
1176
313
  expect(logs).toEqual([{ newVal: { a: "c" }, oldVal: { a: "b" } }]);
1177
314
  });
1178
315
 
1179
316
  it("should trigger when property changes into object", () => {
1180
317
  $rootScope.obj = "test";
1181
- $rootScope.$digest();
1182
318
  expect(logs).toEqual([
1183
319
  { newVal: "test", oldVal: "test", identical: true },
1184
320
  ]);
1185
321
  logs = [];
1186
322
 
1187
323
  $rootScope.obj = {};
1188
- $rootScope.$digest();
1189
324
  expect(logs).toEqual([{ newVal: {}, oldVal: "test" }]);
1190
325
  });
1191
326
 
1192
327
  it("should not trigger change when object in collection changes", () => {
1193
328
  $rootScope.obj = { name: {} };
1194
- $rootScope.$digest();
1195
329
  expect(logs).toEqual([
1196
330
  { newVal: { name: {} }, oldVal: { name: {} }, identical: true },
1197
331
  ]);
1198
332
  logs = [];
1199
333
 
1200
334
  $rootScope.obj.name.bar = "foo";
1201
- $rootScope.$digest();
1202
335
  expect(logs).toEqual([]);
1203
336
  });
1204
337
 
1205
338
  it("should watch object properties", () => {
1206
339
  $rootScope.obj = {};
1207
- $rootScope.$digest();
1208
340
  expect(logs).toEqual([{ newVal: {}, oldVal: {}, identical: true }]);
1209
341
  logs = [];
1210
342
  $rootScope.obj.a = "A";
1211
- $rootScope.$digest();
1212
343
  expect(logs).toEqual([{ newVal: { a: "A" }, oldVal: {} }]);
1213
344
 
1214
345
  logs = [];
1215
346
  $rootScope.obj.a = "B";
1216
- $rootScope.$digest();
1217
347
  expect(logs).toEqual([{ newVal: { a: "B" }, oldVal: { a: "A" } }]);
1218
348
 
1219
349
  logs = [];
1220
350
  $rootScope.obj.b = [];
1221
351
  $rootScope.obj.c = {};
1222
- $rootScope.$digest();
1223
352
  expect(logs).toEqual([
1224
353
  { newVal: { a: "B", b: [], c: {} }, oldVal: { a: "B" } },
1225
354
  ]);
@@ -1228,7 +357,6 @@ describe("Scope", function () {
1228
357
  const temp = $rootScope.obj.a;
1229
358
  $rootScope.obj.a = $rootScope.obj.b;
1230
359
  $rootScope.obj.c = temp;
1231
- $rootScope.$digest();
1232
360
  expect(logs).toEqual([
1233
361
  {
1234
362
  newVal: { a: [], b: [], c: "B" },
@@ -1238,7 +366,6 @@ describe("Scope", function () {
1238
366
 
1239
367
  logs = [];
1240
368
  delete $rootScope.obj.a;
1241
- $rootScope.$digest();
1242
369
  expect(logs).toEqual([
1243
370
  { newVal: { b: [], c: "B" }, oldVal: { a: [], b: [], c: "B" } },
1244
371
  ]);
@@ -1246,22 +373,18 @@ describe("Scope", function () {
1246
373
 
1247
374
  it("should not infinitely digest when current value is NaN", () => {
1248
375
  $rootScope.obj = { a: NaN };
1249
- expect(() => {
1250
- $rootScope.$digest();
1251
- }).not.toThrow();
376
+ expect(() => {}).not.toThrow();
1252
377
  });
1253
378
 
1254
379
  it("should handle objects created using `Object.create(null)`", () => {
1255
380
  $rootScope.obj = Object.create(null);
1256
381
  $rootScope.obj.a = "a";
1257
382
  $rootScope.obj.b = "b";
1258
- $rootScope.$digest();
1259
383
  expect(logs[0].newVal).toEqual(
1260
384
  extend(Object.create(null), { a: "a", b: "b" }),
1261
385
  );
1262
386
 
1263
387
  delete $rootScope.obj.b;
1264
- $rootScope.$digest();
1265
388
  expect(logs[0].newVal).toEqual(
1266
389
  extend(Object.create(null), { a: "a" }),
1267
390
  );
@@ -1287,7 +410,6 @@ describe("Scope", function () {
1287
410
  it("should return oldCollection === newCollection only on the first listener call", () => {
1288
411
  // first time should be identical
1289
412
  $rootScope.obj = "a";
1290
- $rootScope.$digest();
1291
413
  expect(logs).toEqual([
1292
414
  { newVal: ["a"], oldVal: ["a"], identical: true },
1293
415
  ]);
@@ -1295,56 +417,46 @@ describe("Scope", function () {
1295
417
 
1296
418
  // second time should be different
1297
419
  $rootScope.obj = "b";
1298
- $rootScope.$digest();
1299
420
  expect(logs).toEqual([{ newVal: ["b"], oldVal: ["a"] }]);
1300
421
  });
1301
422
 
1302
423
  it("should trigger when property changes into array", () => {
1303
424
  $rootScope.obj = "test";
1304
- $rootScope.$digest();
1305
425
  expect(logs).toEqual([
1306
426
  { newVal: ["test"], oldVal: ["test"], identical: true },
1307
427
  ]);
1308
428
 
1309
429
  logs = [];
1310
430
  $rootScope.obj = [];
1311
- $rootScope.$digest();
1312
431
  expect(logs).toEqual([{ newVal: [[]], oldVal: ["test"] }]);
1313
432
 
1314
433
  logs = [];
1315
434
  $rootScope.obj = {};
1316
- $rootScope.$digest();
1317
435
  expect(logs).toEqual([{ newVal: [{}], oldVal: [[]] }]);
1318
436
 
1319
437
  logs = [];
1320
438
  $rootScope.obj = [];
1321
- $rootScope.$digest();
1322
439
  expect(logs).toEqual([{ newVal: [[]], oldVal: [{}] }]);
1323
440
 
1324
441
  logs = [];
1325
442
  $rootScope.obj = undefined;
1326
- $rootScope.$digest();
1327
443
  expect(logs).toEqual([{ newVal: [undefined], oldVal: [[]] }]);
1328
444
  });
1329
445
 
1330
446
  it("should not trigger change when object in collection changes", () => {
1331
447
  $rootScope.obj = {};
1332
- $rootScope.$digest();
1333
448
  expect(logs).toEqual([
1334
449
  { newVal: [{}], oldVal: [{}], identical: true },
1335
450
  ]);
1336
451
 
1337
452
  logs = [];
1338
453
  $rootScope.obj.name = "foo";
1339
- $rootScope.$digest();
1340
454
  expect(logs).toEqual([]);
1341
455
  });
1342
456
 
1343
457
  it("should not infinitely digest when current value is NaN", () => {
1344
458
  $rootScope.obj = NaN;
1345
- expect(() => {
1346
- $rootScope.$digest();
1347
- }).not.toThrow();
459
+ expect(() => {}).not.toThrow();
1348
460
  });
1349
461
  });
1350
462
 
@@ -1365,7 +477,6 @@ describe("Scope", function () {
1365
477
  it("should return oldCollection === newCollection only on the first listener call", () => {
1366
478
  $rootScope.obj = "b";
1367
479
  // first time should be identical
1368
- $rootScope.$digest();
1369
480
  expect(logs).toEqual([
1370
481
  { newVal: { a: "b" }, oldVal: { a: "b" }, identical: true },
1371
482
  ]);
@@ -1373,20 +484,17 @@ describe("Scope", function () {
1373
484
  // second time not identical
1374
485
  logs = [];
1375
486
  $rootScope.obj = "c";
1376
- $rootScope.$digest();
1377
487
  expect(logs).toEqual([{ newVal: { a: "c" }, oldVal: { a: "b" } }]);
1378
488
  });
1379
489
 
1380
490
  it("should trigger when property changes into object", () => {
1381
491
  $rootScope.obj = "test";
1382
- $rootScope.$digest();
1383
492
  expect(logs).toEqual([
1384
493
  { newVal: { a: "test" }, oldVal: { a: "test" }, identical: true },
1385
494
  ]);
1386
495
 
1387
496
  logs = [];
1388
497
  $rootScope.obj = {};
1389
- $rootScope.$digest();
1390
498
  expect(logs).toEqual([
1391
499
  { newVal: { a: {} }, oldVal: { a: "test" } },
1392
500
  ]);
@@ -1394,7 +502,6 @@ describe("Scope", function () {
1394
502
 
1395
503
  it("should not trigger change when object in collection changes", () => {
1396
504
  $rootScope.obj = { name: "foo" };
1397
- $rootScope.$digest();
1398
505
  expect(logs).toEqual([
1399
506
  {
1400
507
  newVal: { a: { name: "foo" } },
@@ -1405,35 +512,29 @@ describe("Scope", function () {
1405
512
 
1406
513
  logs = [];
1407
514
  $rootScope.obj.name = "bar";
1408
- $rootScope.$digest();
1409
515
  expect(logs).toEqual([]);
1410
516
  });
1411
517
 
1412
518
  it("should watch object properties", () => {
1413
519
  $rootScope.obj = {};
1414
- $rootScope.$digest();
1415
520
  expect(logs).toEqual([
1416
521
  { newVal: { a: {} }, oldVal: { a: {} }, identical: true },
1417
522
  ]);
1418
523
 
1419
524
  logs = [];
1420
525
  $rootScope.obj = "A";
1421
- $rootScope.$digest();
1422
526
  expect(logs).toEqual([{ newVal: { a: "A" }, oldVal: { a: {} } }]);
1423
527
 
1424
528
  logs = [];
1425
529
  $rootScope.obj = "B";
1426
- $rootScope.$digest();
1427
530
  expect(logs).toEqual([{ newVal: { a: "B" }, oldVal: { a: "A" } }]);
1428
531
 
1429
532
  logs = [];
1430
533
  $rootScope.obj = [];
1431
- $rootScope.$digest();
1432
534
  expect(logs).toEqual([{ newVal: { a: [] }, oldVal: { a: "B" } }]);
1433
535
 
1434
536
  logs = [];
1435
537
  delete $rootScope.obj;
1436
- $rootScope.$digest();
1437
538
  expect(logs).toEqual([
1438
539
  { newVal: { a: undefined }, oldVal: { a: [] } },
1439
540
  ]);
@@ -1441,9 +542,7 @@ describe("Scope", function () {
1441
542
 
1442
543
  it("should not infinitely digest when current value is NaN", () => {
1443
544
  $rootScope.obj = NaN;
1444
- expect(() => {
1445
- $rootScope.$digest();
1446
- }).not.toThrow();
545
+ expect(() => {}).not.toThrow();
1447
546
  });
1448
547
  });
1449
548
 
@@ -1463,7 +562,6 @@ describe("Scope", function () {
1463
562
 
1464
563
  it('should default to "undefined" key', () => {
1465
564
  $rootScope.obj = "test";
1466
- $rootScope.$digest();
1467
565
  expect(logs).toEqual([
1468
566
  {
1469
567
  newVal: { undefined: "test" },
@@ -1476,21 +574,18 @@ describe("Scope", function () {
1476
574
  it("should trigger when key changes", () => {
1477
575
  $rootScope.key = "a";
1478
576
  $rootScope.obj = "test";
1479
- $rootScope.$digest();
1480
577
  expect(logs).toEqual([
1481
578
  { newVal: { a: "test" }, oldVal: { a: "test" }, identical: true },
1482
579
  ]);
1483
580
 
1484
581
  logs = [];
1485
582
  $rootScope.key = "b";
1486
- $rootScope.$digest();
1487
583
  expect(logs).toEqual([
1488
584
  { newVal: { b: "test" }, oldVal: { a: "test" } },
1489
585
  ]);
1490
586
 
1491
587
  logs = [];
1492
588
  $rootScope.key = true;
1493
- $rootScope.$digest();
1494
589
  expect(logs).toEqual([
1495
590
  { newVal: { true: "test" }, oldVal: { b: "test" } },
1496
591
  ]);
@@ -1499,30 +594,25 @@ describe("Scope", function () {
1499
594
  it("should not trigger when key changes but stringified key does not", () => {
1500
595
  $rootScope.key = 1;
1501
596
  $rootScope.obj = "test";
1502
- $rootScope.$digest();
1503
597
  expect(logs).toEqual([
1504
598
  { newVal: { 1: "test" }, oldVal: { 1: "test" }, identical: true },
1505
599
  ]);
1506
600
 
1507
601
  logs = [];
1508
602
  $rootScope.key = "1";
1509
- $rootScope.$digest();
1510
603
  expect(logs).toEqual([]);
1511
604
 
1512
605
  $rootScope.key = true;
1513
- $rootScope.$digest();
1514
606
  expect(logs).toEqual([
1515
607
  { newVal: { true: "test" }, oldVal: { 1: "test" } },
1516
608
  ]);
1517
609
 
1518
610
  logs = [];
1519
611
  $rootScope.key = "true";
1520
- $rootScope.$digest();
1521
612
  expect(logs).toEqual([]);
1522
613
 
1523
614
  logs = [];
1524
615
  $rootScope.key = {};
1525
- $rootScope.$digest();
1526
616
  expect(logs).toEqual([
1527
617
  {
1528
618
  newVal: { "[object Object]": "test" },
@@ -1532,14 +622,12 @@ describe("Scope", function () {
1532
622
 
1533
623
  logs = [];
1534
624
  $rootScope.key = {};
1535
- $rootScope.$digest();
1536
625
  expect(logs).toEqual([]);
1537
626
  });
1538
627
 
1539
628
  it("should not trigger change when object in collection changes", () => {
1540
629
  $rootScope.key = "a";
1541
630
  $rootScope.obj = { name: "foo" };
1542
- $rootScope.$digest();
1543
631
  expect(logs).toEqual([
1544
632
  {
1545
633
  newVal: { a: { name: "foo" } },
@@ -1550,16 +638,13 @@ describe("Scope", function () {
1550
638
  logs = [];
1551
639
 
1552
640
  $rootScope.obj.name = "bar";
1553
- $rootScope.$digest();
1554
641
  expect(logs).toEqual([]);
1555
642
  });
1556
643
 
1557
644
  it("should not infinitely digest when key value is NaN", () => {
1558
645
  $rootScope.key = NaN;
1559
646
  $rootScope.obj = NaN;
1560
- expect(() => {
1561
- $rootScope.$digest();
1562
- }).not.toThrow();
647
+ expect(() => {}).not.toThrow();
1563
648
  });
1564
649
  });
1565
650
  });
@@ -1570,7 +655,6 @@ describe("Scope", function () {
1570
655
  const watchSpy = jasmine.createSpy("watchSpy");
1571
656
  $rootScope.$watch(watchSpy);
1572
657
  $rootScope.$suspend();
1573
- $rootScope.$digest();
1574
658
  expect(watchSpy).not.toHaveBeenCalled();
1575
659
  });
1576
660
 
@@ -1579,7 +663,6 @@ describe("Scope", function () {
1579
663
  $rootScope.$watch(watchSpy);
1580
664
  $rootScope.$suspend();
1581
665
  $rootScope.$resume();
1582
- $rootScope.$digest();
1583
666
  expect(watchSpy).toHaveBeenCalled();
1584
667
  });
1585
668
 
@@ -1588,7 +671,6 @@ describe("Scope", function () {
1588
671
  const scope = $rootScope.$new(true);
1589
672
  scope.$watch(watchSpy);
1590
673
  $rootScope.$suspend();
1591
- $rootScope.$digest();
1592
674
  expect(watchSpy).not.toHaveBeenCalled();
1593
675
  });
1594
676
 
@@ -1598,7 +680,6 @@ describe("Scope", function () {
1598
680
  scope.$watch(watchSpy);
1599
681
  $rootScope.$suspend();
1600
682
  $rootScope.$resume();
1601
- $rootScope.$digest();
1602
683
  expect(watchSpy).toHaveBeenCalled();
1603
684
  });
1604
685
 
@@ -1665,7 +746,6 @@ describe("Scope", function () {
1665
746
  sibling.$watch(watchSpySibling);
1666
747
 
1667
748
  child.$suspend();
1668
- $rootScope.$digest();
1669
749
  expect(watchSpyParent).toHaveBeenCalled();
1670
750
  expect(watchSpyChild).not.toHaveBeenCalled();
1671
751
  expect(watchSpySibling).toHaveBeenCalled();
@@ -1706,123 +786,8 @@ describe("Scope", function () {
1706
786
  return scope.w3;
1707
787
  }, log("w3action"));
1708
788
  console.error(logs.length);
1709
- scope.$digest();
1710
789
  logs = [];
1711
790
  }
1712
-
1713
- describe("optimizations", () => {
1714
- beforeEach(() => (logs = []));
1715
- it("should check watches only once during an empty digest", () => {
1716
- setupWatches($rootScope, console.log);
1717
- $rootScope.$digest();
1718
- expect(logs).toEqual(["w1", "w2", "w3"]);
1719
- });
1720
-
1721
- it("should quit digest early after we check the last watch that was previously dirty", () => {
1722
- setupWatches($rootScope, console.log);
1723
- $rootScope.w1 = "x";
1724
- $rootScope.$digest();
1725
- expect(logs).toEqual(["w1", "w2", "w3", "w1"]);
1726
- });
1727
-
1728
- it("should not quit digest early if a new watch was added from an existing watch action", () => {
1729
- setupWatches($rootScope, console.log);
1730
- $rootScope.$watch(
1731
- () => {
1732
- logs.push("w4");
1733
- return "w4";
1734
- },
1735
- () => {
1736
- logs.push("w4action");
1737
- $rootScope.$watch(
1738
- () => {
1739
- logs.push("w5");
1740
- return "w5";
1741
- },
1742
- () => logs.push("w5action"),
1743
- );
1744
- },
1745
- );
1746
- $rootScope.$digest();
1747
- expect(logs).toEqual([
1748
- "w1",
1749
- "w2",
1750
- "w3",
1751
- "w4",
1752
- "w4action",
1753
- "w5",
1754
- "w5action",
1755
- "w1",
1756
- "w2",
1757
- "w3",
1758
- "w4",
1759
- "w5",
1760
- ]);
1761
- });
1762
-
1763
- it("should not quit digest early if an evalAsync task was scheduled from a watch action", () => {
1764
- setupWatches($rootScope, console.log);
1765
- $rootScope.$watch(
1766
- () => {
1767
- logs.push("w4");
1768
- return "w4";
1769
- },
1770
- () => {
1771
- logs.push("w4action");
1772
- $rootScope.$evalAsync(() => {
1773
- logs.push("evalAsync");
1774
- });
1775
- },
1776
- );
1777
- $rootScope.$digest();
1778
- expect(logs).toEqual([
1779
- "w1",
1780
- "w2",
1781
- "w3",
1782
- "w4",
1783
- "w4action",
1784
- "evalAsync",
1785
- "w1",
1786
- "w2",
1787
- "w3",
1788
- "w4",
1789
- ]);
1790
- });
1791
-
1792
- it("should quit digest early but not too early when constious watches fire", () => {
1793
- setupWatches($rootScope, console.log);
1794
- $rootScope.$watch(
1795
- () => {
1796
- logs.push("w4");
1797
- return $rootScope.w4;
1798
- },
1799
- (newVal) => {
1800
- logs.push("w4action");
1801
- $rootScope.w2 = newVal;
1802
- },
1803
- );
1804
-
1805
- $rootScope.$digest();
1806
- logs = [];
1807
-
1808
- $rootScope.w1 = "x";
1809
- $rootScope.w4 = "x";
1810
- $rootScope.$digest();
1811
- expect(logs).toEqual([
1812
- "w1",
1813
- "w2",
1814
- "w3",
1815
- "w4",
1816
- "w4action",
1817
- "w1",
1818
- "w2",
1819
- "w3",
1820
- "w4",
1821
- "w1",
1822
- "w2",
1823
- ]);
1824
- });
1825
- });
1826
791
  });
1827
792
 
1828
793
  describe("$watchGroup", () => {
@@ -1883,21 +848,17 @@ describe("Scope", function () {
1883
848
 
1884
849
  scope.a = "foo";
1885
850
  scope.b = "bar";
1886
- scope.$digest();
1887
851
  expect(logs[0]).toEqual("foo,bar >>> foo,bar");
1888
852
 
1889
853
  logs = [];
1890
- scope.$digest();
1891
854
  expect(logs).toEqual([]);
1892
855
 
1893
856
  scope.a = "a";
1894
- scope.$digest();
1895
857
  expect(logs[0]).toEqual("foo,bar >>> a,bar");
1896
858
 
1897
859
  logs = [];
1898
860
  scope.a = "A";
1899
861
  scope.b = "B";
1900
- scope.$digest();
1901
862
  expect(logs[0]).toEqual("a,bar >>> A,B");
1902
863
  });
1903
864
 
@@ -1909,15 +870,12 @@ describe("Scope", function () {
1909
870
  });
1910
871
 
1911
872
  scope.a = "foo";
1912
- scope.$digest();
1913
873
  expect(logs[0]).toEqual("foo >>> foo");
1914
874
 
1915
875
  logs = [];
1916
- scope.$digest();
1917
876
  expect(logs).toEqual([]);
1918
877
 
1919
878
  scope.a = "bar";
1920
- scope.$digest();
1921
879
  expect(logs[0]).toEqual("foo >>> bar");
1922
880
  });
1923
881
 
@@ -1928,11 +886,9 @@ describe("Scope", function () {
1928
886
  });
1929
887
 
1930
888
  expect(logs).toEqual([]);
1931
- scope.$digest();
1932
889
  expect(logs[0]).toEqual(" >>> ");
1933
890
 
1934
891
  logs = [];
1935
- scope.$digest();
1936
892
  expect(logs).toEqual([]);
1937
893
  });
1938
894
 
@@ -1956,7 +912,6 @@ describe("Scope", function () {
1956
912
  deregisterNone();
1957
913
  scope.a = "xxx";
1958
914
  scope.b = "yyy";
1959
- scope.$digest();
1960
915
  expect(logs).toEqual([]);
1961
916
  });
1962
917
 
@@ -2138,7 +1093,6 @@ describe("Scope", function () {
2138
1093
  log += "3";
2139
1094
  });
2140
1095
 
2141
- $rootScope.$digest();
2142
1096
  log = "";
2143
1097
  });
2144
1098
 
@@ -2162,7 +1116,6 @@ describe("Scope", function () {
2162
1116
  const spy = jasmine.createSpy("$watch spy");
2163
1117
  $rootScope.$watch(spy);
2164
1118
  $rootScope.$destroy();
2165
- $rootScope.$digest();
2166
1119
  expect(spy).not.toHaveBeenCalled();
2167
1120
  });
2168
1121
 
@@ -2174,19 +1127,16 @@ describe("Scope", function () {
2174
1127
 
2175
1128
  it("should remove first", () => {
2176
1129
  first.$destroy();
2177
- $rootScope.$digest();
2178
1130
  expect(log).toEqual("23");
2179
1131
  });
2180
1132
 
2181
1133
  it("should remove middle", () => {
2182
1134
  middle.$destroy();
2183
- $rootScope.$digest();
2184
1135
  expect(log).toEqual("13");
2185
1136
  });
2186
1137
 
2187
1138
  it("should remove last", () => {
2188
1139
  last.$destroy();
2189
- $rootScope.$digest();
2190
1140
  expect(log).toEqual("12");
2191
1141
  });
2192
1142
 
@@ -2200,7 +1150,6 @@ describe("Scope", function () {
2200
1150
  });
2201
1151
 
2202
1152
  it("should $destroy a scope only once and ignore any further destroy calls", () => {
2203
- $rootScope.$digest();
2204
1153
  expect(log).toBe("123");
2205
1154
 
2206
1155
  first.$destroy();
@@ -2224,27 +1173,6 @@ describe("Scope", function () {
2224
1173
  expect(logs).toEqual(["event"]);
2225
1174
  });
2226
1175
 
2227
- it("should decrement ancestor $$listenerCount entries", () => {
2228
- const EVENT = "fooEvent";
2229
- const spy = jasmine.createSpy("listener");
2230
- const firstSecond = first.$new();
2231
-
2232
- firstSecond.$on(EVENT, spy);
2233
- firstSecond.$on(EVENT, spy);
2234
- middle.$on(EVENT, spy);
2235
-
2236
- expect($rootScope.$$listenerCount[EVENT]).toBe(3);
2237
- expect(first.$$listenerCount[EVENT]).toBe(2);
2238
-
2239
- firstSecond.$destroy();
2240
-
2241
- expect($rootScope.$$listenerCount[EVENT]).toBe(1);
2242
- expect(first.$$listenerCount[EVENT]).toBeUndefined();
2243
-
2244
- $rootScope.$broadcast(EVENT);
2245
- expect(spy).toHaveBeenCalledTimes(1);
2246
- });
2247
-
2248
1176
  it("should do nothing when a child event listener is registered after parent's destruction", () => {
2249
1177
  const parent = $rootScope.$new();
2250
1178
  const child = parent.$new();
@@ -2287,20 +1215,6 @@ describe("Scope", function () {
2287
1215
  expect(called).toBe(false);
2288
1216
  });
2289
1217
 
2290
- it("should do nothing when $evalAsync()ing after parent's destruction", () => {
2291
- const parent = $rootScope.$new();
2292
- const child = parent.$new();
2293
-
2294
- parent.$destroy();
2295
-
2296
- let called = false;
2297
- function applyFunc() {
2298
- called = true;
2299
- }
2300
- child.$evalAsync(applyFunc);
2301
- expect(called).toBe(false);
2302
- });
2303
-
2304
1218
  it("should preserve all (own and inherited) model properties on a destroyed scope", () => {
2305
1219
  // This test simulates an async task (xhr response) interacting with the scope after the scope
2306
1220
  // was destroyed. Since we can't abort the request, we should ensure that the task doesn't
@@ -2319,238 +1233,6 @@ describe("Scope", function () {
2319
1233
  });
2320
1234
  });
2321
1235
 
2322
- describe("$eval", () => {
2323
- it("should eval an expression", () => {
2324
- expect($rootScope.$eval("a=1")).toEqual(1);
2325
- expect($rootScope.a).toEqual(1);
2326
-
2327
- $rootScope.$eval((self) => {
2328
- self.b = 2;
2329
- });
2330
- expect($rootScope.b).toEqual(2);
2331
- });
2332
-
2333
- it("should allow passing locals to the expression", () => {
2334
- expect($rootScope.$eval("a+1", { a: 2 })).toBe(3);
2335
-
2336
- $rootScope.$eval(
2337
- (scope, locals) => {
2338
- scope.c = locals.b + 4;
2339
- },
2340
- { b: 3 },
2341
- );
2342
- expect($rootScope.c).toBe(7);
2343
- });
2344
- });
2345
-
2346
- describe("$evalAsync", () => {
2347
- it("should run callback before $watch", () => {
2348
- let log = "";
2349
- const child = $rootScope.$new();
2350
- $rootScope.$evalAsync((scope) => {
2351
- log += "parent.async;";
2352
- });
2353
- $rootScope.$watch("value", () => {
2354
- log += "parent.$digest;";
2355
- });
2356
- child.$evalAsync((scope) => {
2357
- log += "child.async;";
2358
- });
2359
- child.$watch("value", () => {
2360
- log += "child.$digest;";
2361
- });
2362
- $rootScope.$digest();
2363
- expect(log).toEqual(
2364
- "parent.async;child.async;parent.$digest;child.$digest;",
2365
- );
2366
- });
2367
-
2368
- it("should not run another digest for an $$postDigest call", () => {
2369
- let internalWatchCount = 0;
2370
- let externalWatchCount = 0;
2371
-
2372
- $rootScope.internalCount = 0;
2373
- $rootScope.externalCount = 0;
2374
-
2375
- $rootScope.$evalAsync((scope) => {
2376
- $rootScope.internalCount++;
2377
- });
2378
-
2379
- $rootScope.$$postDigest((scope) => {
2380
- $rootScope.externalCount++;
2381
- });
2382
-
2383
- $rootScope.$watch("internalCount", (value) => {
2384
- internalWatchCount = value;
2385
- });
2386
- $rootScope.$watch("externalCount", (value) => {
2387
- externalWatchCount = value;
2388
- });
2389
-
2390
- $rootScope.$digest();
2391
-
2392
- expect(internalWatchCount).toEqual(1);
2393
- expect(externalWatchCount).toEqual(0);
2394
- });
2395
-
2396
- it("should cause a $digest rerun", () => {
2397
- $rootScope.log = "";
2398
- $rootScope.value = 0;
2399
- $rootScope.$watch("value", () => {
2400
- $rootScope.log += ".";
2401
- });
2402
- $rootScope.$watch("init", () => {
2403
- $rootScope.$evalAsync('value = 123; log = log + "=" ');
2404
- expect($rootScope.value).toEqual(0);
2405
- });
2406
- $rootScope.$digest();
2407
- expect($rootScope.log).toEqual(".=.");
2408
- });
2409
-
2410
- it("should run async in the same order as added", () => {
2411
- $rootScope.log = "";
2412
- $rootScope.$evalAsync("log = log + 1");
2413
- $rootScope.$evalAsync("log = log + 2");
2414
- $rootScope.$digest();
2415
- expect($rootScope.log).toBe("12");
2416
- });
2417
-
2418
- it("should allow passing locals to the expression", () => {
2419
- $rootScope.log = "";
2420
- $rootScope.$evalAsync("log = log + a", { a: 1 });
2421
- $rootScope.$digest();
2422
- expect($rootScope.log).toBe("1");
2423
- });
2424
-
2425
- it("should run async expressions in their proper context", () => {
2426
- const child = $rootScope.$new();
2427
- $rootScope.ctx = "root context";
2428
- $rootScope.log = "";
2429
- child.ctx = "child context";
2430
- child.log = "";
2431
- child.$evalAsync("log=ctx");
2432
- $rootScope.$digest();
2433
- expect($rootScope.log).toBe("");
2434
- expect(child.log).toBe("child context");
2435
- });
2436
-
2437
- it("should operate only with a single queue across all child and isolate scopes", () => {
2438
- const childScope = $rootScope.$new();
2439
- const isolateScope = $rootScope.$new(true);
2440
-
2441
- $rootScope.$evalAsync("rootExpression");
2442
- childScope.$evalAsync("childExpression");
2443
- isolateScope.$evalAsync("isolateExpression");
2444
- expect($$asyncQueue).toEqual([
2445
- {
2446
- scope: $rootScope,
2447
- fn: $parse("rootExpression"),
2448
- locals: undefined,
2449
- },
2450
- {
2451
- scope: childScope,
2452
- fn: $parse("childExpression"),
2453
- locals: undefined,
2454
- },
2455
- {
2456
- scope: isolateScope,
2457
- fn: $parse("isolateExpression"),
2458
- locals: undefined,
2459
- },
2460
- ]);
2461
- });
2462
-
2463
- describe("auto-flushing when queueing outside of an $apply", () => {
2464
- it("should auto-flush the queue asynchronously and trigger digest", () => {
2465
- logs = [];
2466
- $rootScope.$evalAsync(() => {
2467
- logs.push("eval-ed!");
2468
- return "eval-ed!";
2469
- });
2470
- $rootScope.$watch(() => {
2471
- logs.push("digesting");
2472
- return "digesting";
2473
- });
2474
- expect(logs).toEqual([]);
2475
- setTimeout(() => {
2476
- expect(logs).toEqual(["eval-ed!", "digesting", "digesting"]);
2477
- });
2478
- });
2479
-
2480
- it("should not trigger digest asynchronously if the queue is empty in the next tick", () => {
2481
- logs = [];
2482
- $rootScope.$evalAsync(() => {
2483
- logs.push("eval-ed!");
2484
- return "eval-ed!";
2485
- });
2486
- $rootScope.$watch(() => {
2487
- logs.push("digesting");
2488
- return "digesting";
2489
- });
2490
- expect(logs).toEqual([]);
2491
-
2492
- $rootScope.$digest();
2493
-
2494
- expect(logs).toEqual(["eval-ed!", "digesting", "digesting"]);
2495
- logs = [];
2496
-
2497
- setTimeout(() => {
2498
- expect(logs).toEqual([]);
2499
- });
2500
- });
2501
-
2502
- it("should not schedule more than one auto-flush task", () => {
2503
- logs = [];
2504
- $rootScope.$evalAsync(() => {
2505
- logs.push("eval-ed 1!");
2506
- return "eval-ed 1!";
2507
- });
2508
- $rootScope.$evalAsync(() => {
2509
- logs.push("eval-ed 2!");
2510
- return "eval-ed 2!";
2511
- });
2512
- expect(logs).toEqual([]);
2513
- setTimeout(() => {
2514
- expect(logs).toEqual(["eval-ed 1!", "eval-ed 2!"]);
2515
- });
2516
-
2517
- setTimeout(() => {
2518
- expect(logs).toEqual(["eval-ed 1!", "eval-ed 2!"]);
2519
- });
2520
- });
2521
-
2522
- it("should not have execution affected by an explicit $digest call", () => {
2523
- const scope1 = $rootScope.$new();
2524
- const scope2 = $rootScope.$new();
2525
-
2526
- scope1.$watch("value", (value) => {
2527
- scope1.result = value;
2528
- });
2529
-
2530
- scope1.$evalAsync(() => {
2531
- scope1.value = "bar";
2532
- });
2533
-
2534
- expect(scope1.result).toBe(undefined);
2535
- scope2.$digest();
2536
-
2537
- setTimeout(() => expect(scope1.result).toBe("bar"));
2538
- });
2539
- });
2540
-
2541
- it("should not pass anything as `this` to scheduled functions", () => {
2542
- let this1 = {};
2543
- const this2 = (function () {
2544
- return this;
2545
- })();
2546
- $rootScope.$evalAsync(function () {
2547
- this1 = this;
2548
- });
2549
- $rootScope.$digest();
2550
- expect(this1).toEqual(this2);
2551
- });
2552
- });
2553
-
2554
1236
  describe("$apply", () => {
2555
1237
  beforeEach(() => (logs = []));
2556
1238
 
@@ -2605,7 +1287,6 @@ describe("Scope", function () {
2605
1287
  $rootScope.$watch(() => {
2606
1288
  log += "$digest;";
2607
1289
  });
2608
- $rootScope.$digest();
2609
1290
  log = "";
2610
1291
  });
2611
1292
 
@@ -2755,714 +1436,98 @@ describe("Scope", function () {
2755
1436
  const expression = jasmine.createSpy("expr");
2756
1437
 
2757
1438
  $rootScope.$applyAsync(expression);
2758
- $rootScope.$digest();
2759
1439
  expect(expression).toHaveBeenCalled();
2760
1440
  expect(cancel).toHaveBeenCalled();
2761
1441
  expression.calls.reset();
2762
1442
  cancel.calls.reset();
2763
1443
 
2764
1444
  // assert that another digest won't call the function again
2765
- $rootScope.$digest();
2766
1445
  expect(expression).not.toHaveBeenCalled();
2767
1446
  expect(cancel).not.toHaveBeenCalled();
2768
1447
  });
2769
1448
  });
2770
1449
 
2771
- describe("$$postDigest", () => {
1450
+ describe("$postUpdate", () => {
2772
1451
  beforeEach(() => (logs = []));
2773
1452
  it("should process callbacks as a queue (FIFO) when the scope is digested", () => {
2774
1453
  let signature = "";
2775
1454
 
2776
- $rootScope.$$postDigest(() => {
1455
+ $rootScope.$postUpdate(() => {
2777
1456
  signature += "A";
2778
- $rootScope.$$postDigest(() => {
1457
+ $rootScope.$postUpdate(() => {
2779
1458
  signature += "D";
2780
1459
  });
2781
1460
  });
2782
1461
 
2783
- $rootScope.$$postDigest(() => {
1462
+ $rootScope.$postUpdate(() => {
2784
1463
  signature += "B";
2785
1464
  });
2786
1465
 
2787
- $rootScope.$$postDigest(() => {
1466
+ $rootScope.$postUpdate(() => {
2788
1467
  signature += "C";
2789
1468
  });
2790
1469
 
2791
1470
  expect(signature).toBe("");
2792
- $rootScope.$digest();
2793
1471
  expect(signature).toBe("ABCD");
2794
1472
  });
2795
1473
 
2796
- it("should support $apply calls nested in $$postDigest callbacks", () => {
1474
+ it("should support $apply calls nested in $postUpdate callbacks", () => {
2797
1475
  let signature = "";
2798
1476
 
2799
- $rootScope.$$postDigest(() => {
1477
+ $rootScope.$postUpdate(() => {
2800
1478
  signature += "A";
2801
1479
  });
2802
1480
 
2803
- $rootScope.$$postDigest(() => {
1481
+ $rootScope.$postUpdate(() => {
2804
1482
  signature += "B";
2805
1483
  $rootScope.$apply();
2806
1484
  signature += "D";
2807
1485
  });
2808
1486
 
2809
- $rootScope.$$postDigest(() => {
1487
+ $rootScope.$postUpdate(() => {
2810
1488
  signature += "C";
2811
1489
  });
2812
1490
 
2813
1491
  expect(signature).toBe("");
2814
- $rootScope.$digest();
2815
1492
  expect(signature).toBe("ABCD");
2816
1493
  });
2817
1494
 
2818
- it("should run a $$postDigest call on all child scopes when a parent scope is digested", () => {
1495
+ it("should run a $postUpdate call on all child scopes when a parent scope is digested", () => {
2819
1496
  const parent = $rootScope.$new();
2820
1497
  const child = parent.$new();
2821
1498
  let count = 0;
2822
1499
 
2823
- $rootScope.$$postDigest(() => {
1500
+ $rootScope.$postUpdate(() => {
2824
1501
  count++;
2825
1502
  });
2826
1503
 
2827
- parent.$$postDigest(() => {
1504
+ parent.$postUpdate(() => {
2828
1505
  count++;
2829
1506
  });
2830
1507
 
2831
- child.$$postDigest(() => {
1508
+ child.$postUpdate(() => {
2832
1509
  count++;
2833
1510
  });
2834
1511
 
2835
1512
  expect(count).toBe(0);
2836
- $rootScope.$digest();
2837
1513
  expect(count).toBe(3);
2838
1514
  });
2839
1515
 
2840
- it("should run a $$postDigest call even if the child scope is isolated", () => {
1516
+ it("should run a $postUpdate call even if the child scope is isolated", () => {
2841
1517
  const parent = $rootScope.$new();
2842
1518
  const child = parent.$new(true);
2843
1519
  let signature = "";
2844
1520
 
2845
- parent.$$postDigest(() => {
1521
+ parent.$postUpdate(() => {
2846
1522
  signature += "A";
2847
1523
  });
2848
1524
 
2849
- child.$$postDigest(() => {
1525
+ child.$postUpdate(() => {
2850
1526
  signature += "B";
2851
1527
  });
2852
1528
 
2853
1529
  expect(signature).toBe("");
2854
- $rootScope.$digest();
2855
1530
  expect(signature).toBe("AB");
2856
1531
  });
2857
1532
  });
2858
-
2859
- describe("events", () => {
2860
- describe("$on", () => {
2861
- it("should add listener for both $emit and $broadcast events", () => {
2862
- logs = "";
2863
- const child = $rootScope.$new();
2864
-
2865
- function eventFn() {
2866
- logs += "X";
2867
- }
2868
-
2869
- child.$on("abc", eventFn);
2870
- expect(logs).toEqual("");
2871
-
2872
- child.$emit("abc");
2873
- expect(logs).toEqual("X");
2874
-
2875
- child.$broadcast("abc");
2876
- expect(logs).toEqual("XX");
2877
- });
2878
-
2879
- it("should increment ancestor $$listenerCount entries", () => {
2880
- const child1 = $rootScope.$new();
2881
- const child2 = child1.$new();
2882
- const spy = jasmine.createSpy();
2883
-
2884
- $rootScope.$on("event1", spy);
2885
- expect($rootScope.$$listenerCount.event1).toEqual(1);
2886
-
2887
- child1.$on("event1", spy);
2888
- expect($rootScope.$$listenerCount.event1).toEqual(2);
2889
- expect(child1.$$listenerCount.event1).toEqual(1);
2890
-
2891
- child2.$on("event2", spy);
2892
- expect($rootScope.$$listenerCount.event1).toEqual(2);
2893
- expect($rootScope.$$listenerCount.event2).toEqual(1);
2894
- expect(child1.$$listenerCount.event1).toEqual(1);
2895
- expect(child1.$$listenerCount.event2).toEqual(1);
2896
- expect(child2.$$listenerCount.event2).toEqual(1);
2897
- });
2898
-
2899
- describe("deregistration", () => {
2900
- it("should return a function that deregisters the listener", () => {
2901
- let log = "";
2902
- const child = $rootScope.$new();
2903
- let listenerRemove;
2904
-
2905
- function eventFn() {
2906
- log += "X";
2907
- }
2908
-
2909
- listenerRemove = child.$on("abc", eventFn);
2910
- expect(log).toEqual("");
2911
- expect(listenerRemove).toBeDefined();
2912
-
2913
- child.$emit("abc");
2914
- child.$broadcast("abc");
2915
- expect(log).toEqual("XX");
2916
- expect($rootScope.$$listenerCount.abc).toBe(1);
2917
-
2918
- log = "";
2919
- listenerRemove();
2920
- child.$emit("abc");
2921
- child.$broadcast("abc");
2922
- expect(log).toEqual("");
2923
- expect($rootScope.$$listenerCount.abc).toBeUndefined();
2924
- });
2925
-
2926
- // See issue https://github.com/angular/angular.js/issues/16135
2927
- it("should deallocate the listener array entry", () => {
2928
- const remove1 = $rootScope.$on("abc", () => {});
2929
- $rootScope.$on("abc", () => {});
2930
-
2931
- expect($rootScope.$$listeners.get("abc").length).toBe(2);
2932
- expect(0 in $rootScope.$$listeners.get("abc")).toBe(true);
2933
-
2934
- remove1();
2935
-
2936
- expect($rootScope.$$listeners.get("abc").length).toBe(2);
2937
- expect(0 in $rootScope.$$listeners.get("abc")).toBe(false);
2938
- });
2939
-
2940
- it("should call next listener after removing the current listener via its own handler", () => {
2941
- const listener1 = jasmine.createSpy("listener1").and.callFake(() => {
2942
- remove1();
2943
- });
2944
- let remove1 = $rootScope.$on("abc", listener1);
2945
-
2946
- const listener2 = jasmine.createSpy("listener2");
2947
- const remove2 = $rootScope.$on("abc", listener2);
2948
-
2949
- const listener3 = jasmine.createSpy("listener3");
2950
- const remove3 = $rootScope.$on("abc", listener3);
2951
-
2952
- $rootScope.$broadcast("abc");
2953
- expect(listener1).toHaveBeenCalled();
2954
- expect(listener2).toHaveBeenCalled();
2955
- expect(listener3).toHaveBeenCalled();
2956
-
2957
- listener1.calls.reset();
2958
- listener2.calls.reset();
2959
- listener3.calls.reset();
2960
-
2961
- $rootScope.$broadcast("abc");
2962
- expect(listener1).not.toHaveBeenCalled();
2963
- expect(listener2).toHaveBeenCalled();
2964
- expect(listener3).toHaveBeenCalled();
2965
- });
2966
-
2967
- it("should call all subsequent listeners when a previous listener is removed via a handler", () => {
2968
- const listener1 = jasmine.createSpy();
2969
- const remove1 = $rootScope.$on("abc", listener1);
2970
-
2971
- const listener2 = jasmine.createSpy().and.callFake(remove1);
2972
- const remove2 = $rootScope.$on("abc", listener2);
2973
-
2974
- const listener3 = jasmine.createSpy();
2975
- const remove3 = $rootScope.$on("abc", listener3);
2976
-
2977
- $rootScope.$broadcast("abc");
2978
- expect(listener1).toHaveBeenCalled();
2979
- expect(listener2).toHaveBeenCalled();
2980
- expect(listener3).toHaveBeenCalled();
2981
-
2982
- listener1.calls.reset();
2983
- listener2.calls.reset();
2984
- listener3.calls.reset();
2985
-
2986
- $rootScope.$broadcast("abc");
2987
- expect(listener1).not.toHaveBeenCalled();
2988
- expect(listener2).toHaveBeenCalled();
2989
- expect(listener3).toHaveBeenCalled();
2990
- });
2991
-
2992
- it("should not call listener when removed by previous", () => {
2993
- const listener1 = jasmine.createSpy("listener1");
2994
- const remove1 = $rootScope.$on("abc", listener1);
2995
-
2996
- const listener2 = jasmine.createSpy("listener2").and.callFake(() => {
2997
- remove3();
2998
- });
2999
- const remove2 = $rootScope.$on("abc", listener2);
3000
-
3001
- const listener3 = jasmine.createSpy("listener3");
3002
- let remove3 = $rootScope.$on("abc", listener3);
3003
-
3004
- const listener4 = jasmine.createSpy("listener4");
3005
- const remove4 = $rootScope.$on("abc", listener4);
3006
-
3007
- $rootScope.$broadcast("abc");
3008
- expect(listener1).toHaveBeenCalled();
3009
- expect(listener2).toHaveBeenCalled();
3010
- expect(listener3).not.toHaveBeenCalled();
3011
- expect(listener4).toHaveBeenCalled();
3012
-
3013
- listener1.calls.reset();
3014
- listener2.calls.reset();
3015
- listener3.calls.reset();
3016
- listener4.calls.reset();
3017
-
3018
- $rootScope.$broadcast("abc");
3019
- expect(listener1).toHaveBeenCalled();
3020
- expect(listener2).toHaveBeenCalled();
3021
- expect(listener3).not.toHaveBeenCalled();
3022
- expect(listener4).toHaveBeenCalled();
3023
- });
3024
-
3025
- it("should decrement ancestor $$listenerCount entries", () => {
3026
- const child1 = $rootScope.$new();
3027
- const child2 = child1.$new();
3028
- const spy = jasmine.createSpy();
3029
-
3030
- $rootScope.$on("event1", spy);
3031
- expect($rootScope.$$listenerCount.event1).toEqual(1);
3032
-
3033
- child1.$on("event1", spy);
3034
- expect($rootScope.$$listenerCount.event1).toEqual(2);
3035
- expect(child1.$$listenerCount.event1).toEqual(1);
3036
-
3037
- const deregisterEvent2Listener = child2.$on("event2", spy);
3038
- expect($rootScope.$$listenerCount.event1).toEqual(2);
3039
- expect($rootScope.$$listenerCount.event2).toEqual(1);
3040
- expect(child1.$$listenerCount.event1).toEqual(1);
3041
- expect(child1.$$listenerCount.event2).toEqual(1);
3042
- expect(child2.$$listenerCount.event2).toEqual(1);
3043
-
3044
- deregisterEvent2Listener();
3045
-
3046
- expect($rootScope.$$listenerCount.event1).toEqual(2);
3047
- expect(child1.$$listenerCount.event1).toEqual(1);
3048
- expect(child2.$$listenerCount).toBeTruthy();
3049
- });
3050
-
3051
- it("should not decrement $$listenerCount when called second time", () => {
3052
- const child = $rootScope.$new();
3053
- const listener1Spy = jasmine.createSpy();
3054
- const listener2Spy = jasmine.createSpy();
3055
-
3056
- child.$on("abc", listener1Spy);
3057
- expect($rootScope.$$listenerCount.abc).toEqual(1);
3058
- expect(child.$$listenerCount.abc).toEqual(1);
3059
-
3060
- const deregisterEventListener = child.$on("abc", listener2Spy);
3061
- expect($rootScope.$$listenerCount.abc).toEqual(2);
3062
- expect(child.$$listenerCount.abc).toEqual(2);
3063
-
3064
- deregisterEventListener();
3065
-
3066
- expect($rootScope.$$listenerCount.abc).toEqual(1);
3067
- expect(child.$$listenerCount.abc).toEqual(1);
3068
-
3069
- deregisterEventListener();
3070
-
3071
- expect($rootScope.$$listenerCount.abc).toEqual(1);
3072
- expect(child.$$listenerCount.abc).toEqual(1);
3073
- });
3074
- });
3075
- });
3076
-
3077
- describe("$emit", () => {
3078
- let log;
3079
- let child;
3080
- let grandChild;
3081
- let greatGrandChild;
3082
-
3083
- function logger(event) {
3084
- log += `${event.currentScope.id}>`;
3085
- }
3086
-
3087
- beforeEach(() => {
3088
- log = "";
3089
- logs = [];
3090
- child = $rootScope.$new();
3091
- grandChild = child.$new();
3092
- greatGrandChild = grandChild.$new();
3093
-
3094
- $rootScope.id = 0;
3095
- child.id = 1;
3096
- grandChild.id = 2;
3097
- greatGrandChild.id = 3;
3098
-
3099
- $rootScope.$on("myEvent", logger);
3100
- child.$on("myEvent", logger);
3101
- grandChild.$on("myEvent", logger);
3102
- greatGrandChild.$on("myEvent", logger);
3103
- });
3104
-
3105
- it("should bubble event up to the root scope", () => {
3106
- grandChild.$emit("myEvent");
3107
- expect(log).toEqual("2>1>0>");
3108
- });
3109
-
3110
- it("should allow all events on the same scope to run even if stopPropagation is called", () => {
3111
- child.$on("myEvent", logger);
3112
- grandChild.$on("myEvent", (e) => {
3113
- e.stopPropagation();
3114
- });
3115
- grandChild.$on("myEvent", logger);
3116
- grandChild.$on("myEvent", logger);
3117
- grandChild.$emit("myEvent");
3118
- expect(log).toEqual("2>2>2>");
3119
- });
3120
-
3121
- it("should dispatch exceptions to the $exceptionHandler", () => {
3122
- child.$on("myEvent", () => {
3123
- throw "bubbleException";
3124
- });
3125
- grandChild.$emit("myEvent");
3126
- expect(log).toEqual("2>1>0>");
3127
- expect(logs).toEqual(["bubbleException"]);
3128
- });
3129
-
3130
- it("should allow stopping event propagation", () => {
3131
- child.$on("myEvent", (event) => {
3132
- event.stopPropagation();
3133
- });
3134
- grandChild.$emit("myEvent");
3135
- expect(log).toEqual("2>1>");
3136
- });
3137
-
3138
- it("should forward method arguments", () => {
3139
- child.$on("abc", (event, arg1, arg2) => {
3140
- expect(event.name).toBe("abc");
3141
- expect(arg1).toBe("arg1");
3142
- expect(arg2).toBe("arg2");
3143
- });
3144
- child.$emit("abc", "arg1", "arg2");
3145
- });
3146
-
3147
- it("should allow removing event listener inside a listener on $emit", () => {
3148
- const spy1 = jasmine.createSpy("1st listener");
3149
- const spy2 = jasmine.createSpy("2nd listener");
3150
- const spy3 = jasmine.createSpy("3rd listener");
3151
-
3152
- const remove1 = child.$on("evt", spy1);
3153
- const remove2 = child.$on("evt", spy2);
3154
- const remove3 = child.$on("evt", spy3);
3155
-
3156
- spy1.and.callFake(remove1);
3157
-
3158
- expect(child.$$listeners.get("evt").length).toBe(3);
3159
-
3160
- // should call all listeners and remove 1st
3161
- child.$emit("evt");
3162
- expect(spy1).toHaveBeenCalled();
3163
- expect(spy2).toHaveBeenCalled();
3164
- expect(spy3).toHaveBeenCalled();
3165
- expect(child.$$listeners.get("evt").length).toBe(3); // cleanup will happen on next $emit
3166
-
3167
- spy1.calls.reset();
3168
- spy2.calls.reset();
3169
- spy3.calls.reset();
3170
-
3171
- // should call only 2nd because 1st was already removed and 2nd removes 3rd
3172
- spy2.and.callFake(remove3);
3173
- child.$emit("evt");
3174
- expect(spy1).not.toHaveBeenCalled();
3175
- expect(spy2).toHaveBeenCalled();
3176
- expect(spy3).not.toHaveBeenCalled();
3177
- expect(child.$$listeners.get("evt").length).toBe(1);
3178
- });
3179
-
3180
- it("should allow removing event listener inside a listener on $broadcast", () => {
3181
- const spy1 = jasmine.createSpy("1st listener");
3182
- const spy2 = jasmine.createSpy("2nd listener");
3183
- const spy3 = jasmine.createSpy("3rd listener");
3184
-
3185
- const remove1 = child.$on("evt", spy1);
3186
- const remove2 = child.$on("evt", spy2);
3187
- const remove3 = child.$on("evt", spy3);
3188
-
3189
- spy1.and.callFake(remove1);
3190
-
3191
- expect(child.$$listeners.get("evt").length).toBe(3);
3192
-
3193
- // should call all listeners and remove 1st
3194
- child.$broadcast("evt");
3195
- expect(spy1).toHaveBeenCalled();
3196
- expect(spy2).toHaveBeenCalled();
3197
- expect(spy3).toHaveBeenCalled();
3198
- expect(child.$$listeners.get("evt").length).toBe(3); // cleanup will happen on next $broadcast
3199
-
3200
- spy1.calls.reset();
3201
- spy2.calls.reset();
3202
- spy3.calls.reset();
3203
-
3204
- // should call only 2nd because 1st was already removed and 2nd removes 3rd
3205
- spy2.and.callFake(remove3);
3206
- child.$broadcast("evt");
3207
- expect(spy1).not.toHaveBeenCalled();
3208
- expect(spy2).toHaveBeenCalled();
3209
- expect(spy3).not.toHaveBeenCalled();
3210
- expect(child.$$listeners.get("evt").length).toBe(1);
3211
- });
3212
-
3213
- describe("event object", () => {
3214
- it("should have methods/properties", () => {
3215
- let eventFired = false;
3216
-
3217
- child.$on("myEvent", (e) => {
3218
- expect(e.targetScope).toBe(grandChild);
3219
- expect(e.currentScope).toBe(child);
3220
- expect(e.name).toBe("myEvent");
3221
- eventFired = true;
3222
- });
3223
- grandChild.$emit("myEvent");
3224
- expect(eventFired).toBe(true);
3225
- });
3226
-
3227
- it("should have its `currentScope` property set to null after emit", () => {
3228
- let event;
3229
-
3230
- child.$on("myEvent", (e) => {
3231
- event = e;
3232
- });
3233
- grandChild.$emit("myEvent");
3234
-
3235
- expect(event.currentScope).toBe(null);
3236
- expect(event.targetScope).toBe(grandChild);
3237
- expect(event.name).toBe("myEvent");
3238
- });
3239
-
3240
- it("should have preventDefault method and defaultPrevented property", () => {
3241
- let event = grandChild.$emit("myEvent");
3242
- expect(event.defaultPrevented).toBe(false);
3243
-
3244
- child.$on("myEvent", (event) => {
3245
- event.preventDefault();
3246
- });
3247
- event = grandChild.$emit("myEvent");
3248
- expect(event.defaultPrevented).toBe(true);
3249
- expect(event.currentScope).toBe(null);
3250
- });
3251
- });
3252
- });
3253
-
3254
- describe("$broadcast", () => {
3255
- describe("event propagation", () => {
3256
- let log;
3257
- let child1;
3258
- let child2;
3259
- let child3;
3260
- let grandChild11;
3261
- let grandChild21;
3262
- let grandChild22;
3263
- let grandChild23;
3264
- let greatGrandChild211;
3265
-
3266
- function logger(event) {
3267
- log += `${event.currentScope.id}>`;
3268
- }
3269
-
3270
- beforeEach(() => {
3271
- log = "";
3272
- child1 = $rootScope.$new();
3273
- child2 = $rootScope.$new();
3274
- child3 = $rootScope.$new();
3275
- grandChild11 = child1.$new();
3276
- grandChild21 = child2.$new();
3277
- grandChild22 = child2.$new();
3278
- grandChild23 = child2.$new();
3279
- greatGrandChild211 = grandChild21.$new();
3280
-
3281
- $rootScope.id = 0;
3282
- child1.id = 1;
3283
- child2.id = 2;
3284
- child3.id = 3;
3285
- grandChild11.id = 11;
3286
- grandChild21.id = 21;
3287
- grandChild22.id = 22;
3288
- grandChild23.id = 23;
3289
- greatGrandChild211.id = 211;
3290
-
3291
- $rootScope.$on("myEvent", logger);
3292
- child1.$on("myEvent", logger);
3293
- child2.$on("myEvent", logger);
3294
- child3.$on("myEvent", logger);
3295
- grandChild11.$on("myEvent", logger);
3296
- grandChild21.$on("myEvent", logger);
3297
- grandChild22.$on("myEvent", logger);
3298
- grandChild23.$on("myEvent", logger);
3299
- greatGrandChild211.$on("myEvent", logger);
3300
-
3301
- // R
3302
- // / | \
3303
- // 1 2 3
3304
- // / / | \
3305
- // 11 21 22 23
3306
- // |
3307
- // 211
3308
- });
3309
-
3310
- it("should broadcast an event from the root scope", () => {
3311
- $rootScope.$broadcast("myEvent");
3312
- expect(log).toBe("0>1>11>2>21>211>22>23>3>");
3313
- });
3314
-
3315
- it("should broadcast an event from a child scope", () => {
3316
- child2.$broadcast("myEvent");
3317
- expect(log).toBe("2>21>211>22>23>");
3318
- });
3319
-
3320
- it("should broadcast an event from a leaf scope with a sibling", () => {
3321
- grandChild22.$broadcast("myEvent");
3322
- expect(log).toBe("22>");
3323
- });
3324
-
3325
- it("should broadcast an event from a leaf scope without a sibling", () => {
3326
- grandChild23.$broadcast("myEvent");
3327
- expect(log).toBe("23>");
3328
- });
3329
-
3330
- it("should not not fire any listeners for other events", () => {
3331
- $rootScope.$broadcast("fooEvent");
3332
- expect(log).toBe("");
3333
- });
3334
-
3335
- it("should not descend past scopes with a $$listerCount of 0 or undefined", () => {
3336
- const EVENT = "fooEvent";
3337
- const spy = jasmine.createSpy("listener");
3338
-
3339
- // Precondition: There should be no listeners for fooEvent.
3340
- expect($rootScope.$$listenerCount[EVENT]).toBeUndefined();
3341
-
3342
- // Add a spy listener to a child scope.
3343
- $rootScope.$$childHead.$$listeners[EVENT] = [spy];
3344
-
3345
- // $rootScope's count for 'fooEvent' is undefined, so spy should not be called.
3346
- $rootScope.$broadcast(EVENT);
3347
- expect(spy).not.toHaveBeenCalled();
3348
- });
3349
-
3350
- it("should return event object", () => {
3351
- const result = child1.$broadcast("some");
3352
-
3353
- expect(result).toBeDefined();
3354
- expect(result.name).toBe("some");
3355
- expect(result.targetScope).toBe(child1);
3356
- });
3357
- });
3358
-
3359
- describe("listener", () => {
3360
- it("should receive event object", () => {
3361
- const scope = $rootScope;
3362
- const child = scope.$new();
3363
- let eventFired = false;
3364
-
3365
- child.$on("fooEvent", (event) => {
3366
- eventFired = true;
3367
- expect(event.name).toBe("fooEvent");
3368
- expect(event.targetScope).toBe(scope);
3369
- expect(event.currentScope).toBe(child);
3370
- });
3371
- scope.$broadcast("fooEvent");
3372
-
3373
- expect(eventFired).toBe(true);
3374
- });
3375
-
3376
- it("should have the event's `currentScope` property set to null after broadcast", () => {
3377
- const scope = $rootScope;
3378
- const child = scope.$new();
3379
- let event;
3380
-
3381
- child.$on("fooEvent", (e) => {
3382
- event = e;
3383
- });
3384
- scope.$broadcast("fooEvent");
3385
-
3386
- expect(event.name).toBe("fooEvent");
3387
- expect(event.targetScope).toBe(scope);
3388
- expect(event.currentScope).toBe(null);
3389
- });
3390
-
3391
- it("should support passing messages as constargs", () => {
3392
- const scope = $rootScope;
3393
- const child = scope.$new();
3394
- let args;
3395
-
3396
- child.$on("fooEvent", function () {
3397
- args = arguments;
3398
- });
3399
- scope.$broadcast("fooEvent", "do", "re", "me", "fa");
3400
-
3401
- expect(args.length).toBe(5);
3402
- expect(sliceArgs(args, 1)).toEqual(["do", "re", "me", "fa"]);
3403
- });
3404
- });
3405
- });
3406
-
3407
- it("should allow recursive $emit/$broadcast", () => {
3408
- let callCount = 0;
3409
- $rootScope.$on("evt", ($event, arg0) => {
3410
- callCount++;
3411
- if (arg0 !== 1234) {
3412
- $rootScope.$emit("evt", 1234);
3413
- $rootScope.$broadcast("evt", 1234);
3414
- }
3415
- });
3416
-
3417
- $rootScope.$emit("evt");
3418
- $rootScope.$broadcast("evt");
3419
- expect(callCount).toBe(6);
3420
- });
3421
-
3422
- it("should allow recursive $emit/$broadcast between parent/child", () => {
3423
- const child = $rootScope.$new();
3424
- let calls = "";
3425
-
3426
- $rootScope.$on("evt", ($event, arg0) => {
3427
- calls += "r"; // For "root".
3428
- if (arg0 === "fromChild") {
3429
- $rootScope.$broadcast("evt", "fromRoot2");
3430
- }
3431
- });
3432
-
3433
- child.$on("evt", ($event, arg0) => {
3434
- calls += "c"; // For "child".
3435
- if (arg0 === "fromRoot1") {
3436
- child.$emit("evt", "fromChild");
3437
- }
3438
- });
3439
-
3440
- $rootScope.$broadcast("evt", "fromRoot1");
3441
- expect(calls).toBe("rccrrc");
3442
- });
3443
- });
3444
-
3445
- describe("doc examples", () => {
3446
- it("should properly fire off watch listeners upon scope changes", () => {
3447
- // <docs tag="docs1">
3448
- const scope = $rootScope.$new();
3449
- scope.salutation = "Hello";
3450
- scope.name = "World";
3451
-
3452
- expect(scope.greeting).toEqual(undefined);
3453
-
3454
- scope.$watch("name", () => {
3455
- scope.greeting = `${scope.salutation} ${scope.name}!`;
3456
- }); // initialize the watch
3457
-
3458
- expect(scope.greeting).toEqual(undefined);
3459
- scope.name = "Misko";
3460
- // still old value, since watches have not been called yet
3461
- expect(scope.greeting).toEqual(undefined);
3462
-
3463
- scope.$digest(); // fire all the watches
3464
- expect(scope.greeting).toEqual("Hello Misko!");
3465
- // </docs>
3466
- });
3467
- });
3468
1533
  });