Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(ngAnimate): introduce $animate.flush for unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
matsko committed Sep 14, 2015
1 parent ec98c94 commit f98e038
Show file tree
Hide file tree
Showing 9 changed files with 472 additions and 288 deletions.
58 changes: 48 additions & 10 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,8 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
};
});

$provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser',
function($delegate, $$asyncCallback, $timeout, $browser) {
$provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser', '$rootScope', '$$rAF',
function($delegate, $$asyncCallback, $timeout, $browser, $rootScope, $$rAF) {
var animate = {
queue: [],
cancel: $delegate.cancel,
Expand All @@ -803,6 +803,43 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
fn();
});
reflowQueue = [];
},
flush: function() {
$rootScope.$digest();
var doNextRun, somethingFlushed = false;
do {
doNextRun = false;
if (reflowQueue.length) {
doNextRun = somethingFlushed = true;
this.triggerReflow();
}
if ($$rAF.queue.length) {
doNextRun = somethingFlushed = true;
$$rAF.flush();
}
if ($$asyncCallback.queue.length) {
doNextRun = somethingFlushed = true;
this.triggerCallbackEvents();
}
if (timeoutsRemaining()) {
var oldValue = timeoutsRemaining();
this.triggerCallbackPromise();
var newValue = timeoutsRemaining();
if (newValue < oldValue) {
doNextRun = somethingFlushed = true;
}
}
} while (doNextRun);

if (!somethingFlushed) {
throw new Error('No pending animations ready to be closed or flushed');
}

$rootScope.$digest();

function timeoutsRemaining() {
return $browser.deferredFns.length;
}
}
};

Expand Down Expand Up @@ -1752,15 +1789,16 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $
}];

angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
var queue = [];
var rafFn = function(fn) {
var queue, rafFn = function(fn) {
var index = queue.length;
queue.push(fn);
return function() {
queue.splice(index, 1);
};
};

queue = rafFn.queue = [];

rafFn.supported = $delegate.supported;

rafFn.flush = function() {
Expand All @@ -1773,22 +1811,22 @@ angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
queue[i]();
}

queue = [];
queue.length = 0;
};

return rafFn;
}];

angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {
var callbacks = [];
var addFn = function(fn) {
callbacks.push(fn);
var queue, addFn = function(fn) {
queue.push(fn);
};
queue = addFn.queue = [];
addFn.flush = function() {
angular.forEach(callbacks, function(fn) {
angular.forEach(queue, function(fn) {
fn();
});
callbacks = [];
queue.length = 0;
};
return addFn;
}];
Expand Down
3 changes: 2 additions & 1 deletion test/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
"spyOnlyCallsWithArgs": false,
"createMockStyleSheet": false,
"browserTrigger": false,
"jqLiteCacheSize": false
"jqLiteCacheSize": false,
"browserSupportsCssAnimations": false
}
}
9 changes: 9 additions & 0 deletions test/helpers/privateMocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,12 @@ function createMockStyleSheet(doc, wind) {
}
};
}

function browserSupportsCssAnimations() {
var nav = window.navigator.appVersion;
if (nav.indexOf('MSIE') >= 0) {
var version = parseInt(navigator.appVersion.match(/MSIE ([\d.]+)/)[1]);
return version >= 10; //only IE10+ support keyframes / transitions
}
return true;
}
2 changes: 1 addition & 1 deletion test/ng/directive/ngClassSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ describe('ngClass animations', function() {
//is spaced-out then it is required so that the original digestion
//is kicked into gear
$rootScope.$digest();
$animate.triggerCallbacks();
$animate.flush();

expect(element.data('state')).toBe('crazy-enter');
expect(enterComplete).toBe(true);
Expand Down
14 changes: 7 additions & 7 deletions test/ng/directive/ngIncludeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ describe('ngInclude', function() {

expect(autoScrollSpy).not.toHaveBeenCalled();
expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

expect(autoScrollSpy).toHaveBeenCalledOnce();
}));
Expand All @@ -450,7 +450,7 @@ describe('ngInclude', function() {
});

expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

$rootScope.$apply(function() {
$rootScope.tpl = 'another.html';
Expand All @@ -459,7 +459,7 @@ describe('ngInclude', function() {

expect($animate.queue.shift().event).toBe('leave');
expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

$rootScope.$apply(function() {
$rootScope.tpl = 'template.html';
Expand All @@ -468,7 +468,7 @@ describe('ngInclude', function() {

expect($animate.queue.shift().event).toBe('leave');
expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

expect(autoScrollSpy).toHaveBeenCalled();
expect(autoScrollSpy.callCount).toBe(3);
Expand All @@ -484,7 +484,7 @@ describe('ngInclude', function() {
});

expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();
expect(autoScrollSpy).not.toHaveBeenCalled();
}));

Expand All @@ -500,7 +500,7 @@ describe('ngInclude', function() {
});

expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

$rootScope.$apply(function() {
$rootScope.tpl = 'template.html';
Expand All @@ -522,7 +522,7 @@ describe('ngInclude', function() {

$rootScope.$apply("tpl = 'template.html'");
expect($animate.queue.shift().event).toBe('enter');
$animate.triggerCallbacks();
$animate.flush();

expect(autoScrollSpy).toHaveBeenCalledOnce();
}
Expand Down
2 changes: 1 addition & 1 deletion test/ng/directive/ngRepeatSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,7 @@ describe('ngRepeat animations', function() {
$rootScope.$digest();

expect(element.text()).toBe('123'); // the original order should be preserved
$animate.triggerReflow();
$animate.flush();
$timeout.flush(1500); // 1s * 1.5 closing buffer
expect(element.text()).toBe('13');

Expand Down
Loading

0 comments on commit f98e038

Please sign in to comment.