aslakhellesoy-cucumber 0.1.12 → 0.1.13

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 (101) hide show
  1. data/History.txt +38 -3
  2. data/Manifest.txt +17 -1
  3. data/README.txt +2 -39
  4. data/bin/cucumber +1 -1
  5. data/examples/calculator_ruby_features/features/addition.rb +16 -0
  6. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
  7. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -0
  8. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +1 -0
  9. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +1 -0
  10. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +1 -0
  11. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -0
  12. data/examples/i18n/fr/features/addition.feature +13 -11
  13. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +6 -2
  14. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +1 -0
  15. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -0
  16. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +2 -0
  17. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +1 -0
  18. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +1 -0
  19. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -0
  20. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -0
  21. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -0
  22. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +1 -0
  23. data/examples/selenium/features/search.feature +1 -1
  24. data/examples/selenium/features/step_definitons/stories_steps.rb +2 -3
  25. data/examples/tickets/features/lib/eatting_machine.rb +18 -0
  26. data/examples/tickets/features/lib/pantry.rb +20 -0
  27. data/examples/tickets/features/scenario_outline.feature +64 -0
  28. data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +34 -0
  29. data/examples/tickets/features/step_definitons/tickets_steps.rb +4 -0
  30. data/gem_tasks/fix_cr_lf.rake +1 -1
  31. data/gem_tasks/yard.rake +8 -0
  32. data/lib/autotest/cucumber_mixin.rb +3 -3
  33. data/lib/cucumber/broadcaster.rb +1 -1
  34. data/lib/cucumber/cli.rb +87 -42
  35. data/lib/cucumber/core_ext/exception.rb +20 -0
  36. data/lib/cucumber/core_ext/string.rb +1 -1
  37. data/lib/cucumber/executor.rb +35 -18
  38. data/lib/cucumber/formatters/ansicolor.rb +65 -74
  39. data/lib/cucumber/formatters/html_formatter.rb +33 -10
  40. data/lib/cucumber/formatters/pretty_formatter.rb +58 -16
  41. data/lib/cucumber/formatters/progress_formatter.rb +3 -0
  42. data/lib/cucumber/formatters/unicode.rb +27 -0
  43. data/lib/cucumber/languages.yml +6 -4
  44. data/lib/cucumber/platform.rb +1 -0
  45. data/lib/cucumber/rails/world.rb +6 -6
  46. data/lib/cucumber/step_mother.rb +3 -0
  47. data/lib/cucumber/tree/feature.rb +28 -2
  48. data/lib/cucumber/tree/scenario.rb +62 -1
  49. data/lib/cucumber/tree/step.rb +32 -1
  50. data/lib/cucumber/treetop_parser/feature.treetop.erb +54 -7
  51. data/lib/cucumber/treetop_parser/feature_ar.rb +377 -18
  52. data/lib/cucumber/treetop_parser/feature_cy.rb +377 -18
  53. data/lib/cucumber/treetop_parser/feature_da.rb +377 -18
  54. data/lib/cucumber/treetop_parser/feature_de.rb +377 -18
  55. data/lib/cucumber/treetop_parser/feature_en-lol.rb +377 -18
  56. data/lib/cucumber/treetop_parser/feature_en-tx.rb +377 -18
  57. data/lib/cucumber/treetop_parser/feature_en.rb +377 -18
  58. data/lib/cucumber/treetop_parser/feature_es.rb +377 -18
  59. data/lib/cucumber/treetop_parser/feature_et.rb +377 -18
  60. data/lib/cucumber/treetop_parser/feature_fr.rb +389 -30
  61. data/lib/cucumber/treetop_parser/feature_id.rb +377 -18
  62. data/lib/cucumber/treetop_parser/feature_it.rb +377 -18
  63. data/lib/cucumber/treetop_parser/feature_ja.rb +377 -18
  64. data/lib/cucumber/treetop_parser/feature_lt.rb +377 -18
  65. data/lib/cucumber/treetop_parser/feature_nl.rb +377 -18
  66. data/lib/cucumber/treetop_parser/feature_no.rb +377 -18
  67. data/lib/cucumber/treetop_parser/feature_pl.rb +377 -18
  68. data/lib/cucumber/treetop_parser/feature_pt.rb +377 -18
  69. data/lib/cucumber/treetop_parser/feature_ro.rb +377 -18
  70. data/lib/cucumber/treetop_parser/feature_ro2.rb +377 -18
  71. data/lib/cucumber/treetop_parser/feature_ru.rb +377 -18
  72. data/lib/cucumber/treetop_parser/feature_se.rb +377 -18
  73. data/lib/cucumber/treetop_parser/feature_zh-CN.rb +377 -18
  74. data/lib/cucumber/version.rb +1 -1
  75. data/lib/cucumber/world/pending.rb +22 -0
  76. data/lib/cucumber/world.rb +1 -0
  77. data/lib/cucumber.rb +2 -0
  78. data/rails_generators/cucumber/templates/env.rb +1 -0
  79. data/rails_generators/feature/feature_generator.rb +22 -2
  80. data/rails_generators/feature/templates/feature.erb +15 -12
  81. data/rails_generators/feature/templates/steps.erb +16 -14
  82. data/spec/cucumber/cli_spec.rb +87 -6
  83. data/spec/cucumber/executor_spec.rb +102 -30
  84. data/spec/cucumber/formatters/ansicolor_spec.rb +10 -10
  85. data/spec/cucumber/formatters/html_formatter_spec.rb +30 -0
  86. data/spec/cucumber/formatters/pretty_formatter_spec.rb +139 -4
  87. data/spec/cucumber/formatters/progress_formatter_spec.rb +16 -0
  88. data/spec/cucumber/tree/feature_spec.rb +84 -5
  89. data/spec/cucumber/tree/row_scenario_outline_spec.rb +73 -0
  90. data/spec/cucumber/tree/row_step_outline_spec.rb +38 -0
  91. data/spec/cucumber/tree/scenario_outline_spec.rb +50 -0
  92. data/spec/cucumber/tree/step_outline_spec.rb +17 -0
  93. data/spec/cucumber/tree/step_spec.rb +9 -0
  94. data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
  95. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +22 -0
  96. data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
  97. data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
  98. data/spec/cucumber/world/pending_spec.rb +46 -0
  99. data/spec/spec_helper.rb +2 -1
  100. metadata +19 -4
  101. data/TODO.txt +0 -26
