cucumber 2.0.0.beta.3 → 2.0.0

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/History.md +131 -32
  4. data/Rakefile +0 -2
  5. data/cucumber.gemspec +4 -3
  6. data/examples/i18n/ht/Rakefile +6 -0
  7. data/examples/i18n/ht/features/adisyon.feature +17 -0
  8. data/examples/i18n/ht/features/divizyon.feature +10 -0
  9. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +25 -0
  10. data/examples/i18n/ht/lib/kalkilatris.rb +14 -0
  11. data/examples/tcl/features/step_definitions/fib_steps.rb +1 -1
  12. data/features/docs/cli/dry_run.feature +48 -0
  13. data/features/docs/cli/exclude_files.feature +1 -2
  14. data/features/docs/cli/run_specific_scenarios.feature +28 -66
  15. data/features/docs/cli/strict_mode.feature +24 -1
  16. data/features/docs/defining_steps/nested_steps.feature +49 -0
  17. data/features/docs/defining_steps/skip_scenario.feature +31 -2
  18. data/features/docs/defining_steps/snippets.feature +15 -0
  19. data/features/docs/exception_in_after_step_hook.feature +1 -1
  20. data/features/docs/exception_in_around_hook.feature +80 -0
  21. data/features/docs/extending_cucumber/custom_filter.feature +29 -0
  22. data/features/docs/extending_cucumber/custom_formatter.feature +65 -7
  23. data/features/docs/formatters/debug_formatter.feature +24 -17
  24. data/features/docs/formatters/json_formatter.feature +65 -1
  25. data/features/docs/formatters/junit_formatter.feature +40 -0
  26. data/features/docs/formatters/pretty_formatter.feature +42 -0
  27. data/features/docs/formatters/rerun_formatter.feature +3 -2
  28. data/features/docs/getting_started.feature +1 -1
  29. data/features/docs/{wire_protocol_erb.feature → wire_protocol/erb_configuration.feature} +2 -2
  30. data/features/docs/wire_protocol/handle_unexpected_response.feature +30 -0
  31. data/features/docs/wire_protocol/invoke_message.feature +216 -0
  32. data/features/docs/wire_protocol/readme.md +26 -0
  33. data/features/docs/wire_protocol/snippets_message.feature +51 -0
  34. data/features/docs/wire_protocol/step_matches_message.feature +81 -0
  35. data/features/docs/{wire_protocol_table_diffing.feature → wire_protocol/table_diffing.feature} +1 -0
  36. data/features/docs/{wire_protocol_tags.feature → wire_protocol/tags.feature} +1 -0
  37. data/features/docs/{wire_protocol_timeouts.feature → wire_protocol/timeouts.feature} +1 -0
  38. data/features/docs/work_in_progress.feature +1 -1
  39. data/features/docs/writing_support_code/after_hooks.feature +24 -0
  40. data/features/docs/writing_support_code/around_hooks.feature +31 -0
  41. data/features/docs/writing_support_code/before_hook.feature +7 -3
  42. data/features/docs/writing_support_code/tagged_hooks.feature +44 -6
  43. data/features/lib/step_definitions/wire_steps.rb +18 -1
  44. data/features/lib/support/fake_wire_server.rb +10 -7
  45. data/lib/cucumber/cli/configuration.rb +6 -11
  46. data/lib/cucumber/cli/main.rb +2 -2
  47. data/lib/cucumber/cli/options.rb +8 -1
  48. data/lib/cucumber/cli/profile_loader.rb +1 -1
  49. data/lib/cucumber/core_ext/instance_exec.rb +1 -1
  50. data/lib/cucumber/encoding.rb +5 -0
  51. data/lib/cucumber/errors.rb +8 -0
  52. data/lib/cucumber/file_specs.rb +3 -1
  53. data/lib/cucumber/filters/activate_steps.rb +33 -0
  54. data/lib/cucumber/filters/apply_after_hooks.rb +9 -0
  55. data/lib/cucumber/filters/apply_after_step_hooks.rb +12 -0
  56. data/lib/cucumber/filters/apply_around_hooks.rb +12 -0
  57. data/lib/cucumber/filters/apply_before_hooks.rb +9 -0
  58. data/lib/cucumber/{runtime → filters}/gated_receiver.rb +5 -1
  59. data/lib/cucumber/filters/prepare_world.rb +45 -0
  60. data/lib/cucumber/filters/quit.rb +28 -0
  61. data/lib/cucumber/filters/randomizer.rb +40 -0
  62. data/lib/cucumber/{runtime → filters}/tag_limits/test_case_index.rb +4 -2
  63. data/lib/cucumber/{runtime → filters}/tag_limits/verifier.rb +4 -2
  64. data/lib/cucumber/filters/tag_limits.rb +45 -0
  65. data/lib/cucumber/filters.rb +9 -0
  66. data/lib/cucumber/formatter/ansicolor.rb +0 -8
  67. data/lib/cucumber/formatter/console.rb +37 -20
  68. data/lib/cucumber/formatter/debug.rb +1 -8
  69. data/lib/cucumber/formatter/fanout.rb +27 -0
  70. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +10 -9
  71. data/lib/cucumber/formatter/html.rb +31 -6
  72. data/lib/cucumber/formatter/ignore_missing_messages.rb +20 -0
  73. data/lib/cucumber/formatter/junit.rb +97 -2
  74. data/lib/cucumber/formatter/legacy_api/adapter.rb +1060 -0
  75. data/lib/cucumber/formatter/legacy_api/ast.rb +376 -0
  76. data/lib/cucumber/formatter/legacy_api/results.rb +51 -0
  77. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +30 -0
  78. data/lib/cucumber/formatter/pretty.rb +14 -0
  79. data/lib/cucumber/formatter/progress.rb +10 -0
  80. data/lib/cucumber/formatter/rerun.rb +14 -88
  81. data/lib/cucumber/hooks.rb +97 -0
  82. data/lib/cucumber/language_support/language_methods.rb +0 -54
  83. data/lib/cucumber/multiline_argument/data_table.rb +41 -29
  84. data/lib/cucumber/platform.rb +3 -3
  85. data/lib/cucumber/project_initializer.rb +43 -0
  86. data/lib/cucumber/rb_support/rb_hook.rb +2 -2
  87. data/lib/cucumber/rb_support/rb_step_definition.rb +11 -2
  88. data/lib/cucumber/rb_support/rb_transform.rb +3 -1
  89. data/lib/cucumber/rb_support/rb_world.rb +2 -2
  90. data/lib/cucumber/rb_support/snippet.rb +1 -1
  91. data/lib/cucumber/rspec/doubles.rb +1 -1
  92. data/lib/cucumber/running_test_case.rb +115 -0
  93. data/lib/cucumber/runtime/after_hooks.rb +24 -0
  94. data/lib/cucumber/runtime/before_hooks.rb +23 -0
  95. data/lib/cucumber/runtime/for_programming_languages.rb +4 -8
  96. data/lib/cucumber/runtime/step_hooks.rb +22 -0
  97. data/lib/cucumber/runtime/support_code.rb +70 -5
  98. data/lib/cucumber/runtime.rb +56 -112
  99. data/lib/cucumber/step_match.rb +26 -2
  100. data/lib/cucumber.rb +7 -3
  101. data/spec/cucumber/cli/configuration_spec.rb +16 -1
  102. data/spec/cucumber/cli/profile_loader_spec.rb +10 -0
  103. data/spec/cucumber/core_ext/instance_exec_spec.rb +4 -0
  104. data/spec/cucumber/file_specs_spec.rb +21 -2
  105. data/spec/cucumber/filters/activate_steps_spec.rb +57 -0
  106. data/spec/cucumber/{runtime → filters}/gated_receiver_spec.rb +3 -3
  107. data/spec/cucumber/{runtime → filters}/tag_limits/test_case_index_spec.rb +3 -3
  108. data/spec/cucumber/{runtime → filters}/tag_limits/verifier_spec.rb +4 -4
  109. data/spec/cucumber/{runtime/tag_limits/filter_spec.rb → filters/tag_limits_spec.rb} +6 -6
  110. data/spec/cucumber/formatter/debug_spec.rb +25 -530
  111. data/spec/cucumber/formatter/html_spec.rb +140 -0
  112. data/spec/cucumber/formatter/junit_spec.rb +212 -156
  113. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +2090 -0
  114. data/spec/cucumber/formatter/pretty_spec.rb +248 -2
  115. data/spec/cucumber/formatter/rerun_spec.rb +107 -0
  116. data/spec/cucumber/formatter/spec_helper.rb +17 -8
  117. data/spec/cucumber/hooks_spec.rb +30 -0
  118. data/spec/cucumber/multiline_argument/data_table_spec.rb +53 -47
  119. data/spec/cucumber/project_initializer_spec.rb +87 -0
  120. data/spec/cucumber/rb_support/rb_language_spec.rb +2 -2
  121. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +32 -7
  122. data/spec/cucumber/rb_support/rb_transform_spec.rb +20 -0
  123. data/spec/cucumber/rb_support/snippet_spec.rb +6 -6
  124. data/spec/cucumber/running_test_case_spec.rb +83 -0
  125. data/spec/cucumber/runtime_spec.rb +1 -5
  126. data/spec/spec_helper.rb +3 -4
  127. metadata +149 -107
  128. data/bin/cuke +0 -60
  129. data/features/docs/extending_cucumber/formatter_callbacks.feature +0 -370
  130. data/features/docs/output_from_hooks.feature +0 -128
  131. data/features/docs/report_called_undefined_steps.feature +0 -57
  132. data/features/docs/wire_protocol.feature +0 -337
  133. data/gem_tasks/yard/default/layout/html/bubble_32x32.png +0 -0
  134. data/gem_tasks/yard/default/layout/html/footer.erb +0 -5
  135. data/gem_tasks/yard/default/layout/html/index.erb +0 -1
  136. data/gem_tasks/yard/default/layout/html/layout.erb +0 -25
  137. data/gem_tasks/yard/default/layout/html/logo.erb +0 -1
  138. data/gem_tasks/yard/default/layout/html/setup.rb +0 -4
  139. data/gem_tasks/yard.rake +0 -43
  140. data/lib/cucumber/mappings.rb +0 -238
  141. data/lib/cucumber/reports/legacy_formatter.rb +0 -1349
  142. data/lib/cucumber/runtime/results.rb +0 -64
  143. data/lib/cucumber/runtime/tag_limits/filter.rb +0 -31
  144. data/lib/cucumber/runtime/tag_limits.rb +0 -15
  145. data/spec/cucumber/mappings_spec.rb +0 -180
  146. data/spec/cucumber/reports/legacy_formatter_spec.rb +0 -1860
  147. data/spec/cucumber/runtime/results_spec.rb +0 -88
