cucumber 0.9.2 → 0.9.3

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.
@@ -8,9 +8,7 @@ module Cucumber
8
8
  end
9
9
 
10
10
  def to_json
11
- @support_code.step_definitions.map do |step_definition|
12
- step_definition.regexp_source
13
- end.to_json
11
+ @support_code.step_definitions.map{|stepdef| stepdef.to_hash}.to_json
14
12
  end
15
13
  end
16
14
  end
@@ -11,6 +11,35 @@ module Cucumber
11
11
  File.stub!(:exist?).and_return(false) # When Configuration checks for cucumber.yml
12
12
  Dir.stub!(:[]).and_return([]) # to prevent cucumber's features dir to being laoded
13
13
  end
14
+
15
+ let(:args) { [] }
16
+ let(:out_stream) { nil }
17
+ let(:err_stream) { nil }
18
+ subject { Main.new(args, out_stream, err_stream)}
19
+
20
+ describe "#execute!" do
21
+ context "passed an existing runtime" do
22
+ let(:existing_runtime) { double('runtime').as_null_object }
23
+
24
+ def do_execute
25
+ subject.execute!(existing_runtime)
26
+ end
27
+
28
+ it "configures that runtime" do
29
+ expected_configuration = double('Configuration', :drb? => false).as_null_object
30
+ Configuration.stub!(:new => expected_configuration)
31
+ existing_runtime.should_receive(:configure).with(expected_configuration)
32
+ do_execute
33
+ end
34
+
35
+ it "uses that runtime for running and reporting results" do
36
+ expected_results = double('results', :failure? => true)
37
+ existing_runtime.should_receive(:run!)
38
+ existing_runtime.stub!(:results).and_return(expected_results)
39
+ do_execute.should == expected_results.failure?
40
+ end
41
+ end
42
+ end
14
43
 
15
44
  describe "verbose mode" do
16
45
 
@@ -32,9 +61,7 @@ module Cucumber
32
61
  end
33
62
 
34
63
  describe "--format with class" do
35
-
36
- describe "in module" do
37
-
64
+ describe "in module" do
38
65
  it "should resolve each module until it gets Formatter class" do
39
66
  cli = Main.new(%w{--format ZooModule::MonkeyFormatterClass}, nil)
40
67
  mock_module = mock('module')
@@ -48,7 +75,6 @@ module Cucumber
48
75
 
49
76
  cli.execute!
50
77
  end
51
-
52
78
  end
53
79
  end
54
80
 
@@ -35,14 +35,14 @@ module Cucumber
35
35
 
36
36
  def run(features)
37
37
  configuration = Cucumber::Configuration.default
38
- tree_walker = Cucumber::Ast::TreeWalker.new(@step_mother, [@formatter], configuration)
38
+ tree_walker = Cucumber::Ast::TreeWalker.new(step_mother, [@formatter], configuration)
39
39
  tree_walker.visit_features(features)
40
40
  end
41
41
 
42
42
  def define_steps
43
43
  return unless step_defs = self.class.step_defs
44
- rb = @step_mother.load_programming_language('rb')
45
- dsl = Object.new
44
+ rb = step_mother.load_programming_language('rb')
45
+ dsl = Object.new
46
46
  dsl.extend RbSupport::RbDsl
47
47
  dsl.instance_exec &step_defs
48
48
  end
@@ -6,65 +6,74 @@ require 'cucumber/rb_support/rb_language'
6
6
  module Cucumber
7
7
  module RbSupport
8
8
  describe RbStepDefinition do
9
- let(:runtime) { Cucumber::Runtime.new }
10
- before do
11
- @rb = runtime.load_programming_language('rb')
9
+ let(:user_interface) { double('user interface') }
10
+ let(:rb) { support_code.load_programming_language('rb')}
11
+ let(:support_code) do
12
+ Cucumber::Runtime::SupportCode.new(user_interface, {})
13
+ end
14
+ let(:dsl) do
15
+ rb
16
+ Object.new.extend(RbSupport::RbDsl)
12
17
  end
