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

feat(ngMock) add atomic flushing strategy for $timeout #13183

Closed
wants to merge 2 commits into from

Conversation

elkeis
Copy link

@elkeis elkeis commented Oct 27, 2015

Hi dear Angular community,

During writing unit tests I found one interesting issue. I need to write tests for some code like this:

$timeout(function() {
 action1();
 $timeout(function() {
  action2();
 });
});

And I'm expecting that I need to execute $timeout.flush() 2 times. First time to reach action1 function and the second time to execute action2 function (let's call this kind of flush "atomic" for example). But for now, for the first flush() it executes the both handlers. One after another. Please check this example: http://jsbin.com/fuziri/edit?js,output .

On the other hand we have some cases in tests when this buggy, for the first look, behaviour can simplify our lifes. In such case for example:

 var callback = jasmine.createSpy();
 $timeout(function() {}, 0, false).then(callback);
 $timeout.flush();
 expect(callback).toHaveBeenCalled();

Here $timeout register new defered task to process callback using $browser.defer during flushing. So to execute callback (if you are using that atomic flush strategy) you should call $timeout.flush() twise.

I think that the both strategies of flushing are pretty useful. And may be it will be a good idea to:

  • implement that atomic flushing
  • to allow to switch between the strategies using some additional flag

What do you think, guys?

P.S. this is a duplicate of #13146, I opened a new one because can't solve the certificate issue for commit with wrong email address.

Add flag to `$timeout.flush()` function. If set to `true` — will handle only the tasks
available at the moment of execution, otherwise will process the tasks that were
added during execution as well (`false` by default).
@@ -103,8 +103,11 @@ angular.mock.$Browser = function() {
* Flushes all pending requests and executes the defer callbacks.
*
* @param {number=} number of milliseconds to flush. See {@link #defer.now}
* @param {boolean=} [atomic=false] If set to `true` — will handle only tasks
* available at the moment of execution, otherwise will process tasks that was
Copy link

Choose a reason for hiding this comment

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

that were*

@atogata
Copy link

atogata commented Nov 11, 2015

+1, using on one of my projects, works great

@elkeis
Copy link
Author

elkeis commented Nov 12, 2015

@atogata, thanks. Spelling corrected.

@petebacondarwin
Copy link
Contributor

@elkeis - did you know that you can pass a delay to $timeout.flush(delay), which will only flush timeouts that should have completed by the given delay. This is not quite what you want, perhaps, since if you have two timeouts with 0 delay then they would both always be flushed at the same time.
But this can help with testing sequencing issues.

@petebacondarwin
Copy link
Contributor

Oh I just looked at the code. I see that you want to ensure that new calls to timeout that are triggered as part of flushing the current timeouts are not triggered...

@petebacondarwin
Copy link
Contributor

Interesting idea. I think this would need some more API thought as the current atomic parameter is not that intuitive to me.

@petebacondarwin
Copy link
Contributor

This is very vaguely related to #5420. It would be interesting to solve both at once...

@petebacondarwin
Copy link
Contributor

petebacondarwin commented May 27, 2016

@elkeis once #14686 lands then as long as your timeouts have a non-zero delay, then they will indeed become separable in tests.

Given your original example, if I add 1ms second delays:

$timeout(function() {
 action1();
 $timeout(function() {
  action2();
 }, 1);
}, 1);

Calling $timeout.flush(1) will only trigger action1().
Calling $timeout.flush(1) a second time will trigger action2().

Is this enough for your testing?

@petebacondarwin
Copy link
Contributor

Closing as #14686 has landed and there has been activity on this PR for 10 months.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants