Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: await jasmine.clock().asyncTick() #1725

Open
stephenfarrar opened this issue Jun 27, 2019 · 2 comments
Open

Proposal: await jasmine.clock().asyncTick() #1725

stephenfarrar opened this issue Jun 27, 2019 · 2 comments

Comments

@stephenfarrar
Copy link

Several previous issues have discussed the way mock clock doesn't work very well with Promises #1659 #1282 #710 . Here I have a proposal for a new method on the mock clock that will inter-operate with Promises nicely.

It's quite common to write code like this:

async function() {
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log('A');
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log('B');
}

You might expect jasmine.clock().tick(2000) to log both A and B, but it will log neither A nor B! The issue is that .tick() runs any scheduled timeouts one after the other, synchronously, and doesn't allow microtasks to run.

Instead, we need to run a timeout, wait for microtasks to run, and then run the remaining timeouts, repeat. This is pretty close to the way the JS engine actually works.

I propose adding an .asyncTick() method that does what I've just described. The test would call it like this:

await jasmine.clock().asyncTick(2000);

One difficulty is knowing how to wait for microtasks to run. In previous issues, people pointed out that various Promise implementations work in different ways. My solution to this (in other settings) has been to schedule a (real) setTimeout. This does slow the test down, but it's a lot better than using a real clock.

Another alternative could be to call jasmine's clearStack(). If a user has a Promise implementation that is slower than whatever clearStack() does, we could just not care. (They can always get a better Promise implementation!) This would be my preferred approach.

If this seems like a reasonable proposal, I will try to code it up and send a PR. Seems like I need to add a runScheduledFunctionsAsync method to DelayedFunctionScheduler.

@slackersoft
Copy link
Member

This sounds reasonable and I'd be happy to review a Pull Request to add an awaitable asyncTick function. This should even be a bit easier now that Jasmine has some other Promise based functionality to have handled configuration of applicable Promise libraries.

Sorry for the delay. Thanks for using Jasmine!

@stephenfarrar
Copy link
Author

I actually have some time now, so I'm taking a look.

Seems like I should inject DelayedFunctionScheduler with (customPromise || global.Promise) ?

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

Successfully merging a pull request may close this issue.

2 participants