@@ -17,12 +17,12 @@ module Cucumber
17
17
  end
18
18
 
19
19
  before(:each) do
20
- Kernel.stub!(:exit)
20
+ Kernel.stub!(:exit).and_return(nil)
21
21
  end
22
22
 
23
- def given_cucumber_yml_defined_as(hash)
23
+ def given_cucumber_yml_defined_as(hash_or_string)
24
24
  File.stub!(:exist?).and_return(true)
25
- cucumber_yml = hash.to_yaml
25
+ cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string
26
26
  IO.stub!(:read).with('cucumber.yml').and_return(cucumber_yml)
27
27
  end
28
28
 
@@ -73,6 +73,18 @@ Defined profiles in cucumber.yml:
73
73
  error.string.should == "Profiles must be defined as a String. The 'foo' profile was [1, 2, 3] (Array).\n"
74
74
  end
75
75
 
76
+ it "should provide a helpful error message when a specified profile exists but is nil or blank" do
77
+ [nil, ' '].each do |bad_input|
78
+ cli = CLI.new(StringIO.new, error = StringIO.new)
79
+
80
+ given_cucumber_yml_defined_as({'foo' => bad_input})
81
+
82
+ cli.parse_options!(%w{--profile foo})
83
+
84
+ error.string.should match(/The 'foo' profile in cucumber.yml was blank. Please define the command line arguments for the 'foo' profile in cucumber.yml./)
85
+ end
86
+ end
87
+
76
88
  it "should provide a helpful error message when no YAML file exists and a profile is specified" do
