-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Introduce Event Bus (WIP) #903
Conversation
- Only handles single handler per event. - Does not deal with errors in the handlers
Notes: 1. We need to use @Spawn here because the puts statements are sent directly to STDOUT rather than being sent to the io stream passed into `Cli::Main`. 2. `expect` doesn't work in the event block - it's evaluated in the context of nil. Would something else make more sense? I'm not sure. cc @tooky
Some thoughts: - it would be better to fire the event from within `Filters::ActivateSteps` because that's the central place that will be used by plugins like Wire and Tcl, but that will require refactoring of the API for matching steps. - we need to be careful exposing objects through the events that will become depended on by people. `StepMatch` has a cluttered graph of attributes. - We could do away with the event object altogether, and pass the payload arguments directly to the handler. I'm instinctively against this, partly because I just like having types for things, and partly because I worry it will make the whole thing harder to document, and more prone to error. - if we do keep the type for the event, having a name symbol is duplication
fa5da87
to
8bb7860
Compare
Matt, I subscribed myself to your PR. Please ping me, when you're finished. |
You might want to change |
Hi @dg-ratiodata this is now live in Cucumber 2.1 I'm unclear how it would help to be able to inject different strategies of EventResolver. Can you give me an example of what you would do with that feature? |
Sorry for my late response. I was on vacation. I see two aspects here:
|
module Events | ||
|
||
# Event fired after each test step has been executed | ||
class AfterTestStep |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mattwynne Is that really an event or a name for a hook? Normally I would say, that TestStepHasRun
would be a name for an event.
One thing I thought about lately at How would you distinguish a hook from an event? From a user perspective you could do more or less the same with both of them. At least for |
In Cucumber, the distinction is that a hook is part of the test-case, and can fail the scenario. An error in and event listener would be handled differently. (Not sure how at the moment!) |
Why is that @mattwynne? Common practice in event APIs is that an error raised in a listener bubbles up to the caller. (See Node.js example further down). I think an error raised in an event listener should bubble up to the event emitter and fail the scenario. In fact, I think making events and hoods the same thing would be a Good Thing. I don't see a reason to distinguish between them. var EventEmitter = require("events").EventEmitter;
var e = new EventEmitter();
e.on('stuff', function () {
throw new Error('oops');
});
try {
e.emit('stuff');
} catch(err) {
console.log('caught error thrown by event listener');
} |
Well, philosophically we see event listeners as being ‘out of the loop’- for example if someone writes a buggy formatter, that’s not a problem with your tests. That’s not to say that Cucumber won’t fail and report the error, but I wouldn’t see it as counting as a test failure. |
I understand that philosophy, but I think it's an unneeded distinction that only provides additional complexity. Why not let a failing listener fail the test, and if users complain they need more fine grained distinction, deal with that later. |
It actually makes things simpler if we assume we can run the tests, publish these result events but not care about what happened at the other end of the pipe. That's how it works now, and I'd prefer to keep it that way until, as you say, someone complains. |
Further up I think you said you're not sure how to handle an error raised from a listener. Does that mean you don't know what happens, or does it mean you want to change how it currently behaves, but you don't know how? |
"Hook" seems to be used for very different things in this discussion. Going back to the question from @dg-ratiodata "Is that [
Then there are the To me it seems natural that event in the Event Bus is handled similar to the formatter (hook-)methods with respect to errors. However in my mind "event" is something fundamentally asynchronous, so errors during the processing of an event, would need to be passed back as a separate event. |
@brasmusson asynchronoys events implies threads (for ruby at least) and that complicates things even more. Even node.js (an inherently async platform) implements core api events synchronoysly. See my code above. I wonder, what is the recommended use case for events (as opposed to hooks and formatters)? Right now the different ways to do the same thing can only confuse users. I don't like menus with too many similar options. |
To me it looks like that events and the event bus are basically the replacement for the formatter API, adding the |
Events are how you get notified about anything that's happening during the test run. They are read-only. They are designed for writing formatters, and other plug-ins that will want to know things about the features being run, but do not need to interact with the run. Our intention is that this will be the way to write formatters from 3.0 onwards. This simplifies things for us internally and for users, as we can be clear about which parts of the API are for output (side-effect free) and which parts of the API allow you to interact with Cucumber. I heard you about Node Aslak, and maybe we've chosen the wrong terminology here. The model in my mind is more pub-sub than synchronous events. I certainly want the option to be able to fire those events asynchronously in the future without breaking people's expectations about the API. |
Thanks guys for the clarification. :-) Will take the discussion into account when I decide about how to go on with hooks in Back to #903 (comment) @mattwynne What about that comment? I can live with taking over the current implentation though I'm not that happy about all the code taken from |
Back to #903 (comment) @mattwynne What about that comment? I can live with taking over the current implentation though I'm not that happy about all the code taken from ActiveSupport. I think it has really nothing to do with the event bus, but is only use to resolve the name of the event and should better be moved to some kind of resolver-class. — Makes sense - want to send a PR? |
Will do. But will take a bit... Need to prepare a going-live at the beginning of oct. Hope to find some time inbetween. |
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. |
With this change, clients both within the Cucumber codebase and built by our users, can consume events about various things that happen as your tests run.
For example:
This should help us remove some of the ugly coupling between different parts of the code, and allow for more flexiblity in the API for users who want to build formatters and other tools.
Feedback please!
The intention is that this change is backwards compatible, with the idea that it will become the mandatory API for writing formatters from version 3.0