diff --git a/features/doc_strings.feature b/features/doc_strings.feature new file mode 100644 index 0000000..b43acac --- /dev/null +++ b/features/doc_strings.feature @@ -0,0 +1,27 @@ +Feature: DocStrings + + Scenario: Match a step with a DocString + Given a file named "features/test.feature" with: + """ + Feature: + Scenario: + Given passing with a DocString: + \"\"\" + DocString content + \"\"\" + """ + And a file named "features/support/env.rb" with: + """ + require 'cucumber/tcl' + """ + And a file named "features/step_defintions/steps.tcl" with: + """ + Given {^passing with a DocString:$} {content} { + puts "Hello $content" + } + """ + When I run `cucumber` + Then it should pass with: + """ + Hello DocString content + """ diff --git a/lib/cucumber/tcl/activate_steps.rb b/lib/cucumber/tcl/activate_steps.rb index 78394e0..6e3d32c 100644 --- a/lib/cucumber/tcl/activate_steps.rb +++ b/lib/cucumber/tcl/activate_steps.rb @@ -14,8 +14,8 @@ def test_case(test_case) private def attempt_to_activate(test_step) - return test_step unless step_definitions.match?(test_step.name) - test_step.with_action &step_definitions.action_for(test_step.name) + return test_step unless step_definitions.match?(test_step) + test_step.with_action &step_definitions.action_for(test_step) end end diff --git a/lib/cucumber/tcl/framework.tcl b/lib/cucumber/tcl/framework.tcl index 7202c88..1e3dbd6 100644 --- a/lib/cucumber/tcl/framework.tcl +++ b/lib/cucumber/tcl/framework.tcl @@ -51,20 +51,20 @@ proc _add_step args { # # Procs needed by cucumber for checking and executing steps proc step_definition_exists { step_name } { - set res [_search_steps $step_name 1] + set res [_search_steps $step_name 0] return $res } -proc execute_step_definition { step_name } { +proc execute_step_definition { step_name {multiline_args {}} } { # TODO: handle parameters in the regexp - set res [_search_steps $step_name 1] + set res [_search_steps $step_name 1 $multiline_args] return $res } -proc _search_steps {step_name {execute 0}} { +proc _search_steps {step_name {execute 0} {multiline_args {}}} { global STEPS foreach step $STEPS { @@ -72,8 +72,15 @@ proc _search_steps {step_name {execute 0}} { set existing_step_params [lindex $step 1] set existing_step_body [lindex $step 2] - if {[regexp $existing_step_name $step_name matchresult {*}[join $existing_step_params]]} { + + # Now we've found a match, handle multiline args. The name of the var + # should be the last value of the $existing_step_params. + if {$multiline_args ne {}} { + set multiline_var_name [lindex $existing_step_params end] + set $multiline_var_name $multiline_args + } + if {$execute == 1} { eval $existing_step_body } diff --git a/lib/cucumber/tcl/step_definitions.rb b/lib/cucumber/tcl/step_definitions.rb index c986b4d..90f9188 100644 --- a/lib/cucumber/tcl/step_definitions.rb +++ b/lib/cucumber/tcl/step_definitions.rb @@ -9,12 +9,30 @@ def initialize(path) @tcl = ::Tcl::Interp.load_from_file(path) end - def match?(step_name) + def match?(test_step) + step_name = test_step.name @tcl.proc('step_definition_exists').call(step_name) == "1" end - def action_for(step_name) - proc { @tcl.proc('execute_step_definition').call(step_name) } + def action_for(test_step) + step_name = test_step.name + arguments = ArgumentList.new(step_name) + test_step.source.last.multiline_arg.describe_to(arguments) + proc { @tcl.proc('execute_step_definition').call(*arguments) } + end + + class ArgumentList + def initialize(*args) + @arguments = args + end + + def doc_string(arg) + @arguments << arg.content + end + + def to_a + @arguments + end end end diff --git a/lib/cucumber/tcl/test/test_framework.tcl b/lib/cucumber/tcl/test/test_framework.tcl index 5e8f2b2..a50de8b 100644 --- a/lib/cucumber/tcl/test/test_framework.tcl +++ b/lib/cucumber/tcl/test/test_framework.tcl @@ -227,6 +227,36 @@ test _search_steps-7 {_search_steps returns 1 and executes body of step if there -output {Second Step*} } +# Testing multiline args +test _search_steps-8 {_search_steps returns 1 and executes body of step if there is a matching step, execute is set to 1 and there is a multiline_arg passed in} { + -setup { + set ::STEPS [list \ + [list {^First Step$} {} {puts "First Step"}] \ + [list {^Second Step:$} {content} {puts "$content"}] \ + ] + } + -body { + _search_steps {Second Step:} {1} {Multiline Content} + } + -result 1 + -match glob + -output {Multiline Content*} +} + +test _search_steps-9 {_search_steps returns 1 and executes body of step if there is a matching step, execute is set to 1 and there is a multiline_arg passed in and there is a parameter match in the regexp} { + -setup { + set ::STEPS [list \ + [list {^First Step$} {} {puts "First Step"}] \ + [list {^Second (\w+):$} {match1 content} {puts "content=$content, match=$match1"}] \ + ] + } + -body { + _search_steps {Second Step:} {1} {Multiline Content} + } + -result 1 + -match glob + -output {content=Multiline Content, match=Step*} +} # # Cleanup diff --git a/spec/cucumber/tcl/step_definitions_spec.rb b/spec/cucumber/tcl/step_definitions_spec.rb index a2f6802..5b25d8e 100644 --- a/spec/cucumber/tcl/step_definitions_spec.rb +++ b/spec/cucumber/tcl/step_definitions_spec.rb @@ -4,7 +4,7 @@ module Cucumber::Tcl describe StepDefinitions do it "can query for a step definition" do step_definitions = StepDefinitions.new(File.dirname(__FILE__) + '/steps.tcl') - expect(step_definitions.match?('passing')).to be_truthy + expect(step_definitions.match?(double(name: 'passing'))).to be_truthy end end end