cucumber 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.rspec +1 -1
  2. data/LICENSE +1 -1
  3. data/Rakefile +5 -51
  4. data/bin/cucumber +7 -1
  5. data/cucumber.gemspec +463 -679
  6. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
  7. data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
  8. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +4 -7
  9. data/examples/i18n/ru/features/division.feature +2 -2
  10. data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +3 -3
  11. data/examples/sinatra/features/support/env.rb +2 -5
  12. data/examples/v8/features/fibonacci.feature +1 -1
  13. data/examples/watir/features/step_definitions/search_steps.rb +1 -1
  14. data/features/background.feature +284 -95
  15. data/features/custom_formatter.feature +3 -73
  16. data/features/json_formatter.feature +160 -245
  17. data/features/step_definitions/cucumber_steps.rb +7 -153
  18. data/features/support/env.rb +18 -140
  19. data/fixtures/junit/features/pending.feature +3 -1
  20. data/fixtures/self_test/features/support/env.rb +8 -0
  21. data/fixtures/tickets/features.html +1 -1
  22. data/gem_tasks/examples.rake +1 -1
  23. data/lib/cucumber.rb +12 -0
  24. data/lib/cucumber/ast.rb +1 -1
  25. data/lib/cucumber/ast/background.rb +21 -5
  26. data/lib/cucumber/ast/examples.rb +12 -4
  27. data/lib/cucumber/ast/feature.rb +13 -5
  28. data/lib/cucumber/ast/feature_element.rb +9 -4
  29. data/lib/cucumber/ast/outline_table.rb +4 -4
  30. data/lib/cucumber/ast/scenario.rb +7 -5
  31. data/lib/cucumber/ast/scenario_outline.rb +23 -15
  32. data/lib/cucumber/ast/step.rb +5 -0
  33. data/lib/cucumber/ast/step_invocation.rb +21 -15
  34. data/lib/cucumber/ast/table.rb +14 -8
  35. data/lib/cucumber/ast/tree_walker.rb +10 -48
  36. data/lib/cucumber/cli/configuration.rb +33 -8
  37. data/lib/cucumber/cli/main.rb +20 -35
  38. data/lib/cucumber/cli/options.rb +8 -7
  39. data/lib/cucumber/cli/profile_loader.rb +2 -0
  40. data/lib/cucumber/core_ext/proc.rb +2 -1
  41. data/lib/cucumber/feature_file.rb +47 -15
  42. data/lib/cucumber/formatter/ansicolor.rb +3 -5
  43. data/lib/cucumber/formatter/console.rb +27 -23
  44. data/lib/cucumber/formatter/cucumber.css +34 -17
  45. data/lib/cucumber/formatter/cucumber.sass +173 -182
  46. data/lib/cucumber/formatter/html.rb +46 -11
  47. data/lib/cucumber/formatter/io.rb +2 -4
  48. data/lib/cucumber/formatter/json.rb +15 -152
  49. data/lib/cucumber/formatter/json_pretty.rb +5 -6
  50. data/lib/cucumber/formatter/junit.rb +28 -22
  51. data/lib/cucumber/formatter/pdf.rb +6 -6
  52. data/lib/cucumber/formatter/pretty.rb +5 -5
  53. data/lib/cucumber/formatter/rerun.rb +22 -11
  54. data/lib/cucumber/formatter/unicode.rb +41 -20
  55. data/lib/cucumber/js_support/js_dsl.js +4 -4
  56. data/lib/cucumber/js_support/js_language.rb +9 -5
  57. data/lib/cucumber/js_support/js_snippets.rb +2 -2
  58. data/lib/cucumber/language_support.rb +2 -2
  59. data/lib/cucumber/parser/gherkin_builder.rb +35 -30
  60. data/lib/cucumber/platform.rb +8 -8
  61. data/lib/cucumber/py_support/py_language.rb +2 -2
  62. data/lib/cucumber/rake/task.rb +80 -31
  63. data/lib/cucumber/rb_support/rb_dsl.rb +1 -0
  64. data/lib/cucumber/rb_support/rb_language.rb +10 -8
  65. data/lib/cucumber/rb_support/rb_step_definition.rb +8 -0
  66. data/lib/cucumber/rb_support/rb_transform.rb +17 -0
  67. data/lib/cucumber/rb_support/rb_world.rb +26 -18
  68. data/lib/cucumber/rspec/doubles.rb +3 -3
  69. data/lib/cucumber/step_match.rb +6 -2
  70. data/lib/cucumber/step_mother.rb +6 -427
  71. data/lib/cucumber/wire_support/configuration.rb +4 -1
  72. data/lib/cucumber/wire_support/wire_language.rb +3 -10
  73. data/spec/cucumber/ast/background_spec.rb +68 -6
  74. data/spec/cucumber/ast/feature_factory.rb +5 -4
  75. data/spec/cucumber/ast/feature_spec.rb +4 -4
  76. data/spec/cucumber/ast/outline_table_spec.rb +1 -1
  77. data/spec/cucumber/ast/scenario_outline_spec.rb +15 -11
  78. data/spec/cucumber/ast/scenario_spec.rb +4 -4
  79. data/spec/cucumber/ast/step_spec.rb +3 -3
  80. data/spec/cucumber/ast/table_spec.rb +38 -2
  81. data/spec/cucumber/ast/tree_walker_spec.rb +2 -2
  82. data/spec/cucumber/broadcaster_spec.rb +1 -1
  83. data/spec/cucumber/cli/configuration_spec.rb +32 -6
  84. data/spec/cucumber/cli/drb_client_spec.rb +2 -3
  85. data/spec/cucumber/cli/main_spec.rb +43 -43
  86. data/spec/cucumber/cli/options_spec.rb +28 -1
  87. data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
  88. data/spec/cucumber/core_ext/proc_spec.rb +1 -1
  89. data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
  90. data/spec/cucumber/formatter/duration_spec.rb +1 -1
  91. data/spec/cucumber/formatter/html_spec.rb +3 -5
  92. data/spec/cucumber/formatter/junit_spec.rb +16 -2
  93. data/spec/cucumber/formatter/progress_spec.rb +1 -1
  94. data/spec/cucumber/formatter/spec_helper.rb +11 -12
  95. data/spec/cucumber/rb_support/rb_language_spec.rb +241 -28
  96. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +33 -28
  97. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
  98. data/spec/cucumber/step_match_spec.rb +11 -9
  99. data/spec/cucumber/wire_support/configuration_spec.rb +1 -1
  100. data/spec/cucumber/wire_support/connection_spec.rb +1 -1
  101. data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
  102. data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
  103. data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
  104. data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
  105. data/spec/cucumber/world/pending_spec.rb +2 -2
  106. data/spec/spec_helper.rb +13 -20
  107. metadata +11 -222
  108. data/.gitignore +0 -20
  109. data/Caliper.yml +0 -4
  110. data/History.txt +0 -1552
  111. data/README.rdoc +0 -26
  112. data/VERSION.yml +0 -5
  113. data/examples/i18n/ro/features/suma.feature +0 -11
  114. data/features/announce.feature +0 -164
  115. data/features/around_hooks.feature +0 -232
  116. data/features/bug_371.feature +0 -32
  117. data/features/bug_464.feature +0 -16
  118. data/features/bug_475.feature +0 -42
  119. data/features/bug_585_tab_indentation.feature +0 -22
  120. data/features/bug_600.feature +0 -67
  121. data/features/call_steps_from_stepdefs.feature +0 -154
  122. data/features/cucumber_cli.feature +0 -591
  123. data/features/cucumber_cli_outlines.feature +0 -117
  124. data/features/default_snippets.feature +0 -42
  125. data/features/diffing.feature +0 -25
  126. data/features/drb_server_integration.feature +0 -174
  127. data/features/exception_in_after_block.feature +0 -127
  128. data/features/exception_in_after_step_block.feature +0 -104
  129. data/features/exception_in_before_block.feature +0 -98
  130. data/features/exclude_files.feature +0 -20
  131. data/features/expand.feature +0 -60
  132. data/features/html_formatter.feature +0 -8
  133. data/features/html_formatter/a.html +0 -582
  134. data/features/junit_formatter.feature +0 -88
  135. data/features/language_from_header.feature +0 -30
  136. data/features/language_help.feature +0 -78
  137. data/features/listener_debugger_formatter.feature +0 -42
  138. data/features/multiline_names.feature +0 -44
  139. data/features/negative_tagged_hooks.feature +0 -60
  140. data/features/post_configuration_hook.feature +0 -37
  141. data/features/profiles.feature +0 -126
  142. data/features/rake_task.feature +0 -152
  143. data/features/report_called_undefined_steps.feature +0 -34
  144. data/features/rerun_formatter.feature +0 -45
  145. data/features/simplest.feature +0 -11
  146. data/features/snippet.feature +0 -23
  147. data/features/snippets_when_using_star_keyword.feature +0 -36
  148. data/features/step_definitions/extra_steps.rb +0 -2
  149. data/features/step_definitions/simplest_steps.rb +0 -3
  150. data/features/step_definitions/wire_steps.rb +0 -32
  151. data/features/support/env.rb.simplest +0 -7
  152. data/features/support/fake_wire_server.rb +0 -77
  153. data/features/table_diffing.feature +0 -45
  154. data/features/table_mapping.feature +0 -34
  155. data/features/tag_logic.feature +0 -258
  156. data/features/transform.feature +0 -245
  157. data/features/unicode_table.feature +0 -35
  158. data/features/usage_and_stepdefs_formatter.feature +0 -169
  159. data/features/wire_protocol.feature +0 -332
  160. data/features/wire_protocol_table_diffing.feature +0 -119
  161. data/features/wire_protocol_tags.feature +0 -87
  162. data/features/wire_protocol_timeouts.feature +0 -63
  163. data/features/work_in_progress.feature +0 -156
  164. data/fixtures/json/features/pystring.feature +0 -8
  165. data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +0 -12
  166. data/fixtures/self_test/features/background/background_with_name.feature +0 -7
  167. data/fixtures/self_test/features/background/failing_background.feature +0 -12
  168. data/fixtures/self_test/features/background/failing_background_after_success.feature +0 -11
  169. data/fixtures/self_test/features/background/multiline_args_background.feature +0 -32
  170. data/fixtures/self_test/features/background/passing_background.feature +0 -10
  171. data/fixtures/self_test/features/background/pending_background.feature +0 -10
  172. data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +0 -16
  173. data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +0 -16
  174. data/gem_tasks/features.rake +0 -14
  175. data/gem_tasks/sdoc.rake +0 -12
  176. data/lib/cucumber/ast/py_string.rb +0 -80
  177. data/lib/cucumber/formatter/color_io.rb +0 -23
  178. data/lib/cucumber/formatter/tag_cloud.rb +0 -35
  179. data/spec/cucumber/ast/py_string_spec.rb +0 -40
  180. data/spec/cucumber/formatter/color_io_spec.rb +0 -29
  181. data/spec/cucumber/step_mother_spec.rb +0 -302
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
1
+ require 'spec_helper'
3
2
 
