Skip to content

Commit

Permalink
adding registerListener and registerHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
devpaul committed Sep 9, 2013
1 parent 2ea1c42 commit 5a024ec
Show file tree
Hide file tree
Showing 7 changed files with 420 additions and 221 deletions.
1 change: 1 addition & 0 deletions lib/cucumber/listener.js
Expand Up @@ -38,6 +38,7 @@ var Listener = function () {
Listener.EVENT_HANDLER_NAME_PREFIX = 'handle';
Listener.EVENT_HANDLER_NAME_SUFFIX = 'Event';

Listener.Events = require('./listener/events');
Listener.Formatter = require('./listener/formatter');
Listener.PrettyFormatter = require('./listener/pretty_formatter');
Listener.ProgressFormatter = require('./listener/progress_formatter');
Expand Down
10 changes: 10 additions & 0 deletions lib/cucumber/listener/events.js
@@ -0,0 +1,10 @@
exports['BeforeFeatures'] = 'BeforeFeatures';
exports['BeforeFeature'] = 'BeforeFeature';
exports['Background'] = 'Background';
exports['BeforeScenario'] = 'BeforeScenario';
exports['BeforeStep'] = 'BeforeStep';
exports['StepResult'] = 'StepResult';
exports['AfterStep'] = 'AfterStep';
exports['AfterScenario'] = 'AfterScenario';
exports['AfterFeature'] = 'AfterFeature';
exports['AfterFeatures'] = 'AfterFeatures';
18 changes: 13 additions & 5 deletions lib/cucumber/runtime/ast_tree_walker.js
@@ -1,7 +1,6 @@
var AstTreeWalker = function(features, supportCodeLibrary, listeners) {
var Cucumber = require('../../cucumber');

var listeners;
var world;
var allFeaturesSucceded = true;
var skippingSteps = false;
Expand Down Expand Up @@ -107,10 +106,19 @@ var AstTreeWalker = function(features, supportCodeLibrary, listeners) {
},

broadcastEvent: function broadcastEvent(event, callback) {
listeners.forEach(
function(listener, callback) { listener.hear(event, callback); },
callback
);
broadcastToListners(listeners, onRuntimeListenersComplete);

function onRuntimeListenersComplete() {
var listeners = supportCodeLibrary.getListeners();
broadcastToListners(listeners, callback);
}

function broadcastToListners(listeners, callback) {
listeners.forEach(
function(listener, callback) { listener.hear(event, callback); },
callback
);
}
},

lookupStepDefinitionByName: function lookupStepDefinitionByName(stepName) {
Expand Down
54 changes: 46 additions & 8 deletions lib/cucumber/support_code/library.js
@@ -1,6 +1,7 @@
var Library = function(supportCodeDefinition) {
var Cucumber = require('../../cucumber');

var listeners = Cucumber.Type.Collection();
var stepDefinitions = Cucumber.Type.Collection();
var hooker = Cucumber.SupportCode.Library.Hooker();
var worldConstructor = Cucumber.SupportCode.WorldConstructor();
Expand Down Expand Up @@ -50,6 +51,20 @@ var Library = function(supportCodeDefinition) {
stepDefinitions.add(stepDefinition);
},

registerListener: function registerListener(listener) {
listeners.add(listener);
},

registerHandler: function registerHandler(eventName, handler) {
var listener = Cucumber.Listener();
listener.setHandlerForEvent(eventName, handler);
self.registerListener(listener);
},

getListeners: function getListeners() {
return listeners;
},

instantiateNewWorld: function instantiateNewWorld(callback) {
var world = new worldConstructor(function(explicitWorld) {
process.nextTick(function() { // release the constructor
Expand All @@ -60,19 +75,42 @@ var Library = function(supportCodeDefinition) {
};

var supportCodeHelper = {
Around : self.defineAroundHook,
Before : self.defineBeforeHook,
After : self.defineAfterHook,
Given : self.defineStep,
When : self.defineStep,
Then : self.defineStep,
defineStep : self.defineStep,
World : worldConstructor
Around : self.defineAroundHook,
Before : self.defineBeforeHook,
After : self.defineAfterHook,
Given : self.defineStep,
When : self.defineStep,
Then : self.defineStep,
defineStep : self.defineStep,
registerListener : self.registerListener,
registerHandler : self.registerHandler,
World : worldConstructor
};

appendEventHandlers(supportCodeHelper, self);
supportCodeDefinition.call(supportCodeHelper);
worldConstructor = supportCodeHelper.World;

return self;
};

function appendEventHandlers(supportCodeHelper, library) {
var Cucumber = require('../../cucumber');
var events = Cucumber.Listener.Events;
var eventName;

for (eventName in events) {
if (events.hasOwnProperty(eventName)) {
supportCodeHelper[eventName] = createEventListenerMethod(library, eventName);
}
}
}

function createEventListenerMethod(library, eventName) {
return function(handler) {
library.registerHandler(eventName, handler);
};
}

Library.Hooker = require('./library/hooker');
module.exports = Library;
20 changes: 20 additions & 0 deletions spec/cucumber/listener/events_spec.js
@@ -0,0 +1,20 @@
require('../../support/spec_helper');

describe('Cucumber.Listener.Events', function () {
var Cucumber = requireLib('cucumber');
var events = Cucumber.Listener.Events;

describe('construction', function () {
it("contains a list of event names", function () {
for(var name in events) {
if(events.hasOwnProperty(name)) {
expect(events[name]).toEqual(name);
}
}
});

it("is defined", function() {
expect(events).toBeDefined();
});
});
});
30 changes: 23 additions & 7 deletions spec/cucumber/runtime/ast_tree_walker_spec.js
Expand Up @@ -2,13 +2,16 @@ require('../../support/spec_helper');

describe("Cucumber.Runtime.AstTreeWalker", function() {
var Cucumber = requireLib('cucumber');
var treeWalker, features, supportCodeLibrary, listeners;
var treeWalker, features, supportCodeLibrary, listeners, supportListeners;

beforeEach(function() {
features = createSpyWithStubs("Features AST element", {acceptVisitor: null});
supportCodeLibrary = createSpy("Support code library");
listeners = [createSpy("First listener"), createSpy("Second listener")];
supportListeners = [createSpy("First support listener"), createSpy("Second support listener")];
spyOnStub(listeners, 'syncForEach').andCallFake(function(cb) { listeners.forEach(cb); });
spyOnStub(supportListeners, 'syncForEach').andCallFake(function(cb) { supportListeners.forEach(cb); });
spyOnStub(supportCodeLibrary, 'getListeners').andCallFake(function() { return supportListeners; });
treeWalker = Cucumber.Runtime.AstTreeWalker(features, supportCodeLibrary, listeners);
});

Expand Down Expand Up @@ -447,7 +450,7 @@ describe("Cucumber.Runtime.AstTreeWalker", function() {

beforeEach(function() {
wrapper = treeWalker.wrapAfterEventBroadcast(event, callback);
spyOn(treeWalker, 'broadcastAfterEvent');;
spyOn(treeWalker, 'broadcastAfterEvent');
});

it("broadcasts an after event with the received callback as callback", function() {
Expand Down Expand Up @@ -501,21 +504,34 @@ describe("Cucumber.Runtime.AstTreeWalker", function() {


describe("broadcastEvent()", function() {
var event, eventName, callback;
var event, callback;

beforeEach(function() {
event = createSpy("Event");
callback = createSpy("Callback");
spyOn(listeners, 'forEach');
spyOnListeners(listeners);
spyOnListeners(supportListeners);
});

function spyOnListeners(listeners) {
spyOn(listeners, 'forEach').andCallFake(function() {
var callback = listeners.forEach.mostRecentCall.args[1];
callback();
});
}

it("iterates over the listeners", function() {
treeWalker.broadcastEvent(event, callback);
expect(listeners.forEach).toHaveBeenCalled();
expect(listeners.forEach).toHaveBeenCalledWithAFunctionAsNthParameter(1);
expect(listeners.forEach).toHaveBeenCalledWithValueAsNthParameter(callback, 2);
assertListenerCollectionCalled(listeners.forEach);
assertListenerCollectionCalled(supportListeners.forEach);
expect(supportListeners.forEach).toHaveBeenCalledWithValueAsNthParameter(callback, 2);
});

function assertListenerCollectionCalled(forEachSpy) {
expect(forEachSpy).toHaveBeenCalled();
expect(forEachSpy).toHaveBeenCalledWithAFunctionAsNthParameter(1);
}

describe("for each listener", function() {
var userFunction, listener, forEachCallback;

Expand Down

0 comments on commit 5a024ec

Please sign in to comment.