| OLD | NEW |
| 1 library ng_if_spec; | 1 library ng_if_spec; |
| 2 | 2 |
| 3 import '../_specs.dart'; | 3 import '../_specs.dart'; |
| 4 | 4 |
| 5 @Decorator( | 5 @NgDirective( |
| 6 selector: '[child-controller]', | 6 selector: '[child-controller]', |
| 7 children: Directive.TRANSCLUDE_CHILDREN) | 7 children: NgAnnotation.TRANSCLUDE_CHILDREN) |
| 8 class ChildController { | 8 class ChildController { |
| 9 ChildController(BoundViewFactory boundViewFactory, | 9 ChildController(BoundBlockFactory boundBlockFactory, |
| 10 ViewPort viewPort, | 10 BlockHole blockHole, |
| 11 Scope scope) { | 11 Scope scope) { |
| 12 scope.context['setBy'] = 'childController'; | 12 scope.context['setBy'] = 'childController'; |
| 13 viewPort.insert(boundViewFactory(scope)); | 13 boundBlockFactory(scope).insertAfter(blockHole); |
| 14 } | 14 } |
| 15 } | 15 } |
| 16 | 16 |
| 17 main() { | 17 main() { |
| 18 var compile, html, element, rootScope, logger, directives; | 18 var compile, html, element, rootScope, logger, directives; |
| 19 | 19 |
| 20 void configInjector(Module module) { | 20 void configInjector() { |
| 21 module..type(ChildController) | 21 module((Module module) { |
| 22 module |
| 23 ..type(ChildController) |
| 22 ..type(LogAttrDirective); | 24 ..type(LogAttrDirective); |
| 25 }); |
| 23 } | 26 } |
| 24 | 27 |
| 25 void configState(Scope scope, Compiler compiler, Injector injector, | 28 void configState() { |
| 26 Logger _logger, DirectiveMap _directives) { | 29 inject((Scope scope, Compiler compiler, Injector injector, Logger _logger, D
irectiveMap _directives) { |
| 27 rootScope = scope; | 30 rootScope = scope; |
| 28 logger = _logger; | 31 logger = _logger; |
| 29 compile = (html, [applyFn]) { | 32 compile = (html, [applyFn]) { |
| 30 element = e(html); | 33 element = $(html); |
| 31 compiler([element], _directives)(injector, [element]); | 34 compiler(element, _directives)(injector, element); |
| 32 scope.apply(applyFn); | 35 scope.apply(applyFn); |
| 33 }; | 36 }; |
| 34 directives = _directives; | 37 directives = _directives; |
| 38 }); |
| 35 } | 39 } |
| 36 | 40 |
| 37 they(should, htmlForElements, callback, [exclusive=false]) { | 41 they(should, htmlForElements, callback, [exclusive=false]) { |
| 38 htmlForElements.forEach((html) { | 42 htmlForElements.forEach((html) { |
| 39 var directiveName = html.contains('ng-if') ? 'ng-if' : 'ng-unless'; | 43 var directiveName = html.contains('ng-if') ? 'ng-if' : 'ng-unless'; |
| 40 describe(directiveName, () { | 44 describe(directiveName, () { |
| 41 beforeEachModule(configInjector); | 45 beforeEach(configInjector); |
| 42 beforeEach(configState); | 46 beforeEach(configState); |
| 43 (exclusive ? iit : it)(should, () { | 47 (exclusive ? iit : it)(should, () { |
| 44 callback(html); | 48 callback(html); |
| 45 }); | 49 }); |
| 46 }); | 50 }); |
| 47 }); | 51 }); |
| 48 } | 52 } |
| 49 | 53 |
| 50 they('should add/remove the element', | 54 they('should add/remove the element', |
| 51 [ '<div><span ng-if="isVisible">content</span></div>', | 55 [ '<div><span ng-if="isVisible">content</span></div>', |
| 52 '<div><span ng-unless="!isVisible">content</span></div>'], | 56 '<div><span ng-unless="!isVisible">content</span></div>'], |
| 53 (html) { | 57 (html) { |
| 54 compile(html); | 58 compile(html); |
| 55 // The span node should NOT exist in the DOM. | 59 // The span node should NOT exist in the DOM. |
| 56 expect(element.querySelectorAll('span').length).toEqual(0); | 60 expect(element.contents().length).toEqual(1); |
| 61 expect(element.find('span').html()).toEqual(''); |
| 57 | 62 |
| 58 rootScope.apply(() { | 63 rootScope.apply(() { |
| 59 rootScope.context['isVisible'] = true; | 64 rootScope.context['isVisible'] = true; |
| 60 }); | 65 }); |
| 61 | 66 |
| 62 // The span node SHOULD exist in the DOM. | 67 // The span node SHOULD exist in the DOM. |
| 63 expect(element.querySelector('span')).toHaveHtml('content'); | 68 expect(element.contents().length).toEqual(2); |
| 69 expect(element.find('span').html()).toEqual('content'); |
| 64 | 70 |
| 65 rootScope.apply(() { | 71 rootScope.apply(() { |
| 66 rootScope.context['isVisible'] = false; | 72 rootScope.context['isVisible'] = false; |
| 67 }); | 73 }); |
| 68 | 74 |
| 69 expect(element.querySelectorAll('span').length).toEqual(0); | 75 expect(element.find('span').html()).toEqual(''); |
| 70 } | 76 } |
| 71 ); | 77 ); |
| 72 | 78 |
| 73 they('should create a child scope', | 79 they('should create a child scope', |
| 74 [ | 80 [ |
| 75 // ng-if | 81 // ng-if |
| 76 '<div>' + | 82 '<div>' + |
| 77 ' <div ng-if="isVisible">'.trim() + | 83 ' <div ng-if="isVisible">'.trim() + |
| 78 ' <span child-controller id="inside">inside {{setBy}};</span>'.trim() + | 84 ' <span child-controller id="inside">{{setBy}}</span>'.trim() + |
| 79 ' </div>'.trim() + | 85 ' </div>'.trim() + |
| 80 ' <span id="outside">outside {{setBy}}</span>'.trim() + | 86 ' <span id="outside">{{setBy}}</span>'.trim() + |
| 81 '</div>', | 87 '</div>', |
| 82 // ng-unless | 88 // ng-unless |
| 83 '<div>' + | 89 '<div>' + |
| 84 ' <div ng-unless="!isVisible">'.trim() + | 90 ' <div ng-unless="!isVisible">'.trim() + |
| 85 ' <span child-controller id="inside">inside {{setBy}};</span>'.trim() + | 91 ' <span child-controller id="inside">{{setBy}}</span>'.trim() + |
| 86 ' </div>'.trim() + | 92 ' </div>'.trim() + |
| 87 ' <span id="outside">outside {{setBy}}</span>'.trim() + | 93 ' <span id="outside">{{setBy}}</span>'.trim() + |
| 88 '</div>'], | 94 '</div>'], |
| 89 (html) { | 95 (html) { |
| 90 rootScope.context['setBy'] = 'topLevel'; | 96 rootScope.context['setBy'] = 'topLevel'; |
| 91 compile(html); | 97 compile(html); |
| 92 expect(element).toHaveText('outside topLevel'); | 98 expect(element.contents().length).toEqual(2); |
| 93 | 99 |
| 94 rootScope.apply(() { | 100 rootScope.apply(() { |
| 95 rootScope.context['isVisible'] = true; | 101 rootScope.context['isVisible'] = true; |
| 96 }); | 102 }); |
| 97 expect(element).toHaveText('inside childController;outside topLevel'); | 103 expect(element.contents().length).toEqual(3); |
| 98 // The value on the parent scope.context['should'] be unchanged. | 104 // The value on the parent scope.context['should'] be unchanged. |
| 99 expect(rootScope.context['setBy']).toEqual('topLevel'); | 105 expect(rootScope.context['setBy']).toEqual('topLevel'); |
| 100 expect(element.querySelector('#outside')).toHaveHtml('outside topLevel'); | 106 expect(element.find('#outside').html()).toEqual('topLevel'); |
| 101 // A child scope.context['must'] have been created and hold a different va
lue. | 107 // A child scope.context['must'] have been created and hold a different va
lue. |
| 102 expect(element.querySelector('#inside')).toHaveHtml('inside childControlle
r;'); | 108 expect(element.find('#inside').html()).toEqual('childController'); |
| 103 } | 109 } |
| 104 ); | 110 ); |
| 105 | 111 |
| 106 they('should play nice with other elements beside it', | 112 they('should play nice with other elements beside it', |
| 107 [ | 113 [ |
| 108 // ng-if | 114 // ng-if |
| 109 '<div>' + | 115 '<div>' + |
| 110 ' <div ng-repeat="i in values">repeat;</div>'.trim() + | 116 ' <div ng-repeat="i in values"></div>'.trim() + |
| 111 ' <div ng-if="values.length==4">if;</div>'.trim() + | 117 ' <div ng-if="values.length==4"></div>'.trim() + |
| 112 ' <div ng-repeat="i in values">repeat2;</div>'.trim() + | 118 ' <div ng-repeat="i in values"></div>'.trim() + |
| 113 '</div>', | 119 '</div>', |
| 114 // ng-unless | 120 // ng-unless |
| 115 '<div>' + | 121 '<div>' + |
| 116 ' <div ng-repeat="i in values">repeat;</div>'.trim() + | 122 ' <div ng-repeat="i in values"></div>'.trim() + |
| 117 ' <div ng-unless="values.length!=4">if;</div>'.trim() + | 123 ' <div ng-unless="values.length!=4"></div>'.trim() + |
| 118 ' <div ng-repeat="i in values">repeat2;</div>'.trim() + | 124 ' <div ng-repeat="i in values"></div>'.trim() + |
| 119 '</div>'], | 125 '</div>'], |
| 120 (html) { | 126 (html) { |
| 121 var values = rootScope.context['values'] = [1, 2, 3, 4]; | 127 var values = rootScope.context['values'] = [1, 2, 3, 4]; |
| 122 compile(html); | 128 compile(html); |
| 123 expect(element).toHaveText('repeat;repeat;repeat;repeat;if;repeat2;repeat2
;repeat2;repeat2;'); | 129 expect(element.contents().length).toBe(12); |
| 124 rootScope.apply(() { | 130 rootScope.apply(() { |
| 125 values.removeRange(0, 1); | 131 values.removeRange(0, 1); |
| 126 }); | 132 }); |
| 127 expect(element).toHaveText('repeat;repeat;repeat;repeat2;repeat2;repeat2;'
); | 133 expect(element.contents().length).toBe(9); |
| 128 rootScope.apply(() { | 134 rootScope.apply(() { |
| 129 values.insert(0, 1); | 135 values.insert(0, 1); |
| 130 }); | 136 }); |
| 131 expect(element).toHaveText('repeat;repeat;repeat;repeat;if;repeat2;repeat2
;repeat2;repeat2;'); | 137 expect(element.contents().length).toBe(12); |
| 132 } | 138 } |
| 133 ); | 139 ); |
| 134 | 140 |
| 135 they('should restore the element to its compiled state', | 141 they('should restore the element to its compiled state', |
| 136 [ | 142 [ |
| 137 '<div><span class="my-class" ng-if="isVisible">content</span></div>', | 143 '<div><span class="my-class" ng-if="isVisible">content</span></div>', |
| 138 '<div><span class="my-class" ng-unless="!isVisible">content</span></div>']
, | 144 '<div><span class="my-class" ng-unless="!isVisible">content</span></div>']
, |
| 139 (html) { | 145 (html) { |
| 140 rootScope.context['isVisible'] = true; | 146 rootScope.context['isVisible'] = true; |
| 141 compile(html); | 147 compile(html); |
| 142 expect(element).toHaveText('content'); | 148 expect(element.contents().length).toEqual(2); |
| 143 element.querySelector('span').classes.remove('my-class'); | 149 element.find('span').removeClass('my-class'); |
| 144 expect(element.querySelector('span')).not.toHaveClass('my-class'); | 150 expect(element.find('span').hasClass('my-class')).not.toBe(true); |
| 145 rootScope.apply(() { | 151 rootScope.apply(() { |
| 146 rootScope.context['isVisible'] = false; | 152 rootScope.context['isVisible'] = false; |
| 147 }); | 153 }); |
| 148 expect(element).toHaveText(''); | 154 expect(element.contents().length).toEqual(1); |
| 149 rootScope.apply(() { | 155 rootScope.apply(() { |
| 150 rootScope.context['isVisible'] = true; | 156 rootScope.context['isVisible'] = true; |
| 151 }); | 157 }); |
| 152 // The newly inserted node should be a copy of the compiled state. | 158 // The newly inserted node should be a copy of the compiled state. |
| 153 expect(element.querySelector('span')).toHaveClass('my-class'); | 159 expect(element.find('span').hasClass('my-class')).toBe(true); |
| 154 } | 160 } |
| 155 ); | 161 ); |
| 156 | 162 |
| 157 they('should not cause ng-click to throw an exception', | 163 they('should not cause ng-click to throw an exception', |
| 158 [ | 164 [ |
| 159 '<div><span ng-click="click" ng-if="isVisible">content</span></div>', | 165 '<div><span ng-click="click" ng-if="isVisible">content</span></div>', |
| 160 '<div><span ng-click="click" ng-unless="!isVisible">content</span></div>']
, | 166 '<div><span ng-click="click" ng-unless="!isVisible">content</span></div>']
, |
| 161 (html) { | 167 (html) { |
| 162 compile(html); | 168 compile(html); |
| 163 rootScope.apply(() { | 169 rootScope.apply(() { |
| 164 rootScope.context['isVisible'] = false; | 170 rootScope.context['isVisible'] = false; |
| 165 }); | 171 }); |
| 166 expect(element.querySelectorAll('span').length).toEqual(0); | 172 expect(element.find('span').html()).toEqual(''); |
| 167 } | 173 } |
| 168 ); | 174 ); |
| 169 | 175 |
| 170 they('should prevent other directives from running when disabled', | 176 they('should prevent other directives from running when disabled', |
| 171 [ | 177 [ |
| 172 '<div><li log="ALWAYS"></li><span log="JAMES" ng-if="isVisible">content</s
pan></div>', | 178 '<div><li log="ALWAYS"></li><span log="JAMES" ng-if="isVisible">content</s
pan></div>', |
| 173 '<div><li log="ALWAYS"></li><span log="JAMES" ng-unless="!isVisible">conte
nt</span></div>'], | 179 '<div><li log="ALWAYS"></li><span log="JAMES" ng-unless="!isVisible">conte
nt</span></div>'], |
| 174 (html) { | 180 (html) { |
| 175 compile(html); | 181 compile(html); |
| 176 expect(element.querySelectorAll('span').length).toEqual(0); | 182 expect(element.find('span').html()).toEqual(''); |
| 177 | 183 |
| 178 rootScope.apply(() { | 184 rootScope.apply(() { |
| 179 rootScope.context['isVisible'] = false; | 185 rootScope.context['isVisible'] = false; |
| 180 }); | 186 }); |
| 181 expect(element.querySelectorAll('span').length).toEqual(0); | 187 expect(element.find('span').html()).toEqual(''); |
| 182 expect(logger.result()).toEqual('ALWAYS'); | 188 expect(logger.result()).toEqual('ALWAYS'); |
| 183 | 189 |
| 184 | 190 |
| 185 rootScope.apply(() { | 191 rootScope.apply(() { |
| 186 rootScope.context['isVisible'] = true; | 192 rootScope.context['isVisible'] = true; |
| 187 }); | 193 }); |
| 188 expect(element.querySelector('span')).toHaveHtml('content'); | 194 expect(element.find('span').html()).toEqual('content'); |
| 189 expect(logger.result()).toEqual('ALWAYS; JAMES'); | 195 expect(logger.result()).toEqual('ALWAYS; JAMES'); |
| 190 } | 196 } |
| 191 ); | 197 ); |
| 192 | 198 |
| 193 they('should prevent other directives from running when disabled', | 199 they('should prevent other directives from running when disabled', |
| 194 [ | 200 [ |
| 195 '<div><div ng-if="a"><div ng-if="b">content</div></div></div>', | 201 '<div><div ng-if="a"><div ng-if="b">content</div></div></div>', |
| 196 '<div><div ng-unless="!a"><div ng-unless="!b">content</div></div></div>'], | 202 '<div><div ng-unless="!a"><div ng-unless="!b">content</div></div></div>'], |
| 197 (html) { | 203 (html) { |
| 198 compile(html); | 204 compile(html); |
| 199 expect(element.querySelectorAll('span').length).toEqual(0); | 205 expect(element.find('span').html()).toEqual(''); |
| 200 | 206 |
| 201 expect(() { | 207 expect(() { |
| 202 rootScope.apply(() { | 208 rootScope.apply(() { |
| 203 rootScope.context['a'] = true; | 209 rootScope.context['a'] = true; |
| 204 rootScope.context['b'] = false; | 210 rootScope.context['b'] = false; |
| 205 }); | 211 }); |
| 206 }).not.toThrow(); | 212 }).not.toThrow(); |
| 207 expect(element.querySelectorAll('span').length).toEqual(0); | 213 expect(element.find('span').html()).toEqual(''); |
| 208 | 214 |
| 209 | 215 |
| 210 expect(() { | 216 expect(() { |
| 211 rootScope.apply(() { | 217 rootScope.apply(() { |
| 212 rootScope.context['a'] = false; | 218 rootScope.context['a'] = false; |
| 213 rootScope.context['b'] = true; | 219 rootScope.context['b'] = true; |
| 214 }); | 220 }); |
| 215 }).not.toThrow(); | 221 }).not.toThrow(); |
| 216 expect(element.querySelectorAll('span').length).toEqual(0); | 222 expect(element.find('span').html()).toEqual(''); |
| 217 } | 223 } |
| 218 ); | 224 ); |
| 219 } | 225 } |
| OLD | NEW |