13
18
 
14
19
  def unindented(s)
15
20
  s.split("\n")[1..-2].join("\n").indent(-10)
16
21
  end
22
+
23
+ describe "snippets" do
17
24
 
18
- it "should recognise numbers in name and make according regexp" do
19
- @rb.snippet_text('Given', 'Cloud 9 yeah', nil).should == unindented(%{
25
+ it "should recognise numbers in name and make according regexp" do
26
+ rb.snippet_text('Given', 'Cloud 9 yeah', nil).should == unindented(%{
20
27
  Given /^Cloud (\\d+) yeah$/ do |arg1|
21
28
  pending # express the regexp above with the code you wish you had
22
29
  end
23
- })
24
- end
30
+ })
31
+ end
25
32
 
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(%{
33
+ it "should recognise a mix of ints, strings and why not a table too" do
34
+ rb.snippet_text('Given', 'I have 9 "awesome" cukes in 37 "boxes"', Cucumber::Ast::Table).should == unindented(%{
28
35
  Given /^I have (\\d+) "([^"]*)" cukes in (\\d+) "([^"]*)"$/ do |arg1, arg2, arg3, arg4, table|
29
36
  # table is a Cucumber::Ast::Table
30
37
  pending # express the regexp above with the code you wish you had
31
38
  end
32
- })
33
- end
39
+ })
40
+ end
34
41
 
35
- it "should recognise quotes in name and make according regexp" do
36
- @rb.snippet_text('Given', 'A "first" arg', nil).should == unindented(%{
42
+ it "should recognise quotes in name and make according regexp" do
43
+ rb.snippet_text('Given', 'A "first" arg', nil).should == unindented(%{
37
44
  Given /^A "([^"]*)" arg$/ do |arg1|
38
45
  pending # express the regexp above with the code you wish you had
39
46
  end
40
- })
41
- end
47
+ })
48
+ end
42
49
 
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(%{
50
+ it "should recognise several quoted words in name and make according regexp and args" do
51
+ rb.snippet_text('Given', 'A "first" and "second" arg', nil).should == unindented(%{
45
52
  Given /^A "([^"]*)" and "([^"]*)" arg$/ do |arg1, arg2|
46
53
  pending # express the regexp above with the code you wish you had
47
54
  end
48
- })
49
- end
55
+ })
56
+ end
50
57
 
51
- it "should not use quote group when there are no quotes" do
52
- @rb.snippet_text('Given', 'A first arg', nil).should == unindented(%{
58
+ it "should not use quote group when there are no quotes" do
59
+ rb.snippet_text('Given', 'A first arg', nil).should == unindented(%{
53
60
  Given /^A first arg$/ do
54
61
  pending # express the regexp above with the code you wish you had
55
62
  end
56
- })
57
- end
63
+ })
64
+ end
58
65
 
59
- it "should be helpful with tables" do
60
- @rb.snippet_text('Given', 'A "first" arg', Cucumber::Ast::Table).should == unindented(%{
66
+ it "should be helpful with tables" do
67
+ rb.snippet_text('Given', 'A "first" arg', Cucumber::Ast::Table).should == unindented(%{
61
68
  Given /^A "([^"]*)" arg$/ do |arg1, table|
62
69
  # table is a Cucumber::Ast::Table
63
70
  pending # express the regexp above with the code you wish you had
64
71
  end
65
- })
66
- end
72
+ })
73
+ end
67
74
 
75
+ end
76
+
68
77
  describe "#load_code_file" do
69
78
  after do
70
79
  FileUtils.rm_rf('tmp.rb')
@@ -81,17 +90,194 @@ module Cucumber
81
90
  "$foo = 1"
82
91
  end
83
92
 
84
- @rb.load_code_file('tmp.rb')
93
+ rb.load_code_file('tmp.rb')
85
94
  $foo.should == 1
86
95
 
87
96
  a_file_called('tmp.rb') do
88
97
  "$foo = 2"
89
98
  end