77
89
  cli = CLI.new(StringIO.new, error = StringIO.new)
78
90
 
@@ -80,7 +92,32 @@ Defined profiles in cucumber.yml:
80
92
 
81
93
  cli.parse_options!(%w{--profile i_do_not_exist})
82
94
 
83
- error.string.should match(/cucumber.yml was not found. Please define your 'i_do_not_exist' and other profiles in cucumber.yml./)
95
+ error.string.should match(/cucumber.yml was not found. Please refer to cucumber's documentaion on defining profiles in cucumber.yml./)
96
+ end
97
+
98
+ it "should provide a helpful error message when cucumber.yml is blank or malformed" do
99
+ expected_error_message = /cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentaion on correct profile usage./
100
+
101
+ ['', 'sfsadfs', "--- \n- an\n- array\n", "---dddfd"].each do |bad_input|
102
+ cli = CLI.new(StringIO.new, error = StringIO.new)
103
+
104
+ given_cucumber_yml_defined_as(bad_input)
105
+ cli.parse_options!([])
106
+
107
+ error.string.should match(expected_error_message)
108
+ end
109
+ end
110
+
111
+ it "should procide a helpful error message when the YAML can not be parsed" do
112
+ expected_error_message = /cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentaion on correct profile usage./
113
+ cli = CLI.new(StringIO.new, error = StringIO.new)
114
+
115
+ given_cucumber_yml_defined_as("input that causes an exception in YAML loading")
116
+ YAML.should_receive(:load).and_raise Exception
117
+
118
+ cli.parse_options!([])
119
+
120
+ error.string.should match(expected_error_message)
84
121
  end
85
122
 
86
123
  it "should accept --no-source option" do
@@ -112,6 +149,21 @@ Defined profiles in cucumber.yml:
112
149
  cli.options[:verbose].should be_true
113
150
  end
114
151
 
152
+ it "should require files in support paths first" do
153
+ File.stub!(:directory?).and_return(true)
154
+ Dir.stub!(:[]).and_return(["/features/step_definitions/foo.rb","/features/support/env.rb"])
155
+
156
+ cli = CLI.new(StringIO.new)
157
+ cli.parse_options!(%w{--require /features})
158
+
159
+ cli.should_receive(:require).twice.with(/treetop_parser/).ordered
160
+ cli.should_receive(:require).with("/features/support/env.rb").ordered
161
+ cli.should_receive(:require).with("/features/step_definitions/foo.rb").ordered
162
+ cli.should_receive(:require).with("spec/expectations/differs/default").ordered
163
+
164
+ cli.execute!(stub('step mother'), mock_executor, mock_features)
165
+ end
166
+
115
167
  describe "verbose mode" do
116
168
 
117
169
  before(:each) do
@@ -384,6 +436,36 @@ Defined profiles in cucumber.yml:
384
436
  cli.execute!(stub('step mother'), mock_executor, stub('features'))
385
437
  end
386
438
 
439
+ describe "--backtrace" do
440
+ before do
441
+ Exception.cucumber_full_backtrace = false
442
+ end
443
+
444
+ it "should show full backtrace when --backtrace is present" do
445
+ cli = CLI.new
446
+ cli.parse_options!(['--backtrace'])
447
+ begin
448
+ "x".should == "y"
449
+ rescue => e
450
+ e.cucumber_backtrace[0].should_not == "#{__FILE__}:#{__LINE__ - 2}"
451
+ end
452
+ end
453
+
454
+ it "should strip gems when --backtrace is absent" do
455
+ cli = CLI.new
456
+ cli.parse_options!(['--'])
457
+ begin
458
+ "x".should == "y"
459
+ rescue => e
460
+ e.cucumber_backtrace[0].should == "#{__FILE__}:#{__LINE__ - 2}"
461
+ end
462
+ end
463
+
464
+ after do
465
+ Exception.cucumber_full_backtrace = false
466
+ end
467
+ end
468
+
387
469
  describe "example.feature:line file arguments" do
388
470
 
389
471
  it "should extract line numbers" do
@@ -413,8 +495,7 @@ Defined profiles in cucumber.yml:
413
495
 
414
496
  cli.options[:lines_for_features].should == {'example.feature' => [11, 12]}
415
497
  end
416
-
417
- end
498
+ end
418
499
 
419
500
  it "should search for all features in the specified directory" do
420
501
  cli = CLI.new
@@ -10,10 +10,24 @@ module Cucumber
10
10
  :name => 'test',
11
11
  :accept => nil,
12
12
  :steps => [],
13
- :pending? => true
13
+ :pending? => true,
14
+ :outline? => false,
14
15
  }.merge(stubs))
