cucumber
Version:
The official JavaScript implementation of Cucumber.
201 lines (172 loc) • 7.09 kB
JavaScript
var AstTreeWalker = function(features, supportCodeLibrary, listeners) {
var Cucumber = require('../../cucumber');
var listeners;
var world;
var allFeaturesSucceded = true;
var skippingSteps = false;
var self = {
walk: function walk(callback) {
self.visitFeatures(features, function() {
var featuresResult = self.didAllFeaturesSucceed();
callback(featuresResult);
});
},
visitFeatures: function visitFeatures(features, callback) {
var event = AstTreeWalker.Event(AstTreeWalker.FEATURES_EVENT_NAME);
self.broadcastEventAroundUserFunction(
event,
function(callback) { features.acceptVisitor(self, callback); },
callback
);
},
visitFeature: function visitFeature(feature, callback) {
var payload = { feature: feature };
var event = AstTreeWalker.Event(AstTreeWalker.FEATURE_EVENT_NAME, payload);
self.broadcastEventAroundUserFunction(
event,
function(callback) { feature.acceptVisitor(self, callback); },
callback
);
},
visitBackground: function visitBackground(background, callback) {
var payload = { background: background };
var event = AstTreeWalker.Event(AstTreeWalker.BACKGROUND_EVENT_NAME, payload);
self.broadcastEvent(event, callback);
},
visitScenario: function visitScenario(scenario, callback) {
supportCodeLibrary.instantiateNewWorld(function(world) {
self.setWorld(world);
self.witnessNewScenario();
var payload = { scenario: scenario };
var event = AstTreeWalker.Event(AstTreeWalker.SCENARIO_EVENT_NAME, payload);
var hookedUpScenarioVisit = supportCodeLibrary.hookUpFunction(
function(callback) { scenario.acceptVisitor(self, callback); },
scenario,
world
);
self.broadcastEventAroundUserFunction(
event,
hookedUpScenarioVisit,
callback
);
});
},
visitStep: function visitStep(step, callback) {
var payload = { step: step };
var event = AstTreeWalker.Event(AstTreeWalker.STEP_EVENT_NAME, payload);
self.broadcastEventAroundUserFunction(
event,
function(callback) {
self.processStep(step, callback);
},
callback
);
},
visitStepResult: function visitStepResult(stepResult, callback) {
if (stepResult.isFailed())
self.witnessFailedStep();
else if (stepResult.isPending())
self.witnessPendingStep();
var payload = { stepResult: stepResult };
var event = AstTreeWalker.Event(AstTreeWalker.STEP_RESULT_EVENT_NAME, payload);
self.broadcastEvent(event, callback);
},
broadcastEventAroundUserFunction: function broadcastEventAroundUserFunction(event, userFunction, callback) {
var userFunctionWrapper = self.wrapUserFunctionAndAfterEventBroadcast(userFunction, event, callback);
self.broadcastBeforeEvent(event, userFunctionWrapper);
},
wrapUserFunctionAndAfterEventBroadcast: function wrapUserFunctionAndAfterEventBroadcast(userFunction, event, callback) {
var callAfterEventBroadcast = self.wrapAfterEventBroadcast(event, callback);
return function callUserFunctionAndBroadcastAfterEvent() {
userFunction(callAfterEventBroadcast);
};
},
wrapAfterEventBroadcast: function wrapAfterEventBroadcast(event, callback) {
return function() { self.broadcastAfterEvent(event, callback); };
},
broadcastBeforeEvent: function broadcastBeforeEvent(event, callback) {
var preEvent = event.replicateAsPreEvent();
self.broadcastEvent(preEvent, callback);
},
broadcastAfterEvent: function broadcastAfterEvent(event, callback) {
var postEvent = event.replicateAsPostEvent();
self.broadcastEvent(postEvent, callback);
},
broadcastEvent: function broadcastEvent(event, callback) {
listeners.forEach(
function(listener, callback) { listener.hear(event, callback); },
callback
);
},
lookupStepDefinitionByName: function lookupStepDefinitionByName(stepName) {
return supportCodeLibrary.lookupStepDefinitionByName(stepName);
},
setWorld: function setWorld(newWorld) {
world = newWorld;
},
getWorld: function getWorld() {
return world;
},
isStepUndefined: function isStepUndefined(step) {
var stepName = step.getName();
return !supportCodeLibrary.isStepDefinitionNameDefined(stepName);
},
didAllFeaturesSucceed: function didAllFeaturesSucceed() {
return allFeaturesSucceded;
},
witnessFailedStep: function witnessFailedStep() {
allFeaturesSucceded = false;
skippingSteps = true;
},
witnessPendingStep: function witnessPendingStep() {
skippingSteps = true;
},
witnessUndefinedStep: function witnessUndefinedStep() {
skippingSteps = true;
},
witnessNewScenario: function witnessNewScenario() {
skippingSteps = false;
},
isSkippingSteps: function isSkippingSteps() {
return skippingSteps;
},
processStep: function processStep(step, callback) {
if (self.isStepUndefined(step)) {
self.witnessUndefinedStep();
self.skipUndefinedStep(step, callback);
} else if (self.isSkippingSteps()) {
self.skipStep(step, callback);
} else {
self.executeStep(step, callback);
}
},
executeStep: function executeStep(step, callback) {
step.acceptVisitor(self, callback);
},
skipStep: function skipStep(step, callback) {
var skippedStepResult = Cucumber.Runtime.SkippedStepResult({step: step});
var payload = { stepResult: skippedStepResult };
var event = AstTreeWalker.Event(AstTreeWalker.STEP_RESULT_EVENT_NAME, payload);
self.broadcastEvent(event, callback);
},
skipUndefinedStep: function skipUndefinedStep(step, callback) {
var undefinedStepResult = Cucumber.Runtime.UndefinedStepResult({step: step});
var payload = { stepResult: undefinedStepResult };
var event = AstTreeWalker.Event(AstTreeWalker.STEP_RESULT_EVENT_NAME, payload);
self.broadcastEvent(event, callback);
}
};
return self;
};
AstTreeWalker.FEATURES_EVENT_NAME = 'Features';
AstTreeWalker.FEATURE_EVENT_NAME = 'Feature';
AstTreeWalker.BACKGROUND_EVENT_NAME = 'Background';
AstTreeWalker.SCENARIO_EVENT_NAME = 'Scenario';
AstTreeWalker.STEP_EVENT_NAME = 'Step';
AstTreeWalker.STEP_RESULT_EVENT_NAME = 'StepResult';
AstTreeWalker.BEFORE_EVENT_NAME_PREFIX = 'Before';
AstTreeWalker.AFTER_EVENT_NAME_PREFIX = 'After';
AstTreeWalker.NON_EVENT_LEADING_PARAMETERS_COUNT = 0;
AstTreeWalker.NON_EVENT_TRAILING_PARAMETERS_COUNT = 2;
AstTreeWalker.Event = require('./ast_tree_walker/event');
module.exports = AstTreeWalker;