90
99
 
91
- @rb.load_code_file('tmp.rb')
100
+ rb.load_code_file('tmp.rb')
92
101
  $foo.should == 2
93
102
  end
94
103
  end
104
+
105
+ describe "Handling the World" do
106
+
107
+ it "should raise an error if the world is nil" do
108
+ dsl.World {}
109
+
110
+ begin
111
+ rb.before(nil)
112
+ raise "Should fail"
113
+ rescue RbSupport::NilWorld => e
114
+ e.message.should == "World procs should never return nil"
115
+ e.backtrace.length.should == 1
116
+ e.backtrace[0].should =~ /spec\/cucumber\/rb_support\/rb_language_spec\.rb\:\d+\:in `World'/
117
+ end
118
+ end
119
+
120
+ module ModuleOne
121
+ end
122
+
123
+ module ModuleTwo
124
+ end
125
+
126
+ class ClassOne
127
+ end
128
+
129
+ it "should implicitly extend world with modules" do
130
+ dsl.World(ModuleOne, ModuleTwo)
131
+ rb.before(mock('scenario').as_null_object)
132
+ class << rb.current_world
133
+ included_modules.inspect.should =~ /ModuleOne/ # Workaround for RSpec/Ruby 1.9 issue with namespaces
134
+ included_modules.inspect.should =~ /ModuleTwo/
135
+ end
136
+ rb.current_world.class.should == Object
137
+ end
138
+
139
+ it "should raise error when we try to register more than one World proc" do
140
+ expected_error = %{You can only pass a proc to #World once, but it's happening
141
+ in 2 places:
142
+
143
+ spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
144
+ spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
145
+
146
+ Use Ruby modules instead to extend your worlds. See the Cucumber::RbSupport::RbDsl#World RDoc
147
+ or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.
148
+
149
+ }
150
+ dsl.World { Hash.new }
151
+ lambda do
152
+ dsl.World { Array.new }
153
+ end.should raise_error(RbSupport::MultipleWorld, /#{expected_error}/)
154
+
155
+ end
156
+ end
157
+
158
+ describe "step argument transformations" do
159
+
160
+ describe "without capture groups" do
161
+ it "complains when registering with a with no transform block" do
162
+ lambda do
163
+ dsl.Transform('^abc$')
164
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
165
+ end
166
+
167
+ it "complains when registering with a zero-arg transform block" do
168
+ lambda do
169
+ dsl.Transform('^abc$') {42}
170
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
171
+ end
172
+
173
+ it "complains when registering with a splat-arg transform block" do
174
+ lambda do
175
+ dsl.Transform('^abc$') {|*splat| 42 }
176
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
177
+ end
178
+
179
+ it "complains when transforming with an arity mismatch" do
180
+ lambda do
181
+ dsl.Transform('^abc$') {|one, two| 42 }
182
+ rb.execute_transforms(['abc'])
183
+ end.should raise_error(Cucumber::ArityMismatchError)
184
+ end
185
+
186
+ it "allows registering a regexp pattern that yields the step_arg matched" do
187
+ dsl.Transform(/^ab*c$/) {|arg| 42}
188
+ rb.execute_transforms(['ab']).should == ['ab']
189
+ rb.execute_transforms(['ac']).should == [42]
190
+ rb.execute_transforms(['abc']).should == [42]
191
+ rb.execute_transforms(['abbc']).should == [42]
192
+ end
193
+ end
194
+
195
+ describe "with capture groups" do
196
+ it "complains when registering with a with no transform block" do
197
+ lambda do
198
+ dsl.Transform('^a(.)c$')
199
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
200
+ end
201
+
202
+ it "complains when registering with a zero-arg transform block" do
203
+ lambda do
204
+ dsl.Transform('^a(.)c$') { 42 }
205
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
206
+ end
207
+
208
+ it "complains when registering with a splat-arg transform block" do
209
+ lambda do
210
+ dsl.Transform('^a(.)c$') {|*splat| 42 }
211
+ end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
212
+ end
213
+
214
+ it "complains when transforming with an arity mismatch" do
215
+ lambda do
216
+ dsl.Transform('^a(.)c$') {|one, two| 42 }
217
+ rb.execute_transforms(['abc'])
218
+ end.should raise_error(Cucumber::ArityMismatchError)
219
+ end
220
+
221
+ it "allows registering a regexp pattern that yields capture groups" do
222
+ dsl.Transform(/^shape: (.+), color: (.+)$/) do |shape, color|
223
+ {shape.to_sym => color.to_sym}
224
+ end
225
+ rb.execute_transforms(['shape: circle, color: blue']).should == [{:circle => :blue}]
226
+ rb.execute_transforms(['shape: square, color: red']).should == [{:square => :red}]
227
+ rb.execute_transforms(['not shape: square, not color: red']).should == ['not shape: square, not color: red']
228
+ end
229
+ end
230
+
231
+ it "allows registering a string pattern" do
232
+ dsl.Transform('^ab*c$') {|arg| 42}
233
+ rb.execute_transforms(['ab']).should == ['ab']
234
+ rb.execute_transforms(['ac']).should == [42]
235
+ rb.execute_transforms(['abc']).should == [42]
236
+ rb.execute_transforms(['abbc']).should == [42]
237
+ end
238
+
239
+ it "gives match priority to transforms defined last" do
240
+ dsl.Transform(/^transform_me$/) {|arg| :foo }
241
+ dsl.Transform(/^transform_me$/) {|arg| :bar }
242
+ dsl.Transform(/^transform_me$/) {|arg| :baz }
243
+ rb.execute_transforms(['transform_me']).should == [:baz]
244
+ end
245
+
246
+ it "allows registering a transform which returns nil" do
247
+ dsl.Transform('^ac$') {|arg| nil}
248
+ rb.execute_transforms(['ab']).should == ['ab']
249
+ rb.execute_transforms(['ac']).should == [nil]
250
+ end
251
+ end
252
+
253
+ describe "hooks" do
254
+
255
+ it "should find before hooks" do
256
+ fish = dsl.Before('@fish'){}
257
+ meat = dsl.Before('@meat'){}
258
+
259
+ scenario = mock('Scenario')
260
+ scenario.should_receive(:accept_hook?).with(fish).and_return(true)
261
+ scenario.should_receive(:accept_hook?).with(meat).and_return(false)
262
+
263
+ rb.hooks_for(:before, scenario).should == [fish]
264
+ end
265
+
266
+ it "should find around hooks" do
267
+ a = dsl.Around do |scenario, block|
268
+ end
269
+
270
+ b = dsl.Around('@tag') do |scenario, block|
271
+ end
272
+
273
+ scenario = mock('Scenario')
274
+ scenario.should_receive(:accept_hook?).with(a).and_return(true)
275
+ scenario.should_receive(:accept_hook?).with(b).and_return(false)
276
+
277
+ rb.hooks_for(:around, scenario).should == [a]
278
+ end
279
+ end
280
+
95
281
  end
96
282
  end
97
283
  end
@@ -7,86 +7,92 @@ require 'cucumber/rb_support/rb_language'
7
7
  module Cucumber
8
8
  module RbSupport
9
9
  describe RbStepDefinition do
10
+ let(:user_interface) { double('user interface') }
11
+ let(:support_code) { Cucumber::Runtime::SupportCode.new(user_interface) }
12
+ let(:rb) { support_code.load_programming_language('rb')}
13
+ let(:dsl) do
14
+ rb
15
+ Object.new.extend(Cucumber::RbSupport::RbDsl)
16
+ end
17
+
10
18
  before do
11
- @step_mother = Cucumber::Runtime.new
12
- @rb = @step_mother.load_programming_language('rb')
13
- @dsl = Object.new
14
- @dsl.extend Cucumber::RbSupport::RbDsl
15
- @step_mother.before(mock('scenario').as_null_object)
19
+ rb.before(mock('scenario').as_null_object)
16
20
 
17
21
  $inside = nil
18
22
  end
19
23
 
20
24
  it "should allow calling of other steps" do
21
- @dsl.Given /Outside/ do
25
+ dsl.Given /Outside/ do
22
26
  Given "Inside"
23
27
  end
24
- @dsl.Given /Inside/ do
28
+ dsl.Given /Inside/ do
25
29
  $inside = true
26
30
  end
27
31
 
28
- @step_mother.step_match("Outside").invoke(nil)
32
+ support_code.step_match("Outside").invoke(nil)
29
33
  $inside.should == true
30
34
  end
31
35
 
32
36
  it "should allow calling of other steps with inline arg" do
33
- @dsl.Given /Outside/ do
37
+ dsl.Given /Outside/ do
34
38
  Given "Inside", Cucumber::Ast::Table.new([['inside']])
35
39
  end
36
- @dsl.Given /Inside/ do |table|
40
+ dsl.Given /Inside/ do |table|
37
41
  $inside = table.raw[0][0]
38
42
  end
39
43
 
40
- @step_mother.step_match("Outside").invoke(nil)
44
+ support_code.step_match("Outside").invoke(nil)
41
45
  $inside.should == 'inside'
42
46
  end
43
47
 
44
48
  it "should raise Undefined when inside step is not defined" do
45
- @dsl.Given /Outside/ do
49
+ dsl.Given /Outside/ do
46
50
  Given 'Inside'
47
51
  end
48
52
 
49
53
  lambda do
50
- @step_mother.step_match('Outside').invoke(nil)
54
+ support_code.step_match('Outside').invoke(nil)
51
55
  end.should raise_error(Cucumber::Undefined, 'Undefined step: "Inside"')
52
56
  end
53
57
 
54
58
  it "should allow forced pending" do
55
- @dsl.Given /Outside/ do
59
+ dsl.Given /Outside/ do
56
60
  pending("Do me!")
57
61
  end
58
62
 
59
63
  lambda do
60
- @step_mother.step_match("Outside").invoke(nil)
64
+ support_code.step_match("Outside").invoke(nil)
61
65
  end.should raise_error(Cucumber::Pending, "Do me!")
62
66
  end
63
67
 
64
68
  it "should raise ArityMismatchError when the number of capture groups differs from the number of step arguments" do
65
- @dsl.Given /No group: \w+/ do |arg|
69
+ dsl.Given /No group: \w+/ do |arg|
66
70
  end
67
71
 
68
72
  lambda do
69
- @step_mother.step_match("No group: arg").invoke(nil)
73
+ support_code.step_match("No group: arg").invoke(nil)
70
74
  end.should raise_error(Cucumber::ArityMismatchError)
71
75
  end
72
76
 
73
77
  it "should allow announce" do
74
- v = mock('visitor')
75
- v.should_receive(:announce).with('wasup')
76
- @step_mother.visitor = v
77
- @dsl.Given /Loud/ do
78
+ user_interface.should_receive(:announce).with('wasup')
79
+ dsl.Given /Loud/ do
78
80
  announce 'wasup'
79
81
  end
80
82
 
81
- @step_mother.step_match("Loud").invoke(nil)
83
+ support_code.step_match("Loud").invoke(nil)
82
84
  end
83
85
 
84
86
  it "should recognize $arg style captures" do
85
- @dsl.Given "capture this: $arg" do |arg|
87
+ dsl.Given "capture this: $arg" do |arg|
86
88
  arg.should == 'this'
87
89
  end
88
90
 
89
- @step_mother.step_match('capture this: this').invoke(nil)
91
+ support_code.step_match('capture this: this').invoke(nil)
92
+ end
93
+
94
+ it "should have a JSON representation of the signature" do
95
+ RbStepDefinition.new(rb, /I CAN HAZ (\d+) CUKES/i, lambda{}).to_hash.should == {'source' => "I CAN HAZ (\\d+) CUKES", 'flags' => 'i'}
90
96
  end
91
97
  end
92
98
  end