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

Vows for events other then 'Success' #145

Closed
wants to merge 1 commit into from
Closed

Conversation

seebees
Copy link

@seebees seebees commented Oct 22, 2011

This is a pull for #109.

I needed to resolve the issue between dealing with topics that are explicitly EventEmitters and topics that inherit from EventEmitters.

The syntax I'm using is like this:

"A topic that emits many events" : {
  topic: function () {
    return new CrazyEmitter();
  },
  "[request]" : {
    "will emit the new request" : function () {},
    "will set my class with a cached element" : function () {},
    "[end]" : {
      "will be clean" : function(){}
    }
  }
}

[request] and [end] I term sub-events. The [end] vows will be tested after the [request] vows. But I do not have anything to guarantee the event order. Which would be nice. Ideas?

If a Context is a sub-event

  • it will have a property this.isEvent === true.
  • it must not have a topic in it's definition.
  • it's parent topic must inherit from EventEmitter.

If the above is not true it will throw. I can change that, now that I'm thinking about it I may need to so that the vows can be stubbed out.

In any event I need explicit tests for all this as well so don't merge it right now. But please do comment on direction and syntax.

Also note, this will resolve #76.

@seebees
Copy link
Author

seebees commented Oct 29, 2011

@cloudhead, @indexzero
Ok. I think that this is done. I don't see a way to update the documentation though.

Are there any tests that I'm missing? Want to try and avoid breaking the world again ;)

@cloudhead
Copy link

This is definitely needed, but I'm not fond of the API. Something like this would be preferred:

"A topic that emits many events" : {
  topic: function () {
    return new CrazyEmitter();
  },
  events: {
    "request" : {
      "will emit the new request" : function () {},
      "will set my class with a cached element" : function () {},
      events: {      
        "end" : {
          "will be clean" : function(){}
        }
      }
    }
  }
}

@indexzero
Copy link

@cloudhead +1 to that API. I like it. It will greatly reduce the nesting level in my tests where I want to test two separate events from the same event emitter.

@seebees
Copy link
Author

seebees commented Nov 17, 2011

np. I have a flight soon and I think I can get this done then. @cloudhead, @indexzero I have a few things I want to get clear before I re-write this ;)

  • I want it to enforce order as well. So in your example if "end" is emitted before "request" the test must fails. Cool?
  • How should I denote this failure? Can someone expect this failure? (hopefully not)
  • Must the output make it clear that "end" must fire after "request"? Or is the current output ok?
A topic that emits many events on 'request' will emit the new request
A topic that emits many events on 'request' will set my class with a cached element
A topic that emits many events on 'end' will be clean
  • Where can a user place a topic?
"A topic that emits many events" : {
  topic: function () {
    return new CrazyEmitter();
  },
  events: {
    topic: "should this throw?",
    "request" : {
      topic: "should this throw?",
      "will emit the new request" : function () {},
      "will set my class with a cached element" : function () {},
      events: {      
        "end" : {
          "will be clean" : function(){}
        }
      }
    }
  }
}
  • In order to enforce order on the events I am going to need a test that fails. i.e. a case where order is violated and the test fails correctly. How should I denote that failure is a good thing?

@indexzero
Copy link

@seebees @cloudhead I think that this fundamentally changes the vows grammar to this

Suite   → Batch*
Batch   → Context*
Context → Topic? Vow* Context* Events?
Events → Event+
Event → Context

i.e. A context can have a single events property which may be set to a JS object literal with string keys. No topic or events keys should be allowed in this object literal.

Basically I don't think it should be vows concern right now to enforce event ordering through nesting of the JSON structure. We can add this down the road, but right now I'd like to see the basic implementation for this feature land. This would make the example from @cloudhead:

"A topic that emits many events" : {
  topic: function () {
    return new CrazyEmitter();
  },
  events: {
    "request" : {
      "will emit the new request" : function () {},
      "will set my class with a cached element" : function () {},
    },
    "end" : {
      "will be clean" : function(){}
    }
  }
}

@seebees
Copy link
Author

seebees commented Nov 18, 2011

I already talked to indexzero, but I like having it all here.

I like this. I'm going to drop order and only implement the events. This say the scope is small and focused. We can talk about order after this is done.

@cloudhead, I'm going to try and work this out tomorrow evening. If there are any additional comments you want to add, let me know.

@cloudhead
Copy link

Awesome. Eventually, yes, if "end" fires before "request", we should get an "unexpected 'end' event" message.

I was also thinking, maybe instead of calling it events, we call it simply on? So it reads easier..

@indexzero
Copy link

@cloudhead Tough call which reads easier to me. Maybe alias events to on?

## context.js

1. added .isEvent property (to distinguish between legacy 'success' and any sub-events)
2. added property .event that is either 'success' or the named sub-event
3. the api for sub-events is a context named either 'on' or 'events' ('events' is transformed into 'on')

## vows.js

1. updated addVow to look at the vow.binding.context.event instead of 'success'
2. if the sub-event is 'error' there is no need to listen for the topics error event again
3. Hooked EventEmitter.prototype.emit so I can capture events that happen before addVow is run.
4. Updated the vow calling params so if we have a known emitted event I don't change the calling structure (i.e. add a null error)

## suite.js

1. Throw if a sub-event or 'on' context has a topic
2. Sub-events can inherit from EventEmitter
3. changed 'success' to ctx.event
4. execute new context even if the event has already fired

Added basic tests to demonstrate "Vows with sub events"

Fixes vowsjs#109
@seebees
Copy link
Author

seebees commented Nov 20, 2011

@indexzero, @cloudhead done. I did both events and on. If you use events it will change the description to on. I did not see anything wrong with that and it made my life easy.

Tests added and should describe functionality.

Fixes #76 as well (test added)

@indexzero
Copy link

@seebees Well done! I'm cherry-picking this into master. It will be published under vows@0.6.0

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

Successfully merging this pull request may close these issues.

Failure to handle promise that is resolved before promise is returned
3 participants