15
16
  end
16
17
 
18
+ def parse_features(feature_file)
19
+ parser = TreetopParser::FeatureParser.new
20
+ feature = parser.parse_feature(feature_file)
21
+ end
22
+
23
+ before do
24
+ ::Term::ANSIColor.coloring = false
25
+ end
26
+
27
+ after do
28
+ ::Term::ANSIColor.coloring = true
29
+ end
30
+
17
31
  before do # TODO: Way more setup and duplication of lib code. Use lib code!
18
32
  @io = StringIO.new
19
33
  @step_mother = StepMother.new
@@ -21,9 +35,8 @@ module Cucumber
21
35
  @formatters = Broadcaster.new [Formatters::ProgressFormatter.new(@io)]
22
36
  @executor.formatters = @formatters
23
37
  @feature_file = File.dirname(__FILE__) + '/sell_cucumbers.feature'
24
- @parser = TreetopParser::FeatureParser.new
25
- @features = Tree::Features.new
26
- @feature = @parser.parse_feature(@feature_file)
38
+ @features = features = Tree::Features.new
39
+ @feature = parse_features(@feature_file)
27
40
  @features << @feature
28
41
  end
29
42
 
@@ -46,7 +59,7 @@ module Cucumber
46
59
 
47
60
  1)
48
61
  dang
49
- #{__FILE__}:43:in `Then /I should owe (\\d*) cucumbers/'
62
+ #{__FILE__}:56:in `Then /I should owe (\\d*) cucumbers/'
50
63
  #{@feature_file}:9:in `Then I should owe 7 cucumbers'
51
64
  })
52
65
  end
@@ -75,6 +88,13 @@ dang
75
88
  world.doit.should == "dunit"
76
89
  world.beatit.should == "beatenit"
77
90
  end
91
+
92
+ it "should add support for calling 'pending' from world" do
93
+ world = @executor.create_world
94
+
95
+ world.should respond_to(:pending)
96
+ end
97
+
78
98
  end
79
99
 
80
100
  describe "visiting feature" do
@@ -162,6 +182,54 @@ dang
162
182
  end
163
183
 
164
184
  end
185
+
186
+ describe "visiting step outline" do
187
+
188
+ it "should trace step" do
189
+ mock_formatter = mock('formatter')
190
+ @executor.formatters = mock_formatter
191
+ mock_step_outline = mock('step outline', :regexp_args_proc => [])
192
+
193
+ mock_formatter.should_receive(:step_traced)
194
+
195
+ @executor.visit_step_outline(mock_step_outline)
196
+ end
197
+
198
+ end
199
+
200
+ describe "visit forced pending step" do
201
+
202
+ before(:each) do
203
+ @executor.formatters = mock('formatter', :null_object => true)
204
+ end
205
+
206
+ it "should store the pending exception with the step" do
207
+ mock_step = mock("mock step", :regexp_args_proc => nil)
208
+ pending_exception = ForcedPending.new("implement me")
209
+ mock_step.stub!(:execute_in).and_raise(pending_exception)
210
+
211
+ mock_step.should_receive(:'error=').with(pending_exception)
212
+
213
+ @executor.visit_step(mock_step)
214
+ end
215
+
216
+ describe "after failed/pending step" do
217
+
218
+ it "should store the pending exception with the step" do
219
+ mock_step_1 = mock("mock step", :null_object => true)
220
+ mock_step_2 = mock("mock step", :regexp_args_proc => nil)
221
+ pending_exception = ForcedPending.new("implement me")
222
+ mock_step_1.stub!(:execute_in).and_raise(StandardError)
223
+ mock_step_2.stub!(:execute_in).and_raise(pending_exception)
224
+
225
+ mock_step_2.should_receive(:'error=').with(pending_exception)
226
+
227
+ @executor.visit_step(mock_step_1)
228
+ @executor.visit_step(mock_step_2)
229
+ end
230
+
231
+ end
232
+ end
165
233
 
