Skip to content

Commit 2951b77

Browse files
committed
Additional options tests
1 parent 2d79681 commit 2951b77

File tree

4 files changed

+95
-78
lines changed

4 files changed

+95
-78
lines changed

index.html

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,20 @@
6565
});
6666
</script>
6767
</head>
68-
<body
69-
ng-app="todo"
70-
ng-init='values = [{ name: "A" }, { name: "B" }, { name: "C" }]'
71-
>
72-
<select
73-
ng-model="selected"
74-
ng-options="value.name for value in values"
75-
></select>
76-
{{ selected.name }}
77-
<select
78-
ng-model="selected"
79-
ng-options="value.name for value in values"
80-
></select>
81-
<button ng-click="selected = values[1]">click</button>
68+
<body ng-app="todo">
69+
<div ng-controller="TodoCtrl as $ctrl">
70+
<h3>Todos</h3>
71+
<button ng-click="$ctrl.archive()">Archive</button>
72+
<ul>
73+
<li ng-repeat="todo in $ctrl.tasks">
74+
{{ todo.task }} {{ todo.done }}
75+
<input type="checkbox" ng-click="todo.done = !todo.done" />
76+
</li>
77+
</ul>
78+
<form ng-submit="$ctrl.add(newTodo)">
79+
<input type="text" ng-model="newTodo" ng-required="true" />
80+
<button type="submit">Add</button>
81+
</form>
82+
</div>
8283
</body>
8384
</html>

src/directive/options/options-example.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
<meta charset="utf-8" />
55
<title>AngularTS</title>
66
<link rel="shortcut icon" type="image/png" href="images/favicon.ico" />
7-
<script
8-
type="module"
9-
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js"
10-
></script>
7+
<script type="module" src="/src/index.js"></script>
118
</head>
129
<body ng-app>
1310
<section ng-init='values = [{ name: "A" }, { name: "B" }, { name: "C" }]'>
@@ -31,5 +28,12 @@
3128
<button ng-click="selected1 = values1[1]">Select Y</button>
3229
<button ng-click="selected1 = values1[2]">Select Z</button>
3330
</section>
31+
32+
<section ng-init="values2 = []">
33+
<select ng-model="selected2" ng-options="value.name for value in values2">
34+
<option value="">blank</option>
35+
</select>
36+
<button ng-click='values2 = [{ name: "A" }]'>Add A</button>
37+
</section>
3438
</body>
3539
</html>

