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

feat($interval): pass arguments in callback #10632

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/ng/interval.js
Expand Up @@ -39,6 +39,7 @@ function $IntervalProvider() {
* indefinitely.
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
* @param {...*=} Pass additional parameters to the executed function.
* @returns {promise} A promise which will be notified on each iteration.
*
* @example
Expand Down Expand Up @@ -132,7 +133,9 @@ function $IntervalProvider() {
* </example>
*/
function interval(fn, delay, count, invokeApply) {
var setInterval = $window.setInterval,
var hasParams = arguments.length > 4,
args = hasParams ? sliceArgs(arguments, 4) : [],
setInterval = $window.setInterval,
clearInterval = $window.clearInterval,
iteration = 0,
skipApply = (isDefined(invokeApply) && !invokeApply),
Expand All @@ -141,7 +144,9 @@ function $IntervalProvider() {

count = isDefined(count) ? count : 0;

promise.then(null, null, fn);
promise.then(null, null, (!hasParams) ? fn : function() {
fn.apply(null, args);
});

promise.$$intervalId = setInterval(function tick() {
deferred.notify(iteration++);
Expand Down
9 changes: 7 additions & 2 deletions src/ngMock/angular-mocks.js
Expand Up @@ -451,6 +451,7 @@ angular.mock.$LogProvider = function() {
* indefinitely.
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
* @param {...*=} Pass additional parameters to the executed function.
* @returns {promise} A promise which will be notified on each iteration.
*/
angular.mock.$IntervalProvider = function() {
Expand All @@ -461,13 +462,17 @@ angular.mock.$IntervalProvider = function() {
now = 0;

var $interval = function(fn, delay, count, invokeApply) {
var iteration = 0,
var hasParams = arguments.length > 4,
args = hasParams ? Array.prototype.slice.call(arguments, 4) : [],
iteration = 0,
skipApply = (angular.isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise;

count = (angular.isDefined(count)) ? count : 0;
promise.then(null, null, fn);
promise.then(null, null, (!hasParams) ? fn : function() {
fn.apply(null, args);
});

promise.$$intervalId = nextRepeatId;

Expand Down
25 changes: 25 additions & 0 deletions test/ng/intervalSpec.js
Expand Up @@ -142,6 +142,31 @@ describe('$interval', function() {
}));


it('should allow you to specify a number of arguments', inject(function($interval, $window) {
var task1 = jasmine.createSpy('task1'),
task2 = jasmine.createSpy('task2'),
task3 = jasmine.createSpy('task3');
$interval(task1, 1000, 2, true, 'Task1');
$interval(task2, 1000, 2, true, 'Task2');
$interval(task3, 1000, 2, true, 'I', 'am', 'a', 'Task3', 'spy');

$window.flush(1000);
expect(task1).toHaveBeenCalledWith('Task1');
expect(task2).toHaveBeenCalledWith('Task2');
expect(task3).toHaveBeenCalledWith('I', 'am', 'a', 'Task3', 'spy');

task1.reset();
task2.reset();
task3.reset();

$window.flush(1000);
expect(task1).toHaveBeenCalledWith('Task1');
expect(task2).toHaveBeenCalledWith('Task2');
expect(task3).toHaveBeenCalledWith('I', 'am', 'a', 'Task3', 'spy');

}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sequence of expectations seems not quite right. Since we are using $interval then each of the spies should have been called once per flush.

How about something more like:

$window.flush(1000);
expect(task1).toHaveBeenCalledWith('Task1');
expect(task2).toHaveBeenCalledWith('Task2');
expect(task3).toHaveBeenCalledWith('I', 'am', 'a', 'Task3', 'spy');
task1.reset();
task2.reset();
task3.reset();
$window.flush(1000);
expect(task1).toHaveBeenCalledWith('Task1');
expect(task2).toHaveBeenCalledWith('Task2');
expect(task3).toHaveBeenCalledWith('I', 'am', 'a', 'Task3', 'spy');

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the tests (and rebase master) with an $interval count of 2 otherwise the second part of this won't work since the .reset() only resets the state of the spy and not $interval.



it('should return a promise which will be updated with the count on each iteration',
inject(function($interval, $window) {
var log = [],
Expand Down