166
234
  describe "visiting row scenarios" do
167
235
 
@@ -175,40 +243,44 @@ dang
175
243
  }.merge(stubs))
176
244
  end
177
245
 
178
- describe "without having first run the matching regular scenario" do
179
-
246
+ %w{regular_scenario scenario_outline}.each do |regular_or_outline|
247
+
180
248
  before(:each) do
181
- @regular_scenario = Tree::Scenario.new(nil, 'test', 1)
249
+ @scenario = mock("#{regular_or_outline} scenario", :name => 'test', :at_line? => true, :pending? => false, :accept => nil)
250
+
182
251
  @executor.lines_for_features = Hash.new([5])
183
- @executor.visit_regular_scenario(@regular_scenario)
252
+ @executor.send("visit_#{regular_or_outline}".to_sym, @scenario)
184
253
  end
254
+
255
+ describe "without having first run the matching #{regular_or_outline}" do
185
256
 
186
- it "should run the regular scenario before the row scenario" do
187
- @regular_scenario.should_receive(:accept)
188
- row_scenario = mock_row_scenario(:name => 'test', :at_line? => true)
189
- row_scenario.should_receive(:accept)
190
- @executor.visit_row_scenario(row_scenario)
191
- end
257
+ it "should run the #{regular_or_outline} before the row scenario" do
258
+ @scenario.should_receive(:accept)
259
+ row_scenario = mock_row_scenario(:name => 'test', :at_line? => true)
260
+ row_scenario.should_receive(:accept)
192
261
 
193
- it "should run the row scenario after running the regular scenario" do
194
- row_scenario = mock_row_scenario(:at_line? => true)
195
- row_scenario.should_receive(:accept)
196
- @executor.visit_row_scenario(row_scenario)
197
- end
198
-
199
- end
262
+ @executor.visit_row_scenario(row_scenario)
263
+ end
264
+
265
+ it "should run the row scenario after running the #{regular_or_outline}" do
266
+ row_scenario = mock_row_scenario(:at_line? => true)
267
+ row_scenario.should_receive(:accept)
268
+ @scenario.stub!(:accept)
200
269
 
201
- describe "having run matching regular scenario" do
270
+ @executor.visit_row_scenario(row_scenario)
271
+ end
202
272
 
203
- it "should not run the regular scenario if it has already run" do
204
- scenario = Tree::Scenario.new(nil, 'test', 1)
205
- @executor.visit_regular_scenario(scenario)
273
+ end
206
274
 
207
- scenario.should_not_receive(:accept)
275
+ describe "having run matching #{regular_or_outline}" do
276
+
277
+ it "should not run the regular scenario if it has already run" do
278
+ @scenario.should_not_receive(:accept)
208
279
 
209
- @executor.visit_row_scenario(mock_row_scenario(:name => 'test', :at_line? => true, :accept => nil))
210
- end
280
+ @executor.visit_row_scenario(mock_row_scenario(:name => 'test', :at_line? => true, :accept => nil))
281
+ end
211
282
 
283
+ end
212
284
  end
213
285
  end
214
286
 
@@ -293,6 +365,6 @@ dang
293
365
  @executor.visit_features(@features)
294
366
  end
295
367
  end
296
-
368
+
297
369
  end
298
370
  end
@@ -6,24 +6,24 @@ module Cucumber
6
6
  describe ANSIColor do
7
7
  include ANSIColor
