| OLD | NEW |
| 1 library ng_repeat_spec; | 1 library ng_repeat_spec; |
| 2 | 2 |
| 3 import '../_specs.dart'; | 3 import '../_specs.dart'; |
| 4 | 4 |
| 5 main() { | 5 main() { |
| 6 describe('NgRepeater', () { | 6 describe('NgRepeater', () { |
| 7 var element, $compile, scope, $exceptionHandler, directives; | 7 var element, $compile, scope, $exceptionHandler; |
| 8 | 8 |
| 9 beforeEach(inject((Injector injector, Scope $rootScope, Compiler compiler, D
irectiveMap _directives) { | 9 beforeEach(inject((Injector injector, Scope $rootScope, Compiler compiler) { |
| 10 $exceptionHandler = injector.get(ExceptionHandler); | 10 $exceptionHandler = injector.get(ExceptionHandler); |
| 11 scope = $rootScope; | 11 scope = $rootScope; |
| 12 $compile = (html) { | 12 $compile = (html) { |
| 13 element = $(html); | 13 element = $(html); |
| 14 var blockFactory = compiler(element, _directives); | 14 var blockFactory = compiler(element); |
| 15 var block = blockFactory(injector, element); | 15 var block = blockFactory(injector, element); |
| 16 return element; | 16 return element; |
| 17 }; | 17 }; |
| 18 directives = _directives; | |
| 19 })); | 18 })); |
| 20 | 19 |
| 21 it(r'should set create a list of items', inject((Scope scope, Compiler compi
ler, Injector injector) { | 20 it(r'should set create a list of items', inject((Scope scope, Compiler compi
ler, Injector injector) { |
| 22 var element = $('<div><div ng-repeat="item in items">{{item}}</div></div>'
); | 21 var element = $('<div><div ng-repeat="item in items">{{item}}</div></div>'
); |
| 23 BlockFactory blockFactory = compiler(element, directives); | 22 BlockFactory blockFactory = compiler(element); |
| 24 Block block = blockFactory(injector, element); | 23 Block block = blockFactory(injector, element); |
| 25 scope.context['items'] = ['a', 'b']; | 24 scope.items = ['a', 'b']; |
| 26 scope.apply(); | 25 scope.$apply(); |
| 27 expect(element.text()).toEqual('ab'); | 26 expect(element.text()).toEqual('ab'); |
| 28 })); | 27 })); |
| 29 | 28 |
| 30 | 29 |
| 31 it(r'should set create a list of items from iterable', | 30 it(r'should set create a list of items from iterable', |
| 32 inject((Scope scope, Compiler compiler, Injector injector) { | 31 inject((Scope scope, Compiler compiler, Injector injector) { |
| 33 var element = $('<div><div ng-repeat="item in items">{{item}}</div></div>'
); | 32 var element = $('<div><div ng-repeat="item in items">{{item}}</div></div>'
); |
| 34 BlockFactory blockFactory = compiler(element, directives); | 33 BlockFactory blockFactory = compiler(element); |
| 35 Block block = blockFactory(injector, element); | 34 Block block = blockFactory(injector, element); |
| 36 scope.context['items'] = ['a', 'b'].map((i) => i); // makes an iterable | 35 scope.items = ['a', 'b'].map((i) => i); // makes an iterable |
| 37 scope.apply(); | 36 scope.$apply(); |
| 38 expect(element.text()).toEqual('ab'); | 37 expect(element.text()).toEqual('ab'); |
| 39 })); | 38 })); |
| 40 | 39 |
| 41 | 40 |
| 42 it(r'should iterate over an array of objects', () { | 41 it(r'should iterate over an array of objects', () { |
| 43 element = $compile( | 42 element = $compile( |
| 44 '<ul>' + | 43 '<ul>' + |
| 45 '<li ng-repeat="item in items">{{item.name}};</li>' + | 44 '<li ng-repeat="item in items">{{item.name}};</li>' + |
| 46 '</ul>'); | 45 '</ul>'); |
| 47 | 46 |
| 48 // INIT | 47 // INIT |
| 49 scope.context['items'] = [{"name": 'misko'}, {"name":'shyam'}]; | 48 scope.items = [{"name": 'misko'}, {"name":'shyam'}]; |
| 50 scope.apply(); | 49 scope.$digest(); |
| 51 expect(element.find('li').length).toEqual(2); | 50 expect(element.find('li').length).toEqual(2); |
| 52 expect(element.text()).toEqual('misko;shyam;'); | 51 expect(element.text()).toEqual('misko;shyam;'); |
| 53 | 52 |
| 54 // GROW | 53 // GROW |
| 55 scope.context['items'].add({"name": 'adam'}); | 54 scope.items.add({"name": 'adam'}); |
| 56 scope.apply(); | 55 scope.$digest(); |
| 57 expect(element.find('li').length).toEqual(3); | 56 expect(element.find('li').length).toEqual(3); |
| 58 expect(element.text()).toEqual('misko;shyam;adam;'); | 57 expect(element.text()).toEqual('misko;shyam;adam;'); |
| 59 | 58 |
| 60 // SHRINK | 59 // SHRINK |
| 61 scope.context['items'].removeLast(); | 60 scope.items.removeLast(); |
| 62 scope.context['items'].removeAt(0); | 61 scope.items.removeAt(0); |
| 63 scope.apply(); | 62 scope.$digest(); |
| 64 expect(element.find('li').length).toEqual(1); | 63 expect(element.find('li').length).toEqual(1); |
| 65 expect(element.text()).toEqual('shyam;'); | 64 expect(element.text()).toEqual('shyam;'); |
| 66 }); | 65 }); |
| 67 | 66 |
| 68 | 67 |
| 69 it(r'should gracefully handle nulls', () { | 68 it(r'should gracefully handle nulls', () { |
| 70 element = $compile( | 69 element = $compile( |
| 71 '<div>' + | 70 '<div>' + |
| 72 '<ul>' + | 71 '<ul>' + |
| 73 '<li ng-repeat="item in null">{{item.name}};</li>' + | 72 '<li ng-repeat="item in null">{{item.name}};</li>' + |
| 74 '</ul>' + | 73 '</ul>' + |
| 75 '</div>'); | 74 '</div>'); |
| 76 scope.apply(); | 75 scope.$digest(); |
| 77 expect(element.find('ul').length).toEqual(1); | 76 expect(element.find('ul').length).toEqual(1); |
| 78 expect(element.find('li').length).toEqual(0); | 77 expect(element.find('li').length).toEqual(0); |
| 79 }); | 78 }); |
| 80 | 79 |
| 81 | 80 |
| 82 describe('track by', () { | 81 describe('track by', () { |
| 83 it(r'should track using expression function', () { | 82 it(r'should track using expression function', () { |
| 84 element = $compile( | 83 element = $compile( |
| 85 '<ul>' + | 84 '<ul>' + |
| 86 '<li ng-repeat="item in items track by item.id">{{item.name}};</
li>' + | 85 '<li ng-repeat="item in items track by item.id">{{item.name}};</
li>' + |
| 87 '</ul>'); | 86 '</ul>'); |
| 88 scope.context['items'] = [{"id": 'misko'}, {"id": 'igor'}]; | 87 scope.items = [{"id": 'misko'}, {"id": 'igor'}]; |
| 89 scope.apply(); | 88 scope.$digest(); |
| 90 var li0 = element.find('li')[0]; | 89 var li0 = element.find('li')[0]; |
| 91 var li1 = element.find('li')[1]; | 90 var li1 = element.find('li')[1]; |
| 92 | 91 |
| 93 scope.context['items'].add(scope.context['items'].removeAt(0)); | 92 scope.items.add(scope.items.removeAt(0)); |
| 94 scope.apply(); | 93 scope.$digest(); |
| 95 expect(element.find('li')[0]).toBe(li1); | 94 expect(element.find('li')[0]).toBe(li1); |
| 96 expect(element.find('li')[1]).toBe(li0); | 95 expect(element.find('li')[1]).toBe(li0); |
| 97 }); | 96 }); |
| 98 | 97 |
| 99 | 98 |
| 100 it(r'should track using build in $id function', () { | 99 it(r'should track using build in $id function', () { |
| 101 element = $compile( | 100 element = $compile( |
| 102 '<ul>' + | 101 '<ul>' + |
| 103 r'<li ng-repeat="item in items track by $id(item)">{{item.name}}
;</li>' + | 102 r'<li ng-repeat="item in items track by $id(item)">{{item.name}}
;</li>' + |
| 104 '</ul>'); | 103 '</ul>'); |
| 105 scope.context['items'] = [{"name": 'misko'}, {"name": 'igor'}]; | 104 scope.items = [{"name": 'misko'}, {"name": 'igor'}]; |
| 106 scope.apply(); | 105 scope.$digest(); |
| 107 var li0 = element.find('li')[0]; | 106 var li0 = element.find('li')[0]; |
| 108 var li1 = element.find('li')[1]; | 107 var li1 = element.find('li')[1]; |
| 109 | 108 |
| 110 scope.context['items'].add(scope.context['items'].removeAt(0)); | 109 scope.items.add(scope.items.removeAt(0)); |
| 111 scope.apply(); | 110 scope.$digest(); |
| 112 expect(element.find('li')[0]).toBe(li1); | 111 expect(element.find('li')[0]).toBe(li1); |
| 113 expect(element.find('li')[1]).toBe(li0); | 112 expect(element.find('li')[1]).toBe(li0); |
| 114 }); | 113 }); |
| 115 | 114 |
| 116 | 115 |
| 117 it(r'should iterate over an array of primitives', () { | 116 xit(r'should iterate over an array of primitives', () { |
| 118 element = $compile( | 117 element = $compile( |
| 119 r'<ul>' + | 118 r'<ul>' + |
| 120 r'<li ng-repeat="item in items track by $index">{{item}};</li>'
+ | 119 r'<li ng-repeat="item in items track by $index">{{item}};</li>'
+ |
| 121 r'</ul>'); | 120 r'</ul>'); |
| 122 | 121 |
| 123 // INIT | 122 // INIT |
| 124 scope.context['items'] = [true, true, true]; | 123 scope.items = [true, true, true]; |
| 125 scope.apply(); | 124 scope.$digest(); |
| 126 expect(element.find('li').length).toEqual(3); | 125 expect(element.find('li').length).toEqual(3); |
| 127 expect(element.text()).toEqual('true;true;true;'); | 126 expect(element.text()).toEqual('true;true;true;'); |
| 128 | 127 |
| 129 scope.context['items'] = [false, true, true]; | 128 scope.items = [false, true, true]; |
| 130 scope.apply(); | 129 scope.$digest(); |
| 131 expect(element.find('li').length).toEqual(3); | 130 expect(element.find('li').length).toEqual(3); |
| 132 expect(element.text()).toEqual('false;true;true;'); | 131 expect(element.text()).toEqual('false;true;true;'); |
| 133 | 132 |
| 134 scope.context['items'] = [false, true, false]; | 133 scope.items = [false, true, false]; |
| 135 scope.apply(); | 134 scope.$digest(); |
| 136 expect(element.find('li').length).toEqual(3); | 135 expect(element.find('li').length).toEqual(3); |
| 137 expect(element.text()).toEqual('false;true;false;'); | 136 expect(element.text()).toEqual('false;true;false;'); |
| 138 | 137 |
| 139 scope.context['items'] = [true]; | 138 scope.items = [true]; |
| 140 scope.apply(); | 139 scope.$digest(); |
| 141 expect(element.find('li').length).toEqual(1); | 140 expect(element.find('li').length).toEqual(1); |
| 142 expect(element.text()).toEqual('true;'); | 141 expect(element.text()).toEqual('true;'); |
| 143 | 142 |
| 144 scope.context['items'] = [true, true, false]; | 143 scope.items = [true, true, false]; |
| 145 scope.apply(); | 144 scope.$digest(); |
| 146 expect(element.find('li').length).toEqual(3); | 145 expect(element.find('li').length).toEqual(3); |
| 147 expect(element.text()).toEqual('true;true;false;'); | 146 expect(element.text()).toEqual('true;true;false;'); |
| 148 | 147 |
| 149 scope.context['items'] = [true, false, false]; | 148 scope.items = [true, false, false]; |
| 150 scope.apply(); | 149 scope.$digest(); |
| 151 expect(element.find('li').length).toEqual(3); | 150 expect(element.find('li').length).toEqual(3); |
| 152 expect(element.text()).toEqual('true;false;false;'); | 151 expect(element.text()).toEqual('true;false;false;'); |
| 153 | 152 |
| 154 // string | 153 // string |
| 155 scope.context['items'] = ['a', 'a', 'a']; | 154 scope.items = ['a', 'a', 'a']; |
| 156 scope.apply(); | 155 scope.$digest(); |
| 157 expect(element.find('li').length).toEqual(3); | 156 expect(element.find('li').length).toEqual(3); |
| 158 expect(element.text()).toEqual('a;a;a;'); | 157 expect(element.text()).toEqual('a;a;a;'); |
| 159 | 158 |
| 160 scope.context['items'] = ['ab', 'a', 'a']; | 159 scope.items = ['ab', 'a', 'a']; |
| 161 scope.apply(); | 160 scope.$digest(); |
| 162 expect(element.find('li').length).toEqual(3); | 161 expect(element.find('li').length).toEqual(3); |
| 163 expect(element.text()).toEqual('ab;a;a;'); | 162 expect(element.text()).toEqual('ab;a;a;'); |
| 164 | 163 |
| 165 scope.context['items'] = ['test']; | 164 scope.items = ['test']; |
| 166 scope.apply(); | 165 scope.$digest(); |
| 167 expect(element.find('li').length).toEqual(1); | 166 expect(element.find('li').length).toEqual(1); |
| 168 expect(element.text()).toEqual('test;'); | 167 expect(element.text()).toEqual('test;'); |
| 169 | 168 |
| 170 scope.context['items'] = ['same', 'value']; | 169 scope.items = ['same', 'value']; |
| 171 scope.apply(); | 170 scope.$digest(); |
| 172 expect(element.find('li').length).toEqual(2); | 171 expect(element.find('li').length).toEqual(2); |
| 173 expect(element.text()).toEqual('same;value;'); | 172 expect(element.text()).toEqual('same;value;'); |
| 174 | 173 |
| 175 // number | 174 // number |
| 176 scope.context['items'] = [12, 12, 12]; | 175 scope.items = [12, 12, 12]; |
| 177 scope.apply(); | 176 scope.$digest(); |
| 178 expect(element.find('li').length).toEqual(3); | 177 expect(element.find('li').length).toEqual(3); |
| 179 expect(element.text()).toEqual('12;12;12;'); | 178 expect(element.text()).toEqual('12;12;12;'); |
| 180 | 179 |
| 181 scope.context['items'] = [53, 12, 27]; | 180 scope.items = [53, 12, 27]; |
| 182 scope.apply(); | 181 scope.$digest(); |
| 183 expect(element.find('li').length).toEqual(3); | 182 expect(element.find('li').length).toEqual(3); |
| 184 expect(element.text()).toEqual('53;12;27;'); | 183 expect(element.text()).toEqual('53;12;27;'); |
| 185 | 184 |
| 186 scope.context['items'] = [89]; | 185 scope.items = [89]; |
| 187 scope.apply(); | 186 scope.$digest(); |
| 188 expect(element.find('li').length).toEqual(1); | 187 expect(element.find('li').length).toEqual(1); |
| 189 expect(element.text()).toEqual('89;'); | 188 expect(element.text()).toEqual('89;'); |
| 190 | 189 |
| 191 scope.context['items'] = [89, 23]; | 190 scope.items = [89, 23]; |
| 192 scope.apply(); | 191 scope.$digest(); |
| 193 expect(element.find('li').length).toEqual(2); | 192 expect(element.find('li').length).toEqual(2); |
| 194 expect(element.text()).toEqual('89;23;'); | 193 expect(element.text()).toEqual('89;23;'); |
| 195 }); | 194 }); |
| 196 | 195 |
| 197 }); | 196 }); |
| 198 | 197 |
| 199 | 198 |
| 200 it(r'should error on wrong parsing of ngRepeat', () { | 199 it(r'should error on wrong parsing of ngRepeat', () { |
| 201 element = $('<ul><li ng-repeat="i dont parse"></li></ul>'); | 200 element = $('<ul><li ng-repeat="i dont parse"></li></ul>'); |
| 202 expect(() { | 201 expect(() { |
| 203 $compile(element); | 202 $compile(element); |
| 204 }).toThrow("[NgErr7] ngRepeat error! Expected expression in form of '_item
_ in _collection_[ track by _id_]' but got 'i dont parse'."); | 203 }).toThrow("[NgErr7] ngRepeat error! Expected expression in form of '_item
_ in _collection_[ track by _id_]' but got 'i dont parse'."); |
| 205 }); | 204 }); |
| 206 | 205 |
| 207 | 206 |
| 208 it("should throw error when left-hand-side of ngRepeat can't be parsed", ()
{ | 207 it("should throw error when left-hand-side of ngRepeat can't be parsed", ()
{ |
| 209 element = $('<ul><li ng-repeat="i dont parse in foo"></li></ul>'); | 208 element = $('<ul><li ng-repeat="i dont parse in foo"></li></ul>'); |
| 210 expect(() { | 209 expect(() { |
| 211 $compile(element); | 210 $compile(element); |
| 212 }).toThrow("[NgErr8] ngRepeat error! '_item_' in '_item_ in _collection_
' should be an identifier or '(_key_, _value_)' expression, but got 'i dont pars
e'."); | 211 }).toThrow("[NgErr8] ngRepeat error! '_item_' in '_item_ in _collection_
' should be an identifier or '(_key_, _value_)' expression, but got 'i dont pars
e'."); |
| 213 }); | 212 }); |
| 214 | 213 |
| 215 | 214 |
| 216 it(r'should expose iterator offset as $index when iterating over arrays', | 215 it(r'should expose iterator offset as $index when iterating over arrays', |
| 217 () { | 216 () { |
| 218 element = $compile( | 217 element = $compile( |
| 219 '<ul>' + | 218 '<ul>' + |
| 220 '<li ng-repeat="item in items">{{item}}:{{\$index}}|</li>' + | 219 '<li ng-repeat="item in items">{{item}}:{{\$index}}|</li>' + |
| 221 '</ul>'); | 220 '</ul>'); |
| 222 scope.context['items'] = ['misko', 'shyam', 'frodo']; | 221 scope.items = ['misko', 'shyam', 'frodo']; |
| 223 scope.apply(); | 222 scope.$digest(); |
| 224 expect(element.text()).toEqual('misko:0|shyam:1|frodo:2|'); | 223 expect(element.text()).toEqual('misko:0|shyam:1|frodo:2|'); |
| 225 }); | 224 }); |
| 226 | 225 |
| 227 | 226 |
| 228 it(r'should expose iterator position as $first, $middle and $last when itera
ting over arrays', | 227 it(r'should expose iterator position as $first, $middle and $last when itera
ting over arrays', |
| 229 () { | 228 () { |
| 230 element = $compile( | 229 element = $compile( |
| 231 '<ul>' + | 230 '<ul>' + |
| 232 '<li ng-repeat="item in items">{{item}}:{{\$first}}-{{\$middle}}-{{\$l
ast}}|</li>' + | 231 '<li ng-repeat="item in items">{{item}}:{{\$first}}-{{\$middle}}-{{\$l
ast}}|</li>' + |
| 233 '</ul>'); | 232 '</ul>'); |
| 234 scope.context['items'] = ['misko', 'shyam', 'doug']; | 233 scope.items = ['misko', 'shyam', 'doug']; |
| 235 scope.apply(); | 234 scope.$digest(); |
| 236 expect(element.text()). | 235 expect(element.text()). |
| 237 toEqual('misko:true-false-false|shyam:false-true-false|doug:false-fals
e-true|'); | 236 toEqual('misko:true-false-false|shyam:false-true-false|doug:false-fals
e-true|'); |
| 238 | 237 |
| 239 scope.context['items'].add('frodo'); | 238 scope.items.add('frodo'); |
| 240 scope.apply(); | 239 scope.$digest(); |
| 241 expect(element.text()). | 240 expect(element.text()). |
| 242 toEqual('misko:true-false-false|' + | 241 toEqual('misko:true-false-false|' + |
| 243 'shyam:false-true-false|' + | 242 'shyam:false-true-false|' + |
| 244 'doug:false-true-false|' + | 243 'doug:false-true-false|' + |
| 245 'frodo:false-false-true|'); | 244 'frodo:false-false-true|'); |
| 246 | 245 |
| 247 scope.context['items'].removeLast(); | 246 scope.items.removeLast(); |
| 248 scope.context['items'].removeLast(); | 247 scope.items.removeLast(); |
| 249 scope.apply(); | 248 scope.$digest(); |
| 250 expect(element.text()).toEqual('misko:true-false-false|shyam:false-false-t
rue|'); | 249 expect(element.text()).toEqual('misko:true-false-false|shyam:false-false-t
rue|'); |
| 251 | 250 |
| 252 scope.context['items'].removeLast(); | 251 scope.items.removeLast(); |
| 253 scope.apply(); | 252 scope.$digest(); |
| 254 expect(element.text()).toEqual('misko:true-false-true|'); | 253 expect(element.text()).toEqual('misko:true-false-true|'); |
| 255 }); | 254 }); |
| 256 | 255 |
| 257 it(r'should report odd', () { | 256 it(r'should report odd', () { |
| 258 element = $compile( | 257 element = $compile( |
| 259 '<ul>' + | 258 '<ul>' + |
| 260 '<li ng-repeat="item in items">{{item}}:{{\$odd}}-{{\$even}}|</li>' + | 259 '<li ng-repeat="item in items">{{item}}:{{\$odd}}-{{\$even}}|</li>' + |
| 261 '</ul>'); | 260 '</ul>'); |
| 262 scope.context['items'] = ['misko', 'shyam', 'doug']; | 261 scope.items = ['misko', 'shyam', 'doug']; |
| 263 scope.apply(); | 262 scope.$digest(); |
| 264 expect(element.text()).toEqual('misko:false-true|shyam:true-false|doug:fal
se-true|'); | 263 expect(element.text()).toEqual('misko:false-true|shyam:true-false|doug:fal
se-true|'); |
| 265 | 264 |
| 266 scope.context['items'].add('frodo'); | 265 scope.items.add('frodo'); |
| 267 scope.apply(); | 266 scope.$digest(); |
| 268 expect(element.text()).toEqual('misko:false-true|shyam:true-false|doug:fal
se-true|frodo:true-false|'); | 267 expect(element.text()).toEqual('misko:false-true|shyam:true-false|doug:fal
se-true|frodo:true-false|'); |
| 269 | 268 |
| 270 scope.context['items'].removeLast(); | 269 scope.items.removeLast(); |
| 271 scope.context['items'].removeLast(); | 270 scope.items.removeLast(); |
| 272 scope.apply(); | 271 scope.$digest(); |
| 273 expect(element.text()).toEqual('misko:false-true|shyam:true-false|'); | 272 expect(element.text()).toEqual('misko:false-true|shyam:true-false|'); |
| 274 | 273 |
| 275 scope.context['items'].removeLast(); | 274 scope.items.removeLast(); |
| 276 scope.apply(); | 275 scope.$digest(); |
| 277 expect(element.text()).toEqual('misko:false-true|'); | 276 expect(element.text()).toEqual('misko:false-true|'); |
| 278 }); | 277 }); |
| 279 | 278 |
| 280 it(r'should repeat over nested arrays', () { | 279 it(r'should repeat over nested arrays', () { |
| 281 element = $compile( | 280 element = $compile( |
| 282 '<ul>' + | 281 '<ul>' + |
| 283 '<li ng-repeat="subgroup in groups">' + | 282 '<li ng-repeat="subgroup in groups">' + |
| 284 '<div ng-repeat="group in subgroup">{{group}}|</div>X' + | 283 '<div ng-repeat="group in subgroup">{{group}}|</div>X' + |
| 285 '</li>' + | 284 '</li>' + |
| 286 '</ul>'); | 285 '</ul>'); |
| 287 scope.context['groups'] = [['a', 'b'], ['c','d']]; | 286 scope.groups = [['a', 'b'], ['c','d']]; |
| 288 scope.apply(); | 287 scope.$digest(); |
| 289 | 288 |
| 290 expect(element.text()).toEqual('a|b|Xc|d|X'); | 289 expect(element.text()).toEqual('a|b|Xc|d|X'); |
| 291 }); | 290 }); |
| 292 | 291 |
| 293 | 292 |
| 294 describe('stability', () { | 293 describe('stability', () { |
| 295 var a, b, c, d, lis; | 294 var a, b, c, d, lis; |
| 296 | 295 |
| 297 beforeEach(() { | 296 beforeEach(() { |
| 298 element = $compile( | 297 element = $compile( |
| 299 '<ul>' + | 298 '<ul>' + |
| 300 '<li ng-repeat="item in items">{{key}}:{{val}}|></li>' + | 299 '<li ng-repeat="item in items">{{key}}:{{val}}|></li>' + |
| 301 '</ul>'); | 300 '</ul>'); |
| 302 a = {}; | 301 a = {}; |
| 303 b = {}; | 302 b = {}; |
| 304 c = {}; | 303 c = {}; |
| 305 d = {}; | 304 d = {}; |
| 306 | 305 |
| 307 scope.context['items'] = [a, b, c]; | 306 scope.items = [a, b, c]; |
| 308 scope.apply(); | 307 scope.$digest(); |
| 309 lis = element.find('li'); | 308 lis = element.find('li'); |
| 310 }); | 309 }); |
| 311 | 310 |
| 312 | 311 |
| 313 it(r'should preserve the order of elements', () { | 312 it(r'should preserve the order of elements', () { |
| 314 scope.context['items'] = [a, c, d]; | 313 scope.items = [a, c, d]; |
| 315 scope.apply(); | 314 scope.$digest(); |
| 316 var newElements = element.find('li'); | 315 var newElements = element.find('li'); |
| 317 expect(newElements[0]).toEqual(lis[0]); | 316 expect(newElements[0]).toEqual(lis[0]); |
| 318 expect(newElements[1]).toEqual(lis[2]); | 317 expect(newElements[1]).toEqual(lis[2]); |
| 319 expect(newElements[2] == lis[1]).toEqual(false); | 318 expect(newElements[2] == lis[1]).toEqual(false); |
| 320 }); | 319 }); |
| 321 | 320 |
| 322 | 321 |
| 323 it(r'should throw error on adding existing duplicates and recover', () { | 322 it(r'should throw error on adding existing duplicates and recover', () { |
| 324 scope.context['items'] = [a, a, a]; | 323 scope.items = [a, a, a]; |
| 325 expect(() { | 324 expect(() { |
| 326 scope.apply(); | 325 scope.$digest(); |
| 327 }).toThrow("[NgErr50] ngRepeat error! Duplicates in a repeater are not a
llowed. Use 'track by' expression to specify unique keys. Repeater: item in item
s, Duplicate key: {}"); | 326 }).toThrow("[NgErr50] ngRepeat error! Duplicates in a repeater are not a
llowed. Use 'track by' expression to specify unique keys. Repeater: item in item
s, Duplicate key: {}"); |
| 328 | 327 |
| 329 // recover | 328 // recover |
| 330 scope.context['items'] = [a]; | 329 scope.items = [a]; |
| 331 scope.apply(); | 330 scope.$digest(); |
| 332 var newElements = element.find('li'); | 331 var newElements = element.find('li'); |
| 333 expect(newElements.length).toEqual(1); | 332 expect(newElements.length).toEqual(1); |
| 334 expect(newElements[0]).toEqual(lis[0]); | 333 expect(newElements[0]).toEqual(lis[0]); |
| 335 | 334 |
| 336 scope.context['items'] = []; | 335 scope.items = []; |
| 337 scope.apply(); | 336 scope.$digest(); |
| 338 newElements = element.find('li'); | 337 newElements = element.find('li'); |
| 339 expect(newElements.length).toEqual(0); | 338 expect(newElements.length).toEqual(0); |
| 340 }); | 339 }); |
| 341 | 340 |
| 342 | 341 |
| 343 it(r'should throw error on new duplicates and recover', () { | 342 it(r'should throw error on new duplicates and recover', () { |
| 344 scope.context['items'] = [d, d, d]; | 343 scope.items = [d, d, d]; |
| 345 expect(() { | 344 expect(() { |
| 346 scope.apply(); | 345 scope.$digest(); |
| 347 }).toThrow("[NgErr50] ngRepeat error! Duplicates in a repeater are not a
llowed. Use 'track by' expression to specify unique keys. Repeater: item in item
s, Duplicate key: {}"); | 346 }).toThrow("[NgErr50] ngRepeat error! Duplicates in a repeater are not a
llowed. Use 'track by' expression to specify unique keys. Repeater: item in item
s, Duplicate key: {}"); |
| 348 | 347 |
| 349 // recover | 348 // recover |
| 350 scope.context['items'] = [a]; | 349 scope.items = [a]; |
| 351 scope.apply(); | 350 scope.$digest(); |
| 352 var newElements = element.find('li'); | 351 var newElements = element.find('li'); |
| 353 expect(newElements.length).toEqual(1); | 352 expect(newElements.length).toEqual(1); |
| 354 expect(newElements[0]).toEqual(lis[0]); | 353 expect(newElements[0]).toEqual(lis[0]); |
| 355 | 354 |
| 356 scope.context['items'] = []; | 355 scope.items = []; |
| 357 scope.apply(); | 356 scope.$digest(); |
| 358 newElements = element.find('li'); | 357 newElements = element.find('li'); |
| 359 expect(newElements.length).toEqual(0); | 358 expect(newElements.length).toEqual(0); |
| 360 }); | 359 }); |
| 361 | 360 |
| 362 | 361 |
| 363 it(r'should reverse items when the collection is reversed', () { | 362 it(r'should reverse items when the collection is reversed', () { |
| 364 scope.context['items'] = [a, b, c]; | 363 scope.items = [a, b, c]; |
| 365 scope.apply(); | 364 scope.$digest(); |
| 366 lis = element.find('li'); | 365 lis = element.find('li'); |
| 367 | 366 |
| 368 scope.context['items'] = [c, b, a]; | 367 scope.items = [c, b, a]; |
| 369 scope.apply(); | 368 scope.$digest(); |
| 370 var newElements = element.find('li'); | 369 var newElements = element.find('li'); |
| 371 expect(newElements.length).toEqual(3); | 370 expect(newElements.length).toEqual(3); |
| 372 expect(newElements[0]).toEqual(lis[2]); | 371 expect(newElements[0]).toEqual(lis[2]); |
| 373 expect(newElements[1]).toEqual(lis[1]); | 372 expect(newElements[1]).toEqual(lis[1]); |
| 374 expect(newElements[2]).toEqual(lis[0]); | 373 expect(newElements[2]).toEqual(lis[0]); |
| 375 }); | 374 }); |
| 376 | 375 |
| 377 | 376 |
| 378 it(r'should reuse elements even when model is composed of primitives', ()
{ | 377 it(r'should reuse elements even when model is composed of primitives', ()
{ |
| 379 // rebuilding repeater from scratch can be expensive, we should try to a
void it even for | 378 // rebuilding repeater from scratch can be expensive, we should try to a
void it even for |
| 380 // model that is composed of primitives. | 379 // model that is composed of primitives. |
| 381 | 380 |
| 382 scope.context['items'] = ['hello', 'cau', 'ahoj']; | 381 scope.items = ['hello', 'cau', 'ahoj']; |
| 383 scope.apply(); | 382 scope.$digest(); |
| 384 lis = element.find('li'); | 383 lis = element.find('li'); |
| 385 lis[2].id = 'yes'; | 384 lis[2].id = 'yes'; |
| 386 | 385 |
| 387 scope.context['items'] = ['ahoj', 'hello', 'cau']; | 386 scope.items = ['ahoj', 'hello', 'cau']; |
| 388 scope.apply(); | 387 scope.$digest(); |
| 389 var newLis = element.find('li'); | 388 var newLis = element.find('li'); |
| 390 expect(newLis.length).toEqual(3); | 389 expect(newLis.length).toEqual(3); |
| 391 expect(newLis[0]).toEqual(lis[2]); | 390 expect(newLis[0]).toEqual(lis[2]); |
| 392 expect(newLis[1]).toEqual(lis[0]); | 391 expect(newLis[1]).toEqual(lis[0]); |
| 393 expect(newLis[2]).toEqual(lis[1]); | 392 expect(newLis[2]).toEqual(lis[1]); |
| 394 }); | 393 }); |
| 395 }); | 394 }); |
| 396 | 395 |
| 396 describe('shalow', () { |
| 397 TestBed _; |
| 398 beforeEach(inject((TestBed tb) => _ = tb)); |
| 399 |
| 400 it('should x', () { |
| 401 _.compile('<ul><li ng-shallow-repeat="i in items">{{i.name}}</li></ul>')
; |
| 402 _.rootScope.items = [{'name': 'a'}, {'name':'b'}]; |
| 403 _.rootScope.$digest(); |
| 404 expect(_.rootElement.text).toEqual('ab'); |
| 405 |
| 406 // Should not see this. |
| 407 _.rootScope.items[0]['name'] = 'x'; |
| 408 _.rootScope.$digest(); |
| 409 expect(_.rootElement.text).toEqual('ab'); |
| 410 |
| 411 // We see additions but not changse |
| 412 _.rootScope.items.add({'name': 'C'}); |
| 413 _.rootScope.$digest(); |
| 414 expect(_.rootElement.text).toEqual('abC'); |
| 415 |
| 416 |
| 417 // Cloning list does a full update |
| 418 _.rootScope.items = new List.from(_.rootScope.items); |
| 419 _.rootScope.$digest(); |
| 420 expect(_.rootElement.text).toEqual('xbC'); |
| 421 }); |
| 422 }); |
| 397 }); | 423 }); |
| 398 } | 424 } |
| OLD | NEW |