src/directive/options/options.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,10 @@ export const ngOptionsDirective = [
381381
// compile the element since there might be bindings in it
382382
const linkFn = $compile(selectCtrl.emptyOption);
383383
assertArg(linkFn, "LinkFn required");
384-
linkFn(scope);
385-
386384
selectElement.prepend(selectCtrl.emptyOption);
385+
linkFn(scope);
387386

388-
if (selectCtrl.emptyOption[0].nodeType === Node.COMMENT_NODE) {
387+
if (selectCtrl.emptyOption.nodeType === Node.COMMENT_NODE) {
389388
// This means the empty option has currently no actual DOM node, probably because
390389
// it has been modified by a transclusion directive.
391390
selectCtrl.hasEmptyOption = false;

src/directive/options/options.spec.js

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ describe("ngOptions", () => {
165165
.module("myModule", ["ng"])
166166
.decorator("$exceptionHandler", function () {
167167
return (exception) => {
168+
console.error(exception.message);
168169
errors.push(exception.message);
169170
};
170171
});
@@ -543,88 +544,82 @@ describe("ngOptions", () => {
543544
expect(element.querySelectorAll("option").length).toEqual(1); // we add back the special empty option
544545
});
545546

546-
it("should shrink and then grow list", () => {
547+
fit("should shrink and then grow list", async () => {
547548
element.innerHTML =
548549
'<select ng-model="selected" ng-options="value.name for value in values"></select>';
549550
injector = window.angular.bootstrap(element, ["myModule"]);
550551
scope = injector.get("$rootScope");
551-
552-
scope.$apply(() => {
553-
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
554-
scope.selected = scope.values[0];
555-
});
556-
552+
await wait();
553+
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
554+
await wait();
555+
scope.selected = scope.values[0];
556+
await wait();
557557
expect(element.querySelectorAll("option").length).toEqual(3);
558558

559-
scope.$apply(() => {
560-
scope.values = [{ name: "1" }, { name: "2" }];
561-
scope.selected = scope.values[0];
562-
});
563-
559+
scope.values = [{ name: "1" }, { name: "2" }];
560+
await wait();
561+
scope.selected = scope.values[0];
562+
await wait();
564563
expect(element.querySelectorAll("option").length).toEqual(2);
565564

566-
scope.$apply(() => {
567-
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
568-
scope.selected = scope.values[0];
569-
});
570-
565+
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
566+
await wait();
567+
scope.selected = scope.values[0];
568+
await wait();
571569
expect(element.querySelectorAll("option").length).toEqual(3);
572570
});
573571

574-
it("should update list", () => {
572+
fit("should update list", async () => {
575573
element.innerHTML =
576574
'<select ng-model="selected" ng-options="value.name for value in values"></select>';
577575
injector = window.angular.bootstrap(element, ["myModule"]);
578576
scope = injector.get("$rootScope");
579577

580-
scope.$apply(() => {
581-
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
582-
scope.selected = scope.values[0];
583-
});
584-
585-
scope.$apply(() => {
586-
scope.values = [{ name: "B" }, { name: "C" }, { name: "D" }];
587-
scope.selected = scope.values[0];
588-
});
589-
578+
scope.values = [{ name: "A" }, { name: "B" }, { name: "C" }];
579+
await wait();
580+
scope.selected = scope.values[0];
581+
await wait();
582+
scope.values = [{ name: "B" }, { name: "C" }, { name: "D" }];
583+
await wait();
584+
scope.selected = scope.values[0];
585+
await wait();
590586
const options = element.querySelectorAll("option");
591587
expect(options.length).toEqual(3);
592588
expect(options[0]).toEqualOption(scope.values[0], "B");
593589
expect(options[1]).toEqualOption(scope.values[1], "C");
594590
expect(options[2]).toEqualOption(scope.values[2], "D");
595591
});
596592

597-
it("should preserve pre-existing empty option", () => {
598-
createSingleSelect(true);
599-
600-
scope.$apply(() => {
601-
scope.values = [];
602-
});
593+
fit("should preserve pre-existing empty option", async () => {
594+
element.innerHTML =
595+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
596+
injector = window.angular.bootstrap(element, ["myModule"]);
597+
scope = injector.get("$rootScope");
598+
await wait();
599+
scope.values = [];
600+
await wait();
603601
expect(element.querySelectorAll("option").length).toEqual(1);
604-
605-
scope.$apply(() => {
606-
scope.values = [{ name: "A" }];
607-
scope.selected = scope.values[0];
608-
});
609-
602+
scope.values = [{ name: "A" }];
603+
await wait();
604+
scope.selected = scope.values[0];
605+
await wait();
610606
expect(element.querySelectorAll("option").length).toEqual(2);
611607
expect(element.querySelectorAll("option")[0].textContent).toEqual("blank");
612608
expect(element.querySelectorAll("option")[1].textContent).toEqual("A");
613609

614-
scope.$apply(() => {
615-
scope.values = [];
616-
scope.selected = null;
617-
});
618-
610+
scope.values = [];
611+
await wait();
612+
scope.selected = null;
613+
await wait();
619614
expect(element.querySelectorAll("option").length).toEqual(1);
620615
expect(element.querySelectorAll("option")[0].textContent).toEqual("blank");
621616
});
622617

623-
it("should ignore $ and $$ properties", () => {
624-
createSelect({
625-
"ng-options": "key as value for (key, value) in object",
626-
"ng-model": "selected",
627-
});
618+
fit("should ignore $ and $$ properties", async () => {
619+
element.innerHTML =
620+
'<select ng-model="selected" ng-options="key as value for (key, value) in object"></select>';
621+
injector = window.angular.bootstrap(element, ["myModule"]);
622+
scope = injector.get("$rootScope");
628623

629624
scope.$apply(() => {
630625
scope.object = {
@@ -634,7 +629,7 @@ describe("ngOptions", () => {
634629
};
635630
scope.selected = "regularProperty";
636631
});
637-
632+
await wait();
638633
const options = element.querySelectorAll("option");
639634
expect(options.length).toEqual(1);
640635
expect(options[0]).toEqualOption("regularProperty", "visible");
@@ -2233,7 +2228,10 @@ describe("ngOptions", () => {
22332228
});
22342229

22352230
it("should select the provided empty option if bound to null", () => {
2236-
createSingleSelect(true);
2231+
element.innerHTML =
2232+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2233+
injector = window.angular.bootstrap(element, ["myModule"]);
2234+
scope = injector.get("$rootScope");
22372235

22382236
scope.$apply(() => {
22392237
scope.values = [{ name: "A" }];
@@ -2254,7 +2252,10 @@ describe("ngOptions", () => {
22542252
});
22552253

22562254
it("should reuse blank option if bound to null", () => {
2257-
createSingleSelect(true);
2255+
element.innerHTML =
2256+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2257+
injector = window.angular.bootstrap(element, ["myModule"]);
2258+
scope = injector.get("$rootScope");
22582259

22592260
scope.$apply(() => {
22602261
scope.values = [{ name: "A" }];
@@ -2326,7 +2327,10 @@ describe("ngOptions", () => {
23262327
() => {
23272328
scope.selected = "C";
23282329
scope.values = [{ name: "A" }, { name: "B" }];
2329-
createSingleSelect(true);
2330+
element.innerHTML =
2331+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2332+
injector = window.angular.bootstrap(element, ["myModule"]);
2333+
scope = injector.get("$rootScope");
23302334

23312335
expect(element.value).toBe("?");
23322336
expect(element.length).toBe(4);
@@ -2363,7 +2367,10 @@ describe("ngOptions", () => {
23632367
it("should remove unknown option when empty option exists and model is undefined", () => {
23642368
scope.selected = "C";
23652369
scope.values = [{ name: "A" }, { name: "B" }];
2366-
createSingleSelect(true);
2370+
element.innerHTML =
2371+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2372+
injector = window.angular.bootstrap(element, ["myModule"]);
2373+
scope = injector.get("$rootScope");
23672374

23682375
expect(element.value).toBe("?");
23692376

@@ -2620,7 +2627,10 @@ describe("ngOptions", () => {
26202627
scope.$apply(() => {
26212628
scope.values = [{ name: "A" }];
26222629
});
2623-
createSingleSelect(true);
2630+
element.innerHTML =
2631+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2632+
injector = window.angular.bootstrap(element, ["myModule"]);
2633+
scope = injector.get("$rootScope");
26242634
// ensure the first option (the blank option) is selected
26252635
expect(element.selectedIndex).toEqual(0);
26262636
// ensure the option has not changed following the digest
@@ -2818,7 +2828,10 @@ describe("ngOptions", () => {
28182828
});
28192829

28202830
it("should update model to null on change", () => {
2821-
createSingleSelect(true);
2831+
element.innerHTML =
2832+
'<select ng-model="selected" ng-options="value.name for value in values"><option value="">blank</option></select>';
2833+
injector = window.angular.bootstrap(element, ["myModule"]);
2834+
scope = injector.get("$rootScope");
28222835

28232836
scope.$apply(() => {
28242837
scope.values = [{ name: "A" }, { name: "B" }];

0 commit comments

Comments
 (0)