8
8
 
9
- before do
9
+ after do
10
10
  ::Term::ANSIColor.coloring = true
11
11
  end
12
12
 
13
- after do
14
- ::Term::ANSIColor.coloring = false
13
+ it "should wrap passed_param with bold green and reset to green" do
14
+ passed_param("foo").should == "\e[32m\e[1mfoo\e[0m\e[0m\e[32m"
15
15
  end
16
-
17
- it "should wrap string in bold green for #passed with string arg" do
18
- passed("foo").should == "\e[0m\e[1m\e[32mfoo\e[0m\e[0m"
16
+
17
+ it "should wrap passed in green" do
18
+ passed("foo").should == "\e[32mfoo\e[0m"
19
19
  end
20
20
 
21
- it "should return bold green without wrapping for #passed without arg" do
22
- passed.should == "\e[0m\e[1m\e[32m"
21
+ it "should not reset passed if there are no arguments" do
22
+ passed.should == "\e[32m"
23
23
  end
24
24
 
25
- it "should return grey for #comment" do
26
- comment("foo").should == "\e[0m\e[90mfoo\e[0m"
25
+ it "should wrap comments in grey" do
26
+ comment("foo").should == "\e[90mfoo\e[0m"
27
27
  end
28
28
 
29
29
  it "should not generate ansi codes when colors are disabled" do
@@ -33,6 +33,18 @@ module Cucumber
33
33
 
34
34
  describe HtmlFormatter do
35
35
  SIMPLE_DIR = File.dirname(__FILE__) + '/../../../examples/simple'
36
+
37
+ def mock_row_step(stubs = {})
38
+ mock('row step', {:id => 1, :outline? => true, :regexp_args_proc => [nil, nil, nil], :visible_args => []}.merge(stubs))
39
+ end
40
+
41
+ def mock_step(stubs = {})
42
+ mock('step', {:id => 1, :keyword => 'Given', :format => '', :regexp_args_proc => [nil, nil, nil]}.merge(stubs))
43
+ end
44
+
45
+ def mock_scenario_outline(stubs = {})
46
+ mock('scenario outline', {:table_header => nil, :accept => nil}.merge(stubs))
47
+ end
36
48
 
37
49
  before do
38
50
  p = Cucumber::TreetopParser::FeatureParser.new
@@ -68,6 +80,24 @@ module Cucumber
68
80
  @io.string.should include(column_header)
69
81
  end
70
82
  end
83
+
84
+ it "should only show arguments in a row step outline that are visible" do
85
+ @formatter.visit_row_step(mock_row_step(:outline? => true, :regexp_args_proc => [nil, ['mouse', 'monkey'], nil], :visible_args => ['mouse']))
86
+
87
+ @io.string.should_not =~ /monkey/
88
+ end
89
+
90
+ it "should escape placeholders in step outline" do
91
+ CGI.should_receive(:escapeHTML).with("I'm a <placeholder>")
92
+
93
+ @formatter.visit_step_outline(mock_step(:format => "I'm a <placeholder>"))
94
+ end
95
+
96
+ it "should show Scenario Outline keyword for scenario outline" do
97
+ @formatter.visit_scenario_outline(mock_scenario_outline(:name => "outline", :accept => nil))
98
+
99
+ @io.string.should =~ /Scenario Outline/
100
+ end
71
101
 
72
102
  end
73
103
  end
@@ -13,9 +13,16 @@ module Cucumber
13
13
  :padding_length => 2,
14
14
  :file => 'test',
15
15
  :line => 1,
16
- :row? => false}.merge(stubs))
16
+ :row? => false,
17
+ :forced_to_pending? => false,
18
+ :regexp_args_proc => [nil, nil, mock_proc],
19
+ :outline? => false}.merge(stubs))
17
20
  end
18
21
 
22
+ def mock_step_outline(stubs={})
23
+ mock_step({:outline? => true}.merge(stubs))
24
+ end
25
+
19
26
  def mock_scenario(stubs={})
