-
Notifications
You must be signed in to change notification settings - Fork 27.4k
ngClass[Odd/Even] overhaul #15228
ngClass[Odd/Even] overhaul #15228
Changes from 3 commits
8822006
0409589
2705085
0ba4be6
89268af
2871a11
a7e69f7
37cec7a
5708424
739f723
181c51b
16e666b
dfe4307
f766698
a9742f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
'use strict'; | ||
|
||
describe('ngClass', function() { | ||
fdescribe('ngClass', function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naught naughty There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I already have a fixup commit at the end 😛 |
||
var element; | ||
|
||
beforeEach(module(function($compileProvider) { | ||
|
@@ -244,31 +244,42 @@ describe('ngClass', function() { | |
})); | ||
|
||
|
||
it('should allow ngClassOdd/Even on the same element with overlapping classes', inject(function($rootScope, $compile, $animate) { | ||
var className; | ||
|
||
element = $compile('<ul><li ng-repeat="i in [0,1,2]" ng-class-odd="\'same odd\'" ng-class-even="\'same even\'"></li><ul>')($rootScope); | ||
it('should allow ngClassOdd/Even on the same element with overlapping classes', | ||
inject(function($compile, $rootScope) { | ||
element = $compile( | ||
'<ul>' + | ||
'<li ng-repeat="i in [0,1,2]" ' + | ||
'ng-class-odd="\'same odd\'" ' + | ||
'ng-class-even="\'same even\'">' + | ||
'</li>' + | ||
'<ul>')($rootScope); | ||
$rootScope.$digest(); | ||
var e1 = jqLite(element[0].childNodes[1]); | ||
var e2 = jqLite(element[0].childNodes[5]); | ||
expect(e1.hasClass('same')).toBeTruthy(); | ||
expect(e1.hasClass('odd')).toBeTruthy(); | ||
expect(e2.hasClass('same')).toBeTruthy(); | ||
expect(e2.hasClass('odd')).toBeTruthy(); | ||
|
||
var e1 = element.children().eq(0); | ||
var e2 = element.children().eq(1); | ||
var e3 = element.children().eq(2); | ||
|
||
expect(e1).toHaveClass('same'); | ||
expect(e1).toHaveClass('odd'); | ||
expect(e1).not.toHaveClass('even'); | ||
expect(e2).toHaveClass('same'); | ||
expect(e2).not.toHaveClass('odd'); | ||
expect(e2).toHaveClass('even'); | ||
expect(e3).toHaveClass('same'); | ||
expect(e3).toHaveClass('odd'); | ||
expect(e3).not.toHaveClass('even'); | ||
}) | ||
); | ||
|
||
it('should allow ngClass with overlapping classes', inject(function($rootScope, $compile, $animate) { | ||
it('should allow ngClass with overlapping classes', inject(function($rootScope, $compile) { | ||
element = $compile('<div ng-class="{\'same yes\': test, \'same no\': !test}"></div>')($rootScope); | ||
$rootScope.$digest(); | ||
|
||
expect(element).toHaveClass('same'); | ||
expect(element).not.toHaveClass('yes'); | ||
expect(element).toHaveClass('no'); | ||
|
||
$rootScope.$apply(function() { | ||
$rootScope.test = true; | ||
}); | ||
$rootScope.$apply('test = true'); | ||
|
||
expect(element).toHaveClass('same'); | ||
expect(element).toHaveClass('yes'); | ||
|
@@ -300,37 +311,79 @@ describe('ngClass', function() { | |
})); | ||
|
||
|
||
it('should reapply ngClass when interpolated class attribute changes', inject(function($rootScope, $compile) { | ||
element = $compile('<div class="one {{cls}} three" ng-class="{four: four}"></div>')($rootScope); | ||
|
||
$rootScope.$apply(function() { | ||
$rootScope.cls = 'two'; | ||
$rootScope.four = true; | ||
}); | ||
expect(element).toHaveClass('one'); | ||
expect(element).toHaveClass('two'); // interpolated | ||
expect(element).toHaveClass('three'); | ||
expect(element).toHaveClass('four'); | ||
|
||
$rootScope.$apply(function() { | ||
$rootScope.cls = 'too'; | ||
}); | ||
expect(element).toHaveClass('one'); | ||
expect(element).toHaveClass('too'); // interpolated | ||
expect(element).toHaveClass('three'); | ||
expect(element).toHaveClass('four'); // should still be there | ||
expect(element.hasClass('two')).toBeFalsy(); | ||
|
||
$rootScope.$apply(function() { | ||
$rootScope.cls = 'to'; | ||
}); | ||
expect(element).toHaveClass('one'); | ||
expect(element).toHaveClass('to'); // interpolated | ||
expect(element).toHaveClass('three'); | ||
expect(element).toHaveClass('four'); // should still be there | ||
expect(element.hasClass('two')).toBeFalsy(); | ||
expect(element.hasClass('too')).toBeFalsy(); | ||
})); | ||
it('should reapply ngClass when interpolated class attribute changes', | ||
inject(function($compile, $rootScope) { | ||
element = $compile( | ||
'<div>' + | ||
'<div class="one {{two}} three" ng-class="{five: five}"></div>' + | ||
'<div class="one {{two}} three {{four}}" ng-class="{five: five}"></div>' + | ||
'</div>')($rootScope); | ||
var e1 = element.children().eq(0); | ||
var e2 = element.children().eq(1); | ||
|
||
$rootScope.$apply('two = "two"; five = true'); | ||
|
||
expect(e1).toHaveClass('one'); | ||
expect(e1).toHaveClass('two'); | ||
expect(e1).toHaveClass('three'); | ||
expect(e1).not.toHaveClass('four'); | ||
expect(e1).toHaveClass('five'); | ||
expect(e2).toHaveClass('one'); | ||
expect(e2).toHaveClass('two'); | ||
expect(e2).toHaveClass('three'); | ||
expect(e2).not.toHaveClass('four'); | ||
expect(e2).toHaveClass('five'); | ||
|
||
$rootScope.$apply('two = "too"'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. although this is very clever "two" and "too" are very similar and actually make the test harder to follow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The cleverness credits go to the original test 😃 |
||
|
||
expect(e1).toHaveClass('one'); | ||
expect(e1).not.toHaveClass('two'); | ||
expect(e1).toHaveClass('too'); | ||
expect(e1).toHaveClass('three'); | ||
expect(e1).not.toHaveClass('four'); | ||
expect(e1).toHaveClass('five'); | ||
expect(e2).toHaveClass('one'); | ||
expect(e2).not.toHaveClass('two'); | ||
expect(e2).toHaveClass('too'); | ||
expect(e2).toHaveClass('three'); | ||
expect(e2).not.toHaveClass('four'); | ||
expect(e2).toHaveClass('five'); | ||
|
||
$rootScope.$apply('two = "to"; four = "four"'); | ||
|
||
expect(e1).toHaveClass('one'); | ||
expect(e1).not.toHaveClass('two'); | ||
expect(e1).not.toHaveClass('too'); | ||
expect(e1).toHaveClass('to'); | ||
expect(e1).toHaveClass('three'); | ||
expect(e1).not.toHaveClass('four'); | ||
expect(e1).toHaveClass('five'); | ||
expect(e2).toHaveClass('one'); | ||
expect(e2).not.toHaveClass('two'); | ||
expect(e2).not.toHaveClass('too'); | ||
expect(e2).toHaveClass('to'); | ||
expect(e2).toHaveClass('three'); | ||
expect(e2).toHaveClass('four'); | ||
expect(e2).toHaveClass('five'); | ||
|
||
$rootScope.$apply('five = false'); | ||
|
||
expect(e1).toHaveClass('one'); | ||
expect(e1).not.toHaveClass('two'); | ||
expect(e1).not.toHaveClass('too'); | ||
expect(e1).toHaveClass('to'); | ||
expect(e1).toHaveClass('three'); | ||
expect(e1).not.toHaveClass('four'); | ||
expect(e1).not.toHaveClass('five'); | ||
expect(e2).toHaveClass('one'); | ||
expect(e2).not.toHaveClass('two'); | ||
expect(e2).not.toHaveClass('too'); | ||
expect(e2).toHaveClass('to'); | ||
expect(e2).toHaveClass('three'); | ||
expect(e2).toHaveClass('four'); | ||
expect(e2).not.toHaveClass('five'); | ||
}) | ||
); | ||
|
||
|
||
it('should not mess up class value due to observing an interpolated class attribute', inject(function($rootScope, $compile) { | ||
|
@@ -424,6 +477,62 @@ describe('ngClass', function() { | |
}) | ||
); | ||
|
||
it('should do value stabilization as expected when one-time binding', | ||
inject(function($rootScope, $compile) { | ||
element = $compile('<div ng-class="::className"></div>')($rootScope); | ||
$rootScope.$digest(); | ||
|
||
$rootScope.className = 'foo'; | ||
$rootScope.$digest(); | ||
expect(element).toHaveClass('foo'); | ||
|
||
$rootScope.className = 'bar'; | ||
$rootScope.$digest(); | ||
expect(element).toHaveClass('foo'); | ||
}) | ||
); | ||
|
||
it('should remove the watcher when static array one-time binding', | ||
inject(function($rootScope, $compile) { | ||
element = $compile('<div ng-class="::[className]"></div>')($rootScope); | ||
$rootScope.$digest(); | ||
|
||
$rootScope.$apply('className = "foo"'); | ||
expect(element).toHaveClass('foo'); | ||
|
||
$rootScope.$apply('className = "bar"'); | ||
expect(element).toHaveClass('foo'); | ||
expect(element).not.toHaveClass('bar'); | ||
}) | ||
); | ||
|
||
it('should do value remove the watcher when static map one-time binding', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the test description here seems like a hybrid of the two tests above :-) |
||
inject(function($rootScope, $compile) { | ||
element = $compile('<div ng-class="::{foo: fooPresent}"></div>')($rootScope); | ||
$rootScope.$digest(); | ||
|
||
$rootScope.fooPresent = true; | ||
$rootScope.$digest(); | ||
expect(element).toHaveClass('foo'); | ||
|
||
$rootScope.fooPresent = false; | ||
$rootScope.$digest(); | ||
expect(element).toHaveClass('foo'); | ||
}) | ||
); | ||
|
||
it('should track changes of mutating object inside an array', | ||
inject(function($rootScope, $compile) { | ||
$rootScope.classVar = [{orange: true}]; | ||
element = $compile('<div ng-class="classVar"></div>')($rootScope); | ||
$rootScope.$digest(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth adding an expectation that it should have the class "orange" here? |
||
|
||
$rootScope.classVar[0].orange = false; | ||
$rootScope.$digest(); | ||
|
||
expect(element).not.toHaveClass('orange'); | ||
}) | ||
); | ||
}); | ||
|
||
describe('ngClass animations', function() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never knew about these helpers!!