Best JavaScript code snippet using appium
ngRepeatSpec.js
Source:ngRepeatSpec.js
...30 // INIT31 scope.items = [{name: 'misko'}, {name:'shyam'}];32 scope.$digest();33 expect(element.find('li').length).toEqual(2);34 expect(element.text()).toEqual('misko;shyam;');35 delete Array.prototype.extraProperty;36 // GROW37 scope.items.push({name: 'adam'});38 scope.$digest();39 expect(element.find('li').length).toEqual(3);40 expect(element.text()).toEqual('misko;shyam;adam;');41 // SHRINK42 scope.items.pop();43 scope.items.shift();44 scope.$digest();45 expect(element.find('li').length).toEqual(1);46 expect(element.text()).toEqual('shyam;');47 });48 it('should be possible to use one-time bindings on the collection', function() {49 element = $compile(50 '<ul>' +51 '<li ng-repeat="item in ::items">{{item.name}};</li>' +52 '</ul>')(scope);53 scope.$digest();54 scope.items = [{name: 'misko'}, {name:'shyam'}];55 scope.$digest();56 expect(element.find('li').length).toEqual(2);57 expect(element.text()).toEqual('misko;shyam;');58 scope.items.push({name: 'adam'});59 scope.$digest();60 expect(element.find('li').length).toEqual(2);61 expect(element.text()).toEqual('misko;shyam;');62 });63 it('should be possible to use one-time bindings on the content', function() {64 element = $compile(65 '<ul>' +66 '<li ng-repeat="item in items">{{::item.name}};</li>' +67 '</ul>')(scope);68 scope.$digest();69 scope.items = [{name: 'misko'}, {name:'shyam'}];70 scope.$digest();71 expect(element.find('li').length).toEqual(2);72 expect(element.text()).toEqual('misko;shyam;');73 scope.items.push({name: 'adam'});74 scope.$digest();75 expect(element.find('li').length).toEqual(3);76 expect(element.text()).toEqual('misko;shyam;adam;');77 });78 it('should iterate over an array-like object', function() {79 element = $compile(80 '<ul>' +81 '<li ng-repeat="item in items">{{item.name}};</li>' +82 '</ul>')(scope);83 document.body.innerHTML = "<p>" +84 "<a name='x'>a</a>" +85 "<a name='y'>b</a>" +86 "<a name='x'>c</a>" +87 "</p>";88 var htmlCollection = document.getElementsByTagName('a');89 scope.items = htmlCollection;90 scope.$digest();91 expect(element.find('li').length).toEqual(3);92 expect(element.text()).toEqual('x;y;x;');93 });94 it('should iterate over an array-like class', function() {95 /* jshint -W009 */96 function Collection() {}97 Collection.prototype = new Array();98 Collection.prototype.length = 0;99 var collection = new Collection();100 collection.push({ name: "x" });101 collection.push({ name: "y" });102 collection.push({ name: "z" });103 element = $compile(104 '<ul>' +105 '<li ng-repeat="item in items">{{item.name}};</li>' +106 '</ul>')(scope);107 scope.items = collection;108 scope.$digest();109 expect(element.find('li').length).toEqual(3);110 expect(element.text()).toEqual('x;y;z;');111 });112 it('should iterate over on object/map', function() {113 element = $compile(114 '<ul>' +115 '<li ng-repeat="(key, value) in items">{{key}}:{{value}}|</li>' +116 '</ul>')(scope);117 scope.items = {misko:'swe', shyam:'set'};118 scope.$digest();119 expect(element.text()).toEqual('misko:swe|shyam:set|');120 });121 it('should iterate over on object/map where (key,value) contains whitespaces', function() {122 element = $compile(123 '<ul>' +124 '<li ng-repeat="( key , value ) in items">{{key}}:{{value}}|</li>' +125 '</ul>')(scope);126 scope.items = {me:'swe', you:'set'};127 scope.$digest();128 expect(element.text()).toEqual('me:swe|you:set|');129 });130 it('should iterate over an object/map with identical values', function() {131 element = $compile(132 '<ul>' +133 '<li ng-repeat="(key, value) in items">{{key}}:{{value}}|</li>' +134 '</ul>')(scope);135 scope.items = {age:20, wealth:20, prodname: "Bingo", dogname: "Bingo", codename: "20"};136 scope.$digest();137 expect(element.text()).toEqual('age:20|wealth:20|prodname:Bingo|dogname:Bingo|codename:20|');138 });139 it('should iterate over on object created using `Object.create(null)`', function() {140 element = $compile(141 '<ul>' +142 '<li ng-repeat="(key, value) in items">{{key}}:{{value}}|</li>' +143 '</ul>')(scope);144 var items = Object.create(null);145 items.misko = 'swe';146 items.shyam = 'set';147 scope.items = items;148 scope.$digest();149 expect(element.text()).toEqual('misko:swe|shyam:set|');150 delete items.shyam;151 scope.$digest();152 expect(element.text()).toEqual('misko:swe|');153 });154 describe('track by', function() {155 it('should track using expression function', function() {156 element = $compile(157 '<ul>' +158 '<li ng-repeat="item in items track by item.id">{{item.name}};</li>' +159 '</ul>')(scope);160 scope.items = [{id: 'misko'}, {id: 'igor'}];161 scope.$digest();162 var li0 = element.find('li')[0];163 var li1 = element.find('li')[1];164 scope.items.push(scope.items.shift());165 scope.$digest();166 expect(element.find('li')[0]).toBe(li1);167 expect(element.find('li')[1]).toBe(li0);168 });169 it('should track using build in $id function', function() {170 element = $compile(171 '<ul>' +172 '<li ng-repeat="item in items track by $id(item)">{{item.name}};</li>' +173 '</ul>')(scope);174 scope.items = [{name: 'misko'}, {name: 'igor'}];175 scope.$digest();176 var li0 = element.find('li')[0];177 var li1 = element.find('li')[1];178 scope.items.push(scope.items.shift());179 scope.$digest();180 expect(element.find('li')[0]).toBe(li1);181 expect(element.find('li')[1]).toBe(li0);182 });183 it('should still filter when track is present', function() {184 scope.isIgor = function(item) {185 return item.name === 'igor';186 };187 element = $compile(188 '<ul>' +189 '<li ng-repeat="item in items | filter:isIgor track by $id(item)">{{item.name}};</li>' +190 '</ul>')(scope);191 scope.items = [{name: 'igor'}, {name: 'misko'}];192 scope.$digest();193 expect(element.find('li').text()).toBe('igor;');194 });195 it('should track using provided function when a filter is present', function() {196 scope.newArray = function(items) {197 var newArray = [];198 angular.forEach(items, function(item) {199 newArray.push({200 id: item.id,201 name: item.name202 });203 });204 return newArray;205 };206 element = $compile(207 '<ul>' +208 '<li ng-repeat="item in items | filter:newArray track by item.id">{{item.name}};</li>' +209 '</ul>')(scope);210 scope.items = [211 {id: 1, name: 'igor'},212 {id: 2, name: 'misko'}213 ];214 scope.$digest();215 expect(element.text()).toBe('igor;misko;');216 var li0 = element.find('li')[0];217 var li1 = element.find('li')[1];218 scope.items.push(scope.items.shift());219 scope.$digest();220 expect(element.find('li')[0]).toBe(li1);221 expect(element.find('li')[1]).toBe(li0);222 });223 it('should iterate over an array of primitives', function() {224 element = $compile(225 '<ul>' +226 '<li ng-repeat="item in items track by $index">{{item}};</li>' +227 '</ul>')(scope);228 Array.prototype.extraProperty = "should be ignored";229 // INIT230 scope.items = [true, true, true];231 scope.$digest();232 expect(element.find('li').length).toEqual(3);233 expect(element.text()).toEqual('true;true;true;');234 delete Array.prototype.extraProperty;235 scope.items = [false, true, true];236 scope.$digest();237 expect(element.find('li').length).toEqual(3);238 expect(element.text()).toEqual('false;true;true;');239 scope.items = [false, true, false];240 scope.$digest();241 expect(element.find('li').length).toEqual(3);242 expect(element.text()).toEqual('false;true;false;');243 scope.items = [true];244 scope.$digest();245 expect(element.find('li').length).toEqual(1);246 expect(element.text()).toEqual('true;');247 scope.items = [true, true, false];248 scope.$digest();249 expect(element.find('li').length).toEqual(3);250 expect(element.text()).toEqual('true;true;false;');251 scope.items = [true, false, false];252 scope.$digest();253 expect(element.find('li').length).toEqual(3);254 expect(element.text()).toEqual('true;false;false;');255 // string256 scope.items = ['a', 'a', 'a'];257 scope.$digest();258 expect(element.find('li').length).toEqual(3);259 expect(element.text()).toEqual('a;a;a;');260 scope.items = ['ab', 'a', 'a'];261 scope.$digest();262 expect(element.find('li').length).toEqual(3);263 expect(element.text()).toEqual('ab;a;a;');264 scope.items = ['test'];265 scope.$digest();266 expect(element.find('li').length).toEqual(1);267 expect(element.text()).toEqual('test;');268 scope.items = ['same', 'value'];269 scope.$digest();270 expect(element.find('li').length).toEqual(2);271 expect(element.text()).toEqual('same;value;');272 // number273 scope.items = [12, 12, 12];274 scope.$digest();275 expect(element.find('li').length).toEqual(3);276 expect(element.text()).toEqual('12;12;12;');277 scope.items = [53, 12, 27];278 scope.$digest();279 expect(element.find('li').length).toEqual(3);280 expect(element.text()).toEqual('53;12;27;');281 scope.items = [89];282 scope.$digest();283 expect(element.find('li').length).toEqual(1);284 expect(element.text()).toEqual('89;');285 scope.items = [89, 23];286 scope.$digest();287 expect(element.find('li').length).toEqual(2);288 expect(element.text()).toEqual('89;23;');289 });290 it('should iterate over object with changing primitive property values', function() {291 // test for issue #933292 element = $compile(293 '<ul>' +294 '<li ng-repeat="(key, value) in items track by $index">' +295 '{{key}}:{{value}};' +296 '<input type="checkbox" ng-model="items[key]">' +297 '</li>' +298 '</ul>')(scope);299 scope.items = {misko: true, shyam: true, zhenbo:true};300 scope.$digest();301 expect(element.find('li').length).toEqual(3);302 expect(element.text()).toEqual('misko:true;shyam:true;zhenbo:true;');303 browserTrigger(element.find('input').eq(0), 'click');304 expect(element.text()).toEqual('misko:false;shyam:true;zhenbo:true;');305 expect(element.find('input')[0].checked).toBe(false);306 expect(element.find('input')[1].checked).toBe(true);307 expect(element.find('input')[2].checked).toBe(true);308 browserTrigger(element.find('input').eq(0), 'click');309 expect(element.text()).toEqual('misko:true;shyam:true;zhenbo:true;');310 expect(element.find('input')[0].checked).toBe(true);311 expect(element.find('input')[1].checked).toBe(true);312 expect(element.find('input')[2].checked).toBe(true);313 browserTrigger(element.find('input').eq(1), 'click');314 expect(element.text()).toEqual('misko:true;shyam:false;zhenbo:true;');315 expect(element.find('input')[0].checked).toBe(true);316 expect(element.find('input')[1].checked).toBe(false);317 expect(element.find('input')[2].checked).toBe(true);318 scope.items = {misko: false, shyam: true, zhenbo: true};319 scope.$digest();320 expect(element.text()).toEqual('misko:false;shyam:true;zhenbo:true;');321 expect(element.find('input')[0].checked).toBe(false);322 expect(element.find('input')[1].checked).toBe(true);323 expect(element.find('input')[2].checked).toBe(true);324 });325 });326 describe('alias as', function() {327 it('should assigned the filtered to the target scope property if an alias is provided', function() {328 element = $compile(329 '<div ng-repeat="item in items | filter:x as results track by $index">{{item.name}}/</div>')(scope);330 scope.items = [331 { name: 'red' },332 { name: 'blue' },333 { name: 'green' },334 { name: 'black' },335 { name: 'orange' },336 { name: 'blonde' }337 ];338 expect(scope.results).toBeUndefined();339 scope.$digest();340 scope.x = 'bl';341 scope.$digest();342 expect(scope.results).toEqual([343 { name: 'blue' },344 { name: 'black' },345 { name: 'blonde' }346 ]);347 scope.items = [];348 scope.$digest();349 expect(scope.results).toEqual([]);350 });351 it('should render a message when the repeat list is empty', function() {352 element = $compile(353 '<div>' +354 ' <div ng-repeat="item in items | filter:x as results">{{item}}</div>' +355 ' <div ng-if="results.length == 0">' +356 ' No results found...' +357 ' </div>' +358 '</div>')(scope);359 scope.items = [1,2,3,4,5,6];360 scope.$digest();361 expect(trim(element.text())).toEqual('123456');362 scope.x = '0';363 scope.$digest();364 expect(trim(element.text())).toEqual('No results found...');365 });366 it('should support alias identifiers containing reserved words', inject(function($exceptionHandler) {367 scope.x = 'bl';368 scope.items = [369 { name: 'red' },370 { name: 'blue' },371 { name: 'green' },372 { name: 'black' },373 { name: 'orange' },374 { name: 'blonde' }375 ];376 forEach([377 'null2',378 'qthis',379 'qthisq',380 'fundefined',381 '$$parent'382 ], function(name) {383 var expr = 'item in items | filter:x as ' + name + ' track by $index';384 element = $compile('<div><div ng-repeat="' + expr + '"></div></div>')(scope);385 scope.$digest();386 expect(scope[name]).toEqual([387 { name: 'blue' },388 { name: 'black' },389 { name: 'blonde' }390 ]);391 dealoc(element);392 });393 }));394 it('should throw if alias identifier is not a simple identifier', inject(function($exceptionHandler) {395 scope.x = 'bl';396 scope.items = [397 { name: 'red' },398 { name: 'blue' },399 { name: 'green' },400 { name: 'black' },401 { name: 'orange' },402 { name: 'blonde' }403 ];404 forEach([405 'null',406 'this',407 'undefined',408 '$parent',409 '$root',410 '$id',411 '$index',412 '$first',413 '$middle',414 '$last',415 '$even',416 '$odd',417 'obj[key]',418 'obj["key"]',419 'obj[\'key\']',420 'obj.property',421 'foo=6'422 ], function(expr) {423 var expression = ('item in items | filter:x as ' + expr + ' track by $index').replace(/"/g, '"');424 element = $compile(425 '<div>' +426 ' <div ng-repeat="' + expression + '">{{item}}</div>' +427 '</div>')(scope);428 var expected = new RegExp('^\\[ngRepeat:badident\\] alias \'' + escape(expr) + '\' is invalid --- must be a valid JS identifier which is not a reserved name');429 expect($exceptionHandler.errors.shift()[0].message).430 toMatch(expected);431 dealoc(element);432 });433 function escape(text) {434 return text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");435 }436 }));437 });438 it('should allow expressions over multiple lines', function() {439 element = $compile(440 '<ul>' +441 '<li ng-repeat="item in items\n' +442 '| filter:isTrue">{{item.name}}/</li>' +443 '</ul>')(scope);444 scope.isTrue = function() {return true;};445 scope.items = [{name: 'igor'}, {name: 'misko'}];446 scope.$digest();447 expect(element.text()).toEqual('igor/misko/');448 });449 it('should strip white space characters correctly', function() {450 element = $compile(451 '<ul>' +452 '<li ng-repeat="item \t\n \t in \n \t\n\n \nitems \t\t\n | filter:\n\n{' +453 '\n\t name:\n\n \'ko\'\n\n}\n\n | orderBy: \t \n \'name\' \n\n' +454 'track \t\n by \n\n\t $index \t\n ">{{item.name}}/</li>' +455 '</ul>')(scope);456 scope.items = [{name: 'igor'}, {name: 'misko'}];457 scope.$digest();458 expect(element.text()).toEqual('misko/');459 });460 it('should not ngRepeat over parent properties', function() {461 var Class = function() {};462 Class.prototype.abc = function() {};463 Class.prototype.value = 'abc';464 element = $compile(465 '<ul>' +466 '<li ng-repeat="(key, value) in items">{{key}}:{{value}};</li>' +467 '</ul>')(scope);468 scope.items = new Class();469 scope.items.name = 'value';470 scope.$digest();471 expect(element.text()).toEqual('name:value;');472 });473 it('should error on wrong parsing of ngRepeat', function() {474 element = jqLite('<ul><li ng-repeat="i dont parse"></li></ul>');475 $compile(element)(scope);476 expect($exceptionHandler.errors.shift()[0].message).477 toMatch(/^\[ngRepeat:iexp\] Expected expression in form of '_item_ in _collection_\[ track by _id_\]' but got 'i dont parse'\./);478 });479 it("should throw error when left-hand-side of ngRepeat can't be parsed", function() {480 element = jqLite('<ul><li ng-repeat="i dont parse in foo"></li></ul>');481 $compile(element)(scope);482 expect($exceptionHandler.errors.shift()[0].message).483 toMatch(/^\[ngRepeat:iidexp\] '_item_' in '_item_ in _collection_' should be an identifier or '\(_key_, _value_\)' expression, but got 'i dont parse'\./);484 });485 it('should expose iterator offset as $index when iterating over arrays',486 function() {487 element = $compile(488 '<ul>' +489 '<li ng-repeat="item in items">{{item}}:{{$index}}|</li>' +490 '</ul>')(scope);491 scope.items = ['misko', 'shyam', 'frodo'];492 scope.$digest();493 expect(element.text()).toEqual('misko:0|shyam:1|frodo:2|');494 });495 it('should expose iterator offset as $index when iterating over objects', function() {496 element = $compile(497 '<ul>' +498 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$index}}|</li>' +499 '</ul>')(scope);500 scope.items = {'misko':'m', 'shyam':'s', 'frodo':'f'};501 scope.$digest();502 expect(element.text()).toEqual('misko:m:0|shyam:s:1|frodo:f:2|');503 });504 it('should expose iterator offset as $index when iterating over objects with length key value 0', function() {505 element = $compile(506 '<ul>' +507 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$index}}|</li>' +508 '</ul>')(scope);509 scope.items = {'misko':'m', 'shyam':'s', 'frodo':'f', 'length':0};510 scope.$digest();511 expect(element.text()).toEqual('misko:m:0|shyam:s:1|frodo:f:2|length:0:3|');512 });513 it('should expose iterator position as $first, $middle and $last when iterating over arrays',514 function() {515 element = $compile(516 '<ul>' +517 '<li ng-repeat="item in items">{{item}}:{{$first}}-{{$middle}}-{{$last}}|</li>' +518 '</ul>')(scope);519 scope.items = ['misko', 'shyam', 'doug'];520 scope.$digest();521 expect(element.text()).522 toEqual('misko:true-false-false|shyam:false-true-false|doug:false-false-true|');523 scope.items.push('frodo');524 scope.$digest();525 expect(element.text()).526 toEqual('misko:true-false-false|' +527 'shyam:false-true-false|' +528 'doug:false-true-false|' +529 'frodo:false-false-true|');530 scope.items.pop();531 scope.items.pop();532 scope.$digest();533 expect(element.text()).toEqual('misko:true-false-false|shyam:false-false-true|');534 scope.items.pop();535 scope.$digest();536 expect(element.text()).toEqual('misko:true-false-true|');537 });538 it('should expose iterator position as $even and $odd when iterating over arrays',539 function() {540 element = $compile(541 '<ul>' +542 '<li ng-repeat="item in items">{{item}}:{{$even}}-{{$odd}}|</li>' +543 '</ul>')(scope);544 scope.items = ['misko', 'shyam', 'doug'];545 scope.$digest();546 expect(element.text()).547 toEqual('misko:true-false|shyam:false-true|doug:true-false|');548 scope.items.push('frodo');549 scope.$digest();550 expect(element.text()).551 toBe('misko:true-false|' +552 'shyam:false-true|' +553 'doug:true-false|' +554 'frodo:false-true|');555 scope.items.shift();556 scope.items.pop();557 scope.$digest();558 expect(element.text()).toBe('shyam:true-false|doug:false-true|');559 });560 it('should expose iterator position as $first, $middle and $last when iterating over objects',561 function() {562 element = $compile(563 '<ul>' +564 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$first}}-{{$middle}}-{{$last}}|</li>' +565 '</ul>')(scope);566 scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f'};567 scope.$digest();568 expect(element.text()).569 toEqual('misko:m:true-false-false|' +570 'shyam:s:false-true-false|' +571 'doug:d:false-true-false|' +572 'frodo:f:false-false-true|');573 delete scope.items.doug;574 delete scope.items.frodo;575 scope.$digest();576 expect(element.text()).toEqual('misko:m:true-false-false|shyam:s:false-false-true|');577 delete scope.items.shyam;578 scope.$digest();579 expect(element.text()).toEqual('misko:m:true-false-true|');580 });581 it('should expose iterator position as $even and $odd when iterating over objects',582 function() {583 element = $compile(584 '<ul>' +585 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$even}}-{{$odd}}|</li>' +586 '</ul>')(scope);587 scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f'};588 scope.$digest();589 expect(element.text()).590 toBe('misko:m:true-false|' +591 'shyam:s:false-true|' +592 'doug:d:true-false|' +593 'frodo:f:false-true|');594 delete scope.items.frodo;595 delete scope.items.shyam;596 scope.$digest();597 expect(element.text()).toBe('misko:m:true-false|doug:d:false-true|');598 });599 it('should calculate $first, $middle and $last when we filter out properties from an obj', function() {600 element = $compile(601 '<ul>' +602 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$first}}-{{$middle}}-{{$last}}|</li>' +603 '</ul>')(scope);604 scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f', '$toBeFilteredOut': 'xxxx'};605 scope.$digest();606 expect(element.text()).607 toEqual('misko:m:true-false-false|' +608 'shyam:s:false-true-false|' +609 'doug:d:false-true-false|' +610 'frodo:f:false-false-true|');611 });612 it('should calculate $even and $odd when we filter out properties from an obj', function() {613 element = $compile(614 '<ul>' +615 '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$even}}-{{$odd}}|</li>' +616 '</ul>')(scope);617 scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f', '$toBeFilteredOut': 'xxxx'};618 scope.$digest();619 expect(element.text()).620 toEqual('misko:m:true-false|' +621 'shyam:s:false-true|' +622 'doug:d:true-false|' +623 'frodo:f:false-true|');624 });625 it('should ignore $ and $$ properties', function() {626 element = $compile('<ul><li ng-repeat="i in items">{{i}}|</li></ul>')(scope);627 scope.items = ['a', 'b', 'c'];628 scope.items.$$hashKey = 'xxx';629 scope.items.$root = 'yyy';630 scope.$digest();631 expect(element.text()).toEqual('a|b|c|');632 });633 it('should repeat over nested arrays', function() {634 element = $compile(635 '<ul>' +636 '<li ng-repeat="subgroup in groups">' +637 '<div ng-repeat="group in subgroup">{{group}}|</div>X' +638 '</li>' +639 '</ul>')(scope);640 scope.groups = [['a', 'b'], ['c','d']];641 scope.$digest();642 expect(element.text()).toEqual('a|b|Xc|d|X');643 });644 it('should ignore non-array element properties when iterating over an array', function() {645 element = $compile('<ul><li ng-repeat="item in array">{{item}}|</li></ul>')(scope);646 scope.array = ['a', 'b', 'c'];647 scope.array.foo = '23';648 scope.array.bar = function() {};649 scope.$digest();650 expect(element.text()).toBe('a|b|c|');651 });652 it('should iterate over non-existent elements of a sparse array', function() {653 element = $compile('<ul><li ng-repeat="item in array track by $index">{{item}}|</li></ul>')(scope);654 scope.array = ['a', 'b'];655 scope.array[4] = 'c';656 scope.array[6] = 'd';657 scope.$digest();658 expect(element.text()).toBe('a|b|||c||d|');659 });660 it('should iterate over all kinds of types', function() {661 element = $compile('<ul><li ng-repeat="item in array">{{item}}|</li></ul>')(scope);662 scope.array = ['a', 1, null, undefined, {}];663 scope.$digest();664 expect(element.text()).toMatch(/a\|1\|\|\|\{\s*\}\|/);665 });666 it('should preserve data on move of elements', function() {667 element = $compile('<ul><li ng-repeat="item in array">{{item}}|</li></ul>')(scope);668 scope.array = ['a', 'b'];669 scope.$digest();670 var lis = element.find('li');671 lis.eq(0).data('mark', 'a');672 lis.eq(1).data('mark', 'b');673 scope.array = ['b', 'a'];674 scope.$digest();675 lis = element.find('li');676 expect(lis.eq(0).data('mark')).toEqual('b');677 expect(lis.eq(1).data('mark')).toEqual('a');678 });679 describe('nesting in replaced directive templates', function() {680 it('should work when placed on a non-root element of attr directive with SYNC replaced template',681 inject(function($templateCache, $compile, $rootScope) {682 $compileProvider.directive('rr', function() {683 return {684 restrict: 'A',685 replace: true,686 template: '<div ng-repeat="i in items">{{i}}|</div>'687 };688 });689 element = jqLite('<div><span rr>{{i}}|</span></div>');690 $compile(element)($rootScope);691 $rootScope.$apply();692 expect(element.text()).toBe('');693 $rootScope.items = [1, 2];694 $rootScope.$apply();695 expect(element.text()).toBe('1|2|');696 expect(sortedHtml(element)).toBe(697 '<div>' +698 '<!-- ngRepeat: i in items -->' +699 '<div ng-repeat="i in items" rr="">1|</div>' +700 '<!-- end ngRepeat: i in items -->' +701 '<div ng-repeat="i in items" rr="">2|</div>' +702 '<!-- end ngRepeat: i in items -->' +703 '</div>'704 );705 }));706 it('should work when placed on a non-root element of attr directive with ASYNC replaced template',707 inject(function($templateCache, $compile, $rootScope) {708 $compileProvider.directive('rr', function() {709 return {710 restrict: 'A',711 replace: true,712 templateUrl: 'rr.html'713 };714 });715 $templateCache.put('rr.html', '<div ng-repeat="i in items">{{i}}|</div>');716 element = jqLite('<div><span rr>{{i}}|</span></div>');717 $compile(element)($rootScope);718 $rootScope.$apply();719 expect(element.text()).toBe('');720 $rootScope.items = [1, 2];721 $rootScope.$apply();722 expect(element.text()).toBe('1|2|');723 expect(sortedHtml(element)).toBe(724 '<div>' +725 '<!-- ngRepeat: i in items -->' +726 '<div ng-repeat="i in items" rr="">1|</div>' +727 '<!-- end ngRepeat: i in items -->' +728 '<div ng-repeat="i in items" rr="">2|</div>' +729 '<!-- end ngRepeat: i in items -->' +730 '</div>'731 );732 }));733 it('should work when placed on a root element of attr directive with SYNC replaced template',734 inject(function($templateCache, $compile, $rootScope) {735 $compileProvider.directive('replaceMeWithRepeater', function() {736 return {737 replace: true,738 template: '<span ng-repeat="i in items">{{log(i)}}</span>'739 };740 });741 element = jqLite('<span replace-me-with-repeater></span>');742 $compile(element)($rootScope);743 expect(element.text()).toBe('');744 var logs = [];745 $rootScope.log = function(t) { logs.push(t); };746 // This creates one item, but it has no parent so we can't get to it747 $rootScope.items = [1, 2];748 $rootScope.$apply();749 expect(logs).toContain(1);750 expect(logs).toContain(2);751 logs.length = 0;752 // This cleans up to prevent memory leak753 $rootScope.items = [];754 $rootScope.$apply();755 expect(angular.mock.dump(element)).toBe('<!-- ngRepeat: i in items -->');756 expect(logs.length).toBe(0);757 }));758 it('should work when placed on a root element of attr directive with ASYNC replaced template',759 inject(function($templateCache, $compile, $rootScope) {760 $compileProvider.directive('replaceMeWithRepeater', function() {761 return {762 replace: true,763 templateUrl: 'replace-me-with-repeater.html'764 };765 });766 $templateCache.put('replace-me-with-repeater.html', '<div ng-repeat="i in items">{{log(i)}}</div>');767 element = jqLite('<span>-</span><span replace-me-with-repeater></span><span>-</span>');768 $compile(element)($rootScope);769 expect(element.text()).toBe('--');770 var logs = [];771 $rootScope.log = function(t) { logs.push(t); };772 // This creates one item, but it has no parent so we can't get to it773 $rootScope.items = [1, 2];774 $rootScope.$apply();775 expect(logs).toContain(1);776 expect(logs).toContain(2);777 logs.length = 0;778 // This cleans up to prevent memory leak779 $rootScope.items = [];780 $rootScope.$apply();781 expect(sortedHtml(element)).toBe('<span>-</span><!-- ngRepeat: i in items --><span>-</span>');782 expect(logs.length).toBe(0);783 }));784 it('should work when placed on a root element of element directive with SYNC replaced template',785 inject(function($templateCache, $compile, $rootScope) {786 $compileProvider.directive('replaceMeWithRepeater', function() {787 return {788 restrict: 'E',789 replace: true,790 template: '<div ng-repeat="i in [1,2,3]">{{i}}</div>'791 };792 });793 element = $compile('<div><replace-me-with-repeater></replace-me-with-repeater></div>')($rootScope);794 expect(element.text()).toBe('');795 $rootScope.$apply();796 expect(element.text()).toBe('123');797 }));798 it('should work when placed on a root element of element directive with ASYNC replaced template',799 inject(function($templateCache, $compile, $rootScope) {800 $compileProvider.directive('replaceMeWithRepeater', function() {801 return {802 restrict: 'E',803 replace: true,804 templateUrl: 'replace-me-with-repeater.html'805 };806 });807 $templateCache.put('replace-me-with-repeater.html', '<div ng-repeat="i in [1,2,3]">{{i}}</div>');808 element = $compile('<div><replace-me-with-repeater></replace-me-with-repeater></div>')($rootScope);809 expect(element.text()).toBe('');810 $rootScope.$apply();811 expect(element.text()).toBe('123');812 }));813 it('should work when combined with an ASYNC template that loads after the first digest', inject(function($httpBackend, $compile, $rootScope) {814 $compileProvider.directive('test', function() {815 return {816 templateUrl: 'test.html'817 };818 });819 $httpBackend.whenGET('test.html').respond('hello');820 element = jqLite('<div><div ng-repeat="i in items" test></div></div>');821 $compile(element)($rootScope);822 $rootScope.items = [1];823 $rootScope.$apply();824 expect(element.text()).toBe('');825 $httpBackend.flush();826 expect(element.text()).toBe('hello');827 $rootScope.items = [];828 $rootScope.$apply();829 // Note: there are still comments in element!830 expect(element.children().length).toBe(0);831 expect(element.text()).toBe('');832 }));833 });834 it('should add separator comments after each item', inject(function($compile, $rootScope) {835 var check = function() {836 var children = element.find('div');837 expect(children.length).toBe(3);838 // Note: COMMENT_NODE === 8839 expect(children[0].nextSibling.nodeType).toBe(8);840 expect(children[0].nextSibling.nodeValue).toBe(' end ngRepeat: val in values ');841 expect(children[1].nextSibling.nodeType).toBe(8);842 expect(children[1].nextSibling.nodeValue).toBe(' end ngRepeat: val in values ');843 expect(children[2].nextSibling.nodeType).toBe(8);844 expect(children[2].nextSibling.nodeValue).toBe(' end ngRepeat: val in values ');845 };846 $rootScope.values = [1, 2, 3];847 element = $compile(848 '<div>' +849 '<div ng-repeat="val in values">val:{{val}};</div>' +850 '</div>'851 )($rootScope);852 $rootScope.$digest();853 check();854 $rootScope.values.shift();855 $rootScope.values.push(4);856 $rootScope.$digest();857 check();858 }));859 it('should remove whole block even if the number of elements inside it changes', inject(860 function($compile, $rootScope) {861 $rootScope.values = [1, 2, 3];862 element = $compile(863 '<div>' +864 '<div ng-repeat-start="val in values"></div>' +865 '<span>{{val}}</span>' +866 '<p ng-repeat-end></p>' +867 '</div>'868 )($rootScope);869 $rootScope.$digest();870 var ends = element.find('p');871 expect(ends.length).toBe(3);872 // insert an extra element inside the second block873 var extra = angular.element('<strong></strong>')[0];874 element[0].insertBefore(extra, ends[1]);875 $rootScope.values.splice(1, 1);876 $rootScope.$digest();877 // expect the strong tag to be removed too878 expect(childrenTagsOf(element)).toEqual([879 'div', 'span', 'p',880 'div', 'span', 'p'881 ]);882 }));883 it('should move whole block even if the number of elements inside it changes', inject(884 function($compile, $rootScope) {885 $rootScope.values = [1, 2, 3];886 element = $compile(887 '<div>' +888 '<div ng-repeat-start="val in values"></div>' +889 '<span>{{val}}</span>' +890 '<p ng-repeat-end></p>' +891 '</div>'892 )($rootScope);893 $rootScope.$digest();894 var ends = element.find('p');895 expect(ends.length).toBe(3);896 // insert an extra element inside the third block897 var extra = angular.element('<strong></strong>')[0];898 element[0].insertBefore(extra, ends[2]);899 // move the third block to the beginning900 $rootScope.values.unshift($rootScope.values.pop());901 $rootScope.$digest();902 // expect the strong tag to be moved too903 expect(childrenTagsOf(element)).toEqual([904 'div', 'span', 'strong', 'p',905 'div', 'span', 'p',906 'div', 'span', 'p'907 ]);908 }));909 describe('stability', function() {910 var a, b, c, d, lis;911 beforeEach(function() {912 element = $compile(913 '<ul>' +914 '<li ng-repeat="item in items">{{item}}</li>' +915 '</ul>')(scope);916 a = {};917 b = {};918 c = {};919 d = {};920 scope.items = [a, b, c];921 scope.$digest();922 lis = element.find('li');923 });924 it('should preserve the order of elements', function() {925 scope.items = [a, c, d];926 scope.$digest();927 var newElements = element.find('li');928 expect(newElements[0]).toEqual(lis[0]);929 expect(newElements[1]).toEqual(lis[2]);930 expect(newElements[2]).not.toEqual(lis[1]);931 });932 it('should throw error on adding existing duplicates and recover', function() {933 scope.items = [a, a, a];934 scope.$digest();935 expect($exceptionHandler.errors.shift().message).936 toMatch(937 /^\[ngRepeat:dupes\] Duplicates in a repeater are not allowed\. Use 'track by' expression to specify unique keys\. Repeater: item in items, Duplicate key: object:3, Duplicate value: {}/);938 // recover939 scope.items = [a];940 scope.$digest();941 var newElements = element.find('li');942 expect(newElements.length).toEqual(1);943 expect(newElements[0]).toEqual(lis[0]);944 scope.items = [];945 scope.$digest();946 newElements = element.find('li');947 expect(newElements.length).toEqual(0);948 });949 it('should throw error on new duplicates and recover', function() {950 scope.items = [d, d, d];951 scope.$digest();952 expect($exceptionHandler.errors.shift().message).953 toMatch(954 /^\[ngRepeat:dupes\] Duplicates in a repeater are not allowed\. Use 'track by' expression to specify unique keys\. Repeater: item in items, Duplicate key: object:9, Duplicate value: {}/);955 // recover956 scope.items = [a];957 scope.$digest();958 var newElements = element.find('li');959 expect(newElements.length).toEqual(1);960 expect(newElements[0]).toEqual(lis[0]);961 scope.items = [];962 scope.$digest();963 newElements = element.find('li');964 expect(newElements.length).toEqual(0);965 });966 it('should reverse items when the collection is reversed', function() {967 scope.items = [a, b, c];968 scope.$digest();969 lis = element.find('li');970 scope.items = [c, b, a];971 scope.$digest();972 var newElements = element.find('li');973 expect(newElements.length).toEqual(3);974 expect(newElements[0]).toEqual(lis[2]);975 expect(newElements[1]).toEqual(lis[1]);976 expect(newElements[2]).toEqual(lis[0]);977 });978 it('should reuse elements even when model is composed of primitives', function() {979 // rebuilding repeater from scratch can be expensive, we should try to avoid it even for980 // model that is composed of primitives.981 scope.items = ['hello', 'cau', 'ahoj'];982 scope.$digest();983 lis = element.find('li');984 lis[2].id = 'yes';985 scope.items = ['ahoj', 'hello', 'cau'];986 scope.$digest();987 var newLis = element.find('li');988 expect(newLis.length).toEqual(3);989 expect(newLis[0]).toEqual(lis[2]);990 expect(newLis[1]).toEqual(lis[0]);991 expect(newLis[2]).toEqual(lis[1]);992 });993 it('should be stable even if the collection is initially undefined', function() {994 scope.items = undefined;995 scope.$digest();996 scope.items = [997 { name: 'A' },998 { name: 'B' },999 { name: 'C' }1000 ];1001 scope.$digest();1002 lis = element.find('li');1003 scope.items.shift();1004 scope.$digest();1005 var newLis = element.find('li');1006 expect(newLis.length).toBe(2);1007 expect(newLis[0]).toBe(lis[1]);1008 });1009 });1010 describe('compatibility', function() {1011 it('should allow mixing ngRepeat and another element transclusion directive', function() {1012 $compileProvider.directive('elmTrans', valueFn({1013 transclude: 'element',1014 controller: function($transclude, $scope, $element) {1015 $transclude(function(transcludedNodes) {1016 $element.after(']]').after(transcludedNodes).after('[[');1017 });1018 }1019 }));1020 inject(function($compile, $rootScope) {1021 element = $compile('<div><div ng-repeat="i in [1,2]" elm-trans>{{i}}</div></div>')($rootScope);1022 $rootScope.$digest();1023 expect(element.text()).toBe('[[1]][[2]]');1024 });1025 });1026 it('should allow mixing ngRepeat with ngInclude', inject(function($compile, $rootScope, $httpBackend) {1027 $httpBackend.whenGET('someTemplate.html').respond('<p>some template; </p>');1028 element = $compile('<div><div ng-repeat="i in [1,2]" ng-include="\'someTemplate.html\'"></div></div>')($rootScope);1029 $rootScope.$digest();1030 $httpBackend.flush();1031 expect(element.text()).toBe('some template; some template; ');1032 }));1033 it('should allow mixing ngRepeat with ngIf', inject(function($compile, $rootScope) {1034 element = $compile('<div><div ng-repeat="i in [1,2,3,4]" ng-if="i % 2 == 0">{{i}};</div></div>')($rootScope);1035 $rootScope.$digest();1036 expect(element.text()).toBe('2;4;');1037 }));1038 });1039 describe('ngRepeatStart', function() {1040 it('should grow multi-node repeater', inject(function($compile, $rootScope) {1041 $rootScope.show = false;1042 $rootScope.books = [1043 {title:'T1', description: 'D1'},1044 {title:'T2', description: 'D2'}1045 ];1046 element = $compile(1047 '<div>' +1048 '<dt ng-repeat-start="book in books">{{book.title}}:</dt>' +1049 '<dd ng-repeat-end>{{book.description}};</dd>' +1050 '</div>')($rootScope);1051 $rootScope.$digest();1052 expect(element.text()).toEqual('T1:D1;T2:D2;');1053 $rootScope.books.push({title:'T3', description: 'D3'});1054 $rootScope.$digest();1055 expect(element.text()).toEqual('T1:D1;T2:D2;T3:D3;');1056 }));1057 it('should not clobber ng-if when updating collection', inject(function($compile, $rootScope) {1058 $rootScope.values = [1, 2, 3];1059 $rootScope.showMe = true;1060 element = $compile(1061 '<div>' +1062 '<div ng-repeat-start="val in values">val:{{val}};</div>' +1063 '<div ng-if="showMe" ng-repeat-end>if:{{val}};</div>' +1064 '</div>'1065 )($rootScope);1066 $rootScope.$digest();1067 expect(element.find('div').length).toBe(6);1068 $rootScope.values.shift();1069 $rootScope.values.push(4);1070 $rootScope.$digest();1071 expect(element.find('div').length).toBe(6);1072 expect(element.text()).not.toContain('if:1;');1073 }));1074 });1075});1076describe('ngRepeat and transcludes', function() {1077 it('should allow access to directive controller from children when used in a replace template', function() {1078 var controller;1079 module(function($compileProvider) {1080 var directive = $compileProvider.directive;1081 directive('template', valueFn({1082 template: '<div ng-repeat="l in [1]"><span test></span></div>',1083 replace: true,1084 controller: function() {1085 this.flag = true;1086 }1087 }));1088 directive('test', valueFn({1089 require: '^template',1090 link: function(scope, el, attr, ctrl) {1091 controller = ctrl;1092 }1093 }));1094 });1095 inject(function($compile, $rootScope) {1096 var element = $compile('<div><div template></div></div>')($rootScope);1097 $rootScope.$apply();1098 expect(controller.flag).toBe(true);1099 dealoc(element);1100 });1101 });1102 it('should use the correct transcluded scope', function() {1103 module(function($compileProvider) {1104 $compileProvider.directive('iso', valueFn({1105 restrict: 'E',1106 transclude: true,1107 template: '<div ng-repeat="a in [1]"><div ng-transclude></div></div>',1108 scope: {}1109 }));1110 });1111 inject(function($compile, $rootScope) {1112 $rootScope.val = 'transcluded content';1113 var element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);1114 $rootScope.$digest();1115 expect(trim(element.text())).toEqual('transcluded content');1116 dealoc(element);1117 });1118 });1119 it('should set the state before linking', function() {1120 module(function($compileProvider) {1121 $compileProvider.directive('assertA', valueFn(function(scope) {1122 // This linking function asserts that a is set.1123 // If we only test this by asserting binding, it will work even if the value is set later.1124 expect(scope.a).toBeDefined();1125 }));1126 });1127 inject(function($compile, $rootScope) {1128 var element = $compile('<div><span ng-repeat="a in [1]"><span assert-a></span></span></div>')($rootScope);1129 $rootScope.$digest();1130 dealoc(element);1131 });1132 });1133 it('should work with svg elements when the svg container is transcluded', function() {1134 module(function($compileProvider) {1135 $compileProvider.directive('svgContainer', function() {1136 return {1137 template: '<svg ng-transclude></svg>',1138 replace: true,1139 transclude: true1140 };1141 });1142 });1143 inject(function($compile, $rootScope) {1144 var element = $compile('<svg-container><circle ng-repeat="r in rows"></circle></svg-container>')($rootScope);1145 $rootScope.rows = [1];1146 $rootScope.$apply();1147 var circle = element.find('circle');1148 expect(circle[0].toString()).toMatch(/SVG/);1149 dealoc(element);1150 });1151 });1152});1153describe('ngRepeat animations', function() {1154 var body, element, $rootElement;1155 function html(content) {1156 $rootElement.html(content);1157 element = $rootElement.children().eq(0);1158 return element;1159 }1160 beforeEach(module('ngAnimate'));1161 beforeEach(module('ngAnimateMock'));1162 beforeEach(module(function() {1163 // we need to run animation on attached elements;1164 return function(_$rootElement_) {1165 $rootElement = _$rootElement_;1166 body = jqLite(document.body);1167 body.append($rootElement);1168 };1169 }));1170 afterEach(function() {1171 body.empty();1172 });1173 it('should fire off the enter animation',1174 inject(function($compile, $rootScope, $animate) {1175 var item;1176 element = $compile(html(1177 '<div><div ' +1178 'ng-repeat="item in items">' +1179 '{{ item }}' +1180 '</div></div>'1181 ))($rootScope);1182 $rootScope.$digest(); // re-enable the animations;1183 $rootScope.items = ['1','2','3'];1184 $rootScope.$digest();1185 item = $animate.queue.shift();1186 expect(item.event).toBe('enter');1187 expect(item.element.text()).toBe('1');1188 item = $animate.queue.shift();1189 expect(item.event).toBe('enter');1190 expect(item.element.text()).toBe('2');1191 item = $animate.queue.shift();1192 expect(item.event).toBe('enter');1193 expect(item.element.text()).toBe('3');1194 }));1195 it('should fire off the leave animation',1196 inject(function($compile, $rootScope, $animate) {1197 var item;1198 element = $compile(html(1199 '<div><div ' +1200 'ng-repeat="item in items">' +1201 '{{ item }}' +1202 '</div></div>'1203 ))($rootScope);1204 $rootScope.items = ['1','2','3'];1205 $rootScope.$digest();1206 item = $animate.queue.shift();1207 expect(item.event).toBe('enter');1208 expect(item.element.text()).toBe('1');1209 item = $animate.queue.shift();1210 expect(item.event).toBe('enter');1211 expect(item.element.text()).toBe('2');1212 item = $animate.queue.shift();1213 expect(item.event).toBe('enter');1214 expect(item.element.text()).toBe('3');1215 $rootScope.items = ['1','3'];1216 $rootScope.$digest();1217 item = $animate.queue.shift();1218 expect(item.event).toBe('leave');1219 expect(item.element.text()).toBe('2');1220 }));1221 it('should not change the position of the block that is being animated away via a leave animation',1222 inject(function($compile, $rootScope, $animate, $document, $sniffer, $timeout) {1223 if (!$sniffer.transitions) return;1224 var item;1225 var ss = createMockStyleSheet($document);1226 try {1227 $animate.enabled(true);1228 ss.addRule('.animate-me div',1229 '-webkit-transition:1s linear all; transition:1s linear all;');1230 element = $compile(html('<div class="animate-me">' +1231 '<div ng-repeat="item in items">{{ item }}</div>' +1232 '</div>'))($rootScope);1233 $rootScope.items = ['1','2','3'];1234 $rootScope.$digest();1235 expect(element.text()).toBe('123');1236 $rootScope.items = ['1','3'];1237 $rootScope.$digest();1238 expect(element.text()).toBe('123'); // the original order should be preserved1239 $animate.flush();1240 $timeout.flush(1500); // 1s * 1.5 closing buffer1241 expect(element.text()).toBe('13');1242 } finally {1243 ss.destroy();1244 }1245 })1246 );1247 it('should fire off the move animation',1248 inject(function($compile, $rootScope, $animate) {1249 var item;1250 element = $compile(html(1251 '<div>' +1252 '<div ng-repeat="item in items">' +1253 '{{ item }}' +1254 '</div>' +1255 '</div>'1256 ))($rootScope);1257 $rootScope.items = ['1','2','3'];1258 $rootScope.$digest();1259 item = $animate.queue.shift();1260 expect(item.event).toBe('enter');1261 expect(item.element.text()).toBe('1');1262 item = $animate.queue.shift();1263 expect(item.event).toBe('enter');1264 expect(item.element.text()).toBe('2');1265 item = $animate.queue.shift();1266 expect(item.event).toBe('enter');1267 expect(item.element.text()).toBe('3');1268 $rootScope.items = ['2','3','1'];1269 $rootScope.$digest();1270 item = $animate.queue.shift();1271 expect(item.event).toBe('move');1272 expect(item.element.text()).toBe('2');1273 item = $animate.queue.shift();1274 expect(item.event).toBe('move');1275 expect(item.element.text()).toBe('3');1276 })1277 );...
messagesSpec.js
Source:messagesSpec.js
...16 element = $compile('<div ng-messages="col">' +17 ' <div ng-message="val">Message is set</div>' +18 '</div>')($rootScope);19 $rootScope.$digest();20 expect(element.text()).not.toContain('Message is set');21 $rootScope.$apply(function() {22 $rootScope.col = { val: true };23 });24 expect(element.text()).toContain('Message is set');25 }));26 it('should render the same message if multiple message keys match', inject(function($rootScope, $compile) {27 element = $compile('<div ng-messages="col">' +28 ' <div ng-message="one, two, three">Message is set</div>' +29 '</div>')($rootScope);30 $rootScope.$digest();31 expect(element.text()).not.toContain('Message is set');32 $rootScope.$apply(function() {33 $rootScope.col = { one: true };34 });35 expect(element.text()).toContain('Message is set');36 $rootScope.$apply(function() {37 $rootScope.col = { two: true, one: false };38 });39 expect(element.text()).toContain('Message is set');40 $rootScope.$apply(function() {41 $rootScope.col = { three: true, two: false };42 });43 expect(element.text()).toContain('Message is set');44 $rootScope.$apply(function() {45 $rootScope.col = { three: false };46 });47 expect(element.text()).not.toContain('Message is set');48 }));49 it('should use the when attribute when an element directive is used',50 inject(function($rootScope, $compile) {51 element = $compile('<ng-messages for="col">' +52 ' <ng-message when="val">Message is set</div>' +53 '</ng-messages>')($rootScope);54 $rootScope.$digest();55 expect(element.text()).not.toContain('Message is set');56 $rootScope.$apply(function() {57 $rootScope.col = { val: true };58 });59 expect(element.text()).toContain('Message is set');60 }));61 it('should render the same message if multiple message keys match based on the when attribute', inject(function($rootScope, $compile) {62 element = $compile('<ng-messages for="col">' +63 ' <ng-message when=" one two three ">Message is set</div>' +64 '</ng-messages>')($rootScope);65 $rootScope.$digest();66 expect(element.text()).not.toContain('Message is set');67 $rootScope.$apply(function() {68 $rootScope.col = { one: true };69 });70 expect(element.text()).toContain('Message is set');71 $rootScope.$apply(function() {72 $rootScope.col = { two: true, one: false };73 });74 expect(element.text()).toContain('Message is set');75 $rootScope.$apply(function() {76 $rootScope.col = { three: true, two: false };77 });78 expect(element.text()).toContain('Message is set');79 $rootScope.$apply(function() {80 $rootScope.col = { three: false };81 });82 expect(element.text()).not.toContain('Message is set');83 }));84 it('should allow a dynamic expression to be set when ng-message-exp is used',85 inject(function($rootScope, $compile) {86 element = $compile('<div ng-messages="col">' +87 ' <div ng-message-exp="variable">Message is crazy</div>' +88 '</div>')($rootScope);89 $rootScope.$digest();90 expect(element.text()).not.toContain('Message is crazy');91 $rootScope.$apply(function() {92 $rootScope.variable = 'error';93 $rootScope.col = { error: true };94 });95 expect(element.text()).toContain('Message is crazy');96 $rootScope.$apply(function() {97 $rootScope.col = { error: false, failure: true };98 });99 expect(element.text()).not.toContain('Message is crazy');100 $rootScope.$apply(function() {101 $rootScope.variable = ['failure'];102 });103 expect(element.text()).toContain('Message is crazy');104 $rootScope.$apply(function() {105 $rootScope.variable = null;106 });107 expect(element.text()).not.toContain('Message is crazy');108 }));109 it('should allow a dynamic expression to be set when the when-exp attribute is used',110 inject(function($rootScope, $compile) {111 element = $compile('<ng-messages for="col">' +112 ' <ng-message when-exp="variable">Message is crazy</ng-message>' +113 '</ng-messages>')($rootScope);114 $rootScope.$digest();115 expect(element.text()).not.toContain('Message is crazy');116 $rootScope.$apply(function() {117 $rootScope.variable = 'error, failure';118 $rootScope.col = { error: true };119 });120 expect(element.text()).toContain('Message is crazy');121 $rootScope.$apply(function() {122 $rootScope.col = { error: false, failure: true };123 });124 expect(element.text()).toContain('Message is crazy');125 $rootScope.$apply(function() {126 $rootScope.variable = [];127 });128 expect(element.text()).not.toContain('Message is crazy');129 $rootScope.$apply(function() {130 $rootScope.variable = null;131 });132 expect(element.text()).not.toContain('Message is crazy');133 }));134 they('should render empty when $prop is used as a collection value',135 { 'null': null,136 'false': false,137 '0': 0,138 '[]': [],139 '[{}]': [{}],140 '': '',141 '{ val2 : true }': { val2: true } },142 function(prop) {143 inject(function($rootScope, $compile) {144 element = $compile('<div ng-messages="col">' +145 ' <div ng-message="val">Message is set</div>' +146 '</div>')($rootScope);147 $rootScope.$digest();148 $rootScope.$apply(function() {149 $rootScope.col = prop;150 });151 expect(element.text()).not.toContain('Message is set');152 });153 });154 they('should insert and remove matching inner elements when $prop is used as a value',155 { 'true': true,156 '1': 1,157 '{}': {},158 '[]': [],159 '[null]': [null] },160 function(prop) {161 inject(function($rootScope, $compile) {162 element = $compile('<div ng-messages="col">' +163 ' <div ng-message="blue">This message is blue</div>' +164 ' <div ng-message="red">This message is red</div>' +165 '</div>')($rootScope);166 $rootScope.$apply(function() {167 $rootScope.col = {};168 });169 expect(messageChildren(element).length).toBe(0);170 expect(trim(element.text())).toEqual('');171 $rootScope.$apply(function() {172 $rootScope.col = {173 blue: true,174 red: false175 };176 });177 expect(messageChildren(element).length).toBe(1);178 expect(trim(element.text())).toEqual('This message is blue');179 $rootScope.$apply(function() {180 $rootScope.col = {181 red: prop182 };183 });184 expect(messageChildren(element).length).toBe(1);185 expect(trim(element.text())).toEqual('This message is red');186 $rootScope.$apply(function() {187 $rootScope.col = null;188 });189 expect(messageChildren(element).length).toBe(0);190 expect(trim(element.text())).toEqual('');191 $rootScope.$apply(function() {192 $rootScope.col = {193 blue: 0,194 red: null195 };196 });197 expect(messageChildren(element).length).toBe(0);198 expect(trim(element.text())).toEqual('');199 });200 });201 it('should display the elements in the order defined in the DOM',202 inject(function($rootScope, $compile) {203 element = $compile('<div ng-messages="col">' +204 ' <div ng-message="one">Message#one</div>' +205 ' <div ng-message="two">Message#two</div>' +206 ' <div ng-message="three">Message#three</div>' +207 '</div>')($rootScope);208 $rootScope.$apply(function() {209 $rootScope.col = {210 three: true,211 one: true,212 two: true213 };214 });215 angular.forEach(['one','two','three'], function(key) {216 expect(s(element.text())).toEqual('Message#' + key);217 $rootScope.$apply(function() {218 $rootScope.col[key] = false;219 });220 });221 expect(s(element.text())).toEqual('');222 }));223 it('should add ng-active/ng-inactive CSS classes to the element when errors are/aren\'t displayed',224 inject(function($rootScope, $compile) {225 element = $compile('<div ng-messages="col">' +226 ' <div ng-message="ready">This message is ready</div>' +227 '</div>')($rootScope);228 $rootScope.$apply(function() {229 $rootScope.col = {};230 });231 expect(element.hasClass('ng-active')).toBe(false);232 expect(element.hasClass('ng-inactive')).toBe(true);233 $rootScope.$apply(function() {234 $rootScope.col = { ready: true };235 });236 expect(element.hasClass('ng-active')).toBe(true);237 expect(element.hasClass('ng-inactive')).toBe(false);238 }));239 it('should automatically re-render the messages when other directives dynmically change them',240 inject(function($rootScope, $compile) {241 element = $compile('<div ng-messages="col">' +242 ' <div ng-message="primary">Enter something</div>' +243 ' <div ng-repeat="item in items">' +244 ' <div ng-message-exp="item.name">{{ item.text }}</div>' +245 ' </div>' +246 '</div>')($rootScope);247 $rootScope.$apply(function() {248 $rootScope.col = {};249 $rootScope.items = [250 { text: 'Your age is incorrect', name: 'age' },251 { text: 'You\'re too tall man!', name: 'height' },252 { text: 'Your hair is too long', name: 'hair' }253 ];254 });255 expect(messageChildren(element).length).toBe(0);256 expect(trim(element.text())).toEqual("");257 $rootScope.$apply(function() {258 $rootScope.col = { hair: true };259 });260 expect(messageChildren(element).length).toBe(1);261 expect(trim(element.text())).toEqual("Your hair is too long");262 $rootScope.$apply(function() {263 $rootScope.col = { age: true, hair: true};264 });265 expect(messageChildren(element).length).toBe(1);266 expect(trim(element.text())).toEqual("Your age is incorrect");267 $rootScope.$apply(function() {268 // remove the age!269 $rootScope.items.shift();270 });271 expect(messageChildren(element).length).toBe(1);272 expect(trim(element.text())).toEqual("Your hair is too long");273 $rootScope.$apply(function() {274 // remove the hair!275 $rootScope.items.length = 0;276 $rootScope.col.primary = true;277 });278 expect(messageChildren(element).length).toBe(1);279 expect(trim(element.text())).toEqual("Enter something");280 }));281 it('should be compatible with ngBind',282 inject(function($rootScope, $compile) {283 element = $compile('<div ng-messages="col">' +284 ' <div ng-message="required" ng-bind="errorMessages.required"></div>' +285 ' <div ng-message="extra" ng-bind="errorMessages.extra"></div>' +286 '</div>')($rootScope);287 $rootScope.$apply(function() {288 $rootScope.col = {289 required: true,290 extra: true291 };292 $rootScope.errorMessages = {293 required: 'Fill in the text field.',294 extra: 'Extra error message.'295 };296 });297 expect(messageChildren(element).length).toBe(1);298 expect(trim(element.text())).toEqual('Fill in the text field.');299 $rootScope.$apply(function() {300 $rootScope.col.required = false;301 $rootScope.col.extra = true;302 });303 expect(messageChildren(element).length).toBe(1);304 expect(trim(element.text())).toEqual('Extra error message.');305 $rootScope.$apply(function() {306 $rootScope.errorMessages.extra = 'New error message.';307 });308 expect(messageChildren(element).length).toBe(1);309 expect(trim(element.text())).toEqual('New error message.');310 }));311 // issue #12856312 it('should only detach the message object that is associated with the message node being removed',313 inject(function($rootScope, $compile, $animate) {314 // We are going to spy on the `leave` method to give us control over315 // when the element is actually removed316 spyOn($animate, 'leave');317 // Create a basic ng-messages set up318 element = $compile('<div ng-messages="col">' +319 ' <div ng-message="primary">Enter something</div>' +320 '</div>')($rootScope);321 // Trigger the message to be displayed322 $rootScope.col = { primary: true };323 $rootScope.$digest();324 expect(messageChildren(element).length).toEqual(1);325 var oldMessageNode = messageChildren(element)[0];326 // Remove the message327 $rootScope.col = { primary: undefined };328 $rootScope.$digest();329 // Since we have spied on the `leave` method, the message node is still in the DOM330 expect($animate.leave).toHaveBeenCalledOnce();331 var nodeToRemove = $animate.leave.mostRecentCall.args[0][0];332 expect(nodeToRemove).toBe(oldMessageNode);333 $animate.leave.reset();334 // Add the message back in335 $rootScope.col = { primary: true };336 $rootScope.$digest();337 // Simulate the animation completing on the node338 jqLite(nodeToRemove).remove();339 // We should not get another call to `leave`340 expect($animate.leave).not.toHaveBeenCalled();341 // There should only be the new message node342 expect(messageChildren(element).length).toEqual(1);343 var newMessageNode = messageChildren(element)[0];344 expect(newMessageNode).not.toBe(oldMessageNode);345 }));346 it('should render animations when the active/inactive classes are added/removed', function() {347 module('ngAnimate');348 module('ngAnimateMock');349 inject(function($rootScope, $compile, $animate) {350 element = $compile('<div ng-messages="col">' +351 ' <div ng-message="ready">This message is ready</div>' +352 '</div>')($rootScope);353 $rootScope.$apply(function() {354 $rootScope.col = {};355 });356 var event = $animate.queue.pop();357 expect(event.event).toBe('setClass');358 expect(event.args[1]).toBe('ng-inactive');359 expect(event.args[2]).toBe('ng-active');360 $rootScope.$apply(function() {361 $rootScope.col = { ready: true };362 });363 event = $animate.queue.pop();364 expect(event.event).toBe('setClass');365 expect(event.args[1]).toBe('ng-active');366 expect(event.args[2]).toBe('ng-inactive');367 });368 });369 describe('when including templates', function() {370 they('should work with a dynamic collection model which is managed by ngRepeat',371 {'<div ng-messages-include="...">': '<div ng-messages="item">' +372 '<div ng-messages-include="abc.html"></div>' +373 '</div>',374 '<ng-messages-include src="...">': '<ng-messages for="item">' +375 '<ng-messages-include src="abc.html"></ng-messages-include>' +376 '</ng-messages>'},377 function(html) {378 inject(function($compile, $rootScope, $templateCache) {379 $templateCache.put('abc.html', '<div ng-message="a">A</div>' +380 '<div ng-message="b">B</div>' +381 '<div ng-message="c">C</div>');382 html = '<div><div ng-repeat="item in items">' + html + '</div></div>';383 $rootScope.items = [{},{},{}];384 element = $compile(html)($rootScope);385 $rootScope.$apply(function() {386 $rootScope.items[0].a = true;387 $rootScope.items[1].b = true;388 $rootScope.items[2].c = true;389 });390 var elements = element[0].querySelectorAll('[ng-repeat]');391 // all three collections should have at least one error showing up392 expect(messageChildren(element).length).toBe(3);393 expect(messageChildren(elements[0]).length).toBe(1);394 expect(messageChildren(elements[1]).length).toBe(1);395 expect(messageChildren(elements[2]).length).toBe(1);396 // this is the standard order of the displayed error messages397 expect(element.text().trim()).toBe('ABC');398 $rootScope.$apply(function() {399 $rootScope.items[0].a = false;400 $rootScope.items[0].c = true;401 $rootScope.items[1].b = false;402 $rootScope.items[2].c = false;403 $rootScope.items[2].a = true;404 });405 // with the 2nd item gone and the values changed406 // we should see both 1 and 3 changed407 expect(element.text().trim()).toBe('CA');408 $rootScope.$apply(function() {409 // add the value for the 2nd item back410 $rootScope.items[1].b = true;411 $rootScope.items.reverse();412 });413 // when reversed we get back to our original value414 expect(element.text().trim()).toBe('ABC');415 });416 });417 they('should remove the $prop element and place a comment anchor node where it used to be',418 {'<div ng-messages-include="...">': '<div ng-messages="data">' +419 '<div ng-messages-include="abc.html"></div>' +420 '</div>',421 '<ng-messages-include src="...">': '<ng-messages for="data">' +422 '<ng-messages-include src="abc.html"></ng-messages-include>' +423 '</ng-messages>'},424 function(html) {425 inject(function($compile, $rootScope, $templateCache) {426 $templateCache.put('abc.html', '<div></div>');427 element = $compile(html)($rootScope);428 $rootScope.$digest();429 var includeElement = element[0].querySelector('[ng-messages-include], ng-messages-include');430 expect(includeElement).toBeFalsy();431 var comment = element[0].childNodes[0];432 expect(comment.nodeType).toBe(8);433 expect(comment.nodeValue).toBe(' ngMessagesInclude: abc.html ');434 });435 });436 they('should load a remote template using $prop',437 {'<div ng-messages-include="...">': '<div ng-messages="data">' +438 '<div ng-messages-include="abc.html"></div>' +439 '</div>',440 '<ng-messages-include src="...">': '<ng-messages for="data">' +441 '<ng-messages-include src="abc.html"></ng-messages-include>' +442 '</ng-messages>'},443 function(html) {444 inject(function($compile, $rootScope, $templateCache) {445 $templateCache.put('abc.html', '<div ng-message="a">A</div>' +446 '<div ng-message="b">B</div>' +447 '<div ng-message="c">C</div>');448 element = $compile(html)($rootScope);449 $rootScope.$apply(function() {450 $rootScope.data = {451 'a': 1,452 'b': 2,453 'c': 3454 };455 });456 expect(messageChildren(element).length).toBe(1);457 expect(trim(element.text())).toEqual("A");458 $rootScope.$apply(function() {459 $rootScope.data = {460 'c': 3461 };462 });463 expect(messageChildren(element).length).toBe(1);464 expect(trim(element.text())).toEqual("C");465 });466 });467 it('should cache the template after download',468 inject(function($rootScope, $compile, $templateCache, $httpBackend) {469 $httpBackend.expect('GET', 'tpl').respond(201, '<div>abc</div>');470 expect($templateCache.get('tpl')).toBeUndefined();471 element = $compile('<div ng-messages="data"><div ng-messages-include="tpl"></div></div>')($rootScope);472 $rootScope.$digest();473 $httpBackend.flush();474 expect($templateCache.get('tpl')).toBeDefined();475 }));476 it('should re-render the messages after download without an extra digest',477 inject(function($rootScope, $compile, $httpBackend) {478 $httpBackend.expect('GET', 'my-messages').respond(201,479 '<div ng-message="required">You did not enter a value</div>');480 element = $compile('<div ng-messages="data">' +481 ' <div ng-messages-include="my-messages"></div>' +482 ' <div ng-message="failed">Your value is that of failure</div>' +483 '</div>')($rootScope);484 $rootScope.data = {485 required: true,486 failed: true487 };488 $rootScope.$digest();489 expect(messageChildren(element).length).toBe(1);490 expect(trim(element.text())).toEqual("Your value is that of failure");491 $httpBackend.flush();492 $rootScope.$digest();493 expect(messageChildren(element).length).toBe(1);494 expect(trim(element.text())).toEqual("You did not enter a value");495 }));496 it('should allow for overriding the remote template messages within the element depending on where the remote template is placed',497 inject(function($compile, $rootScope, $templateCache) {498 $templateCache.put('abc.html', '<div ng-message="a">A</div>' +499 '<div ng-message="b">B</div>' +500 '<div ng-message="c">C</div>');501 element = $compile('<div ng-messages="data">' +502 ' <div ng-message="a">AAA</div>' +503 ' <div ng-messages-include="abc.html"></div>' +504 ' <div ng-message="c">CCC</div>' +505 '</div>')($rootScope);506 $rootScope.$apply(function() {507 $rootScope.data = {508 'a': 1,509 'b': 2,510 'c': 3511 };512 });513 expect(messageChildren(element).length).toBe(1);514 expect(trim(element.text())).toEqual("AAA");515 $rootScope.$apply(function() {516 $rootScope.data = {517 'b': 2,518 'c': 3519 };520 });521 expect(messageChildren(element).length).toBe(1);522 expect(trim(element.text())).toEqual("B");523 $rootScope.$apply(function() {524 $rootScope.data = {525 'c': 3526 };527 });528 expect(messageChildren(element).length).toBe(1);529 expect(trim(element.text())).toEqual("C");530 }));531 });532 describe('when multiple', function() {533 they('should show all truthy messages when the $prop attr is present',534 { 'multiple': 'multiple',535 'ng-messages-multiple': 'ng-messages-multiple' },536 function(prop) {537 inject(function($rootScope, $compile) {538 element = $compile('<div ng-messages="data" ' + prop + '>' +539 ' <div ng-message="one">1</div>' +540 ' <div ng-message="two">2</div>' +541 ' <div ng-message="three">3</div>' +542 '</div>')($rootScope);543 $rootScope.$apply(function() {544 $rootScope.data = {545 'one': true,546 'two': false,547 'three': true548 };549 });550 expect(messageChildren(element).length).toBe(2);551 expect(s(element.text())).toContain("13");552 });553 });554 it('should render all truthy messages from a remote template',555 inject(function($rootScope, $compile, $templateCache) {556 $templateCache.put('xyz.html', '<div ng-message="x">X</div>' +557 '<div ng-message="y">Y</div>' +558 '<div ng-message="z">Z</div>');559 element = $compile('<div ng-messages="data" ng-messages-multiple="true">' +560 '<div ng-messages-include="xyz.html"></div>' +561 '</div>')($rootScope);562 $rootScope.$apply(function() {563 $rootScope.data = {564 'x': 'a',565 'y': null,566 'z': true567 };568 });569 expect(messageChildren(element).length).toBe(2);570 expect(s(element.text())).toEqual("XZ");571 $rootScope.$apply(function() {572 $rootScope.data.y = {};573 });574 expect(messageChildren(element).length).toBe(3);575 expect(s(element.text())).toEqual("XYZ");576 }));577 it('should render and override all truthy messages from a remote template',578 inject(function($rootScope, $compile, $templateCache) {579 $templateCache.put('xyz.html', '<div ng-message="x">X</div>' +580 '<div ng-message="y">Y</div>' +581 '<div ng-message="z">Z</div>');582 element = $compile('<div ng-messages="data" ng-messages-multiple="true">' +583 '<div ng-message="y">YYY</div>' +584 '<div ng-message="z">ZZZ</div>' +585 '<div ng-messages-include="xyz.html"></div>' +586 '</div>')($rootScope);587 $rootScope.$apply(function() {588 $rootScope.data = {589 'x': 'a',590 'y': null,591 'z': true592 };593 });594 expect(messageChildren(element).length).toBe(2);595 expect(s(element.text())).toEqual("ZZZX");596 $rootScope.$apply(function() {597 $rootScope.data.y = {};598 });599 expect(messageChildren(element).length).toBe(3);600 expect(s(element.text())).toEqual("YYYZZZX");601 }));602 });...
ngPluralizeSpec.js
Source:ngPluralizeSpec.js
...25 }));26 it('should show single/plural strings', inject(function($rootScope) {27 $rootScope.email = 0;28 $rootScope.$digest();29 expect(element.text()).toBe('You have no new email');30 expect(elementAlt.text()).toBe('You have no new email');31 $rootScope.email = '0';32 $rootScope.$digest();33 expect(element.text()).toBe('You have no new email');34 expect(elementAlt.text()).toBe('You have no new email');35 $rootScope.email = 1;36 $rootScope.$digest();37 expect(element.text()).toBe('You have one new email');38 expect(elementAlt.text()).toBe('You have one new email');39 $rootScope.email = 0.01;40 $rootScope.$digest();41 expect(element.text()).toBe('You have 0.01 new emails');42 expect(elementAlt.text()).toBe('You have 0.01 new emails');43 $rootScope.email = '0.1';44 $rootScope.$digest();45 expect(element.text()).toBe('You have 0.1 new emails');46 expect(elementAlt.text()).toBe('You have 0.1 new emails');47 $rootScope.email = 2;48 $rootScope.$digest();49 expect(element.text()).toBe('You have 2 new emails');50 expect(elementAlt.text()).toBe('You have 2 new emails');51 $rootScope.email = -0.1;52 $rootScope.$digest();53 expect(element.text()).toBe('You have -0.1 new emails');54 expect(elementAlt.text()).toBe('You have -0.1 new emails');55 $rootScope.email = '-0.01';56 $rootScope.$digest();57 expect(element.text()).toBe('You have -0.01 new emails');58 expect(elementAlt.text()).toBe('You have -0.01 new emails');59 $rootScope.email = -2;60 $rootScope.$digest();61 expect(element.text()).toBe('You have -2 new emails');62 expect(elementAlt.text()).toBe('You have -2 new emails');63 $rootScope.email = -1;64 $rootScope.$digest();65 expect(element.text()).toBe('You have negative email. Whohoo!');66 expect(elementAlt.text()).toBe('You have negative email. Whohoo!');67 }));68 it('should show single/plural strings with mal-formed inputs', inject(69 function($log, $rootScope) {70 $rootScope.email = '';71 $rootScope.$digest();72 expect(element.text()).toBe('');73 expect(elementAlt.text()).toBe('');74 expect($log.debug.logs.shift()).toEqual([75 "ngPluralize: no rule defined for 'NaN' in {" +76 "'-1': 'You have negative email. Whohoo!'," +77 "'0': 'You have no new email'," +78 "'one': 'You have one new email'," +79 "'other': 'You have {} new emails'}"80 ]);81 expect($log.debug.logs.shift()).toEqual([82 "ngPluralize: no rule defined for 'NaN' in undefined"83 ]);84 $rootScope.email = null;85 $rootScope.$digest();86 expect(element.text()).toBe('');87 expect(elementAlt.text()).toBe('');88 $rootScope.email = undefined;89 $rootScope.$digest();90 expect(element.text()).toBe('');91 expect(elementAlt.text()).toBe('');92 $rootScope.email = 'a3';93 $rootScope.$digest();94 expect(element.text()).toBe('');95 expect(elementAlt.text()).toBe('');96 $rootScope.email = '011';97 $rootScope.$digest();98 expect(element.text()).toBe('You have 11 new emails');99 expect(elementAlt.text()).toBe('You have 11 new emails');100 $rootScope.email = '-011';101 $rootScope.$digest();102 expect(element.text()).toBe('You have -11 new emails');103 expect(elementAlt.text()).toBe('You have -11 new emails');104 $rootScope.email = '1fff';105 $rootScope.$digest();106 expect(element.text()).toBe('You have one new email');107 expect(elementAlt.text()).toBe('You have one new email');108 $rootScope.email = '0aa22';109 $rootScope.$digest();110 expect(element.text()).toBe('You have no new email');111 expect(elementAlt.text()).toBe('You have no new email');112 $rootScope.email = '000001';113 $rootScope.$digest();114 expect(element.text()).toBe('You have one new email');115 expect(elementAlt.text()).toBe('You have one new email');116 }117 ));118 });119 describe('edge cases', function() {120 it('should be able to handle empty strings as possible values', inject(function($rootScope, $compile) {121 element = $compile(122 '<ng:pluralize count="email"' +123 "when=\"{'0': ''," +124 "'one': 'Some text'," +125 "'other': 'Some text'}\">" +126 '</ng:pluralize>')($rootScope);127 $rootScope.email = '0';128 $rootScope.$digest();129 expect(element.text()).toBe('');130 }));131 it('should be able to specify a message for null/undefined values', inject(132 function($compile, $rootScope) {133 element = $compile(134 '<ng:pluralize count="email"' +135 "when=\"{'NaN': 'Unspecified email count'," +136 "'0': ''," +137 "'one': 'Some text'," +138 "'other': 'Some text'}\">" +139 '</ng:pluralize>')($rootScope);140 $rootScope.email = '0';141 $rootScope.$digest();142 expect(element.text()).toBe('');143 $rootScope.email = undefined;144 $rootScope.$digest();145 expect(element.text()).toBe('Unspecified email count');146 $rootScope.email = '1';147 $rootScope.$digest();148 expect(element.text()).toBe('Some text');149 $rootScope.email = null;150 $rootScope.$digest();151 expect(element.text()).toBe('Unspecified email count');152 }));153 });154 describe('undefined rule cases', function() {155 var $locale, $log;156 beforeEach(inject(function(_$locale_, _$log_) {157 $locale = _$locale_;158 $log = _$log_;159 }));160 afterEach(inject(function($log) {161 $log.reset();162 }));163 it('should generate a warning when being asked to use a rule that is not defined',164 inject(function($rootScope, $compile) {165 element = $compile(166 '<ng:pluralize count="email"' +167 "when=\"{'0': 'Zero'," +168 "'one': 'Some text'," +169 "'other': 'Some text'}\">" +170 '</ng:pluralize>')($rootScope);171 $locale.pluralCat = function() {return "few";};172 $rootScope.email = '3';173 expect($log.debug.logs).toEqual([]);174 $rootScope.$digest();175 expect(element.text()).toBe('');176 expect($log.debug.logs.shift())177 .toEqual(["ngPluralize: no rule defined for 'few' in {'0': 'Zero','one': 'Some text','other': 'Some text'}"]);178 }));179 it('should empty the element content when using a rule that is not defined',180 inject(function($rootScope, $compile) {181 element = $compile(182 '<ng:pluralize count="email"' +183 "when=\"{'0': 'Zero'," +184 "'one': 'Some text'," +185 "'other': 'Some text'}\">" +186 '</ng:pluralize>')($rootScope);187 $locale.pluralCat = function(count) {return count === 1 ? "one" : "few";};188 $rootScope.email = '0';189 $rootScope.$digest();190 expect(element.text()).toBe('Zero');191 $rootScope.email = '3';192 $rootScope.$digest();193 expect(element.text()).toBe('');194 $rootScope.email = '1';195 $rootScope.$digest();196 expect(element.text()).toBe('Some text');197 $rootScope.email = null;198 $rootScope.$digest();199 expect(element.text()).toBe('');200 }));201 });202 describe('deal with pluralized strings with offset', function() {203 it('should show single/plural strings with offset', inject(function($rootScope, $compile) {204 element = $compile(205 "<ng:pluralize count='viewCount' offset='2' " +206 "when=\"{'0': 'Nobody is viewing.'," +207 "'1': '{{p1}} is viewing.'," +208 "'2': '{{p1}} and {{p2}} are viewing.'," +209 "'one': '{{p1}}, {{p2}} and one other person are viewing.'," +210 "'other': '{{p1}}, {{p2}} and {} other people are viewing.'}\">" +211 "</ng:pluralize>")($rootScope);212 elementAlt = $compile(213 "<ng:pluralize count='viewCount' offset='2' " +214 "when-0='Nobody is viewing.'" +215 "when-1='{{p1}} is viewing.'" +216 "when-2='{{p1}} and {{p2}} are viewing.'" +217 "when-one='{{p1}}, {{p2}} and one other person are viewing.'" +218 "when-other='{{p1}}, {{p2}} and {} other people are viewing.'>" +219 "</ng:pluralize>")($rootScope);220 $rootScope.p1 = 'Igor';221 $rootScope.p2 = 'Misko';222 $rootScope.viewCount = 0;223 $rootScope.$digest();224 expect(element.text()).toBe('Nobody is viewing.');225 expect(elementAlt.text()).toBe('Nobody is viewing.');226 $rootScope.viewCount = 1;227 $rootScope.$digest();228 expect(element.text()).toBe('Igor is viewing.');229 expect(elementAlt.text()).toBe('Igor is viewing.');230 $rootScope.viewCount = 2;231 $rootScope.$digest();232 expect(element.text()).toBe('Igor and Misko are viewing.');233 expect(elementAlt.text()).toBe('Igor and Misko are viewing.');234 $rootScope.viewCount = 3;235 $rootScope.$digest();236 expect(element.text()).toBe('Igor, Misko and one other person are viewing.');237 expect(elementAlt.text()).toBe('Igor, Misko and one other person are viewing.');238 $rootScope.viewCount = 4;239 $rootScope.$digest();240 expect(element.text()).toBe('Igor, Misko and 2 other people are viewing.');241 expect(elementAlt.text()).toBe('Igor, Misko and 2 other people are viewing.');242 $rootScope.viewCount = null;243 $rootScope.$digest();244 expect(element.text()).toBe('');245 expect(elementAlt.text()).toBe('');246 }));247 });248 describe('interpolation', function() {249 it('should support custom interpolation symbols', function() {250 module(function($interpolateProvider) {251 $interpolateProvider.startSymbol('[[').endSymbol('%%');252 });253 inject(function($compile, $rootScope) {254 element = $compile(255 "<ng:pluralize count=\"viewCount\" offset=\"1\"" +256 "when=\"{'0': 'Nobody is viewing.'," +257 "'1': '[[p1%% is viewing.'," +258 "'one': '[[p1%% and one other person are viewing.'," +259 "'other': '[[p1%% and {} other people are viewing.'}\">" +260 "</ng:pluralize>")($rootScope);261 elementAlt = $compile(262 "<ng:pluralize count='viewCount' offset='1'" +263 "when-0='Nobody is viewing.'" +264 "when-1='[[p1%% is viewing.'" +265 "when-one='[[p1%% and one other person are viewing.'" +266 "when-other='[[p1%% and {} other people are viewing.'>" +267 "</ng:pluralize>")($rootScope);268 $rootScope.p1 = 'Igor';269 $rootScope.viewCount = 0;270 $rootScope.$digest();271 expect(element.text()).toBe('Nobody is viewing.');272 expect(elementAlt.text()).toBe('Nobody is viewing.');273 $rootScope.viewCount = 1;274 $rootScope.$digest();275 expect(element.text()).toBe('Igor is viewing.');276 expect(elementAlt.text()).toBe('Igor is viewing.');277 $rootScope.viewCount = 2;278 $rootScope.$digest();279 expect(element.text()).toBe('Igor and one other person are viewing.');280 expect(elementAlt.text()).toBe('Igor and one other person are viewing.');281 $rootScope.viewCount = 3;282 $rootScope.$digest();283 expect(element.text()).toBe('Igor and 2 other people are viewing.');284 expect(elementAlt.text()).toBe('Igor and 2 other people are viewing.');285 });286 });287 });288 describe('bind-once', function() {289 it('should support for `count` to be a one-time expression',290 inject(function($compile, $rootScope) {291 element = $compile(292 '<ng:pluralize count="::email"' +293 "when=\"{'one': 'You have one new email'," +294 "'other': 'You have {} new emails'}\">" +295 '</ng:pluralize>')($rootScope);296 elementAlt = $compile(297 '<ng:pluralize count="::email" ' +298 "when-one='You have one new email' " +299 "when-other='You have {} new emails'>" +300 '</ng:pluralize>')($rootScope);301 $rootScope.email = undefined;302 $rootScope.$digest();303 expect(element.text()).toBe('');304 expect(elementAlt.text()).toBe('');305 $rootScope.email = 3;306 $rootScope.$digest();307 expect(element.text()).toBe('You have 3 new emails');308 expect(elementAlt.text()).toBe('You have 3 new emails');309 $rootScope.email = null;310 $rootScope.$digest();311 expect(element.text()).toBe('You have 3 new emails');312 expect(elementAlt.text()).toBe('You have 3 new emails');313 $rootScope.email = 2;314 $rootScope.$digest();315 expect(element.text()).toBe('You have 3 new emails');316 expect(elementAlt.text()).toBe('You have 3 new emails');317 $rootScope.email = 1;318 $rootScope.$digest();319 expect(element.text()).toBe('You have 3 new emails');320 expect(elementAlt.text()).toBe('You have 3 new emails');321 })322 );323 it('should still update other embedded expressions',324 inject(function($compile, $rootScope) {325 element = $compile(326 '<ng:pluralize count="::email"' +327 "when=\"{'one': 'You, {{user}}, have one new email'," +328 "'other': 'You, {{user}}, have {} new emails'}\">" +329 '</ng:pluralize>')($rootScope);330 elementAlt = $compile(331 '<ng:pluralize count="::email" ' +332 "when-one='You, {{user}}, have one new email' " +333 "when-other='You, {{user}}, have {} new emails'>" +334 '</ng:pluralize>')($rootScope);335 $rootScope.user = 'Lucas';336 $rootScope.email = undefined;337 $rootScope.$digest();338 expect(element.text()).toBe('');339 expect(elementAlt.text()).toBe('');340 $rootScope.email = 3;341 $rootScope.$digest();342 expect(element.text()).toBe('You, Lucas, have 3 new emails');343 expect(elementAlt.text()).toBe('You, Lucas, have 3 new emails');344 $rootScope.user = 'Pete';345 $rootScope.email = 2;346 $rootScope.$digest();347 expect(element.text()).toBe('You, Pete, have 3 new emails');348 expect(elementAlt.text()).toBe('You, Pete, have 3 new emails');349 })350 );351 });...
year.spec.js
Source:year.spec.js
1/* globals describe, beforeEach, it, expect, module, inject, jQuery, moment */2/**3 * @license angular-bootstrap-datetimepicker4 * Copyright 2016 Knight Rider Consulting, Inc. http://www.knightrider.com5 * License: MIT6 *7 * @author Dale "Ducky" Lotts8 * @since 7/21/139 */10describe('current view displayed on the markup', function () {11 'use strict'12 var element13 beforeEach(module('ui.bootstrap.datetimepicker'))14 beforeEach(inject(function ($compile, $rootScope) {15 moment.locale('de')16 $rootScope.date = moment('2013-01-22T00:00:00.000').toDate()17 element = $compile('<datetimepicker data-datetimepicker-config="{ startView: \'year\'}" data-ng-model="date"></datetimepicker>')($rootScope)18 $rootScope.$digest()19 }))20 it('should have `.year-view` class', function () {21 expect(jQuery('table', element).hasClass('year-view')).toBeTruthy()22 })23})24describe('year view with ng-model = null', function () {25 'use strict'26 var rootScope27 var element28 beforeEach(module('ui.bootstrap.datetimepicker'))29 beforeEach(inject(function ($compile, $rootScope) {30 moment.locale('de')31 rootScope = $rootScope32 $rootScope.date = null33 element = $compile('<datetimepicker data-ng-model="date" data-datetimepicker-config="{ startView: \'year\' }"></datetimepicker>')($rootScope)34 $rootScope.$digest()35 }))36 // this feels rather fragile - the implementation details are not important - consider deleting.37 describe('where initial structure', function () {38 it('is a `<div>` element', function () {39 expect(element.prop('tagName')).toBe('DIV')40 })41 it('`<div>` element has a `datetimepicker` class', function () {42 expect(element.hasClass('datetimepicker')).toBe(true)43 })44 it('has a `<div>` that contains a table element', function () {45 expect(element.find('table').length).toBe(1)46 })47 it('has a `<table>` that contains a thead element', function () {48 expect(element.find('table').find('thead').length).toBe(1)49 })50 it('has a `<thead>` that contains two tr elements', function () {51 expect(element.find('table').find('thead').find('tr').length).toBe(2)52 })53 it('has a `<tr>` that contains a <th class=`left`> element', function () {54 expect(jQuery('th[class*=left]', element).length).toBe(1)55 })56 it('has a `<th class=`left`>` that contains a <i class=`icon-arrow-left`> element', function () {57 expect(jQuery('th[class*=left] > i[class*=icon-arrow-left]', element).length).toBe(1)58 })59 it('has a `<tr>` that contains a <th class=`switch` colspan="5"> element', function () {60 expect(jQuery('th[class*=switch][colspan=5]', element).length).toBe(1)61 })62 it('has a `<tr>` that contains a <th class=`right`> element', function () {63 expect(jQuery('th[class*=right]', element).length).toBe(1)64 })65 it('has a `<th class=`right`>` that contains a <i class=`icon-arrow-right`> element', function () {66 expect(jQuery('th[class*=right] > i[class*=icon-arrow-right]', element).length).toBe(1)67 })68 it('has a `<th class=`left`>` that contains a sr description set in german', function () {69 expect(jQuery('th[class*=left] .sr-only', element).text()).toBe('vorige')70 })71 it('has a `<th class=`right`>` that contains a sr description set in english', function () {72 expect(jQuery('th[class*=right] .sr-only', element).text()).toBe('weiter')73 })74 it('has a `<table>` that contains a tbody element', function () {75 expect(element.find('table').find('tbody').length).toBe(1)76 })77 })78 describe('where year view', function () {79 it('has a `<th class="switch">` element that contains the current decade range (2010-2019)', function () {80 expect(jQuery('thead th[class*=switch]', element).html()).toBe('2010-2019')81 })82 it('has a total of 12 `<span class="year">` elements', function () {83 expect(jQuery('tbody span[class*=year]', element).length).toBe(12)84 })85 it('does not have a `<span class="year active">` element', function () {86 // At this point there is not date set, so there is no active date.87 expect(jQuery('tbody span[class*=year][class*=active]', element).length).toBe(0)88 })89 it('has a `<span class="year past">` element that contains a year value prior to the current decade', function () {90 expect(jQuery('tbody span[class*=year][class*=past]', element).length).toBe(1)91 expect(jQuery('tbody span[class*=year][class*=past]', element).text()).toBe('2009')92 })93 it('has a `<span class="year future">` element that contains a year value after to the current decade', function () {94 expect(jQuery('tbody span[class*=year][class*=future]', element).length).toBe(1)95 expect(jQuery('tbody span[class*=year][class*=future]', element).text()).toBe('2020')96 })97 it('has a `<th class="left">` element that, when clicked, changes the title to the previous decade.', function () {98 jQuery('.left', element).trigger('click')99 expect(jQuery('.switch', element).html()).toBe('2000-2009')100 })101 it('has a `<th class="right">` element that, when clicked, changes the title to the previous decade.', function () {102 jQuery('.right', element).trigger('click')103 expect(jQuery('.switch', element).html()).toBe('2020-2029')104 })105 it('has a `<th class="switch">` element that, when clicked, changes nothing while in the year view.', function () {106 jQuery('.switch', element).trigger('click')107 expect(jQuery('.switch', element).html()).toBe('2010-2019')108 })109 it('has a `<span class="year past">` element that, when clicked, changes the calendar to the month view for the selected year.', function () {110 var pastElement = jQuery('.past', element)111 pastElement.trigger('click')112 expect(jQuery('.switch', element).text()).toBe(pastElement.text())113 })114 it('has a `<span class="year future">` element that, when clicked, changes the calendar to the month view for the selected year.', function () {115 var futureElement = jQuery('.future', element)116 futureElement.trigger('click')117 expect(jQuery('.switch', element).text()).toBe(futureElement.text())118 })119 it('has a `<th class="switch">` element that, when clicked, changes the calendar to the previous view.', function () {120 // First, click a given date121 var pastElement = jQuery('.past', element)122 pastElement.trigger('click')123 expect(jQuery('.switch', element).text()).toBe(pastElement.text())124 // Second, click .switch and the view should update125 jQuery('.switch', element).trigger('click')126 expect(jQuery('.switch', element).text()).toBe('2000-2009')127 })128 it('has one `.active` element with a value of 2010 when view is month and date is 2010', function () {129 expect(jQuery('.active', element).length).toBe(0)130 rootScope.date = moment('2010-10-01').toDate()131 rootScope.$apply()132 expect(jQuery('.active', element).length).toBe(1)133 expect(jQuery('.active', element).text()).toBe('2010')134 })135 })136 describe('where month view', function () {137 beforeEach(function () {138 rootScope.date = moment('2010-10-01').toDate()139 rootScope.$digest()140 // Switch to month view...141 var pastElement = jQuery('.past', element)142 pastElement.trigger('click')143 })144 it('has one `.right` element, when clicked, changes the view to the next year', function () {145 // Starts on 2009 because the setup clicks the .past element.146 var rightElement = jQuery('.right', element)147 rightElement.trigger('click')148 expect(jQuery('.switch', element).text()).toBe('2010')149 })150 it('has one `.left` element, when clicked, changes the view to the next year', function () {151 var rightElement = jQuery('.left', element)152 rightElement.trigger('click')153 expect(jQuery('.switch', element).text()).toBe('2008')154 })155 it('has one `.switch` element, when clicked, changes the view to year view', function () {156 var rightElement = jQuery('.switch', element)157 rightElement.trigger('click')158 expect(jQuery('.switch', element).text()).toBe('2000-2009')159 })160 it('has zero `.past` elements', function () {161 expect(jQuery('.past', element).length).toBe(0)162 })163 it('has zero `.future` elements', function () {164 expect(jQuery('.future', element).length).toBe(0)165 })166 it('has one `.active` element with a value of 2010 when view is month and date is 2010', function () {167 expect(jQuery('.active', element).length).toBe(0)168 var rightElement = jQuery('.right', element)169 rightElement.trigger('click')170 expect(jQuery('.active', element).length).toBe(1)171 expect(jQuery('.switch', element).text()).toBe('2010')172 jQuery('.active', element).trigger('click')173 expect(jQuery('.switch', element).text()).toBe('2010-Okt.')174 expect(jQuery('.active', element).length).toBe(1)175 expect(jQuery('.active', element).text()).toBe('1')176 })177 })178 describe('where day view', function () {179 beforeEach(inject(function () {180 rootScope.date = moment('2010-10-01').toDate()181 rootScope.$digest()182 // Switch to day view...183 var pastElement = jQuery('.active', element)184 pastElement.trigger('click')185 pastElement = jQuery('.active', element)186 pastElement.trigger('click')187 }))188 it('has one `.active` element with a value of 1 when view is day and date is 2010', function () {189 expect(jQuery('.active', element).length).toBe(1)190 expect(jQuery('.active', element).text()).toBe('1')191 })192 it('has one `.left` element, when clicked, changes the view to the previous month', function () {193 var selectedElement = jQuery('.left', element)194 selectedElement.trigger('click')195 expect(jQuery('.switch', element).text()).toBe('2010-Sept.')196 })197 it('has one `.right` element, when clicked, changes the view to the next month', function () {198 var selectedElement = jQuery('.right', element)199 selectedElement.trigger('click')200 expect(jQuery('.switch', element).text()).toBe('2010-Nov.')201 })202 it('has one `.switch` element, when clicked, changes the view to month view', function () {203 var selectedElement = jQuery('.switch', element)204 selectedElement.trigger('click')205 expect(jQuery('.switch', element).text()).toBe('2010')206 })207 it('changes to hour view after clicking a `.past` element', function () {208 var selectedElement = jQuery(jQuery('.past', element)[0])209 selectedElement.trigger('click')210 expect(jQuery('.switch', element).text()).toBe('27. Sept. 2010')211 })212 it('changes to hour view after clicking a `.future` element', function () {213 var selectedElement = jQuery(jQuery('.future', element)[0])214 selectedElement.trigger('click')215 expect(jQuery('.switch', element).text()).toBe('1. Nov. 2010')216 })217 it('has 42 `.day` elements when date is oct-2010', function () {218 expect(jQuery('.day', element).length).toBe(42)219 })220 it('has 5 `.past` elements when date is oct-2010', function () {221 expect(jQuery('.past', element).length).toBe(4)222 })223 it('has 6 `.future` elements when date is oct-2010', function () {224 expect(jQuery('.future', element).length).toBe(7)225 })226 })227 describe('where hour view', function () {228 beforeEach(inject(function () {229 rootScope.date = moment('2010-10-01').toDate()230 rootScope.$digest()231 // Switch to day view...232 var selectedElement = jQuery('.active', element)233 selectedElement.trigger('click')234 selectedElement = jQuery('.active', element)235 selectedElement.trigger('click')236 selectedElement = jQuery('.active', element)237 selectedElement.trigger('click')238 }))239 it('has one `.active` element with a value of 0:00 when view is hour and date is 2010-Oct-01 00:00', function () {240 expect(jQuery('.active', element).length).toBe(1)241 expect(jQuery('.active', element).text()).toBe(moment(rootScope.date).format('LT'))242 })243 it('changes the view to the previous day when `.left` element is clicked', function () {244 var selectedElement = jQuery('.left', element)245 selectedElement.trigger('click')246 expect(jQuery('.switch', element).text()).toBe('30. Sept. 2010')247 })248 it('changes the view to the next day when `.right` element is clicked', function () {249 var selectedElement = jQuery('.right', element)250 selectedElement.trigger('click')251 expect(jQuery('.switch', element).text()).toBe('2. Okt. 2010')252 })253 it('changes the view to day view when `.switch` element is clicked', function () {254 var selectedElement = jQuery('.switch', element)255 selectedElement.trigger('click')256 expect(jQuery('.switch', element).text()).toBe('2010-Okt.')257 })258 it('changes the view to minute view when `.active` element is clicked', function () {259 var selectedElement = jQuery('.active', element)260 selectedElement.trigger('click')261 expect(jQuery('.minute', element).length).toBe(12)262 })263 })264})265describe('year view with with ng-model = null and minView="year"', function () {266 'use strict'267 var rootScope268 var element269 beforeEach(module('ui.bootstrap.datetimepicker'))270 beforeEach(inject(function ($compile, $rootScope) {271 rootScope = $rootScope272 $rootScope.date = null273 element = $compile('<datetimepicker data-datetimepicker-config="{ startView: \'year\', minView: \'year\' }" data-ng-model="date"></datetimepicker>')($rootScope)274 $rootScope.$digest()275 }))276 it('clicking the `.future` element will set the date value to 2020-01-01T00:00:00.000"', function () {277 expect(jQuery('.switch', element).text()).toBe('2010-2019')278 var selectedElement = jQuery('.future', element)279 selectedElement.trigger('click')280 expect(jQuery('.active', element).text()).toBe('2020')281 expect(rootScope.date).toEqual(moment('2020-01-01T00:00:00.000').toDate())282 })283})284describe('year view with with ng-model = 1970-1-1 (unix date of zero) and minView="year"', function () {285 'use strict'286 var rootScope287 var element288 beforeEach(module('ui.bootstrap.datetimepicker'))289 beforeEach(inject(function ($compile, $rootScope) {290 rootScope = $rootScope291 $rootScope.date = moment('1970-01-01T00:00:00.000').toDate()292 element = $compile('<datetimepicker data-datetimepicker-config="{ startView: \'year\', minView: \'year\' }" data-ng-model="date"></datetimepicker>')($rootScope)293 $rootScope.$digest()294 }))295 it('clicking the `.left` element will change the view to 1960-1969"', function () {296 expect(jQuery('.switch', element).text()).toBe('1970-1979')297 var selectedElement = jQuery('.left', element)298 selectedElement.trigger('click')299 expect(jQuery('.switch', element).text()).toBe('1960-1969')300 expect(rootScope.date).toEqual(moment('1970-01-01T00:00:00.000').toDate())301 })...
ngSwitchSpec.js
Source:ngSwitchSpec.js
...14 expect(element.html()).toEqual(15 '<!-- ngSwitchWhen: 1 --><!-- ngSwitchWhen: 2 --><!-- ngSwitchWhen: true -->');16 $rootScope.select = 1;17 $rootScope.$apply();18 expect(element.text()).toEqual('first:');19 $rootScope.name="shyam";20 $rootScope.$apply();21 expect(element.text()).toEqual('first:shyam');22 $rootScope.select = 2;23 $rootScope.$apply();24 expect(element.text()).toEqual('second:shyam');25 $rootScope.name = 'misko';26 $rootScope.$apply();27 expect(element.text()).toEqual('second:misko');28 $rootScope.select = true;29 $rootScope.$apply();30 expect(element.text()).toEqual('true:misko');31 }));32 it('should show all switch-whens that match the current value', inject(function($rootScope, $compile) {33 element = $compile(34 '<ul ng-switch="select">' +35 '<li ng-switch-when="1">first:{{name}}</li>' +36 '<li ng-switch-when="1">, first too:{{name}}</li>' +37 '<li ng-switch-when="2">second:{{name}}</li>' +38 '<li ng-switch-when="true">true:{{name}}</li>' +39 '</ul>')($rootScope);40 expect(element.html()).toEqual('<!-- ngSwitchWhen: 1 -->' +41 '<!-- ngSwitchWhen: 1 -->' +42 '<!-- ngSwitchWhen: 2 -->' +43 '<!-- ngSwitchWhen: true -->');44 $rootScope.select = 1;45 $rootScope.$apply();46 expect(element.text()).toEqual('first:, first too:');47 $rootScope.name="shyam";48 $rootScope.$apply();49 expect(element.text()).toEqual('first:shyam, first too:shyam');50 $rootScope.select = 2;51 $rootScope.$apply();52 expect(element.text()).toEqual('second:shyam');53 $rootScope.name = 'misko';54 $rootScope.$apply();55 expect(element.text()).toEqual('second:misko');56 $rootScope.select = true;57 $rootScope.$apply();58 expect(element.text()).toEqual('true:misko');59 }));60 it('should show all elements between start and end markers that match the current value',61 inject(function($rootScope, $compile) {62 element = $compile(63 '<ul ng-switch="select">' +64 '<li ng-switch-when-start="1">A</li>' +65 '<li>B</li>' +66 '<li ng-switch-when-end>C</li>' +67 '<li ng-switch-when-start="2">D</li>' +68 '<li>E</li>' +69 '<li ng-switch-when-end>F</li>' +70 '</ul>')($rootScope);71 $rootScope.$apply('select = "1"');72 expect(element.find('li').length).toBe(3);73 expect(element.find('li').eq(0).text()).toBe('A');74 expect(element.find('li').eq(1).text()).toBe('B');75 expect(element.find('li').eq(2).text()).toBe('C');76 $rootScope.$apply('select = "2"');77 expect(element.find('li').length).toBe(3);78 expect(element.find('li').eq(0).text()).toBe('D');79 expect(element.find('li').eq(1).text()).toBe('E');80 expect(element.find('li').eq(2).text()).toBe('F');81 }));82 it('should switch on switch-when-default', inject(function($rootScope, $compile) {83 element = $compile(84 '<ng:switch on="select">' +85 '<div ng:switch-when="1">one</div>' +86 '<div ng:switch-default>other</div>' +87 '</ng:switch>')($rootScope);88 $rootScope.$apply();89 expect(element.text()).toEqual('other');90 $rootScope.select = 1;91 $rootScope.$apply();92 expect(element.text()).toEqual('one');93 }));94 it('should show all default elements between start and end markers when no match',95 inject(function($rootScope, $compile) {96 element = $compile(97 '<ul ng-switch="select">' +98 '<li ng-switch-when-start="1">A</li>' +99 '<li>B</li>' +100 '<li ng-switch-when-end>C</li>' +101 '<li ng-switch-default-start>D</li>' +102 '<li>E</li>' +103 '<li ng-switch-default-end>F</li>' +104 '</ul>')($rootScope);105 $rootScope.$apply('select = "1"');106 expect(element.find('li').length).toBe(3);107 expect(element.find('li').eq(0).text()).toBe('A');108 expect(element.find('li').eq(1).text()).toBe('B');109 expect(element.find('li').eq(2).text()).toBe('C');110 $rootScope.$apply('select = "2"');111 expect(element.find('li').length).toBe(3);112 expect(element.find('li').eq(0).text()).toBe('D');113 expect(element.find('li').eq(1).text()).toBe('E');114 expect(element.find('li').eq(2).text()).toBe('F');115 }));116 it('should show all switch-when-default', inject(function($rootScope, $compile) {117 element = $compile(118 '<ul ng-switch="select">' +119 '<li ng-switch-when="1">one</li>' +120 '<li ng-switch-default>other</li>' +121 '<li ng-switch-default>, other too</li>' +122 '</ul>')($rootScope);123 $rootScope.$apply();124 expect(element.text()).toEqual('other, other too');125 $rootScope.select = 1;126 $rootScope.$apply();127 expect(element.text()).toEqual('one');128 }));129 it('should always display the elements that do not match a switch',130 inject(function($rootScope, $compile) {131 element = $compile(132 '<ul ng-switch="select">' +133 '<li>always </li>' +134 '<li ng-switch-when="1">one </li>' +135 '<li ng-switch-when="2">two </li>' +136 '<li ng-switch-default>other, </li>' +137 '<li ng-switch-default>other too </li>' +138 '</ul>')($rootScope);139 $rootScope.$apply();140 expect(element.text()).toEqual('always other, other too ');141 $rootScope.select = 1;142 $rootScope.$apply();143 expect(element.text()).toEqual('always one ');144 }));145 it('should display the elements that do not have ngSwitchWhen nor ' +146 'ngSwitchDefault at the position specified in the template, when the ' +147 'first and last elements in the ngSwitch body do not have a ngSwitch* ' +148 'directive', inject(function($rootScope, $compile) {149 element = $compile(150 '<ul ng-switch="select">' +151 '<li>1</li>' +152 '<li ng-switch-when="1">2</li>' +153 '<li>3</li>' +154 '<li ng-switch-when="2">4</li>' +155 '<li ng-switch-default>5</li>' +156 '<li>6</li>' +157 '<li ng-switch-default>7</li>' +158 '<li>8</li>' +159 '</ul>')($rootScope);160 $rootScope.$apply();161 expect(element.text()).toEqual('135678');162 $rootScope.select = 1;163 $rootScope.$apply();164 expect(element.text()).toEqual('12368');165 }));166 it('should display the elements that do not have ngSwitchWhen nor ' +167 'ngSwitchDefault at the position specified in the template when the ' +168 'first and last elements in the ngSwitch have a ngSwitch* directive',169 inject(function($rootScope, $compile) {170 element = $compile(171 '<ul ng-switch="select">' +172 '<li ng-switch-when="1">2</li>' +173 '<li>3</li>' +174 '<li ng-switch-when="2">4</li>' +175 '<li ng-switch-default>5</li>' +176 '<li>6</li>' +177 '<li ng-switch-default>7</li>' +178 '</ul>')($rootScope);179 $rootScope.$apply();180 expect(element.text()).toEqual('3567');181 $rootScope.select = 1;182 $rootScope.$apply();183 expect(element.text()).toEqual('236');184 }));185 it('should properly create and destroy child scopes', inject(function($rootScope, $compile) {186 element = $compile(187 '<ng:switch on="url">' +188 '<div ng-switch-when="a">{{name}}</div>' +189 '</ng:switch>')($rootScope);190 $rootScope.$apply();191 var getChildScope = function() { return element.find('div').scope(); };192 expect(getChildScope()).toBeUndefined();193 $rootScope.url = 'a';194 $rootScope.$apply();195 var child1 = getChildScope();196 expect(child1).toBeDefined();197 spyOn(child1, '$destroy');198 $rootScope.url = 'x';199 $rootScope.$apply();200 expect(getChildScope()).toBeUndefined();201 expect(child1.$destroy).toHaveBeenCalled();202 $rootScope.url = 'a';203 $rootScope.$apply();204 var child2 = getChildScope();205 expect(child2).toBeDefined();206 expect(child2).not.toBe(child1);207 }));208 it("should interoperate with other transclusion directives like ngRepeat", inject(function($rootScope, $compile) {209 element = $compile(210 '<div ng-switch="value">' +211 '<div ng-switch-when="foo" ng-repeat="foo in foos">{{value}}:{{foo}}|</div>' +212 '<div ng-switch-default ng-repeat="bar in bars">{{value}}:{{bar}}|</div>' +213 '</div>'214 )($rootScope);215 $rootScope.$apply('value="foo";foos=["one", "two"]');216 expect(element.text()).toEqual('foo:one|foo:two|');217 $rootScope.$apply('value="foo";foos=["one"]');218 expect(element.text()).toEqual('foo:one|');219 $rootScope.$apply('value="foo";foos=["one","two","three"]');220 expect(element.text()).toEqual('foo:one|foo:two|foo:three|');221 $rootScope.$apply('value="bar";bars=["up", "down"]');222 expect(element.text()).toEqual('bar:up|bar:down|');223 $rootScope.$apply('value="bar";bars=["up", "down", "forwards", "backwards"]');224 expect(element.text()).toEqual('bar:up|bar:down|bar:forwards|bar:backwards|');225 }));226 it('should not leak jq data when compiled but not attached to parent when parent is destroyed',227 inject(function($rootScope, $compile) {228 element = $compile(229 '<div ng-repeat="i in []">' +230 '<ng-switch on="url">' +231 '<div ng-switch-when="a">{{name}}</div>' +232 '</ng-switch>' +233 '</div>')($rootScope);234 $rootScope.$apply();235 // element now contains only empty repeater. this element is deallocated by local afterEach.236 // afterwards a global afterEach will check for leaks in jq data cache object237 }));238 it('should properly support case labels with different numbers of transclude fns', inject(function($rootScope, $compile) {239 element = $compile(240 '<div ng-switch="mode">' +241 '<p ng-switch-when="a">Block1</p>' +242 '<p ng-switch-when="a">Block2</p>' +243 '<a href ng-switch-when="b">a</a>' +244 '</div>'245 )($rootScope);246 $rootScope.$apply('mode = "a"');247 expect(element.children().length).toBe(2);248 $rootScope.$apply('mode = "b"');249 expect(element.children().length).toBe(1);250 $rootScope.$apply('mode = "a"');251 expect(element.children().length).toBe(2);252 $rootScope.$apply('mode = "b"');253 expect(element.children().length).toBe(1);254 }));255});256describe('ngSwitch animation', function() {257 var body, element, $rootElement;258 function html(content) {259 $rootElement.html(content);260 element = $rootElement.children().eq(0);261 return element;262 }263 beforeEach(module(function() {264 // we need to run animation on attached elements;265 return function(_$rootElement_) {266 $rootElement = _$rootElement_;267 body = jqLite(document.body);268 body.append($rootElement);269 };270 }));271 afterEach(function() {272 dealoc(body);273 dealoc(element);274 });275 describe('behavior', function() {276 it('should destroy the previous leave animation if a new one takes place', function() {277 module('ngAnimate');278 module(function($animateProvider) {279 $animateProvider.register('.long-leave', function() {280 return {281 leave: function(element, done) {282 //do nothing at all283 }284 };285 });286 });287 inject(function($compile, $rootScope, $animate, $templateCache) {288 var item;289 var $scope = $rootScope.$new();290 element = $compile(html(291 '<div ng-switch="inc">' +292 '<div ng-switch-when="one">one</div>' +293 '<div ng-switch-when="two">two</div>' +294 '</div>'295 ))($scope);296 $scope.$apply('inc = "one"');297 var destroyed, inner = element.children(0);298 inner.on('$destroy', function() {299 destroyed = true;300 });301 $scope.$apply('inc = "two"');302 $scope.$apply('inc = "one"');303 expect(destroyed).toBe(true);304 });305 });306 });307 describe('events', function() {308 beforeEach(module('ngAnimateMock'));309 it('should fire off the enter animation',310 inject(function($compile, $rootScope, $animate) {311 var item;312 var $scope = $rootScope.$new();313 element = $compile(html(314 '<div ng-switch on="val">' +315 '<div ng-switch-when="one">one</div>' +316 '<div ng-switch-when="two">two</div>' +317 '<div ng-switch-when="three">three</div>' +318 '</div>'319 ))($scope);320 $rootScope.$digest(); // re-enable the animations;321 $scope.val = 'one';322 $scope.$digest();323 item = $animate.queue.shift();324 expect(item.event).toBe('enter');325 expect(item.element.text()).toBe('one');326 })327 );328 it('should fire off the leave animation',329 inject(function($compile, $rootScope, $animate) {330 var item;331 var $scope = $rootScope.$new();332 element = $compile(html(333 '<div ng-switch on="val">' +334 '<div ng-switch-when="one">one</div>' +335 '<div ng-switch-when="two">two</div>' +336 '<div ng-switch-when="three">three</div>' +337 '</div>'338 ))($scope);339 $rootScope.$digest(); // re-enable the animations;340 $scope.val = 'two';341 $scope.$digest();342 item = $animate.queue.shift();343 expect(item.event).toBe('enter');344 expect(item.element.text()).toBe('two');345 $scope.val = 'three';346 $scope.$digest();347 item = $animate.queue.shift();348 expect(item.event).toBe('leave');349 expect(item.element.text()).toBe('two');350 item = $animate.queue.shift();351 expect(item.event).toBe('enter');352 expect(item.element.text()).toBe('three');353 })354 );355 it('should work with svg elements when the svg container is transcluded', function() {356 module(function($compileProvider) {357 $compileProvider.directive('svgContainer', function() {358 return {359 template: '<svg ng-transclude></svg>',360 replace: true,361 transclude: true362 };363 });364 });365 inject(function($compile, $rootScope) {366 element = $compile('<svg-container ng-switch="inc"><circle ng-switch-when="one"></circle>' +...
node.spec.js
Source:node.spec.js
1import {2 compileAndStringify,3 prepareRuntime,4 resetRuntime,5 createInstance,6 syncPromise,7 checkRefresh8} from '../helpers/index'9describe('node in render function', () => {10 let runtime11 beforeAll(() => {12 runtime = prepareRuntime()13 })14 afterAll(() => {15 resetRuntime()16 runtime = null17 })18 it('should be generated', () => {19 const instance = createInstance(runtime, `20 new Vue({21 render: function (createElement) {22 return createElement('div', {}, [23 createElement('text', { attrs: { value: 'Hello' }}, [])24 ])25 },26 el: "body"27 })28 `)29 expect(instance.getRealRoot()).toEqual({30 type: 'div',31 children: [32 { type: 'text', attr: { value: 'Hello' }}33 ]34 })35 })36 it('should be generated with all types of text', () => {37 const instance = createInstance(runtime, `38 new Vue({39 render: function (createElement) {40 return createElement('div', {}, [41 createElement('text', { attrs: { value: 'Hello' }}, []),42 'World',43 createElement('text', {}, ['Weex'])44 ])45 },46 el: "body"47 })48 `)49 expect(instance.getRealRoot()).toEqual({50 type: 'div',51 children: [52 { type: 'text', attr: { value: 'Hello' }},53 { type: 'text', attr: { value: 'World' }},54 { type: 'text', attr: { value: 'Weex' }}55 ]56 })57 })58 it('should be generated with comments', () => {59 // todo60 })61 it('should be generated with module diff', (done) => {62 const instance = createInstance(runtime, `63 new Vue({64 data: {65 counter: 066 },67 methods: {68 foo: function () {}69 },70 render: function (createElement) {71 switch (this.counter) {72 case 1:73 return createElement('div', {}, [74 createElement('text', { attrs: { value: 'World' }}, [])75 ])76 case 2:77 return createElement('div', {}, [78 createElement('text', { attrs: { value: 'World' }, style: { fontSize: 100 }}, [])79 ])80 case 3:81 return createElement('div', {}, [82 createElement('text', {83 attrs: { value: 'World' },84 style: { fontSize: 100 },85 on: { click: this.foo }86 }, [])87 ])88 case 4:89 return createElement('div', {}, [90 createElement('text', {91 attrs: { value: 'Weex' },92 style: { color: '#ff0000' }93 }, [])94 ])95 default:96 return createElement('div', {}, [97 createElement('text', { attrs: { value: 'Hello' }}, [])98 ])99 }100 },101 el: "body"102 })103 `)104 expect(instance.getRealRoot()).toEqual({105 type: 'div',106 children: [107 { type: 'text', attr: { value: 'Hello' }}108 ]109 })110 syncPromise([111 checkRefresh(instance, { counter: 1 }, result => {112 expect(result).toEqual({113 type: 'div',114 children: [115 { type: 'text', attr: { value: 'World' }}116 ]117 })118 }),119 checkRefresh(instance, { counter: 2 }, result => {120 expect(result).toEqual({121 type: 'div',122 children: [123 { type: 'text', attr: { value: 'World' }, style: { fontSize: 100 }}124 ]125 })126 }),127 checkRefresh(instance, { counter: 3 }, result => {128 expect(result).toEqual({129 type: 'div',130 children: [131 { type: 'text', attr: { value: 'World' }, style: { fontSize: 100 }, event: ['click'] }132 ]133 })134 }),135 checkRefresh(instance, { counter: 4 }, result => {136 expect(result).toEqual({137 type: 'div',138 children: [139 { type: 'text', attr: { value: 'Weex' }, style: { fontSize: '', color: '#ff0000' }}140 ]141 })142 done()143 })144 ])145 })146 it('should be generated with sub components', () => {147 const instance = createInstance(runtime, `148 new Vue({149 render: function (createElement) {150 return createElement('div', {}, [151 createElement('text', { attrs: { value: 'Hello' }}, []),152 createElement('foo', { props: { x: 'Weex' }})153 ])154 },155 components: {156 foo: {157 props: {158 x: { default: 'World' }159 },160 render: function (createElement) {161 return createElement('text', { attrs: { value: this.x }}, [])162 }163 }164 },165 el: "body"166 })167 `)168 expect(instance.getRealRoot()).toEqual({169 type: 'div',170 children: [171 { type: 'text', attr: { value: 'Hello' }},172 { type: 'text', attr: { value: 'Weex' }}173 ]174 })175 })176 it('should be generated with if/for diff', (done) => {177 const { render, staticRenderFns } = compileAndStringify(`178 <div>179 <text v-for="item in list" v-if="item.x">{{item.v}}</text>180 </div>181 `)182 const instance = createInstance(runtime, `183 new Vue({184 data: {185 list: [186 { v: 'Hello', x: true },187 { v: 'World', x: false },188 { v: 'Weex', x: true }189 ]190 },191 computed: {192 x: {193 get: function () { return 0 },194 set: function (v) {195 switch (v) {196 case 1:197 this.list[1].x = true198 break199 case 2:200 this.list.push({ v: 'v-if' })201 break202 case 3:203 this.list.push({ v: 'v-for', x: true })204 break205 case 4:206 this.list.splice(1, 2)207 break208 }209 }210 }211 },212 render: ${render},213 staticRenderFns: ${staticRenderFns},214 el: "body"215 })216 `)217 expect(instance.getRealRoot()).toEqual({218 type: 'div',219 children: [220 { type: 'text', attr: { value: 'Hello' }},221 { type: 'text', attr: { value: 'Weex' }}222 ]223 })224 syncPromise([225 checkRefresh(instance, { x: 1 }, result => {226 expect(result).toEqual({227 type: 'div',228 children: [229 { type: 'text', attr: { value: 'Hello' }},230 { type: 'text', attr: { value: 'World' }},231 { type: 'text', attr: { value: 'Weex' }}232 ]233 })234 }),235 checkRefresh(instance, { x: 2 }, result => {236 expect(result).toEqual({237 type: 'div',238 children: [239 { type: 'text', attr: { value: 'Hello' }},240 { type: 'text', attr: { value: 'World' }},241 { type: 'text', attr: { value: 'Weex' }}242 ]243 })244 }),245 checkRefresh(instance, { x: 3 }, result => {246 expect(result).toEqual({247 type: 'div',248 children: [249 { type: 'text', attr: { value: 'Hello' }},250 { type: 'text', attr: { value: 'World' }},251 { type: 'text', attr: { value: 'Weex' }},252 { type: 'text', attr: { value: 'v-for' }}253 ]254 })255 }),256 checkRefresh(instance, { x: 4 }, result => {257 expect(result).toEqual({258 type: 'div',259 children: [260 { type: 'text', attr: { value: 'Hello' }},261 { type: 'text', attr: { value: 'v-for' }}262 ]263 })264 done()265 })266 ])267 })268 it('should be generated with node structure diff', (done) => {269 const instance = createInstance(runtime, `270 new Vue({271 data: {272 counter: 0273 },274 render: function (createElement) {275 switch (this.counter) {276 case 1:277 return createElement('div', {}, [278 createElement('text', { attrs: { value: 'Hello' }}, []),279 createElement('text', { attrs: { value: 'World' }}, [])280 ])281 case 2:282 return createElement('div', {}, [283 createElement('text', { attrs: { value: 'Hello' }}, []),284 createElement('text', { attrs: { value: 'World' }}, []),285 createElement('text', { attrs: { value: 'Weex' }}, [])286 ])287 case 3:288 return createElement('div', {}, [289 createElement('text', { attrs: { value: 'Hello' }}, []),290 createElement('text', { attrs: { value: 'Weex' }}, [])291 ])292 case 4:293 return createElement('div', {}, [294 createElement('text', { attrs: { value: 'Weex' }}, [])295 ])296 case 5:297 return createElement('div', {}, [298 createElement('text', { attrs: { value: 'Hello' }}, []),299 createElement('text', { attrs: { value: 'Weex' }}, [])300 ])301 case 6:302 return createElement('div', {}, [303 createElement('input', { attrs: { value: 'Hello' }}, []),304 createElement('text', { attrs: { value: 'Weex' }}, [])305 ])306 default:307 return createElement('div', {}, [308 createElement('text', { attrs: { value: 'Hello' }}, []),309 ])310 }311 },312 el: "body"313 })314 `)315 expect(instance.getRealRoot()).toEqual({316 type: 'div',317 children: [318 { type: 'text', attr: { value: 'Hello' }}319 ]320 })321 syncPromise([322 checkRefresh(instance, { counter: 1 }, result => {323 expect(result).toEqual({324 type: 'div',325 children: [326 { type: 'text', attr: { value: 'Hello' }},327 { type: 'text', attr: { value: 'World' }}328 ]329 })330 }),331 checkRefresh(instance, { counter: 2 }, result => {332 expect(result).toEqual({333 type: 'div',334 children: [335 { type: 'text', attr: { value: 'Hello' }},336 { type: 'text', attr: { value: 'World' }},337 { type: 'text', attr: { value: 'Weex' }}338 ]339 })340 }),341 checkRefresh(instance, { counter: 3 }, result => {342 expect(result).toEqual({343 type: 'div',344 children: [345 { type: 'text', attr: { value: 'Hello' }},346 { type: 'text', attr: { value: 'Weex' }}347 ]348 })349 }),350 checkRefresh(instance, { counter: 4 }, result => {351 expect(result).toEqual({352 type: 'div',353 children: [354 { type: 'text', attr: { value: 'Weex' }}355 ]356 })357 }),358 checkRefresh(instance, { counter: 5 }, result => {359 expect(result).toEqual({360 type: 'div',361 children: [362 { type: 'text', attr: { value: 'Hello' }},363 { type: 'text', attr: { value: 'Weex' }}364 ]365 })366 }),367 checkRefresh(instance, { counter: 6 }, result => {368 expect(result).toEqual({369 type: 'div',370 children: [371 { type: 'input', attr: { value: 'Hello' }},372 { type: 'text', attr: { value: 'Weex' }}373 ]374 })375 done()376 })377 ])378 })379 it('should be generated with component diff', (done) => {380 const instance = createInstance(runtime, `381 new Vue({382 data: {383 counter: 0384 },385 components: {386 foo: {387 props: { a: { default: '1' }, b: { default: '2' }},388 render: function (createElement) {389 return createElement('text', { attrs: { value: this.a + '-' + this.b }}, [])390 }391 },392 bar: {393 render: function (createElement) {394 return createElement('text', { attrs: { value: 'Bar' }, style: { fontSize: 100 }})395 }396 },397 baz: {398 render: function (createElement) {399 return createElement('image', { attrs: { src: 'http://example.com/favicon.ico' }})400 }401 }402 },403 render: function (createElement) {404 switch (this.counter) {405 case 1:406 return createElement('div', {}, [407 createElement('foo', { props: { a: '111', b: '222' }}, [])408 ])409 case 2:410 return createElement('div', {}, [411 createElement('foo', {}, [])412 ])413 case 3:414 return createElement('div', {}, [415 createElement('bar', {}, [])416 ])417 case 4:418 return createElement('div', {}, [419 createElement('baz', {}, [])420 ])421 case 5:422 return createElement('div', {}, [423 createElement('foo', {}, []),424 createElement('bar', {}, []),425 createElement('baz', {}, [])426 ])427 default:428 return createElement('div', {}, [429 createElement('foo', { props: { a: '111' }}, [])430 ])431 }432 },433 el: "body"434 })435 `)436 expect(instance.getRealRoot()).toEqual({437 type: 'div',438 children: [439 { type: 'text', attr: { value: '111-2' }}440 ]441 })442 syncPromise([443 checkRefresh(instance, { counter: 1 }, result => {444 expect(result).toEqual({445 type: 'div',446 children: [447 { type: 'text', attr: { value: '111-222' }}448 ]449 })450 }),451 checkRefresh(instance, { counter: 2 }, result => {452 expect(result).toEqual({453 type: 'div',454 children: [455 { type: 'text', attr: { value: '1-2' }}456 ]457 })458 }),459 checkRefresh(instance, { counter: 3 }, result => {460 expect(result).toEqual({461 type: 'div',462 children: [463 { type: 'text', attr: { value: 'Bar' }, style: { fontSize: 100 }}464 ]465 })466 }),467 checkRefresh(instance, { counter: 4 }, result => {468 expect(result).toEqual({469 type: 'div',470 children: [471 { type: 'image', attr: { src: 'http://example.com/favicon.ico' }}472 ]473 })474 }),475 checkRefresh(instance, { counter: 5 }, result => {476 expect(result).toEqual({477 type: 'div',478 children: [479 { type: 'text', attr: { value: '1-2' }},480 { type: 'text', attr: { value: 'Bar' }, style: { fontSize: 100 }},481 { type: 'image', attr: { src: 'http://example.com/favicon.ico' }}482 ]483 })484 done()485 })486 ])487 })...
ngBindSpec.js
Source:ngBindSpec.js
...6 });7 describe('ngBind', function() {8 it('should set text', inject(function($rootScope, $compile) {9 element = $compile('<div ng-bind="a"></div>')($rootScope);10 expect(element.text()).toEqual('');11 $rootScope.a = 'misko';12 $rootScope.$digest();13 expect(element.hasClass('ng-binding')).toEqual(true);14 expect(element.text()).toEqual('misko');15 }));16 it('should set text to blank if undefined', inject(function($rootScope, $compile) {17 element = $compile('<div ng-bind="a"></div>')($rootScope);18 $rootScope.a = 'misko';19 $rootScope.$digest();20 expect(element.text()).toEqual('misko');21 $rootScope.a = undefined;22 $rootScope.$digest();23 expect(element.text()).toEqual('');24 $rootScope.a = null;25 $rootScope.$digest();26 expect(element.text()).toEqual('');27 }));28 it('should suppress rendering of falsy values', inject(function($rootScope, $compile) {29 element = $compile('<div><span ng-bind="null"></span>' +30 '<span ng-bind="undefined"></span>' +31 '<span ng-bind="\'\'"></span>-' +32 '<span ng-bind="0"></span>' +33 '<span ng-bind="false"></span>' +34 '</div>')($rootScope);35 $rootScope.$digest();36 expect(element.text()).toEqual('-0false');37 }));38 it('should one-time bind if the expression starts with two colons', inject(function($rootScope, $compile) {39 element = $compile('<div ng-bind="::a"></div>')($rootScope);40 $rootScope.a = 'lucas';41 expect($rootScope.$$watchers.length).toEqual(1);42 $rootScope.$digest();43 expect(element.text()).toEqual('lucas');44 expect($rootScope.$$watchers.length).toEqual(0);45 $rootScope.a = undefined;46 $rootScope.$digest();47 expect(element.text()).toEqual('lucas');48 }));49 it('should be possible to bind to a new value within the same $digest', inject(function($rootScope, $compile) {50 element = $compile('<div ng-bind="::a"></div>')($rootScope);51 $rootScope.$watch('a', function(newVal) { if (newVal === 'foo') { $rootScope.a = 'bar'; } });52 $rootScope.a = 'foo';53 $rootScope.$digest();54 expect(element.text()).toEqual('bar');55 $rootScope.a = undefined;56 $rootScope.$digest();57 expect(element.text()).toEqual('bar');58 }));59 it('should remove the binding if the value is defined at the end of a $digest loop', inject(function($rootScope, $compile) {60 element = $compile('<div ng-bind="::a"></div>')($rootScope);61 $rootScope.$watch('a', function(newVal) { if (newVal === 'foo') { $rootScope.a = undefined; } });62 $rootScope.a = 'foo';63 $rootScope.$digest();64 expect(element.text()).toEqual('');65 $rootScope.a = 'bar';66 $rootScope.$digest();67 expect(element.text()).toEqual('bar');68 $rootScope.a = 'man';69 $rootScope.$digest();70 expect(element.text()).toEqual('bar');71 }));72 });73 describe('ngBindTemplate', function() {74 it('should ngBindTemplate', inject(function($rootScope, $compile) {75 element = $compile('<div ng-bind-template="Hello {{name}}!"></div>')($rootScope);76 $rootScope.name = 'Misko';77 $rootScope.$digest();78 expect(element.hasClass('ng-binding')).toEqual(true);79 expect(element.text()).toEqual('Hello Misko!');80 }));81 it('should one-time bind the expressions that start with ::', inject(function($rootScope, $compile) {82 element = $compile('<div ng-bind-template="{{::hello}} {{::name}}!"></div>')($rootScope);83 $rootScope.name = 'Misko';84 expect($rootScope.$$watchers.length).toEqual(2);85 $rootScope.$digest();86 expect(element.hasClass('ng-binding')).toEqual(true);87 expect(element.text()).toEqual(' Misko!');88 expect($rootScope.$$watchers.length).toEqual(1);89 $rootScope.hello = 'Hello';90 $rootScope.name = 'Lucas';91 $rootScope.$digest();92 expect(element.text()).toEqual('Hello Misko!');93 expect($rootScope.$$watchers.length).toEqual(0);94 }));95 it('should render object as JSON ignore $$', inject(function($rootScope, $compile) {96 element = $compile('<pre>{{ {key:"value", $$key:"hide"} }}</pre>')($rootScope);97 $rootScope.$digest();98 expect(fromJson(element.text())).toEqual({key:'value'});99 }));100 });101 describe('ngBindHtml', function() {102 it('should complain about accidental use of interpolation', inject(function($compile) {103 expect(function() {104 $compile('<div ng-bind-html="{{myHtml}}"></div>');105 }).toThrowMinErr('$parse', 'syntax',106 "Syntax Error: Token '{' invalid key at column 2 of the expression [{{myHtml}}] starting at [{myHtml}}]");107 }));108 describe('SCE disabled', function() {109 beforeEach(function() {110 module(function($sceProvider) { $sceProvider.enabled(false); });111 });112 it('should set html', inject(function($rootScope, $compile) {113 element = $compile('<div ng-bind-html="html"></div>')($rootScope);114 $rootScope.html = '<div onclick="">hello</div>';115 $rootScope.$digest();116 expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');117 }));118 it('should one-time bind if the expression starts with two colons', inject(function($rootScope, $compile) {119 element = $compile('<div ng-bind-html="::html"></div>')($rootScope);120 $rootScope.html = '<div onclick="">hello</div>';121 expect($rootScope.$$watchers.length).toEqual(1);122 $rootScope.$digest();123 expect(element.text()).toEqual('hello');124 expect($rootScope.$$watchers.length).toEqual(0);125 $rootScope.html = '<div onclick="">hello</div>';126 $rootScope.$digest();127 expect(element.text()).toEqual('hello');128 }));129 });130 describe('SCE enabled', function() {131 it('should NOT set html for untrusted values', inject(function($rootScope, $compile) {132 element = $compile('<div ng-bind-html="html"></div>')($rootScope);133 $rootScope.html = '<div onclick="">hello</div>';134 expect(function() { $rootScope.$digest(); }).toThrow();135 }));136 it('should NOT set html for wrongly typed values', inject(function($rootScope, $compile, $sce) {137 element = $compile('<div ng-bind-html="html"></div>')($rootScope);138 $rootScope.html = $sce.trustAsCss('<div onclick="">hello</div>');139 expect(function() { $rootScope.$digest(); }).toThrow();140 }));141 it('should set html for trusted values', inject(function($rootScope, $compile, $sce) {...
final-draft.js
Source:final-draft.js
1const fs = require('fs')2const util = require('../utils')3const xml2js = require('xml2js')4const R = require('ramda')5const wordCount = text =>6 text &&7 // HACK ensure this is a string and .trim exists, fixes some errors #9628 text.trim9 ? text.trim().replace(/ +(?= )/g,'').split(' ').length10 : 011const durationOfWords = (text, durationPerWord) =>12 text13 ? wordCount(text) * durationPerWord14 : 015const elementText = element => {16 if (typeof element.Text[0] === 'string') {17 return element.Text[0]18 } else if (element.Text[0]._) {19 return element.Text[0]._20 }21 return undefined22}23const _wrapAsync = fn => async (...rest) =>24 new Promise((resolve, reject) =>25 fn(...rest, (err, ...result) =>26 err27 ? reject(err)28 : resolve(...result)))29const parseXmlStringAsync = _wrapAsync((new xml2js.Parser()).parseString)30const readFdxFile = async filepath => {31 return await parseXmlStringAsync(fs.readFileSync(filepath))32}33// mutates fdxObj34const insertSceneIds = (fdxObj, generateNumber = () => util.uidGen(5)) => {35 let inserted = []36 fdxObj.FinalDraft.Content[0].Paragraph.forEach((element, i) => {37 switch (element.$.Type) {38 case 'Scene Heading':39 if (typeof element.$.Number === 'undefined') {40 let uid = generateNumber()41 inserted.push(uid)42 element.$.Number = uid43 }44 break45 }46 })47 return inserted48}49const importFdxData = fdxObj => {50 let script = []51 let sceneAtom = { type: 'scene', script: [] }52 let currentTime = 053 let currentCharacter54 let currentScene = 055 let inDialogue = false56 // stats57 let totalWordCount = 058 let sceneWordCount = 059 let startSceneTime = 060 let token61 let flush = () => {62 if (sceneAtom['script'].length > 0) {63 sceneAtom['duration'] = (currentTime - startSceneTime)64 sceneAtom['word_count'] = sceneWordCount65 if (!sceneAtom['scene_number']) {66 sceneAtom['scene_number'] = currentScene67 }68 if (!sceneAtom['scene_id']) {69 sceneAtom['scene_id'] = "G" + currentScene70 }71 if (!sceneAtom['slugline']) {72 sceneAtom['slugline'] = "BLACK"73 }74 script.push(sceneAtom)75 }76 }77 fdxObj.FinalDraft.Content[0].Paragraph.forEach((element, i) => {78 switch (element.$.Type) {79 case 'Scene Heading':80 flush()81 startSceneTime = currentTime82 sceneWordCount = 083 sceneAtom = { type: 'scene', script: [] }84 currentScene++85 let atom = {86 time: currentTime,87 duration: 2000,88 type: 'scene_padding',89 scene: currentScene,90 //page: token.page,91 }92 currentTime += atom['duration']93 sceneAtom['script'].push(atom)94 sceneAtom['scene_number'] = currentScene95 //sceneAtom['scene_id'] = token.scene_number96 if (element.Text[0]._) {97 sceneAtom['slugline'] = element.Text[0]._98 } else {99 if (typeof element.Text[0] === 'string') {100 sceneAtom['slugline'] = element.Text[0]101 }102 }103 sceneAtom['slugline'] = sceneAtom['slugline'] && sceneAtom['slugline'].toUpperCase()104 sceneAtom['time'] = currentTime105 //console.log(element.Text[0])106 break107 case 'Action':108 case 'General':109 if ( element.DualDialogue) {110 // TODO HANDLE DUAL DIALOGUE111 // loop through, add the nodes112 //console.log(element.DualDialogue[0].Paragraph)113 } else {114 if (typeof element.Text[0] == 'string') {115 //console.log(typeof element.Text[0])116 token = {}117 token['type'] = 'action'118 token['time'] = currentTime119 if (element.Text.length > 1) {120 token['text'] = element.Text[0] + element.Text[1]._121 } else {122 token['text'] = element.Text[0]123 }124 token['duration'] = durationOfWords(token.text, 200)+500125 token['scene'] = currentScene126 currentTime += token['duration']127 sceneAtom['script'].push(token)128 sceneWordCount += wordCount(token.text)129 }130 }131 break132 case 'Character':133 //console.log(element.Text[0])134 if (elementText(element)) {135 currentCharacter = elementText(element).toUpperCase()136 sceneWordCount += wordCount(currentCharacter)137 }138 break139 case 'Parenthetical':140 //console.log(element.Text[0])141 token = {}142 token['type'] = 'parenthetical'143 token['text'] = element.Text[0]144 token['time'] = currentTime145 token['duration'] = durationOfWords(token.text, 300)+1000146 token['scene'] = currentScene147 token['character'] = currentCharacter148 currentTime += token['duration']149 sceneAtom['script'].push(token)150 sceneWordCount += wordCount(token.text)151 break152 case 'Dialogue':153 if (typeof element.Text == 'array') {154 //console.log(element.Text)155 } else {156 if (typeof element.Text[0] == 'string') {157 token = {}158 token['type'] = 'dialogue'159 token['text'] = element.Text[0]160 token['time'] = currentTime161 token['duration'] = durationOfWords(token.text, 300)+1000162 token['scene'] = currentScene163 token['character'] = currentCharacter164 currentTime += token['duration']165 sceneAtom['script'].push(token)166 sceneWordCount += wordCount(token.text)167 }168 }169 break170 }171 // console.log(element.$.Type)172 })173 flush()174 return script175}176const getScriptCharacters = scriptData =>177 R.pipe(178 R.filter(node => node.type === 'scene'),179 R.reduce((characters, scene) => {180 R.pipe(181 R.filter(n => typeof n.character !== 'undefined'),182 R.forEach(node => {183 character = node.character.split('(')[0].split(' AND ')[0].trim()184 characters[character] = R.defaultTo(0, characters[character]) + 1185 })186 )(scene.script)187 return characters188 }, []),189 R.toPairs190 )(scriptData)191const getScriptLocations = scriptData =>192 R.toPairs(scriptData193 .filter(x => x.type === 'scene')194 .reduce((locations, scene) => {195 location = scene.slugline.split(' - ')196 if (location.length > 1) {197 location.pop()198 }199 location = location.join(' - ')200 locations[location] = R.defaultTo(0, locations[location]) + 1201 return locations202 }, []))203module.exports = {204 readFdxFile,205 importFdxData,206 insertSceneIds,207 getScriptLocations,208 getScriptCharacters...
Using AI Code Generation
1var webdriver = require('selenium-webdriver');2var driver = new webdriver.Builder().forBrowser('chrome').build();3driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');4driver.findElement(webdriver.By.name('btnG')).click();5driver.wait(function() {6 return driver.getTitle().then(function(title) {7 return title === 'webdriver - Google Search';8 });9}, 1000);10var webdriver = require('selenium-webdriver');11var driver = new webdriver.Builder().forBrowser('chrome').build();12driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');13driver.findElement(webdriver.By.name('btnG')).click();14driver.wait(function() {15 return driver.getTitle().then(function(title) {16 return title === 'webdriver - Google Search';17 });18}, 1000);19var webdriver = require('selenium-webdriver');20var driver = new webdriver.Builder().forBrowser('chrome').build();21driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');22driver.findElement(webdriver.By.name('btnG')).click();23driver.wait(function() {24 return driver.getTitle().then(function(title) {25 return title === 'webdriver - Google Search';26 });27}, 1000);28var webdriver = require('selenium-webdriver');29var driver = new webdriver.Builder().forBrowser('chrome').build();30driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');31driver.findElement(webdriver.By.name('btnG')).click();32driver.wait(function() {33 return driver.getTitle().then(function(title) {34 return title === 'webdriver - Google Search';35 });36}, 1000);37var webdriver = require('selenium-webdriver');38var driver = new webdriver.Builder().forBrowser('chrome').build();39driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');40driver.findElement(webdriver.By.name('btnG')).click();41driver.wait(function() {42 return driver.getTitle().then(function(title) {43 return title === 'webdriver - Google Search';44 });45}, 1000);
Using AI Code Generation
1var webdriver = require('selenium-webdriver');2driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');3driver.findElement(webdriver.By.name('btnG')).click();4driver.wait(function() {5 return driver.getTitle().then(function(title) {6 return title === 'webdriver - Google Search';7 });8}, 1000);9driver.quit();10Error: spawn C:\Program Files (x86)\Appium\resources\app\node_modules\appium\build\lib\main.js ENOENT11 at exports._errnoException (util.js:1022:11)12 at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)13 at onErrorNT (internal/child_process.js:359:16)14 at _combinedTickCallback (internal/process/next_tick.js:74:11)15 at process._tickCallback (internal/process/next_tick.js:98:9)16I am trying to run Appium tests on a real device (Samsung Galaxy S6) and I am getting the following error:
Using AI Code Generation
1var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));2element.getText().then(function (text) {3 console.log(text);4});5var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));6element.getText().then(function (text) {7 console.log(text);8});9var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));10console.log(element.getText());11var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));12console.log(element.getText());13var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));14console.log(element.getText());15var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));16console.log(element.getText());17var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));18console.log(element.getText());19var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));20console.log(element.getText());21var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));22console.log(element.getText());23var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));24console.log(element.getText());25var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));26console.log(element.getText());27var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));28console.log(element.getText());29var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));30console.log(element.getText());31var element = driver.findElement(By.id("com.example.android.basicnetworking:id/test_action"));32console.log(element.getText());
Using AI Code Generation
1element.click() method2element.sendKeys() method3element.submit() method4element.text() method5element.clear() method6element.getAttribute() method7element.getLocation() method8element.getSize() method9element.isDisplayed() method10element.isEnabled() method11element.isSelected() method12element.getTagName() method13element.getCssValue() method14element.isDisplayed() method15element.isEnabled() method16element.isSelected() method17element.getTagName() method18element.getCssValue() method19element.isDisplayed() method20element.isEnabled() method
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!