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

Support asynchronous world constructor #39

Closed
salikh opened this issue Jan 10, 2012 · 12 comments
Closed

Support asynchronous world constructor #39

salikh opened this issue Jan 10, 2012 · 12 comments

Comments

@salikh
Copy link

salikh commented Jan 10, 2012

I am trying to use cucumber.js to test an express.js web application.
The test scenarios are creating new objects in MongoDb database,
and I need to clear it before running the tests.

Mongodb operations are asynchronous, so if I clear the database
from world constructor, then I have a race condition with test execution.

I came up with an idea how asynchronous initialization can be supported,
please see the fork at git://github.com/salikh/cucumber-js.git.

To request asynchronous initialization, the feature writer needs
to inherit from the EventEmitter by writing the following line:

this.__proto__ = new process.EventEmitter

Then the world constructor can indicate that it finished initialization
by firing an event on itself:

world.emit('init done')

The world initializer tests if the asynchronous initialization is
required by the following condition:

if (world.__proto__.constructor == process.EventEmitter)

and if the condition matches, it starts test execution asynchronously:

world.on('init done', function() {
cont()
})
@jbpros
Copy link
Member

jbpros commented Jan 10, 2012

This is interesting and definitely worth considering. Thank you for suggesting it.

I'm not sure about the EventEmitter inheritance check though. What about something more flexible? Like a simple property on the World instance that, when set to true would make the world instantiator wait for a callback:

this.World = function MyWorld(callback) {
  this.asynchronous = true; // tells Cucumber to wait for 
                            // the callback to be fired
  // do your thing
  someAsyncFuncWithCallback(callback);
};

Or maybe even better: always asynchronous world constructors:

this.World = function MyWorld(callback) {
  // do your thing
  someAsyncFuncWithCallback(callback);
};

Thoughts?

@salikh
Copy link
Author

salikh commented Jan 11, 2012

Yes, I agree. Either way works for me. The 'always use callback' variant seems better to me
because of simplicity, but it will break existing test suites (how many are there in the wild?).

@jbpros
Copy link
Member

jbpros commented Jan 11, 2012

It's still ok to make changes to the public API.

The more we run into asynchronous issues, the more I think we should make Cucumber totally asynchronous.

@jbpros jbpros closed this as completed in 15b9435 Jan 13, 2012
@salikh
Copy link
Author

salikh commented Jan 13, 2012

Thanks for the implementation! It is very helpful

@jbpros
Copy link
Member

jbpros commented Jan 13, 2012

@salikh You're welcome!

@jbpros
Copy link
Member

jbpros commented Jan 13, 2012

0.2.4 was released so that this rather important change is available on NPM too.

@theycallmeswift
Copy link

This change actually broke my existing test suite.

I require cucumber using "0.2.x" (under the assumption that all patches should be backwards compatible). Took me a while to figure out what happened. Probably should have been classified as a minor API change or included code to preserve existing World functions.

@jbpros
Copy link
Member

jbpros commented Jan 17, 2012

@theycallmeswift Yeah, I realised too late I didn't bump the version properly. I'm sorry about that. Now there are actual consumers of Cucumber.js and not only testers, I'm going to pay more attention to communicating backward-incompatible changes.

@Izhaki
Copy link
Contributor

Izhaki commented Aug 15, 2016

This feature is no longer supported.

For people like me trying to see if World can be async, see docs:

Breaking Change: The World constructor is now strictly synchronous and does not receive a callback from Cucumber anymore... This is a breaking change that was introduced in release v0.8.0

@kaworu
Copy link

kaworu commented Jun 6, 2017

This is not supported anymore as correctly pointed out by @Izhaki,

Then, how or when should "async world setup code" run?

@jbpros
Copy link
Member

jbpros commented Jun 6, 2017

@kaworu use a Before hook that calls a method on your world.

@lock
Copy link

lock bot commented Oct 25, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Oct 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants