@angular-wave/angular.ts 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular-ts.esm.js +1 -1
- package/dist/angular-ts.umd.js +1 -1
- package/package.json +1 -1
- package/src/loader.js +1 -1
- package/src/router/stateProvider.js +1 -2
- package/test/router/state.spec.js +534 -455
- package/types/index.d.ts +1 -1
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import { dealoc } from "../../src/jqLite";
|
|
1
|
+
import { dealoc, jqLite } from "../../src/jqLite";
|
|
2
2
|
import { Angular } from "../../src/loader";
|
|
3
3
|
import { publishExternalAPI } from "../../src/public";
|
|
4
4
|
import { isFunction } from "../../src/shared/utils";
|
|
5
|
+
import { wait } from "../test-utils";
|
|
5
6
|
|
|
6
7
|
describe("$state", () => {
|
|
7
|
-
let $
|
|
8
|
-
$injector,
|
|
9
|
-
locationProvider,
|
|
10
|
-
templateParams,
|
|
11
|
-
template,
|
|
12
|
-
ctrlName,
|
|
13
|
-
errors,
|
|
14
|
-
$provide,
|
|
15
|
-
$compile,
|
|
16
|
-
module;
|
|
8
|
+
let $router, $injector, template, ctrlName, $provide, $compile, module;
|
|
17
9
|
|
|
18
10
|
/** @type {import("../../src/router/stateProvider").StateProvider} */
|
|
19
11
|
let $stateProvider;
|
|
@@ -102,20 +94,23 @@ describe("$state", () => {
|
|
|
102
94
|
};
|
|
103
95
|
}
|
|
104
96
|
|
|
105
|
-
window.angular = new Angular();
|
|
106
|
-
publishExternalAPI();
|
|
107
|
-
|
|
108
97
|
afterEach(() => {
|
|
109
98
|
dealoc(document.getElementById("dummy"));
|
|
110
99
|
});
|
|
111
100
|
|
|
112
101
|
describe("provider", () => {
|
|
113
102
|
beforeEach(() => {
|
|
103
|
+
dealoc(document.getElementById("dummy"));
|
|
104
|
+
jqLite.CACHE.clear(); // some tests are polluting the cache
|
|
105
|
+
window.angular = new Angular();
|
|
106
|
+
publishExternalAPI();
|
|
114
107
|
module = window.angular.module("defaultModule", ["ui.router"]);
|
|
115
108
|
module.config((_$stateProvider_, _$provide_) => {
|
|
116
109
|
$stateProvider = _$stateProvider_;
|
|
117
110
|
});
|
|
118
|
-
angular.bootstrap(document.getElementById("dummy"), [
|
|
111
|
+
window.angular.bootstrap(document.getElementById("dummy"), [
|
|
112
|
+
"defaultModule",
|
|
113
|
+
]);
|
|
119
114
|
});
|
|
120
115
|
|
|
121
116
|
afterEach(() => {
|
|
@@ -155,6 +150,9 @@ describe("$state", () => {
|
|
|
155
150
|
let $rootScope, $state, $stateParams, $transitions, $q, $location;
|
|
156
151
|
|
|
157
152
|
beforeEach(() => {
|
|
153
|
+
dealoc(document.getElementById("dummy"));
|
|
154
|
+
window.angular = new Angular();
|
|
155
|
+
publishExternalAPI();
|
|
158
156
|
module = window.angular.module("defaultModule", ["ui.router"]);
|
|
159
157
|
module.config((_$stateProvider_, _$provide_) => {
|
|
160
158
|
$stateProvider = _$stateProvider_;
|
|
@@ -313,7 +311,8 @@ describe("$state", () => {
|
|
|
313
311
|
|
|
314
312
|
$provide.value("AppInjectable", AppInjectable);
|
|
315
313
|
});
|
|
316
|
-
|
|
314
|
+
|
|
315
|
+
$injector = window.angular.bootstrap(document.getElementById("dummy"), [
|
|
317
316
|
"defaultModule",
|
|
318
317
|
]);
|
|
319
318
|
|
|
@@ -326,6 +325,7 @@ describe("$state", () => {
|
|
|
326
325
|
_$q_,
|
|
327
326
|
_$location_,
|
|
328
327
|
_$compile_,
|
|
328
|
+
_$router_,
|
|
329
329
|
) => {
|
|
330
330
|
$rootScope = _$rootScope_;
|
|
331
331
|
$state = _$state_;
|
|
@@ -334,10 +334,15 @@ describe("$state", () => {
|
|
|
334
334
|
$q = _$q_;
|
|
335
335
|
$location = _$location_;
|
|
336
336
|
$compile = _$compile_;
|
|
337
|
+
$router = _$router_;
|
|
337
338
|
},
|
|
338
339
|
);
|
|
339
340
|
});
|
|
340
341
|
|
|
342
|
+
afterEach(() => {
|
|
343
|
+
dealoc(document.getElementById("dummy"));
|
|
344
|
+
});
|
|
345
|
+
|
|
341
346
|
it("returns a promise for the target state", () => {
|
|
342
347
|
const promise = $state.transitionTo(A, {});
|
|
343
348
|
expect(isFunction(promise.then)).toBeTruthy();
|
|
@@ -449,10 +454,18 @@ describe("$state", () => {
|
|
|
449
454
|
search: "s1",
|
|
450
455
|
searchDyn: "sd1",
|
|
451
456
|
});
|
|
452
|
-
expect(dynlog
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
457
|
+
expect(dynlog.endsWith("enter:dyn;success;")).toBeTrue();
|
|
458
|
+
Object.entries({
|
|
459
|
+
path: "p1",
|
|
460
|
+
pathDyn: "pd1",
|
|
461
|
+
search: "s1",
|
|
462
|
+
searchDyn: "sd1",
|
|
463
|
+
}).forEach(([k, v]) => {
|
|
464
|
+
expect($stateParams[k]).toEqual(v);
|
|
465
|
+
});
|
|
466
|
+
expect($location.url()).toEqual(
|
|
467
|
+
"/dynstate/p1/pd1?search=s1&searchDyn=sd1",
|
|
468
|
+
);
|
|
456
469
|
});
|
|
457
470
|
|
|
458
471
|
describe("[ transition.dynamic() ]:", function () {
|
|
@@ -466,7 +479,7 @@ describe("$state", () => {
|
|
|
466
479
|
expect(promise.transition.dynamic()).toBeFalsy();
|
|
467
480
|
});
|
|
468
481
|
|
|
469
|
-
it("is not considered fully dynamic if any state is exited", async
|
|
482
|
+
it("is not considered fully dynamic if any state is exited", async () => {
|
|
470
483
|
await initStateTo(childWithParam, {
|
|
471
484
|
config: "p1",
|
|
472
485
|
path: "p1",
|
|
@@ -489,443 +502,509 @@ describe("$state", () => {
|
|
|
489
502
|
});
|
|
490
503
|
});
|
|
491
504
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
505
|
+
describe("[ promises ]", function () {
|
|
506
|
+
beforeEach(() => (dynlog = ""));
|
|
507
|
+
it("runs successful transition when fully dynamic", async () => {
|
|
508
|
+
let transSuccess,
|
|
509
|
+
promise = $state.go(dynamicstate, { searchDyn: "sd2" }),
|
|
510
|
+
transition = promise.transition;
|
|
511
|
+
transition.promise.then(function (result) {
|
|
512
|
+
transSuccess = true;
|
|
513
|
+
});
|
|
514
|
+
await promise;
|
|
515
|
+
expect(transition.dynamic()).toBeTruthy();
|
|
516
|
+
expect(transSuccess).toBeTruthy();
|
|
517
|
+
expect(dynlog).toBe("success;[searchDyn=sd2];");
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
it("resolves the $state.go() promise with the original/final state, when fully dynamic", async () => {
|
|
521
|
+
initStateTo(dynamicstate, {
|
|
522
|
+
path: "p1",
|
|
523
|
+
pathDyn: "pd1",
|
|
524
|
+
search: "s1",
|
|
525
|
+
searchDyn: "sd1",
|
|
526
|
+
});
|
|
527
|
+
let destState,
|
|
528
|
+
promise = $state.go(dynamicstate, {
|
|
529
|
+
pathDyn: "pd2",
|
|
530
|
+
searchDyn: "sd2",
|
|
531
|
+
});
|
|
532
|
+
promise.then(function (result) {
|
|
533
|
+
destState = result;
|
|
534
|
+
});
|
|
535
|
+
await promise;
|
|
536
|
+
expect(promise.transition.dynamic()).toBeTruthy();
|
|
537
|
+
expect($state.current).toBe(dynamicstate);
|
|
538
|
+
expect(destState).toBe(dynamicstate);
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
describe("[ enter/exit ]", function () {
|
|
543
|
+
beforeEach(() => (dynlog = ""));
|
|
544
|
+
it("does not exit nor enter any states when fully dynamic", async () => {
|
|
545
|
+
const promise = $state.go(dynamicstate, { searchDyn: "sd2" });
|
|
546
|
+
await promise;
|
|
547
|
+
expect(promise.transition.dynamic()).toBeTruthy();
|
|
548
|
+
expect(promise.transition.treeChanges().entering.length).toBe(0);
|
|
549
|
+
expect(promise.transition.treeChanges().exiting.length).toBe(0);
|
|
550
|
+
expect(promise.transition.treeChanges().retained.length).toBe(2);
|
|
551
|
+
expect(dynlog).toBe("success;[searchDyn=sd2];");
|
|
552
|
+
Object.entries({
|
|
553
|
+
path: "p1",
|
|
554
|
+
pathDyn: "pd1",
|
|
555
|
+
search: "s1",
|
|
556
|
+
searchDyn: "sd2",
|
|
557
|
+
}).forEach(([k, v]) => {
|
|
558
|
+
expect($stateParams[k]).toEqual(v);
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it("does not exit nor enter the state when only dynamic search params change", async () => {
|
|
563
|
+
const promise = $state.go(dynamicstate, { searchDyn: "sd2" });
|
|
564
|
+
await promise;
|
|
565
|
+
expect(promise.transition.dynamic()).toBeTruthy();
|
|
566
|
+
expect(dynlog).toBe("success;[searchDyn=sd2];");
|
|
567
|
+
Object.entries({
|
|
568
|
+
path: "p1",
|
|
569
|
+
pathDyn: "pd1",
|
|
570
|
+
search: "s1",
|
|
571
|
+
searchDyn: "sd2",
|
|
572
|
+
}).forEach(([k, v]) => {
|
|
573
|
+
expect($stateParams[k]).toEqual(v);
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it("does not exit nor enter the state when only dynamic path params change", async () => {
|
|
578
|
+
const promise = $state.go(dynamicstate, { pathDyn: "pd2" });
|
|
579
|
+
await promise;
|
|
580
|
+
expect(promise.transition.dynamic()).toBeTruthy();
|
|
581
|
+
expect(dynlog).toBe("success;[pathDyn=pd2];");
|
|
582
|
+
Object.entries({
|
|
583
|
+
path: "p1",
|
|
584
|
+
pathDyn: "pd2",
|
|
585
|
+
search: "s1",
|
|
586
|
+
searchDyn: "sd1",
|
|
587
|
+
}).forEach(([k, v]) => {
|
|
588
|
+
expect($stateParams[k]).toEqual(v);
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
it("exits and enters a state when a non-dynamic search param changes", async () => {
|
|
593
|
+
const promise = $state.go(dynamicstate, { search: "s2" });
|
|
594
|
+
await promise;
|
|
595
|
+
expect(promise.transition.dynamic()).toBeFalsy();
|
|
596
|
+
expect(dynlog).toBe("exit:dyn;enter:dyn;success;");
|
|
597
|
+
Object.entries({
|
|
598
|
+
path: "p1",
|
|
599
|
+
pathDyn: "pd1",
|
|
600
|
+
search: "s2",
|
|
601
|
+
searchDyn: "sd1",
|
|
602
|
+
}).forEach(([k, v]) => {
|
|
603
|
+
expect($stateParams[k]).toEqual(v);
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it("exits and enters a state when a non-dynamic path param changes", async () => {
|
|
608
|
+
const promise = $state.go(dynamicstate, { path: "p2" });
|
|
609
|
+
await promise;
|
|
610
|
+
expect(promise.transition.dynamic()).toBeFalsy();
|
|
611
|
+
expect(dynlog).toBe("exit:dyn;enter:dyn;success;");
|
|
612
|
+
Object.entries({
|
|
613
|
+
path: "p2",
|
|
614
|
+
pathDyn: "pd1",
|
|
615
|
+
search: "s1",
|
|
616
|
+
searchDyn: "sd1",
|
|
617
|
+
}).forEach(([k, v]) => {
|
|
618
|
+
expect($stateParams[k]).toEqual(v);
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
it("does not exit nor enter a state when only dynamic params change (triggered via url)", async () => {
|
|
623
|
+
$location.search({ search: "s1", searchDyn: "sd2" });
|
|
624
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
625
|
+
await wait(10);
|
|
626
|
+
expect(dynlog).toBe("success;[searchDyn=sd2];");
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
it("exits and enters a state when any non-dynamic params change (triggered via url)", async () => {
|
|
630
|
+
$location.search({ search: "s2", searchDyn: "sd2" });
|
|
631
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
632
|
+
await wait(10);
|
|
633
|
+
expect(dynlog).toBe("exit:dyn;enter:dyn;success;");
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it("does not exit nor enter a state when only dynamic params change (triggered via $state transition)", async () => {
|
|
637
|
+
await $state.go(".", { searchDyn: "sd2" }, { inherit: true });
|
|
638
|
+
expect(dynlog).toBe("success;[searchDyn=sd2];");
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
describe("[ global $stateParams service ]", function () {
|
|
643
|
+
it("updates the global $stateParams object", async () => {
|
|
644
|
+
await $state.go(dynamicstate, { searchDyn: "sd2" });
|
|
645
|
+
|
|
646
|
+
Object.entries({
|
|
647
|
+
path: "p1",
|
|
648
|
+
pathDyn: "pd1",
|
|
649
|
+
search: "s1",
|
|
650
|
+
searchDyn: "sd2",
|
|
651
|
+
}).forEach(([k, v]) => {
|
|
652
|
+
expect($stateParams[k]).toEqual(v);
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
it("updates $stateParams and $location.search when only dynamic params change (triggered via url)", async () => {
|
|
657
|
+
$location.search({ search: "s1", searchDyn: "sd2" });
|
|
658
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
659
|
+
await wait(10);
|
|
660
|
+
expect($stateParams.search).toBe("s1");
|
|
661
|
+
expect($stateParams.searchDyn).toBe("sd2");
|
|
662
|
+
expect($location.search()).toEqual({
|
|
663
|
+
search: "s1",
|
|
664
|
+
searchDyn: "sd2",
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it("updates $stateParams and $location.search when only dynamic params change (triggered via $state transition)", async () => {
|
|
669
|
+
await $state.go(".", { searchDyn: "sd2" });
|
|
670
|
+
expect($stateParams.search).toBe("s1");
|
|
671
|
+
expect($stateParams.searchDyn).toBe("sd2");
|
|
672
|
+
expect($location.search()).toEqual({
|
|
673
|
+
search: "s1",
|
|
674
|
+
searchDyn: "sd2",
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
it("dynamic param changes can be observed by watching the global $stateParams", async () => {
|
|
679
|
+
let observedParamValue;
|
|
680
|
+
function stateParamsTerm() {
|
|
681
|
+
return $stateParams.searchDyn;
|
|
682
|
+
}
|
|
683
|
+
$rootScope.$watch(stateParamsTerm, function (newval, oldval) {
|
|
684
|
+
observedParamValue = newval;
|
|
685
|
+
});
|
|
686
|
+
await wait(10);
|
|
687
|
+
|
|
688
|
+
$location.search({ search: "s1", searchDyn: "sd2" });
|
|
689
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
690
|
+
await wait(10);
|
|
691
|
+
|
|
692
|
+
expect(observedParamValue).toBe("sd2");
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
describe("[ uiOnParamsChanged ]", function () {
|
|
697
|
+
beforeEach(() => (dynlog = ""));
|
|
698
|
+
it("should be called when dynamic parameter values change", async () => {
|
|
699
|
+
await $state.go(".", { searchDyn: "sd2" });
|
|
700
|
+
|
|
701
|
+
expect(paramsChangedLog).toBe("searchDyn;");
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it("should not be called if a non-dynamic parameter changes (causing the controller's state to exit/enter)", async () => {
|
|
705
|
+
await $state.go(".", { search: "s2", searchDyn: "sd2" });
|
|
706
|
+
|
|
707
|
+
expect(paramsChangedLog).toBe("");
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
it("should not be called, when entering a new state, if no parameter values change", async () => {
|
|
711
|
+
await $state.go(childNoParam);
|
|
712
|
+
|
|
713
|
+
expect(paramsChangedLog).toBe("");
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it("should be called, when entering a new state, if any dynamic parameter value changed", async () => {
|
|
717
|
+
await $state.go(childNoParam, { searchDyn: "sd2" });
|
|
718
|
+
|
|
719
|
+
expect(paramsChangedLog).toBe("searchDyn;");
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it("should be called, when entering a new state, if a new parameter value is added", async () => {
|
|
723
|
+
await $state.go(childWithParam, { config: "c2" });
|
|
724
|
+
|
|
725
|
+
expect(paramsChangedLog).toBe("config,configDyn;");
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
it("should be called, when reactivating the uiOnParamsChanged state, if a dynamic parameter changed", async () => {
|
|
729
|
+
await initStateTo(childNoParam, {
|
|
730
|
+
path: "p1",
|
|
731
|
+
pathDyn: "pd1",
|
|
732
|
+
search: "s1",
|
|
733
|
+
searchDyn: "sd1",
|
|
734
|
+
});
|
|
735
|
+
dynlog = paramsChangedLog = "";
|
|
736
|
+
|
|
737
|
+
await $state.go(dynamicstate, { pathDyn: "pd2" });
|
|
738
|
+
|
|
739
|
+
expect(paramsChangedLog).toBe("pathDyn;");
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it('should not be called, when reactivating the uiOnParamsChanged state "dyn", if any of dyns non-dynamic parameters changed', async () => {
|
|
743
|
+
await initStateTo(childNoParam, {
|
|
744
|
+
path: "p1",
|
|
745
|
+
pathDyn: "pd1",
|
|
746
|
+
search: "s1",
|
|
747
|
+
searchDyn: "sd1",
|
|
748
|
+
});
|
|
749
|
+
dynlog = paramsChangedLog = "";
|
|
750
|
+
|
|
751
|
+
await $state.go(dynamicstate, { path: "p2" });
|
|
752
|
+
|
|
753
|
+
expect(paramsChangedLog).toBe("");
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
it("should be called with an object containing only the changed params", async () => {
|
|
757
|
+
await $state.go(dynamicstate, { pathDyn: "pd2" });
|
|
758
|
+
|
|
759
|
+
expect(dynlog).toBe("success;[pathDyn=pd2];");
|
|
760
|
+
|
|
761
|
+
await $state.go(dynamicstate, { pathDyn: "pd3", searchDyn: "sd2" });
|
|
762
|
+
|
|
763
|
+
expect(dynlog).toBe(
|
|
764
|
+
"success;[pathDyn=pd2];success;[pathDyn=pd3,searchDyn=sd2];",
|
|
765
|
+
);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
it("should be called on all active controllers that have a uiOnParamsChanged", async () => {
|
|
769
|
+
await initStateTo(childWithParam, {
|
|
770
|
+
path: "p1",
|
|
771
|
+
pathDyn: "pd1",
|
|
772
|
+
search: "s1",
|
|
773
|
+
searchDyn: "sd1",
|
|
774
|
+
config: "p1",
|
|
775
|
+
configDyn: "c1",
|
|
776
|
+
});
|
|
777
|
+
dynlog = paramsChangedLog = "";
|
|
778
|
+
|
|
779
|
+
await $state.go(childWithParam, { pathDyn: "pd2" });
|
|
780
|
+
|
|
781
|
+
expect(dynlog).toBe("success;[pathDyn=pd2];{pathDyn=pd2};");
|
|
782
|
+
|
|
783
|
+
dynlog = paramsChangedLog = "";
|
|
784
|
+
await $state.go(childWithParam, {
|
|
785
|
+
pathDyn: "pd2",
|
|
786
|
+
searchDyn: "sd2",
|
|
787
|
+
configDyn: "cd2",
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
expect(dynlog).toBe(
|
|
791
|
+
"success;[configDyn=cd2,searchDyn=sd2];{configDyn=cd2,searchDyn=sd2};",
|
|
792
|
+
);
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
describe("(with dynamic params because reloadOnSearch=false)", function () {
|
|
798
|
+
describe("and only query params changed", () => {
|
|
799
|
+
let entered = false;
|
|
800
|
+
beforeEach(async () => {
|
|
801
|
+
await initStateTo(RS);
|
|
802
|
+
$transitions.onEnter({ entering: "RS" }, function () {
|
|
803
|
+
entered = true;
|
|
804
|
+
});
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// this passes in isolation
|
|
808
|
+
xit("updates $stateParams", async () => {
|
|
809
|
+
await initStateTo(RS);
|
|
810
|
+
$location.search({ term: "hello" });
|
|
811
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
812
|
+
await wait(10);
|
|
813
|
+
expect($stateParams.term).toEqual("hello");
|
|
814
|
+
expect(entered).toBeFalsy();
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
it("doesn't re-enter state (triggered by url change)", async () => {
|
|
818
|
+
$location.search({ term: "hello" });
|
|
819
|
+
$rootScope.$broadcast("$locationChangeSuccess");
|
|
820
|
+
|
|
821
|
+
expect($location.search()).toEqual({ term: "hello" });
|
|
822
|
+
expect(entered).toBeFalsy();
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
it("doesn't re-enter state (triggered by $state transition)", async () => {
|
|
826
|
+
await initStateTo(RS);
|
|
827
|
+
const promise = $state.go(".", { term: "hello" });
|
|
828
|
+
await promise;
|
|
829
|
+
let success = false,
|
|
830
|
+
transition = promise.transition;
|
|
831
|
+
await transition.promise.then(async () => {
|
|
832
|
+
success = true;
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
expect($state.current).toBe(RS);
|
|
836
|
+
expect(entered).toBeFalsy();
|
|
837
|
+
expect(success).toBeTruthy();
|
|
838
|
+
expect($location.search()).toEqual({ term: "hello" });
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it("updates URL when (triggered by $state transition)", async () => {
|
|
842
|
+
await initStateTo(RS);
|
|
843
|
+
await $state.go(".", { term: "goodbye" });
|
|
844
|
+
|
|
845
|
+
expect($stateParams.term).toEqual("goodbye");
|
|
846
|
+
expect($location.url()).toEqual("/search?term=goodbye");
|
|
847
|
+
expect(entered).toBeFalsy();
|
|
848
|
+
});
|
|
849
|
+
});
|
|
707
850
|
});
|
|
708
851
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
// }));
|
|
777
|
-
|
|
778
|
-
// it('aborts pending transitions (last call wins)', () => {
|
|
779
|
-
// initStateTo(A);
|
|
780
|
-
// logEvents = true;
|
|
781
|
-
|
|
782
|
-
// const superseded = $state.transitionTo(B, {});
|
|
783
|
-
// $state.transitionTo(C, {});
|
|
784
|
-
// $q.flush();
|
|
785
|
-
// expect($state.current).toBe(C);
|
|
786
|
-
// expect(resolvedError(superseded)).toBeTruthy();
|
|
787
|
-
// }));
|
|
788
|
-
|
|
789
|
-
// it('aborts pending transitions even when going back to the current state', () => {
|
|
790
|
-
// initStateTo(A);
|
|
791
|
-
// logEvents = true;
|
|
792
|
-
|
|
793
|
-
// const superseded = $state.transitionTo(B, {});
|
|
794
|
-
// $state.transitionTo(A, {});
|
|
795
|
-
// $q.flush();
|
|
796
|
-
// expect($state.current).toBe(A);
|
|
797
|
-
// expect(resolvedError(superseded)).toBeTruthy();
|
|
798
|
-
// }));
|
|
799
|
-
|
|
800
|
-
// it('aborts pending transitions when aborted from callbacks', () => {
|
|
801
|
-
// const superseded = $state.transitionTo('home.redirect');
|
|
802
|
-
// $q.flush();
|
|
803
|
-
// expect($state.current.name).toBe('about');
|
|
804
|
-
// }));
|
|
805
|
-
|
|
806
|
-
// it('triggers onEnter and onExit callbacks', () => {
|
|
807
|
-
// initStateTo(A);
|
|
808
|
-
// logEnterExit = true;
|
|
809
|
-
// $state.transitionTo(D, {});
|
|
810
|
-
// $q.flush();
|
|
811
|
-
// log += $state.current.name + ';';
|
|
812
|
-
// $state.transitionTo(DD, {});
|
|
813
|
-
// $q.flush();
|
|
814
|
-
// log += $state.current.name + ';';
|
|
815
|
-
// $state.transitionTo(A, {});
|
|
816
|
-
// $q.flush();
|
|
817
|
-
// expect(log).toBe(
|
|
818
|
-
// 'A.onExit;' + 'D.onEnter;' + 'D;' + 'DD.onEnter;' + 'DD;' + 'DD.onExit;' + 'D.onExit;' + 'A.onEnter;'
|
|
819
|
-
// );
|
|
820
|
-
// }));
|
|
852
|
+
it("ignores non-applicable state parameters", async () => {
|
|
853
|
+
await $state.transitionTo("A", { w00t: "hi mom!" });
|
|
854
|
+
|
|
855
|
+
expect($state.current).toBe(A);
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
it("is a no-op when passing the current state and identical parameters", async () => {
|
|
859
|
+
await initStateTo(A);
|
|
860
|
+
const promise = $state.transitionTo(A, {}); // no-op
|
|
861
|
+
expect(promise).toBeDefined(); // but we still get a valid promise
|
|
862
|
+
await promise;
|
|
863
|
+
expect(promise.$$state.value).toBe(A);
|
|
864
|
+
expect($state.current).toBe(A);
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
it("aborts pending transitions (last call wins)", async () => {
|
|
868
|
+
await initStateTo(A);
|
|
869
|
+
logEvents = true;
|
|
870
|
+
|
|
871
|
+
const superseded = $state.transitionTo(B, {});
|
|
872
|
+
await superseded;
|
|
873
|
+
await $state.transitionTo(C, {});
|
|
874
|
+
|
|
875
|
+
expect($state.current).toBe(C);
|
|
876
|
+
expect(superseded.$$state.status).toBeTruthy();
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
it("aborts pending transitions even when going back to the current state", async () => {
|
|
880
|
+
await initStateTo(A);
|
|
881
|
+
logEvents = true;
|
|
882
|
+
|
|
883
|
+
const superseded = $state.transitionTo(B, {});
|
|
884
|
+
await superseded;
|
|
885
|
+
await $state.transitionTo(A, {});
|
|
886
|
+
|
|
887
|
+
expect($state.current).toBe(A);
|
|
888
|
+
expect(superseded.$$state.status).toBeTruthy();
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
xit("aborts pending transitions when aborted from callbacks", () => {
|
|
892
|
+
$state.transitionTo("home.redirect");
|
|
893
|
+
expect($state.current.name).toBe("about");
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
it("triggers onEnter and onExit callbacks", async () => {
|
|
897
|
+
log = "";
|
|
898
|
+
await initStateTo(A);
|
|
899
|
+
logEnterExit = true;
|
|
900
|
+
await $state.transitionTo(D, {});
|
|
901
|
+
|
|
902
|
+
log += $state.current.name + ";";
|
|
903
|
+
await $state.transitionTo(DD, {});
|
|
904
|
+
|
|
905
|
+
log += $state.current.name + ";";
|
|
906
|
+
await $state.transitionTo(A, {});
|
|
907
|
+
|
|
908
|
+
expect(log).toBe(
|
|
909
|
+
"A.onExit;" +
|
|
910
|
+
"D.onEnter;" +
|
|
911
|
+
"D;" +
|
|
912
|
+
"DD.onEnter;" +
|
|
913
|
+
"DD;" +
|
|
914
|
+
"DD.onExit;" +
|
|
915
|
+
"D.onExit;" +
|
|
916
|
+
"A.onEnter;",
|
|
917
|
+
);
|
|
918
|
+
});
|
|
821
919
|
|
|
822
920
|
// // test for #3081
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
//
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
// $state.transitionTo('home.item', { id: 'world', '#': 'frag' });
|
|
913
|
-
// $q.flush();
|
|
914
|
-
// expect($location.hash()).toBe('frag');
|
|
915
|
-
// expect(transitionCount).toBe(1);
|
|
916
|
-
|
|
917
|
-
// $state.transitionTo('home.item', { id: 'world', '#': 'blarg' });
|
|
918
|
-
// $q.flush();
|
|
919
|
-
// expect($location.hash()).toBe('blarg');
|
|
920
|
-
// expect(transitionCount).toBe(2);
|
|
921
|
-
// }));
|
|
922
|
-
|
|
923
|
-
// it('injects $transition$ into resolves', () => {
|
|
924
|
-
// $state.transitionTo('home');
|
|
925
|
-
// $q.flush();
|
|
926
|
-
// $state.transitionTo('about');
|
|
927
|
-
// $q.flush();
|
|
928
|
-
// expect(log).toBe('home => about');
|
|
929
|
-
// }));
|
|
921
|
+
it("injects resolve values from the exited state into onExit", async () => {
|
|
922
|
+
const registry = $router.stateRegistry;
|
|
923
|
+
registry.register({
|
|
924
|
+
name: "design",
|
|
925
|
+
url: "/design",
|
|
926
|
+
resolve: {
|
|
927
|
+
cc: function () {
|
|
928
|
+
return "cc resolve";
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
onExit: function (cc, $state$, $transition$) {
|
|
932
|
+
expect($transition$.to().name).toBe("A");
|
|
933
|
+
expect($transition$.from().name).toBe("design");
|
|
934
|
+
|
|
935
|
+
expect($state$).toBe(registry.get("design"));
|
|
936
|
+
|
|
937
|
+
expect(cc).toBe("cc resolve");
|
|
938
|
+
},
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
await $state.go("design");
|
|
942
|
+
|
|
943
|
+
await $state.go("A");
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
it("doesn't transition to parent state when child has no URL", async () => {
|
|
947
|
+
await $state.transitionTo("about.sidebar");
|
|
948
|
+
|
|
949
|
+
expect($state.current.name).toEqual("about.sidebar");
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
it("notifies on failed relative state resolution", async () => {
|
|
953
|
+
await $state.transitionTo(DD);
|
|
954
|
+
|
|
955
|
+
let actual,
|
|
956
|
+
err = "Could not resolve '^.Z' from state 'DD'";
|
|
957
|
+
await $state
|
|
958
|
+
.transitionTo("^.Z", null, { relative: $state.$current })
|
|
959
|
+
.catch(function (err) {
|
|
960
|
+
actual = err;
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
expect(actual.detail).toEqual(err);
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
it("uses the templateProvider to get template dynamically", async () => {
|
|
967
|
+
await $state.transitionTo("dynamicTemplate", { type: "Acme" });
|
|
968
|
+
|
|
969
|
+
expect(template).toEqual("AcmeFooTemplate");
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it("uses the controllerProvider to get controller dynamically", async () => {
|
|
973
|
+
await $state.transitionTo("dynamicController", { type: "Acme" });
|
|
974
|
+
|
|
975
|
+
expect(ctrlName).toEqual("AcmeController");
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
it("updates the location #fragment", async () => {
|
|
979
|
+
await $state.transitionTo("home.item", { id: "world", "#": "frag" });
|
|
980
|
+
|
|
981
|
+
expect($location.url()).toBe("/front/world#frag");
|
|
982
|
+
expect($location.hash()).toBe("frag");
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
// passes in isolation. on success callback being polluted
|
|
986
|
+
xit("runs a transition when the location #fragment is updated", (done) => {
|
|
987
|
+
let transitionCount = 0;
|
|
988
|
+
$transitions.onSuccess({}, function () {
|
|
989
|
+
transitionCount++;
|
|
990
|
+
done();
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
$state.transitionTo("home.item", { id: "world", "#": "frag" });
|
|
994
|
+
expect($location.hash()).toBe("frag");
|
|
995
|
+
expect(transitionCount).toBeGreaterThan(0);
|
|
996
|
+
|
|
997
|
+
$state.transitionTo("home.item", { id: "world", "#": "blarg" });
|
|
998
|
+
|
|
999
|
+
expect($location.hash()).toBe("blarg");
|
|
1000
|
+
expect(transitionCount).toBeGreaterThan(1);
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
it("injects $transition$ into resolves", async () => {
|
|
1004
|
+
await $state.transitionTo("home");
|
|
1005
|
+
await $state.transitionTo("about");
|
|
1006
|
+
|
|
1007
|
+
expect(log).toBe("home => about");
|
|
1008
|
+
});
|
|
930
1009
|
});
|
|
931
1010
|
});
|