Skip to content

Commit

Permalink
Option to show unused step definitions
Browse files Browse the repository at this point in the history
Closes cucumber#4
Requires grunt-cucumber-sigma 0.3.3+
  • Loading branch information
i-e-b committed Mar 26, 2015
1 parent b90e3a5 commit 302e89f
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 7 deletions.
2 changes: 2 additions & 0 deletions lib/cucumber/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ function Cli(argv) {
--brkOnSupportCodeLoaded Trigger a debugger break once support code\n\
is loaded.\n\
\n\
--unusedSteps Show unused step definitions\n\
\n\
-i, --no-snippets Don't print snippets for pending steps.\n\
\n\
-S, --strict Fail if there are any undefined or pending steps.\n\
Expand Down
7 changes: 7 additions & 0 deletions lib/cucumber/cli/argument_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ function ArgumentParser(argv) {
definitions[ArgumentParser.FIND_STEP_DEFINITION] = [String, String];
definitions[ArgumentParser.FORMAT_OPTION_NAME] = String;
definitions[ArgumentParser.USE_SHORT_STACK_OPTION_NAME] = Boolean;
definitions[ArgumentParser.SHOW_UNUSED_STEPS] = Boolean;
definitions[ArgumentParser.HELP_FLAG_NAME] = Boolean;
definitions[ArgumentParser.VERSION_FLAG_NAME] = Boolean;
definitions[ArgumentParser.COFFEE_SCRIPT_SNIPPETS_FLAG_NAME] = Boolean;
Expand All @@ -102,6 +103,10 @@ function ArgumentParser(argv) {
return self.getOptionOrDefault(ArgumentParser.FIND_STEP_DEFINITION);
},

shouldShowUnusedSteps: function findStepDef(){
return self.getOptionOrDefault(ArgumentParser.SHOW_UNUSED_STEPS, ArgumentParser.DEFAULT_UNUSED_STEPS);
},

isStrictRequested: function isStrictRequested() {
return self.getOptionOrDefault(ArgumentParser.STRICT_FLAG_NAME, ArgumentParser.DEFAULT_STRICT_FLAG_VALUE);
},
Expand Down Expand Up @@ -154,6 +159,8 @@ ArgumentParser.DEFAULT_FORMAT_VALUE = 'progress';
ArgumentParser.TAGS_OPTION_NAME = 'tags';
ArgumentParser.TAGS_OPTION_SHORT_NAME = 't';
ArgumentParser.USE_SHORT_STACK_OPTION_NAME = 'shortStackTraces';
ArgumentParser.SHOW_UNUSED_STEPS = 'unusedSteps';
ArgumentParser.DEFAULT_UNUSED_STEPS = false;
ArgumentParser.BRK_ON_SUPPORT_CODE_LOADED = 'brkOnSupportCodeLoaded';
ArgumentParser.FIND_STEP_DEFINITION = 'findStepDef';
ArgumentParser.DEFAULT_BRK_ON_SUPPORT_CODE_LOADED = false;
Expand Down
10 changes: 6 additions & 4 deletions lib/cucumber/cli/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,16 @@ function Configuration(argv) {
return argumentParser.isVersionRequested();
},

shouldShowUnusedSteps: function shouldShowUnusedSteps() {
return argumentParser.shouldShowUnusedSteps();
},

shouldSnippetsBeInCoffeeScript: function shouldSnippetsBeInCoffeeScript() {
var coffeeDisplay = argumentParser.shouldSnippetsBeInCoffeeScript();
return coffeeDisplay;
return argumentParser.shouldSnippetsBeInCoffeeScript();
},

shouldSnippetsBeShown: function shouldSnippetsBeShown() {
var snippetsDisplay = argumentParser.shouldSnippetsBeShown();
return snippetsDisplay;
return argumentParser.shouldSnippetsBeShown();
}

};
Expand Down
25 changes: 25 additions & 0 deletions lib/cucumber/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,34 @@ function Runtime(configuration) {

stackSettings.useShortTraces = self.getStackSettings();
var astTreeWalker = Runtime.AstTreeWalker(features, supportCodeLibrary, listeners, isStrictRequested);

// this odd way of injecting the unused steps works around problems with the mock library.
if (configuration.shouldShowUnusedSteps()) {
var originalCallback = callback;
callback = function () {
self.showUnusedSteps(supportCodeLibrary);
return originalCallback();
};
}

astTreeWalker.walk(callback);
},

showUnusedSteps: function showUnusedSteps(supportCodeLibrary) {
var lastFile = '';
var unused = supportCodeLibrary.unusedSteps();
if (unused.length > 0) console.log('Unused steps:');
for (var i = 0; i < unused.length; i++) {
var s = unused[i];
if (lastFile !== s.getUri()) {
lastFile = s.getUri();
console.log();
console.log(s.getUri());
}
console.log(' '+s.getPatternRegexp());
}
},

findStepDefinition: function findStepDefinition(features, supportCodeLibrary) {
var findTarget = configuration.findStepDef();

Expand Down
9 changes: 8 additions & 1 deletion lib/cucumber/support_code/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ function Library(supportCodeDefinition) {
return matchingHooks;
},

// TODO: issue #3: find definition given a step definition... this is the hook. Trace backwards
lookupStepDefinitionByName: function lookupStepDefinitionByName(name, tagNames) {
var matches = [];
stepDefinitions.syncForEach(function(stepDefinition) {
Expand All @@ -62,6 +61,14 @@ function Library(supportCodeDefinition) {
return matches.pop();
},

unusedSteps: function unusedSteps() {
var matches = [];
stepDefinitions.syncForEach(function(step){
if (step.invocationCount < 1) matches.push(step);
});
return matches;
},

isStepDefinitionNameDefined: function isStepDefinitionNameDefined(name, tagNames) {
var stepDefinition = self.lookupStepDefinitionByName(name, tagNames);
return (stepDefinition !== undefined);
Expand Down
4 changes: 4 additions & 0 deletions lib/cucumber/support_code/step_definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ function StepDefinition (pattern, code, uri, codeType) {
return found;
},

invocationCount: 0,

invoke: function invoke(step, world, scenario, stepDomain, callback) {
self.invocationCount++;

function time() {
if (typeof process !== 'undefined' && process.hrtime) {
return process.hrtime();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"gherkin",
"tests"
],
"version": "0.4.10",
"version": "0.4.11",
"homepage": "http://github.com/i-e-b/cucumber-js",
"author": "Julien Biezemans <jb@jbpros.com> (http://jbpros.net)",
"contributors": [
Expand Down
2 changes: 1 addition & 1 deletion spec/cucumber/runtime_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("Cucumber.Runtime", function () {
beforeEach(function () {
isStrictRequested = false;
listeners = createSpyWithStubs("listener collection", {add: null});
configuration = createSpyWithStubs("configuration", { isStrictRequested: isStrictRequested, findStepDef:false });
configuration = createSpyWithStubs("configuration", { isStrictRequested: isStrictRequested, findStepDef:false, shouldShowUnusedSteps:false});
spyOn(Cucumber.Type, 'Collection').andReturn(listeners);
runtime = Cucumber.Runtime(configuration);
});
Expand Down

0 comments on commit 302e89f

Please sign in to comment.