4
3
  module Cucumber
5
4
  module Cli
@@ -30,7 +29,7 @@ module Cucumber
30
29
 
31
30
  it "returns raises an error when it can't connect to the server" do
32
31
  DRbObject.stub!(:new_with_uri).and_raise(DRb::DRbConnError)
33
- running { DRbClient.run(@args, @error_stream, @out_stream) }.should raise_error(DRbClientError, "No DRb server is running.")
32
+ lambda { DRbClient.run(@args, @error_stream, @out_stream) }.should raise_error(DRbClientError, "No DRb server is running.")
34
33
  end
35
34
 
36
35
  it "returns the result from the DRb server call" do
@@ -1,5 +1,7 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'yaml'
3
+ require 'cucumber/parser/gherkin_builder'
4
+ require 'gherkin/formatter/model'
3
5
 
4
6
  module Cucumber
5
7
  module Cli
@@ -11,11 +13,41 @@ module Cucumber
11
13
  File.stub!(:exist?).and_return(false) # When Configuration checks for cucumber.yml
12
14
  Dir.stub!(:[]).and_return([]) # to prevent cucumber's features dir to being laoded
13
15
  end
16
+
17
+ let(:args) { [] }
18
+ let(:out_stream) { nil }
19
+ let(:err_stream) { nil }
20
+ subject { Main.new(args, out_stream, err_stream)}
21
+
22
+ describe "#execute!" do
23
+ context "passed an existing runtime" do
24
+ let(:existing_runtime) { double('runtime').as_null_object }
25
+
26
+ def do_execute
27
+ subject.execute!(existing_runtime)
28
+ end
29
+
30
+ it "configures that runtime" do
31
+ expected_configuration = double('Configuration', :drb? => false).as_null_object
32
+ Configuration.stub!(:new => expected_configuration)
33
+ existing_runtime.should_receive(:configure).with(expected_configuration)
34
+ do_execute
35
+ end
36
+
37
+ it "uses that runtime for running and reporting results" do
38
+ expected_results = double('results', :failure? => true)
39
+ existing_runtime.should_receive(:run!)
40
+ existing_runtime.stub!(:results).and_return(expected_results)
41
+ do_execute.should == expected_results.failure?
42
+ end
43
+ end
44
+ end
14
45
 
