Skip to content
Browse files

Allow for unsafe regexp characters in stepdef string patterns (close #77

)
  • Loading branch information...
1 parent 729f927 commit 1fa696be94a46ab95350819709cfe204d4d94e40 @jbpros jbpros committed Oct 9, 2012
View
13 features/step_definitions/cucumber_js_mappings.rb
@@ -344,30 +344,33 @@ def write_main_step_definitions_file
end
def write_coffee_script_definition_file
+ @mapping_name = "a CoffeeScript mapping"
append_to_file COFFEE_SCRIPT_DEFINITIONS_FILE, <<-EOF
fs = require('fs')
stepDefinitions = () ->
- this.defineStep(/^a mapping$/, (callback) ->
- fs.writeFileSync('a_mapping.step', '')
+ this.defineStep(/^#{@mapping_name}$/, (callback) ->
+ fs.writeFileSync('#{step_file(@mapping_name)}', '')
callback()
)
module.exports = stepDefinitions
EOF
end
def write_string_based_pattern_mapping
+ @mapping_name = "a mapping + fancy characters"
append_support_code <<-EOF
-this.defineStep("a mapping", function(callback) {
- fs.writeFileSync("#{step_file("a mapping")}", "");
+this.defineStep("a mapping + fancy characters", function(callback) {
+ fs.writeFileSync("#{step_file(@mapping_name)}", "");
callback();
});
EOF
end
def write_string_based_pattern_mapping_with_parameters
+ @mapping_name = "a string-based mapping with parameters"
append_support_code <<-EOF
this.defineStep('a mapping with $word_param "$multi_word_param"', function(p1, p2, callback) {
- fs.writeFileSync("#{step_file("a mapping")}", p1 + "\\n" + p2);
+ fs.writeFileSync("#{step_file(@mapping_name)}", p1 + "\\n" + p2);
callback();
});
EOF
View
6 features/step_definitions/cucumber_steps.rb
@@ -41,7 +41,7 @@
write_feature <<-EOF
Feature:
Scenario:
- Given a mapping
+ Given #{@mapping_name}
EOF
run_feature
end
@@ -67,11 +67,11 @@
end
Then /^the mapping is run$/ do
- assert_passed "a mapping"
+ assert_passed @mapping_name
end
Then /^the mapping receives the arguments$/ do
- assert_passed_with_arguments "a mapping", @mapping_arguments
+ assert_passed_with_arguments @mapping_name, @mapping_arguments
end
Then /^the explicit World object function should have been called$/ do
View
12 features/step_definitions/cucumber_world.js
@@ -56,7 +56,7 @@ proto.runAScenario = function runAScenario(callback) {
};
proto.runAScenarioCallingMapping = function runAScenarioCallingMapping(callback) {
- this.addScenario("", "Given a mapping");
+ this.addScenario("", "Given " + this.mappingName);
this.runFeature({}, callback);
};
@@ -89,15 +89,17 @@ proto.isStepTouched = function isStepTouched(pattern) {
};
proto.addStringBasedPatternMapping = function addStringBasedPatternMapping() {
- this.stepDefinitions += "Given('a mapping', function(callback) {\
- world.logCycleEvent('a mapping');\
+ this.mappingName = "/a string-based mapping with fancy characters |\\ ^*-{(})+[a].?";
+ this.stepDefinitions += "Given('/a string-based mapping with fancy characters |\\\\ ^*-{(})+[a].?', function(callback) {\
+ world.logCycleEvent('/a string-based mapping with fancy characters |\\\\ ^*-{(})+[a].?');\
callback();\
});";
};
proto.addStringBasedPatternMappingWithParameters = function addStringBasedPatternMappingWithParameters() {
+ this.mappingName = "a string-based mapping";
this.stepDefinitions += "Given('a mapping with $word_param \"$multi_word_param\"', function(p1, p2, callback) {\
- world.logCycleEvent('a mapping');\
+ world.logCycleEvent('a string-based mapping');\
world.actualMappingArguments = [p1, p2];\
callback();\
});";
@@ -193,7 +195,7 @@ proto.assertSkippedStep = function assertSkippedStep(stepName) {
};
proto.assertPassedMapping = function assertPassedMapping() {
- this.assertCycleSequence("a mapping");
+ this.assertCycleSequence(this.mappingName);
};
proto.assertPassedMappingWithArguments = function assertPassedMappingWithArguments() {
View
3 lib/cucumber/support_code/step_definition.js
@@ -6,6 +6,7 @@ var StepDefinition = function (pattern, code) {
var regexp;
if (pattern.replace) {
var regexpString = pattern
+ .replace(StepDefinition.UNSAFE_STRING_CHARACTERS_REGEXP, StepDefinition.PREVIOUS_REGEXP_MATCH)
.replace(StepDefinition.QUOTED_DOLLAR_PARAMETER_REGEXP, StepDefinition.QUOTED_DOLLAR_PARAMETER_SUBSTITUTION)
.replace(StepDefinition.DOLLAR_PARAMETER_REGEXP, StepDefinition.DOLLAR_PARAMETER_SUBSTITUTION);
regexpString =
@@ -90,10 +91,12 @@ var StepDefinition = function (pattern, code) {
StepDefinition.DOLLAR_PARAMETER_REGEXP = /\$[a-zA-Z_-]+/;
StepDefinition.DOLLAR_PARAMETER_SUBSTITUTION = '(.*)';
+StepDefinition.PREVIOUS_REGEXP_MATCH = "\\$&";
StepDefinition.QUOTED_DOLLAR_PARAMETER_REGEXP = /"\$[a-zA-Z_-]+"/;
StepDefinition.QUOTED_DOLLAR_PARAMETER_SUBSTITUTION = '"([^"]*)"';
StepDefinition.STRING_PATTERN_REGEXP_PREFIX = '^';
StepDefinition.STRING_PATTERN_REGEXP_SUFFIX = '$';
+StepDefinition.UNSAFE_STRING_CHARACTERS_REGEXP = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\|]/g;
StepDefinition.UNKNOWN_STEP_FAILURE_MESSAGE = "Step failure";
module.exports = StepDefinition;
View
13 spec/cucumber/support_code/step_definition_spec.js
@@ -23,19 +23,26 @@ describe("Cucumber.SupportCode.StepDefinition", function () {
});
describe("when the pattern is a String", function () {
- var regexp, quotedDollarParameterSubstitutedPattern, regexpString;
+ var regexp, quotedDollarParameterSubstitutedPattern, safeString, regexpString;
beforeEach(function () {
regexp = createSpy("regexp");
regexpString = "regexp string";
+ safeString = createSpyWithStubs("safe string");
quotedDollarParameterSubstitutedPattern = createSpyWithStubs("quoted dollar param substituted pattern", {replace: regexpString});
- spyOnStub(pattern, 'replace').andReturn(quotedDollarParameterSubstitutedPattern);
+ spyOnStub(pattern, 'replace').andReturn(safeString);
+ spyOnStub(safeString, 'replace').andReturn(quotedDollarParameterSubstitutedPattern);
global.RegExp.andReturn(regexp);
});
+ it("escapes unsafe regexp characters from the string", function () {
+ stepDefinition.getPatternRegexp();
+ expect(pattern.replace).toHaveBeenCalledWith(Cucumber.SupportCode.StepDefinition.UNSAFE_STRING_CHARACTERS_REGEXP, Cucumber.SupportCode.StepDefinition.PREVIOUS_REGEXP_MATCH);
+ });
+
it("replaces quoted dollar-prefixed parameters with the regexp equivalent", function () {
stepDefinition.getPatternRegexp();
- expect(pattern.replace).toHaveBeenCalledWith(Cucumber.SupportCode.StepDefinition.QUOTED_DOLLAR_PARAMETER_REGEXP, Cucumber.SupportCode.StepDefinition.QUOTED_DOLLAR_PARAMETER_SUBSTITUTION);
+ expect(safeString.replace).toHaveBeenCalledWith(Cucumber.SupportCode.StepDefinition.QUOTED_DOLLAR_PARAMETER_REGEXP, Cucumber.SupportCode.StepDefinition.QUOTED_DOLLAR_PARAMETER_SUBSTITUTION);
});
it("replaces other dollar-prefixed parameter with the regexp equivalent", function () {

0 comments on commit 1fa696b

Please sign in to comment.
Something went wrong with that request. Please try again.