@@ -6,7 +6,7 @@ module Cucumber
6
6
  module MultilineArgument
7
7
  describe DataTable do
8
8
  before do
9
- @table = DataTable.new([
9
+ @table = DataTable.from([
10
10
  %w{one four seven},
11
11
  %w{4444 55555 666666}
12
12
  ])
@@ -48,7 +48,7 @@ module Cucumber
48
48
  it "applies the block once to each value" do
49
49
  headers = ['header']
50
50
  rows = ['value']
51
- table = DataTable.new [headers, rows]
51
+ table = DataTable.from [headers, rows]
52
52
  count = 0
53
53
  table.map_column!('header') { |value| count +=1 }
54
54
  table.rows
@@ -94,7 +94,7 @@ module Cucumber
94
94
  it "applies the block once to each value" do
95
95
  headers = ['header']
96
96
  rows = ['value']
97
- table = DataTable.new [headers, rows]
97
+ table = DataTable.from [headers, rows]
98
98
  count = 0
99
99
  new_table = table.map_column('header') { |value| count +=1 }
100
100
  new_table.rows
@@ -133,7 +133,7 @@ module Cucumber
133
133
 
134
134
  describe "#match" do
135
135
  before(:each) do
136
- @table = DataTable.new([
136
+ @table = DataTable.from([
137
137
  %w{one four seven},
138
138
  %w{4444 55555 666666}
139
139
  ])
@@ -152,7 +152,7 @@ module Cucumber
152
152
 
153
153
  describe "#transpose" do
154
154
  before(:each) do
155
- @table = DataTable.new([
155
+ @table = DataTable.from([
156
156
  %w{one 1111},
157
157
  %w{two 22222}
158
158
  ])
@@ -166,7 +166,7 @@ module Cucumber
166
166
  describe "#rows_hash" do
167
167
 
168
168
  it "should return a hash of the rows" do
169
- table = DataTable.new([
169
+ table = DataTable.from([
170
170
  %w{one 1111},
171
171
  %w{two 22222}
172
172
  ])
@@ -174,7 +174,7 @@ module Cucumber
174
174
  end
175
175
 
176
176
  it "should fail if the table doesn't have two columns" do
177
- faulty_table = DataTable.new([
177
+ faulty_table = DataTable.from([
178
178
  %w{one 1111 abc},
179
179
  %w{two 22222 def}
180
180
  ])
@@ -184,7 +184,7 @@ module Cucumber
184
184
  end
185
185
 
186
186
  it "should support header and column mapping" do
187
- table = DataTable.new([
187
+ table = DataTable.from([
188
188
  %w{one 1111},
189
189
  %w{two 22222}
190
190
  ])
@@ -196,7 +196,7 @@ module Cucumber
196
196
 
197
197
  describe '#map_headers!' do
198
198
  let(:table) do
199
- DataTable.new([
199
+ DataTable.from([
200
200
  %w{HELLO WORLD},
201
201
  %w{4444 55555}
202
202
  ])
@@ -236,7 +236,7 @@ module Cucumber
236
236
 
237
237
  describe '#map_headers' do
238
238
  let(:table) do
239
- DataTable.new([
239
+ DataTable.from([
240
240
  %w{HELLO WORLD},
241
241
  %w{4444 55555}
242
242
  ])
@@ -277,20 +277,20 @@ module Cucumber
277
277
 
278
278
  describe "diff!" do
279
279
  it "should detect a complex diff" do
280
- t1 = table(%{
280
+ t1 = DataTable.from(%{
281
281
  | 1 | 22 | 333 | 4444 |
282
282
  | 55555 | 666666 | 7777777 | 88888888 |
283
283
  | 999999999 | 0000000000 | 01010101010 | 121212121212 |
284
284
  | 4000 | ABC | DEF | 50000 |
285
- }, __FILE__, __LINE__)
285
+ })
286
286
 
287
- t2 = table(%{
287
+ t2 = DataTable.from(%{
288
288
  | a | 4444 | 1 |
289
289
  | bb | 88888888 | 55555 |
290
290
  | ccc | xxxxxxxx | 999999999 |
291
291
  | dddd | 4000 | 300 |
292
292
  | e | 50000 | 4000 |
293
- }, __FILE__, __LINE__)
293
+ })
294
294
  expect { t1.diff!(t2) }.to raise_error
295
295
  expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
296
296
  | 1 | (-) 22 | (-) 333 | 4444 | (+) a |
@@ -303,11 +303,11 @@ module Cucumber
303
303
  end
304
304
 
305
305
  it "should not change table when diffed with identical" do
306
- t = table(%{
306
+ t = DataTable.from(%{
307
307
  |a|b|c|
308
308
  |d|e|f|
309
309
  |g|h|i|
310
- }, __FILE__, __LINE__)
310
+ })
311
311
  t.diff!(t.dup)
312
312
  expect( t.to_s(:indent => 12, :color => false) ).to eq %{
313
313
  | a | b | c |
@@ -317,11 +317,11 @@ module Cucumber
317
317
  end
318
318
 
319
319
  it "should inspect missing and surplus cells" do
320
- t1 = DataTable.new([
320
+ t1 = DataTable.from([
321
321
  ['name', 'male', 'lastname', 'swedish'],
322
322
  ['aslak', 'true', 'hellesøy', 'false']
323
323
  ])
324
- t2 = DataTable.new([
324
+ t2 = DataTable.from([
325
325
  ['name', 'male', 'lastname', 'swedish'],
326
326
  ['aslak', true, 'hellesøy', false]
327
327
  ])
@@ -335,12 +335,12 @@ module Cucumber
335
335
  end
336
336
 
337
337
  it "should allow column mapping of target before diffing" do
338
- t1 = DataTable.new([
338
+ t1 = DataTable.from([
339
339
  ['name', 'male'],
340
340
  ['aslak', 'true']
341
341
  ])
342
342
  t1.map_column!('male') { |m| m == 'true' }
343
- t2 = DataTable.new([
343
+ t2 = DataTable.from([
344
344
  ['name', 'male'],
345
345
  ['aslak', true]
346
346
  ])
@@ -352,14 +352,14 @@ module Cucumber
352
352
  end
353
353
 
354
354
  it "should allow column mapping of argument before diffing" do
355
- t1 = DataTable.new([
355
+ t1 = DataTable.from([
356
356
  ['name', 'male'],
357
357
  ['aslak', true]
358
358
  ])
359
359
  t1.map_column!('male') {
360
360
  'true'
361
361
  }
362
- t2 = DataTable.new([
362
+ t2 = DataTable.from([
363
363
  ['name', 'male'],
364
364
  ['aslak', 'true']
365
365
  ])
@@ -371,13 +371,13 @@ module Cucumber
371
371
  end
372
372
 
373
373
  it "should allow header mapping before diffing" do
374
- t1 = DataTable.new([
374
+ t1 = DataTable.from([
375
375
  ['Name', 'Male'],
376
376
  ['aslak', 'true']
377
377
  ])
378
378
  t1.map_headers!('Name' => 'name', 'Male' => 'male')
379
379
  t1.map_column!('male') { |m| m == 'true' }
380
- t2 = DataTable.new([
380
+ t2 = DataTable.from([
381
381
  ['name', 'male'],
382
382
  ['aslak', true]
383
383
  ])
@@ -389,11 +389,11 @@ module Cucumber
389
389
  end
390
390
 
391
391
  it "should detect seemingly identical tables as different" do
392
- t1 = DataTable.new([
392
+ t1 = DataTable.from([
393
393
  ['X', 'Y'],
394
394
  ['2', '1']
395
395
  ])
396
- t2 = DataTable.new([
396
+ t2 = DataTable.from([
397
397
  ['X', 'Y'],
398
398
  [2, 1]
399
399
  ])
@@ -406,7 +406,7 @@ module Cucumber
406
406
  end
407
407
 
408
408
  it "should not allow mappings that match more than 1 column" do
409
- t1 = DataTable.new([
409
+ t1 = DataTable.from([
410
410
  ['Cuke', 'Duke'],
411
411
  ['Foo', 'Bar']
412
412
  ])
@@ -418,85 +418,91 @@ module Cucumber
418
418
 
419
419
  describe "raising" do
420
420
  before do
421
- @t = table(%{
421
+ @t = DataTable.from(%{
422
422
  | a | b |
423
423
  | c | d |
424
- }, __FILE__, __LINE__)
424
+ })
425
425
  expect( @t ).not_to eq nil
426
426
  end
427
427
 
428
428
  it "should raise on missing rows" do
429
- t = table(%{
429
+ t = DataTable.from(%{
430
430
  | a | b |
431
- }, __FILE__, __LINE__)
431
+ })
432
432
  expect( lambda { @t.dup.diff!(t) } ).to raise_error
433
433
  expect { @t.dup.diff!(t, :missing_row => false) }.not_to raise_error
434
434
  end
435
435
 
436
436
  it "should not raise on surplus rows when surplus is at the end" do
437
- t = table(%{
437
+ t = DataTable.from(%{
438
438
  | a | b |
439
439
  | c | d |
440
440
  | e | f |
441
- }, __FILE__, __LINE__)
441
+ })
442
442
  expect { @t.dup.diff!(t) }.to raise_error
443
443
  expect { @t.dup.diff!(t, :surplus_row => false) }.not_to raise_error
444
444
  end
445
445
 
446
446
  it "should not raise on surplus rows when surplus is interleaved" do
447
- t1 = table(%{
447
+ t1 = DataTable.from(%{
448
448
  | row_1 | row_2 |
449
449
  | four | 4 |
450
- }, __FILE__, __LINE__)
451
- t2 = table(%{
450
+ })
451
+ t2 = DataTable.from(%{
452
452
  | row_1 | row_2 |
453
453
  | one | 1 |
454
454
  | two | 2 |
455
455
  | three | 3 |
456
456
  | four | 4 |
457
457
  | five | 5 |
458
- }, __FILE__, __LINE__)
458
+ })
459
459
  expect { t1.dup.diff!(t2) }.to raise_error
460
460
 
461
461
  expect { t1.dup.diff!(t2, :surplus_row => false) }.not_to raise_error
462
462
  end
463
463
 
464
464
  it "should raise on missing columns" do
465
- t = table(%{
465
+ t = DataTable.from(%{
466
466
  | a |
467
467
  | c |
468
- }, __FILE__, __LINE__)
468
+ })
469
469
  expect { @t.dup.diff!(t) }.to raise_error
470
470
  expect { @t.dup.diff!(t, :missing_col => false) }.not_to raise_error
471
471
  end
472
472
 
473
473
  it "should not raise on surplus columns" do
474
- t = table(%{
474
+ t = DataTable.from(%{
475
475
  | a | b | x |
476
476
  | c | d | y |
477
- }, __FILE__, __LINE__)
477
+ })
478
478
  expect { @t.dup.diff!(t) }.not_to raise_error
479
479
  expect { @t.dup.diff!(t, :surplus_col => true) }.to raise_error
480
480
  end
481
481
 
482
482
  it "should not raise on misplaced columns" do
483
- t = table(%{
483
+ t = DataTable.from(%{
484
484
  | b | a |
485
485
  | d | c |
486
- }, __FILE__, __LINE__)
486
+ })
487
487
  expect { @t.dup.diff!(t) }.not_to raise_error
488
488
  expect { @t.dup.diff!(t, :misplaced_col => true) }.to raise_error
489
489
  end
490
490
  end
491
491
 
492
- def table(text, file, offset)
493
- DataTable.parse(text, file, offset)
492
+ it "can compare to an Array" do
493
+ t = DataTable.from(%{
494
+ | b | a |
495
+ | d | c |
496
+ })
497
+ other = [ %w{b a}, %w{d c} ]
498
+
499
+ expect { t.diff!(other) }.not_to raise_error
494
500
  end
495
501
  end
496
502
 
497
- describe "#new" do
503
+ describe "#from" do
498
504
  it "should allow Array of Hash" do
499
- t1 = DataTable.new([{'name' => 'aslak', 'male' => 'true'}])
505
+ t1 = DataTable.from([{'name' => 'aslak', 'male' => 'true'}])
500
506
  expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
501
507
  | male | name |
502
508
  | true | aslak |
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ module Cucumber
5
+ describe ProjectInitializer, :isolated_home => true do
6
+ let(:command_line_config) { ProjectInitializer.new }
7
+
8
+ before do
9
+ allow(command_line_config).to receive(:puts)
10
+ end
11
+
12
+ context "no files created" do
13
+ around(:example) do |example|
14
+
15
+ dir = Dir.mktmpdir
16
+ original_dir = Dir.pwd
17
+ begin
18
+ FileUtils.cd dir
19
+ example.call
20
+ ensure
21
+ FileUtils.cd original_dir
22
+ FileUtils.rm_rf dir
23
+ end
24
+ end
25
+
26
+ it "should create features directory" do
27
+ expect(command_line_config).to receive(:puts).with %r(^\s+create\s+features$)
28
+ command_line_config.run
29
+ end
30
+
31
+ it "should create step_definitions directory" do
32
+ expect(command_line_config).to receive(:puts).with %r(^\s+create\s+features/step_definitions$)
33
+ command_line_config.run
34
+ end
35
+
36
+ it "should create support directory" do
37
+ expect(command_line_config).to receive(:puts).with %r(^\s+create\s+features/support$)
38
+ command_line_config.run
39
+ end
40
+
41
+ it "should create env.rb directory" do
42
+ expect(command_line_config).to receive(:puts).with %r(^\s+create\s+features/support/env.rb$)
43
+ command_line_config.run
44
+ end
45
+
46
+ end
47
+
48
+ context "files created" do
49
+ around(:example) do |example|
50
+ dir = Dir.mktmpdir
51
+ FileUtils.mkdir_p "#{dir}/features"
52
+ FileUtils.mkdir_p "#{dir}/features/step_definitions"
53
+ FileUtils.mkdir_p "#{dir}/features/support"
54
+ FileUtils.touch "#{dir}/features/support/env.rb"
55
+ original_dir = Dir.pwd
56
+ begin
57
+ FileUtils.cd dir
58
+ example.call
59
+ ensure
60
+ FileUtils.cd original_dir
61
+ FileUtils.rm_rf dir
62
+ end
63
+ end
64
+
65
+ it "should not create features directory" do
66
+ expect(command_line_config).to receive(:puts).with %r(^\s+exist\s+features$)
67
+ command_line_config.run
68
+ end
69
+
70
+ it "should not create step_definitions directory" do
71
+ expect(command_line_config).to receive(:puts).with %r(^\s+exist\s+features/step_definitions$)
72
+ command_line_config.run
73
+ end
74
+
75
+ it "should not create support directory" do
76
+ expect(command_line_config).to receive(:puts).with %r(^\s+exist\s+features/support$)
77
+ command_line_config.run
78
+ end
79
+
80
+ it "should not create env.rb directory" do
81
+ expect(command_line_config).to receive(:puts).with %r(^\s+exist\s+features/support/env.rb$)
82
+ command_line_config.run
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -91,7 +91,7 @@ module Cucumber
91
91
  dsl.World {}
92
92
 
93
93
  begin
94
- rb.before(nil)
94
+ rb.begin_scenario(nil)
95
95
  raise "Should fail"
96
96
  rescue RbSupport::NilWorld => e
97
97
  expect(e.message).to eq "World procs should never return nil"
@@ -111,7 +111,7 @@ module Cucumber
111
111
 
112
112
  it "implicitlys extend world with modules" do
113
113
  dsl.World(ModuleOne, ModuleTwo)
114
- rb.before(double('scenario').as_null_object)
114
+ rb.begin_scenario(double('scenario').as_null_object)
115
115
  class << rb.current_world
116
116
  extend RSpec::Matchers
117
117
 
@@ -7,18 +7,23 @@ module Cucumber
7
7
  let(:user_interface) { double('user interface') }
8
8
  let(:support_code) { Cucumber::Runtime::SupportCode.new(user_interface) }
9
9
  let(:rb) { support_code.load_programming_language('rb') }
10
+ let(:scenario) { double('scenario', iso_code: 'en').as_null_object }
10
11
  let(:dsl) do
11
12
  rb
12
13
  Object.new.extend(Cucumber::RbSupport::RbDsl)
13
14
  end
14
15
 
15
16
  before do
16
- rb.before(double('scenario').as_null_object)
17
+ rb.begin_scenario(scenario)
17
18
  $inside = nil
18
19
  end
19
20
 
20
21
  def run_step(text)
21
- support_code.step_match(text).invoke(MultilineArgument::None.new)
22
+ step_match(text).invoke(MultilineArgument::None.new)
23
+ end
24
+
25
+ def step_match(text)
26
+ support_code.step_match(text)
22
27
  end
23
28
 
24
29
  it "allows calling of other steps" do
@@ -80,16 +85,33 @@ module Cucumber
80
85
 
81
86
  run_step "With symbol on symbol"
82
87
  end
88
+
89
+ it "has the correct location" do
90
+ dsl.Given /With symbol/, :with_symbol
91
+ expect(step_match("With symbol").file_colon_line).to eq "spec/cucumber/rb_support/rb_step_definition_spec.rb:#{__LINE__-1}"
92
+ end
83
93
  end
84
94
 
85
- it "raises Undefined when inside step is not defined" do
95
+ it "raises UndefinedDynamicStep when inside step is not defined" do
86
96
  dsl.Given(/Outside/) do
87
97
  step 'Inside'
88
98
  end
89
99
 
90
100
  expect(-> {
91
101
  run_step "Outside"
92
- }).to raise_error(Cucumber::Undefined)
102
+ }).to raise_error(Cucumber::UndefinedDynamicStep)
103
+ end
104
+
105
+ it "raises UndefinedDynamicStep when an undefined step is parsed dynamically" do
106
+ dsl.Given(/Outside/) do
107
+ steps %{
108
+ Given Inside
109
+ }
110
+ end
111
+
112
+ expect(-> {
113
+ run_step "Outside"
114
+ }).to raise_error(Cucumber::UndefinedDynamicStep)
93
115
  end
94
116
 
95
117
  it "allows forced pending" do
@@ -111,14 +133,17 @@ module Cucumber
111
133
  }).to raise_error(Cucumber::ArityMismatchError)
112
134
  end
113
135
 
114
- it "does not allow modification of args since it messes up pretty formatting" do
136
+ it "does not modify the step_match arg when arg is modified in a step" do
115
137
  dsl.Given(/My car is (.*)/) do |colour|
116
138
  colour << "xxx"
117
139
  end
118
140
 
141
+ step_name = "My car is white"
142
+ step_args = step_match(step_name).args
143
+
119
144
  expect(-> {
120
- run_step "My car is white"
121
- }).to raise_error(RuntimeError, /can't modify frozen String/i)
145
+ run_step step_name
146
+ }).not_to change{ step_args.first }
122
147
  end
123
148
 
124
149
  it "allows puts" do
@@ -9,6 +9,26 @@ module Cucumber
9
9
  end
10
10
 
11
11
  describe "#to_s" do
12
+ it "does not touch positive lookahead captures" do
13
+ expect(transform(/^xy(?=z)/).to_s).to eq "xy(?=z)"
14
+ end
15
+
16
+ it "does not touch negative lookahead captures" do
17
+ expect(transform(/^xy(?!z)/).to_s).to eq "xy(?!z)"
18
+ end
19
+
20
+ it "does not touch positive lookbehind captures" do
21
+ expect(transform(/^xy(?<=z)/).to_s).to eq "xy(?<=z)"
22
+ end
23
+
24
+ it "does not touch negative lookbehind captures" do
25
+ expect(transform(/^xy(?<!z)/).to_s).to eq "xy(?<!z)"
26
+ end
27
+
28
+ it "converts named captures" do
29
+ expect(transform(/^(?<str>xyz)/).to_s).to eq "(?:<str>xyz)"
30
+ end
31
+
12
32
  it "converts captures groups to non-capture groups" do
13
33
  expect(transform(/(a|b)bc/).to_s).to eq "(?:a|b)bc"
14
34
  end
@@ -27,7 +27,7 @@ module Cucumber
27
27
  @pattern = 'A "string" with 4 spaces'
28
28
 
29
29
  expect(snippet_text).to eq unindented(%{
30
- Given(/^A "(.*?)" with (\\d+) spaces$/) do |arg1, arg2|
30
+ Given(/^A "([^"]*)" with (\\d+) spaces$/) do |arg1, arg2|
31
31
  pending # Write code here that turns the phrase above into concrete actions
32
32
  end
33
33
  })
@@ -48,7 +48,7 @@ module Cucumber
48
48
  @multiline_argument = Core::Ast::DataTable.new([[]], Core::Ast::Location.new(''))
49
49
 
50
50
  expect(snippet_text).to eq unindented(%{
51
- Given(/^I have (\\d+) "(.*?)" cukes in (\\d+) "(.*?)"$/) do |arg1, arg2, arg3, arg4, table|
51
+ Given(/^I have (\\d+) "([^"]*)" cukes in (\\d+) "([^"]*)"$/) do |arg1, arg2, arg3, arg4, table|
52
52
  # table is a Cucumber::Core::Ast::DataTable
53
53
  pending # Write code here that turns the phrase above into concrete actions
54
54
  end
@@ -59,7 +59,7 @@ module Cucumber
59
59
  @pattern = 'A "first" arg'
60
60
 
61
61
  expect(snippet_text).to eq unindented(%{
62
- Given(/^A "(.*?)" arg$/) do |arg1|
62
+ Given(/^A "([^"]*)" arg$/) do |arg1|
63
63
  pending # Write code here that turns the phrase above into concrete actions
64
64
  end
65
65
  })
@@ -69,7 +69,7 @@ module Cucumber
69
69
  @pattern = 'A "first" and "second" arg'
70
70
 
71
71
  expect(snippet_text).to eq unindented(%{
72
- Given(/^A "(.*?)" and "(.*?)" arg$/) do |arg1, arg2|
72
+ Given(/^A "([^"]*)" and "([^"]*)" arg$/) do |arg1, arg2|
73
73
  pending # Write code here that turns the phrase above into concrete actions
74
74
  end
75
75
  })
@@ -90,7 +90,7 @@ module Cucumber
90
90
  @multiline_argument = Core::Ast::DataTable.new([[]], Core::Ast::Location.new(""))
91
91
 
92
92
  expect(snippet_text).to eq unindented(%{
93
- Given(/^A "(.*?)" arg$/) do |arg1, table|
93
+ Given(/^A "([^"]*)" arg$/) do |arg1, table|
94
94
  # table is a Cucumber::Core::Ast::DataTable
95
95
  pending # Write code here that turns the phrase above into concrete actions
96
96
  end
@@ -102,7 +102,7 @@ module Cucumber
102
102
  @multiline_argument = MultilineArgument.from("", Core::Ast::Location.new(""))
103
103
 
104
104
  expect(snippet_text).to eq unindented(%{
105
- Given(/^A "(.*?)" arg$/) do |arg1, string|
105
+ Given(/^A "([^"]*)" arg$/) do |arg1, string|
106
106
  pending # Write code here that turns the phrase above into concrete actions
107
107
  end
108
108
  })
@@ -0,0 +1,83 @@
1
+ require 'cucumber/running_test_case'
2
+ require 'cucumber/core'
3
+ require 'cucumber/core/gherkin/writer'
4
+
5
+ module Cucumber
6
+ describe RunningTestCase do
7
+ include Core
8
+ include Core::Gherkin::Writer
9
+
10
+ attr_accessor :wrapped_test_case, :core_test_case
11
+
12
+ before do
13
+ receiver = double.as_null_object
14
+ allow(receiver).to receive(:test_case) { |core_test_case|
15
+ self.core_test_case = core_test_case
16
+ self.wrapped_test_case = RunningTestCase.new(core_test_case)
17
+ }
18
+ compile [gherkin_doc], receiver
19
+ end
20
+
21
+ context "for a regular scenario" do
22
+ let(:gherkin_doc) do
23
+ gherkin do
24
+ feature "feature name" do
25
+ scenario "scenario name" do
26
+ step "passing"
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ it "sets the scenario name correctly" do
33
+ expect(wrapped_test_case.name).to eq "scenario name"
34
+ end
35
+
36
+ it "sets the feature name correctly" do
37
+ expect(wrapped_test_case.feature.name).to eq "feature name"
38
+ end
39
+
40
+ it "exposes properties of the test_case" do
41
+ expect(wrapped_test_case.location).to eq core_test_case.location
42
+ expect(wrapped_test_case.source).to eq core_test_case.source
43
+ expect(wrapped_test_case.keyword).to eq core_test_case.keyword
44
+ end
45
+ end
46
+
47
+ context "for a scenario outline" do
48
+ let(:gherkin_doc) do
49
+ gherkin do
50
+ feature "feature name" do
51
+ scenario_outline "scenario outline name" do
52
+ step "passing with <arg1> <arg2>"
53
+
54
+ examples "examples name" do
55
+ row "arg1", "arg2"
56
+ row "a", "b"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ it "sets the test case's name correctly" do
64
+ expect(wrapped_test_case.name).to eq "scenario outline name, examples name (#1)"
65
+ end
66
+
67
+ it "sets the feature name correctly" do
68
+ expect(wrapped_test_case.feature.name).to eq "feature name"
69
+ end
70
+
71
+ it "exposes properties of the test_case" do
72
+ expect(wrapped_test_case.location).to eq core_test_case.location
73
+ expect(wrapped_test_case.source).to eq core_test_case.source
74
+ expect(wrapped_test_case.keyword).to eq core_test_case.keyword
75
+ end
76
+
77
+ it "exposes the examples table row cell values" do
78
+ expect(wrapped_test_case.cell_values).to eq ["a", "b"]
79
+ end
80
+
81
+ end
82
+ end
83
+ end