15
46
  describe "verbose mode" do
16
47
 
17
48
  before(:each) do
18
- @empty_feature = Cucumber::Ast::Feature.new(nil, Cucumber::Ast::Comment.new(''), Cucumber::Ast::Tags.new(2, []), "Feature", "Foo", [])
49
+ b = Cucumber::Parser::GherkinBuilder.new
50
+ @empty_feature = b.feature(Gherkin::Formatter::Model::Feature.new([], [], "Feature", "Foo", "", 99))
19
51
  end
20
52
 
21
53
  it "should show feature files parsed" do
@@ -24,7 +56,7 @@ module Cucumber
24
56
 
25
57
  Cucumber::FeatureFile.stub!(:new).and_return(mock("feature file", :parse => @empty_feature))
26
58
 
27
- @cli.execute!(Cucumber::StepMother.new)
59
+ @cli.execute!
28
60
 
29
61
  @out.string.should include('example.feature')
30
62
  end
@@ -32,9 +64,7 @@ module Cucumber
32
64
  end
33
65
 
34
66
  describe "--format with class" do
35
-
36
- describe "in module" do
37
-
67
+ describe "in module" do
38
68
  it "should resolve each module until it gets Formatter class" do
39
69
  cli = Main.new(%w{--format ZooModule::MonkeyFormatterClass}, nil)