20
27
  stub('scenario', {
21
28
  :name => 'test',
@@ -23,7 +30,12 @@ module Cucumber
23
30
  :pending? => false,
24
31
  :file => 'file',
25
32
  :line => 1,
26
- :padding_length => 2}.merge(stubs))
33
+ :padding_length => 2,
34
+ :outline? => false}.merge(stubs))
35
+ end
36
+
37
+ def mock_scenario_outline(stubs={})
38
+ mock_scenario({:outline? => true}.merge(stubs))
27
39
  end
28
40
 
29
41
  def mock_feature(stubs={})
@@ -36,8 +48,16 @@ module Cucumber
36
48
  :backtrace => 'example backtrace'}.merge(stubs))
37
49
  end
38
50
 
39
- def mock_proc
40
- stub(Proc, :to_comment_line => '# steps/example_steps.rb:11')
51
+ def mock_proc(stubs={})
52
+ stub(Proc, {:to_comment_line => '# steps/example_steps.rb:11'}.merge(stubs))
53
+ end
54
+
55
+ before do
56
+ ::Term::ANSIColor.coloring = false
57
+ end
58
+
59
+ after do
60
+ ::Term::ANSIColor.coloring = true
41
61
  end
42
62
 
43
63
  it "should print step file and line when passed" do
@@ -81,6 +101,27 @@ module Cucumber
81
101
  io.string.should =~ /\n\n Scenario: spacey/
82
102
  end
83
103
 
104
+ it "should distinguish a scenario outline from a scenario when displaying keywords" do
105
+ io = StringIO.new
106
+ formatter = PrettyFormatter.new(io, mock('step_mother'))
107
+
108
+ formatter.scenario_executing(mock_scenario_outline(:name => 'outliner'))
109
+
110
+ io.string.should =~ /Scenario Outline: outliner/
111
+ end
112
+
113
+ %w{passed pending failed skipped}.each do |result|
114
+ it "should only show visible placeholder values in #{result} step " do
115
+ io = StringIO.new
116
+ formatter = PrettyFormatter.new(io, mock('step_mother'))
117
+ formatter.instance_variable_set('@table_column_widths', [0])
118
+
119
+ formatter.send("step_#{result}".to_sym, mock_step_outline(:row? => true, :visible_args => ['monkey'], :padding_length => 2), nil, ['mouse'])
120
+
121
+ io.string.should =~ /monkey/
122
+ end
123
+ end
124
+
84
125
  {'should' => true, 'should not' => false}.each do |should_or_should_not, show_snippet|
85
126
  describe "snippets option #{show_snippet}" do
86
127
 
@@ -136,6 +177,12 @@ module Cucumber
136
177
  end
137
178
  end
138
179
 
180
+ it "should display feature file and line for step outline" do
181
+ @formatter.step_traced(mock_step_outline(:file => "features/example.feature", :line => 11, :padding_length => 2), nil, nil)
182
+
183
+ @io.string.should include("Given formatted yes # features/example.feature:11")
184
+ end
185
+
139
186
  it "should display feature file and line for pending step" do
140
187
  @formatter.step_pending(mock_step(:name => 'test', :file => 'features/example.feature', :line => 5, :padding_length => 2), nil, nil)
141
188
 
@@ -199,6 +246,94 @@ module Cucumber
199
246
  }.should_not raise_error(TypeError)
200
247
  end
201
248
 
