cucumber 0.8.5 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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