40
70
  mock_module = mock('module')
@@ -46,42 +76,11 @@ module Cucumber
46
76
  Object.should_receive(:const_get).with('ZooModule').and_return(mock_module)
47
77
  mock_module.should_receive(:const_get).with('MonkeyFormatterClass').and_return(mock('formatter class', :new => f))
48
78
 
49
- cli.execute!(Cucumber::StepMother.new)
79
+ cli.execute!
50
80
  end
51
-
52
81
  end
53
82
  end
54
83
 
55
- describe "setup step sequence" do
56
-
57
- it "should load files and execute hooks in order" do
58
- Configuration.stub!(:new).and_return(configuration = mock('configuration').as_null_object)
59
- step_mother = mock('step mother').as_null_object
60
- configuration.stub!(:drb?).and_return false
61
- cli = Main.new(%w{--verbose example.feature}, @out)
62
- cli.stub!(:require)
63
-
64
- configuration.stub!(:support_to_load).and_return(['support'])
65
- configuration.stub!(:step_defs_to_load).and_return(['step defs'])
66
-
67
- # Support must be loaded first to ensure post configuration hook can
68
- # run before anything else.
69
- step_mother.should_receive(:load_code_files).with(['support']).ordered
70
- # The post configuration hook/s (if any) need to be run next to enable
71
- # extensions to do their thing before features are loaded
72
- step_mother.should_receive(:after_configuration).with(configuration).ordered
73
- # Feature files must be loaded before step definitions are required.
74
- # This is because i18n step methods are only aliased when
75
- # features are loaded. If we swap the order, the requires
76
- # will fail.
77
- step_mother.should_receive(:load_plain_text_features).ordered
78
- step_mother.should_receive(:load_code_files).with(['step defs']).ordered
79
-
80
- cli.execute!(step_mother)
81
- end
82
-
83
- end
84
-
85
84
  [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_klass|
86
85
 
87
86
  it "rescues #{exception_klass}, prints the message to the error stream and returns true" do
@@ -89,7 +88,7 @@ module Cucumber
89
88
  configuration.stub!(:parse!).and_raise(exception_klass.new("error message"))
90
89
 
91
90
  main = Main.new('', out = StringIO.new, error = StringIO.new)
92
- main.execute!(Cucumber::StepMother.new).should be_true
91
+ main.execute!.should be_true
93
92
  error.string.should == "error message\n"
94
93
  end
95
94
  end
@@ -103,30 +102,31 @@ module Cucumber
103
102
 
104
103
  @cli = Main.new(@args, @out, @err)
105
104
  @step_mother = mock('StepMother').as_null_object
105
+ StepMother.stub!(:new).and_return(@step_mother)
106
106
  end
107
107
 
108
108
  it "delegates the execution to the DRB client passing the args and streams" do
109
109
  @configuration.stub :drb_port => 1450
110
110
  DRbClient.should_receive(:run).with(@args, @err, @out, 1450).and_return(true)
111
- @cli.execute!(@step_mother)
111
+ @cli.execute!
112
112
  end
113
113
 
114
114
  it "returns the result from the DRbClient" do
115
115
  DRbClient.stub!(:run).and_return('foo')
116
- @cli.execute!(@step_mother).should == 'foo'
116
+ @cli.execute!.should == 'foo'
117
117
  end
118
118
 
119
119
  it "ceases execution if the DrbClient is able to perform the execution" do
120
120
  DRbClient.stub!(:run).and_return(true)
121
121
  @configuration.should_not_receive(:build_formatter_broadcaster)
122
- @cli.execute!(@step_mother)
122
+ @cli.execute!
123
123
  end
124
124
 
125
125
  context "when the DrbClient is unable to perfrom the execution" do
126
126
  before { DRbClient.stub!(:run).and_raise(DRbClientError.new('error message.')) }
127
127
 
128
128
  it "alerts the user that execution will be performed locally" do
129
- @cli.execute!(@step_mother)
129
+ @cli.execute!
130
130
  @err.string.should include("WARNING: error message. Running features locally:")
131
131
  end
132
132
 
@@ -1,5 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'yaml'
3
+ require 'cucumber/cli/options'
3
4
 
4
5
  module Cucumber
5
6
  module Cli
@@ -111,6 +112,13 @@ module Cli
111
112
  end
112
113
  end
113
114
 
115
+ context '-l LINES or --lines LINES' do
116
+ it "adds line numbers to args" do
117
+ options.parse!(%w{-l24 FILE})
118
+ options.instance_variable_get(:@args).should == ['FILE:24']
119
+ end
120
+ end
121
+
114
122
  context '-p PROFILE or --profile PROFILE' do
115
123
 
116
124
  it "notifies the user that an individual profile is being used" do
@@ -324,6 +332,25 @@ module Cli
324
332
 
325
333
  end
326
334
 
335
+ describe "dry-run" do
336
+ it "should have the default value for snippets" do
337
+ given_cucumber_yml_defined_as({'foo' => %w[--dry-run]})
338
+ options.parse!(%w{--dry-run})
339
+ options[:snippets].should == true
340
+ end
341
+
342
+ it "should set snippets to false when no-snippets provided after dry-run" do
343
+ given_cucumber_yml_defined_as({'foo' => %w[--dry-run --no-snippets]})
344
+ options.parse!(%w{--dry-run --no-snippets})
345
+ options[:snippets].should == false
346
+ end
347
+
348
+ it "should set snippets to false when no-snippets provided before dry-run" do
349
+ given_cucumber_yml_defined_as({'foo' => %w[--no-snippet --dry-run]})
350
+ options.parse!(%w{--no-snippets --dry-run})
351
+ options[:snippets].should == false
352
+ end
353
+ end
327
354
  end
328
355
 
329
356
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'yaml'
3
3
 
4
4
  module Cucumber
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'cucumber/core_ext/proc'
3
3
 
4
4
  describe Proc do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'cucumber/formatter/ansicolor'
3
3
 
4
4
  module Cucumber
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'cucumber/formatter/duration'
3
3
 
4
4
  module Cucumber
@@ -1,5 +1,5 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
+ require 'cucumber/formatter/spec_helper'
3
3
  require 'cucumber/formatter/html'
4
4
  require 'nokogiri'
5
5
  require 'cucumber/rb_support/rb_language'
@@ -11,9 +11,7 @@ module Cucumber
11
11
  extend SpecHelperDsl
12
12
  include SpecHelper
13
13
 
14
- matcher = defined?(Spec::Matchers) ? Spec::Matchers : RSpec::Matchers
15
-
16
- matcher.define :have_css_node do |css, regexp|
14
+ RSpec::Matchers.define :have_css_node do |css, regexp|
17
15
  match do |doc|
18
16
  nodes = doc.css(css)
19
17
  nodes.detect{ |node| node.text =~ regexp }
@@ -1,5 +1,5 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
+ require 'cucumber/formatter/spec_helper'
3
3
 
4
4
  require 'cucumber/formatter/junit'
5
5
  require 'nokogiri'
@@ -51,6 +51,19 @@ module Cucumber::Formatter
51
51
 
52
52
  it { @doc.to_s.should =~ /One passing scenario, one failing scenario/ }
53
53
  end
54
+
55
+ describe "with a scenario in a subdirectory" do
56
+ define_feature %{
57
+ Feature: One passing scenario, one failing scenario
58
+
59
+ Scenario: Passing
60
+ Given a passing scenario
61
+ }, File.join('features', 'some', 'path', 'spec.feature')
62
+
63
+ it 'writes the filename including the subdirectory' do
64
+ @formatter.written_files.keys.first.should == File.join('', 'TEST-some_path_spec.xml')
65
+ end
66
+ end
54
67
 
55
68
  describe "with a scenario outline table" do
56
69
  define_steps do
@@ -81,6 +94,7 @@ module Cucumber::Formatter
81
94
  it { @doc.to_s.should =~ /Big Mac/ }
82
95
  it { @doc.to_s.should_not =~ /Things/ }
83
96
  it { @doc.to_s.should_not =~ /Good|Evil/ }
97
+ it { @doc.to_s.should_not =~ /type="skipped"/}
84
98
  end
85
99
 
86
100
  describe "with a regular data table scenario" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
  require 'cucumber/formatter/progress'
3
3
 
4
4
  module Cucumber
@@ -2,10 +2,11 @@ module Cucumber
2
2
  module Formatter
3
3
 
4
4
  module SpecHelperDsl
5
- attr_reader :feature_content, :step_defs
5
+ attr_reader :feature_content, :step_defs, :feature_filename
6
6
 
7
- def define_feature(string)
7
+ def define_feature(string, feature_file = 'spec.feature')
8
8
  @feature_content = string
9
+ @feature_filename = feature_file
9
10
  end
10
11
 
11
12
  def define_steps(&block)
@@ -21,33 +22,31 @@ module Cucumber
21
22
  end
22
23
 
23
24
  def step_mother
24
- @step_mother ||= StepMother.new
25
+ @step_mother ||= Runtime.new
25
26
  end
26
27
 
27
28
  def load_features(content)
28
- feature_file = FeatureFile.new('spec.feature', content)
29
+ feature_file = FeatureFile.new(self.class.feature_filename, content)
29
30
  features = Ast::Features.new
30
- feature = feature_file.parse(options, {})
31
+ filters = []
32
+ feature = feature_file.parse(filters, {})
31
33
  features.add_feature(feature) if feature
32
34
  features
33
35
  end
34
36
 
35
37
  def run(features)
36
- tree_walker = Cucumber::Ast::TreeWalker.new(@step_mother, [@formatter], options, STDOUT)
38
+ configuration = Cucumber::Configuration.default
39
+ tree_walker = Cucumber::Ast::TreeWalker.new(step_mother, [@formatter], configuration)
37
40
  tree_walker.visit_features(features)
38
41
  end
39
42
 
40
43
  def define_steps
41
44
  return unless step_defs = self.class.step_defs
42
- rb = @step_mother.load_programming_language('rb')
43
- dsl = Object.new
45
+ rb = step_mother.load_programming_language('rb')
46
+ dsl = Object.new
44
47
  dsl.extend RbSupport::RbDsl
45
48
  dsl.instance_exec &step_defs
46
49
  end
47
-
48
- def options
49
- @options ||= mock(Cucumber::Cli::Options, :filters => [], :[] => nil)
50
- end
51
50
  end
52
51
  end
53
52
  end
@@ -1,69 +1,282 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
1
+ require 'spec_helper'
3
2
  require 'cucumber/step_mother'
4
3
  require 'cucumber/rb_support/rb_language'
5
4
 
6
5
  module Cucumber
7
6
  module RbSupport
8
7
  describe RbStepDefinition do
9
- before do
10
- @step_mother = Cucumber::StepMother.new
11
- @rb = @step_mother.load_programming_language('rb')
8
+ let(:user_interface) { double('user interface') }
9
+ let(:rb) { support_code.load_programming_language('rb')}
10
+ let(:support_code) do
11
+ Cucumber::Runtime::SupportCode.new(user_interface, {})
12
+ end
13
+ let(:dsl) do
14
+ rb
15
+ Object.new.extend(RbSupport::RbDsl)
12
16
  end
13
17
 
14
18
  def unindented(s)
15
19
  s.split("\n")[1..-2].join("\n").indent(-10)
16
20
  end
21
+
22
+ describe "snippets" do
17
23
 
18
- it "should recognise numbers in name and make according regexp" do
19
- @rb.snippet_text('Given', 'Cloud 9 yeah', nil).should == unindented(%{
24
+ it "should recognise numbers in name and make according regexp" do
25
+ rb.snippet_text('Given', 'Cloud 9 yeah', nil).should == unindented(%{
20
26
  Given /^Cloud (\\d+) yeah$/ do |arg1|
21
27
  pending # express the regexp above with the code you wish you had
22
28
  end
23
- })
24
- end
29
+ })
30
+ end
25
31
 
26
- it "should recognise a mix of ints, strings and why not a table too" do
27
- @rb.snippet_text('Given', 'I have 9 "awesome" cukes in 37 "boxes"', Cucumber::Ast::Table).should == unindented(%{
32
+ it "should recognise a mix of ints, strings and why not a table too" do
33
+ rb.snippet_text('Given', 'I have 9 "awesome" cukes in 37 "boxes"', Cucumber::Ast::Table).should == unindented(%{
28
34
  Given /^I have (\\d+) "([^"]*)" cukes in (\\d+) "([^"]*)"$/ do |arg1, arg2, arg3, arg4, table|
29
35
  # table is a Cucumber::Ast::Table
30
36
  pending # express the regexp above with the code you wish you had
31
37
  end
32
- })
33
- end
38
+ })
39
+ end
34
40
 
35
- it "should recognise quotes in name and make according regexp" do
36
- @rb.snippet_text('Given', 'A "first" arg', nil).should == unindented(%{
41
+ it "should recognise quotes in name and make according regexp" do
42
+ rb.snippet_text('Given', 'A "first" arg', nil).should == unindented(%{
37
43
  Given /^A "([^"]*)" arg$/ do |arg1|
38
44
  pending # express the regexp above with the code you wish you had
39
45
  end
40
- })
41
- end
46
+ })
47
+ end
42
48
 