249
+ describe "pending messages" do
250
+
251
+ before(:each) do
252
+ @io = StringIO.new
253
+ @formatter = PrettyFormatter.new @io, mock('step_mother')
254
+ end
255
+
256
+ it "should show pending message for step" do
257
+ @formatter.step_pending(mock_step(:keyword => 'Given', :forced_to_pending? => true, :error => ForcedPending.new("please implement me")), /yatta/, nil)
258
+
259
+ @formatter.dump
260
+
261
+ @io.string.should include("Given /yatta/ (please implement me)")
262
+ end
263
+
264
+ it "should show pending step's file and line" do
265
+ @formatter.step_pending(mock_step(:forced_to_pending? => true, :error => ForcedPending.new("please implement me"),
266
+ :regexp_args_proc => [nil, nil, mock_proc(:to_comment_line => "steps/example_steps.rb:11")]), nil, nil)
267
+
268
+ @formatter.dump
269
+
270
+ @io.string.should include("steps/example_steps.rb:11")
271
+ end
272
+
273
+ it "should not show duplicates" do
274
+ @formatter.step_pending(mock_step(:keyword => 'Given', :forced_to_pending? => true, :error => ForcedPending.new("please implement me")), /yatta/, [])
275
+ @formatter.step_pending(mock_step(:forced_to_pending? => true, :error => ForcedPending.new("please implement me"), :row? => true), /yatta/, [])
276
+
277
+ @formatter.dump
278
+
279
+ @io.string.scan(/please implement me/).length.should_not == 2
280
+ end
281
+
282
+ it "should ignore messages from steps that where not forced to pending" do
283
+ @formatter.step_pending(mock_step(:keyword => 'Given', :forced_to_pending? => false, :error => Pending.new("do not show me")), nil, [])
284
+
285
+ @formatter.dump
286
+
287
+ @io.string.should_not include("do not show me")
288
+ end
289
+
290
+ end
291
+
292
+ describe "no pending messages" do
293
+
294
+ it "should not show any pending message information" do
295
+ io = StringIO.new
296
+ formatter = PrettyFormatter.new io, mock('step_mother')
297
+
298
+ formatter.dump
299
+
300
+ io.string.should_not include("Pending Notes:\n")
301
+ end
302
+
303
+ end
304
+
305
+ it "should show number of pending steps that have no step definition" do
306
+ io = StringIO.new
307
+ formatter = PrettyFormatter.new io, mock('step_mother')
308
+
309
+ formatter.step_pending(mock_step(:error => ForcedPending.new, :forced_to_pending? => true), nil, [])
310
+ formatter.step_pending(mock_step(:error => Pending.new, :forced_to_pending? => false), nil, [])
311
+
312
+ formatter.dump
313
+
314
+ io.string.should include("1 with no step definition")
315
+ end
316
+
317
+ describe "colour" do
318
+
319
+ before(:all) do
320
+ Term::ANSIColor.coloring = true
321
+ end
322
+
323
+ after(:all) do
324
+ Term::ANSIColor.coloring = false
325
+ end
326
+
327
+ it "should show the scenario outline keyword and title as pending blue" do
328
+ ::Term::ANSIColor.coloring = true
329
+ io = StringIO.new
330
+ formatter = PrettyFormatter.new io, mock('step_mother')
331
+ formatter.scenario_executing(mock_scenario(:outline? => true, :name => 'blue'))
332
+
333
+ io.string.should =~ /\e\[36m\s*Scenario Outline: blue\e\[0m/
334
+ end
335
+
336
+ end
202
337
  end
203
338
  end
204
339
  end
@@ -3,6 +3,14 @@ require File.dirname(__FILE__) + '/../../spec_helper'
3
3
  module Cucumber
4
4
  module Formatters
5
5
  describe ProgressFormatter do
6
+ before do
7
+ ::Term::ANSIColor.coloring = false
8
+ end
9
+
10
+ after do
11
+ ::Term::ANSIColor.coloring = true
12
+ end
13
+
6
14
  it "should print . when passed" do
7
15
  io = StringIO.new
8
16
  formatter = ProgressFormatter.new io
@@ -41,6 +49,14 @@ module Cucumber
41
49
  io.string.should =~ /^_$/
42
50
  end
43
51
 
52
+ it "should print nothing when traced" do
53
+ io = StringIO.new
54
+ formatter = ProgressFormatter.new io
55
+ formatter.step_traced(nil, nil, nil)
56
+
57
+ io.string.should =~ /^$/
58
+ end
59
+
44
60
  describe "scenario without any steps" do
45
61
  before :each do
46
62
  @io = StringIO.new