43
- it "should recognise several quoted words in name and make according regexp and args" do
44
- @rb.snippet_text('Given', 'A "first" and "second" arg', nil).should == unindented(%{
49
+ it "should recognise several quoted words in name and make according regexp and args" do
50
+ rb.snippet_text('Given', 'A "first" and "second" arg', nil).should == unindented(%{
45
51
  Given /^A "([^"]*)" and "([^"]*)" arg$/ do |arg1, arg2|
46
52
  pending # express the regexp above with the code you wish you had
47
53
  end
48
- })
49
- end
54
+ })
55
+ end
50
56
 
51
- it "should not use quote group when there are no quotes" do
52
- @rb.snippet_text('Given', 'A first arg', nil).should == unindented(%{
57
+ it "should not use quote group when there are no quotes" do
58
+ rb.snippet_text('Given', 'A first arg', nil).should == unindented(%{
53
59
  Given /^A first arg$/ do
54
60
  pending # express the regexp above with the code you wish you had
55
61
  end
56
- })
57
- end
62
+ })
63
+ end
58
64
 
59
- it "should be helpful with tables" do
60
- @rb.snippet_text('Given', 'A "first" arg', Cucumber::Ast::Table).should == unindented(%{
65
+ it "should be helpful with tables" do
66
+ rb.snippet_text('Given', 'A "first" arg', Cucumber::Ast::Table).should == unindented(%{
61
67
  Given /^A "([^"]*)" arg$/ do |arg1, table|
62
68
  # table is a Cucumber::Ast::Table
63
69
  pending # express the regexp above with the code you wish you had
64
70
  end
65
- })
71
+ })
72
+ end
73
+
74
+ end
75
+
76
+ describe "#load_code_file" do
77
+ after do
78
+ FileUtils.rm_rf('tmp.rb')
79
+ end
80
+
81
+ def a_file_called(name)
82
+ File.open('tmp.rb', 'w') do |f|
83
+ f.puts yield
84
+ end
85
+ end
86
+
87
+ it "re-loads the file when called multiple times" do
88
+ a_file_called('tmp.rb') do
89
+ "$foo = 1"
90
+ end
91
+
92
+ rb.load_code_file('tmp.rb')
93
+ $foo.should == 1
94
+
95
+ a_file_called('tmp.rb') do
96
+ "$foo = 2"
97
+ end
98
+
99
+ rb.load_code_file('tmp.rb')
100
+ $foo.should == 2
101
+ end
102
+ end
103
+
104
+ describe "Handling the World" do
105
+
106
+ it "should raise an error if the world is nil" do
107
+ dsl.World {}
108
+
109
+ begin
110
+ rb.before(nil)
111
+ raise "Should fail"
112
+ rescue RbSupport::NilWorld => e
113
+ e.message.should == "World procs should never return nil"
114
+ e.backtrace.length.should == 1
115
+ e.backtrace[0].should =~ /spec\/cucumber\/rb_support\/rb_language_spec\.rb\:\d+\:in `World'/
116
+ end
117
+ end
118
+
119
+ module ModuleOne
120
+ end
121
+
122
+ module ModuleTwo
123
+ end
124
+
125
+ class ClassOne
126
+ end
127
+
128
+ it "should implicitly extend world with modules" do
129
+ dsl.World(ModuleOne, ModuleTwo)
130
+ rb.before(mock('scenario').as_null_object)
131
+ class << rb.current_world
132
+ included_modules.inspect.should =~ /ModuleOne/ # Workaround for RSpec/Ruby 1.9 issue with namespaces
133
+ included_modules.inspect.should =~ /ModuleTwo/
134
+ end
135
+ rb.current_world.class.should == Object
136
+ end
137
+
138
+ it "should raise error when we try to register more than one World proc" do
139
+ expected_error = %{You can only pass a proc to #World once, but it's happening
140
+ in 2 places:
141
+
142
+ spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
143
+ spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
144
+
145
+ Use Ruby modules instead to extend your worlds. See the Cucumber::RbSupport::RbDsl#World RDoc
146
+ or http://wiki.github.com/cucumber/cucumber/a-whole-new-world.
147
+
148
+ }
149
+ dsl.World { Hash.new }
150
+ lambda do
151
+ dsl.World { Array.new }
152
+ end.should raise_error(RbSupport::MultipleWorld, /#{expected_error}/)
153
+
154
+ end
155
+ end
156
+
157
+ describe "step argument transformations" do
158
+
159
+ describe "without capture groups" do
160
+ it "complains when registering with a with no transform block" do
161
+ lambda do
162
+ dsl.Transform('^abc$')
163
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
164
+ end
165
+
166
+ it "complains when registering with a zero-arg transform block" do
167
+ lambda do
168
+ dsl.Transform('^abc$') {42}
169
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
170
+ end
171
+
172
+ it "complains when registering with a splat-arg transform block" do
173
+ lambda do
174
+ dsl.Transform('^abc$') {|*splat| 42 }
175
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
176
+ end
177
+
178
+ it "complains when transforming with an arity mismatch" do
179
+ lambda do
180
+ dsl.Transform('^abc$') {|one, two| 42 }
181
+ rb.execute_transforms(['abc'])
182
+ end.should raise_error(Cucumber::ArityMismatchError)
183
+ end
184
+
185
+ it "allows registering a regexp pattern that yields the step_arg matched" do
186
+ dsl.Transform(/^ab*c$/) {|arg| 42}
187
+ rb.execute_transforms(['ab']).should == ['ab']
188
+ rb.execute_transforms(['ac']).should == [42]
189
+ rb.execute_transforms(['abc']).should == [42]
190
+ rb.execute_transforms(['abbc']).should == [42]
191
+ end
192
+ end
193
+
194
+ describe "with capture groups" do
195
+ it "complains when registering with a with no transform block" do
196
+ lambda do
197
+ dsl.Transform('^a(.)c$')
198
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
199
+ end
200
+
201
+ it "complains when registering with a zero-arg transform block" do
202
+ lambda do
203
+ dsl.Transform('^a(.)c$') { 42 }
204
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
205
+ end
206
+
207
+ it "complains when registering with a splat-arg transform block" do
208
+ lambda do
209
+ dsl.Transform('^a(.)c$') {|*splat| 42 }
210
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
211
+ end
212
+
213
+ it "complains when transforming with an arity mismatch" do
214
+ lambda do
215
+ dsl.Transform('^a(.)c$') {|one, two| 42 }
216
+ rb.execute_transforms(['abc'])
217
+ end.should raise_error(Cucumber::ArityMismatchError)
218
+ end
219
+
220
+ it "allows registering a regexp pattern that yields capture groups" do
221
+ dsl.Transform(/^shape: (.+), color: (.+)$/) do |shape, color|
222
+ {shape.to_sym => color.to_sym}
223
+ end
224
+ rb.execute_transforms(['shape: circle, color: blue']).should == [{:circle => :blue}]
225
+ rb.execute_transforms(['shape: square, color: red']).should == [{:square => :red}]
226
+ rb.execute_transforms(['not shape: square, not color: red']).should == ['not shape: square, not color: red']
227
+ end
228
+ end
229
+
230
+ it "allows registering a string pattern" do
231
+ dsl.Transform('^ab*c$') {|arg| 42}
232
+ rb.execute_transforms(['ab']).should == ['ab']
233
+ rb.execute_transforms(['ac']).should == [42]
234
+ rb.execute_transforms(['abc']).should == [42]
235
+ rb.execute_transforms(['abbc']).should == [42]
236
+ end
237
+
238
+ it "gives match priority to transforms defined last" do
239
+ dsl.Transform(/^transform_me$/) {|arg| :foo }
240
+ dsl.Transform(/^transform_me$/) {|arg| :bar }
241
+ dsl.Transform(/^transform_me$/) {|arg| :baz }
242
+ rb.execute_transforms(['transform_me']).should == [:baz]
243
+ end
244
+
245
+ it "allows registering a transform which returns nil" do
246
+ dsl.Transform('^ac$') {|arg| nil}
247
+ rb.execute_transforms(['ab']).should == ['ab']
248
+ rb.execute_transforms(['ac']).should == [nil]
249
+ end
250
+ end
251
+
252
+ describe "hooks" do
253
+
254
+ it "should find before hooks" do
255
+ fish = dsl.Before('@fish'){}
256
+ meat = dsl.Before('@meat'){}
257
+
258
+ scenario = mock('Scenario')
259
+ scenario.should_receive(:accept_hook?).with(fish).and_return(true)
260
+ scenario.should_receive(:accept_hook?).with(meat).and_return(false)
261
+
262
+ rb.hooks_for(:before, scenario).should == [fish]
263
+ end
264
+
265
+ it "should find around hooks" do
266
+ a = dsl.Around do |scenario, block|
267
+ end
268
+
269
+ b = dsl.Around('@tag') do |scenario, block|
270
+ end
271
+
272
+ scenario = mock('Scenario')
273
+ scenario.should_receive(:accept_hook?).with(a).and_return(true)
274
+ scenario.should_receive(:accept_hook?).with(b).and_return(false)
275
+
276
+ rb.hooks_for(:around, scenario).should == [a]
277
+ end
66
278
  end
279
+
67
280
  end
68
281
  end
69
282
  end