square-cucumber 0.3.12.2 → 0.3.93.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/History.txt +117 -4
  2. data/Manifest.txt +11 -0
  3. data/Rakefile +1 -1
  4. data/config/hoe.rb +3 -2
  5. data/cucumber.yml +2 -2
  6. data/examples/i18n/ko/features/addition.feature +5 -5
  7. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
  8. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +1 -1
  9. data/examples/i18n/pt/features/adicao.feature +4 -4
  10. data/examples/self_test/features/support/env.rb +2 -1
  11. data/examples/sinatra/features/support/env.rb +7 -1
  12. data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
  13. data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
  14. data/examples/tickets/features/step_definitons/tickets_steps.rb +15 -0
  15. data/examples/tickets/features/table_diffing.feature +13 -0
  16. data/examples/watir/features/step_definitons/search_steps.rb +5 -1
  17. data/features/cucumber_cli_diff_disabled.feature +2 -1
  18. data/features/html_formatter/a.html +5 -7
  19. data/features/junit_formatter.feature +21 -14
  20. data/features/profiles.feature +99 -0
  21. data/features/rake_task.feature +28 -0
  22. data/features/step_definitions/cucumber_steps.rb +28 -15
  23. data/features/steps_formatter.feature +25 -0
  24. data/features/support/env.rb +9 -5
  25. data/features/table_diffing.feature +45 -0
  26. data/features/unicode_table.feature +35 -0
  27. data/features/work_in_progress.feature +1 -0
  28. data/gem_tasks/contributors.rake +4 -0
  29. data/lib/cucumber/ast/background.rb +1 -0
  30. data/lib/cucumber/ast/comment.rb +1 -0
  31. data/lib/cucumber/ast/examples.rb +1 -0
  32. data/lib/cucumber/ast/feature.rb +10 -0
  33. data/lib/cucumber/ast/features.rb +6 -1
  34. data/lib/cucumber/ast/outline_table.rb +4 -1
  35. data/lib/cucumber/ast/py_string.rb +1 -1
  36. data/lib/cucumber/ast/scenario.rb +1 -0
  37. data/lib/cucumber/ast/scenario_outline.rb +2 -0
  38. data/lib/cucumber/ast/step.rb +5 -1
  39. data/lib/cucumber/ast/step_collection.rb +1 -0
  40. data/lib/cucumber/ast/step_invocation.rb +1 -0
  41. data/lib/cucumber/ast/table.rb +306 -52
  42. data/lib/cucumber/ast/tags.rb +1 -0
  43. data/lib/cucumber/ast/visitor.rb +2 -1
  44. data/lib/cucumber/cli/configuration.rb +28 -278
  45. data/lib/cucumber/cli/drb_client.rb +3 -1
  46. data/lib/cucumber/cli/language_help_formatter.rb +9 -7
  47. data/lib/cucumber/cli/main.rb +16 -2
  48. data/lib/cucumber/cli/options.rb +370 -0
  49. data/lib/cucumber/cli/profile_loader.rb +65 -0
  50. data/lib/cucumber/core_ext/instance_exec.rb +8 -5
  51. data/lib/cucumber/feature_file.rb +7 -1
  52. data/lib/cucumber/filter.rb +2 -2
  53. data/lib/cucumber/formatter/ansicolor.rb +42 -9
  54. data/lib/cucumber/formatter/console.rb +1 -1
  55. data/lib/cucumber/formatter/html.rb +12 -10
  56. data/lib/cucumber/formatter/junit.rb +63 -26
  57. data/lib/cucumber/formatter/pretty.rb +20 -5
  58. data/lib/cucumber/formatter/progress.rb +1 -1
  59. data/lib/cucumber/formatter/steps.rb +49 -0
  60. data/lib/cucumber/languages.yml +6 -6
  61. data/lib/cucumber/parser/feature.rb +90 -63
  62. data/lib/cucumber/parser/feature.tt +28 -1
  63. data/lib/cucumber/parser/i18n/language.rb +12 -5
  64. data/lib/cucumber/parser/table.rb +25 -25
  65. data/lib/cucumber/rake/task.rb +9 -3
  66. data/lib/cucumber/step_definition.rb +1 -1
  67. data/lib/cucumber/step_match.rb +1 -1
  68. data/lib/cucumber/step_mother.rb +3 -1
  69. data/lib/cucumber/version.rb +2 -2
  70. data/lib/cucumber/webrat/table_locator.rb +66 -0
  71. data/rails_generators/cucumber/cucumber_generator.rb +5 -1
  72. data/rails_generators/cucumber/templates/cucumber +3 -2
  73. data/rails_generators/cucumber/templates/cucumber.rake +18 -6
  74. data/rails_generators/cucumber/templates/cucumber_environment.rb +7 -4
  75. data/rails_generators/cucumber/templates/env.rb +1 -0
  76. data/rails_generators/cucumber/templates/spork_env.rb +1 -0
  77. data/rails_generators/cucumber/templates/webrat_steps.rb +22 -0
  78. data/rails_generators/feature/templates/feature.erb +1 -1
  79. data/rails_generators/feature/templates/steps.erb +2 -8
  80. data/spec/cucumber/ast/table_spec.rb +169 -0
  81. data/spec/cucumber/cli/configuration_spec.rb +144 -101
  82. data/spec/cucumber/cli/main_spec.rb +14 -5
  83. data/spec/cucumber/cli/options_spec.rb +311 -0
  84. data/spec/cucumber/cli/profile_loader_spec.rb +10 -0
  85. data/spec/cucumber/core_ext/proc_spec.rb +16 -2
  86. data/spec/cucumber/formatter/html_spec.rb +18 -0
  87. data/spec/cucumber/formatter/progress_spec.rb +2 -2
  88. data/spec/cucumber/parser/table_parser_spec.rb +1 -1
  89. data/spec/spec.opts +3 -1
  90. metadata +18 -4
  91. data/lib/cucumber/webrat/mechanize_world.rb +0 -82
@@ -13,13 +13,13 @@ module Cucumber
13
13
  @out = StringIO.new
14
14
  @err = StringIO.new
15
15
  Kernel.stub!(:exit).and_return(nil)
16
+ File.stub!(:exist?).and_return(false) # When Configuration checks for cucumber.yml
16
17
  end
17
18
 
18
19
  describe "verbose mode" do
19
20
 
20
21
  before(:each) do
21
22
  @empty_feature = Ast::Feature.new(nil, Ast::Comment.new(''), Ast::Tags.new(2, []), "Feature", [])
22
- Dir.stub!(:[])
23
23
  end
24
24
 
25
25
  it "should show ruby files required" do
@@ -94,6 +94,19 @@ module Cucumber
94
94
  end
95
95
  end
96
96
 
97
+ [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_klass|
98
+
99
+ it "rescues #{exception_klass}, prints the message to the error stream and returns true" do
100
+ Configuration.stub!(:new).and_return(configuration = mock('configuration'))
101
+ configuration.stub!(:parse!).and_raise(exception_klass.new("error message"))
102
+
103
+ main = Main.new('', out = StringIO.new, error = StringIO.new)
104
+ main.execute!(Object.new.extend(StepMother)).should be_true
105
+ error.string.should == "error message\n"
106
+ end
107
+ end
108
+
109
+
97
110
  context "--drb" do
98
111
  before(:each) do
99
112
  @configuration = mock('Configuration', :drb? => true, :null_object => true)
@@ -129,10 +142,6 @@ module Cucumber
129
142
  @err.string.should include("WARNING: error message. Running features locally:")
130
143
  end
131
144
 
132
- it "reparses the configuration since the --drb flag causes the initial parsing to short circuit" do
133
- @configuration.should_receive(:parse!).exactly(:twice)
134
- @cli.execute!(@step_mother)
135
- end
136
145
  end
137
146
  end
138
147
  end
@@ -0,0 +1,311 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'yaml'
3
+
4
+ module Cucumber
5
+ module Cli
6
+ describe Options do
7
+
8
+ def given_cucumber_yml_defined_as(hash_or_string)
9
+ File.stub!(:exist?).and_return(true)
10
+ cucumber_yml = hash_or_string.is_a?(Hash) ? hash_or_string.to_yaml : hash_or_string
11
+ IO.stub!(:read).with('cucumber.yml').and_return(cucumber_yml)
12
+ end
13
+
14
+ before(:each) do
15
+ File.stub!(:exist?).and_return(false) # Meaning, no cucumber.yml exists
16
+ Kernel.stub!(:exit).and_return(nil)
17
+ end
18
+
19
+ def output_stream
20
+ @output_stream ||= StringIO.new
21
+ end
22
+
23
+ def error_stream
24
+ @error_stream ||= StringIO.new
25
+ end
26
+
27
+ def options
28
+ @options ||= Options.new(output_stream, error_stream)
29
+ end
30
+
31
+ def prepare_args(args)
32
+ args.is_a?(Array) ? args : args.split(' ')
33
+ end
34
+
35
+ describe 'parsing' do
36
+
37
+ def when_parsing(args)
38
+ yield
39
+ options.parse!(prepare_args(args))
40
+ end
41
+
42
+ def after_parsing(args)
43
+ options.parse!(prepare_args(args))
44
+ yield
45
+ end
46
+
47
+ context '-r or --require' do
48
+ it "collects all specified files into an array" do
49
+ after_parsing ('--require some_file.rb -r another_file.rb') do
50
+ options[:require].should == ['some_file.rb', 'another_file.rb']
51
+ end
52
+ end
53
+ end
54
+
55
+ context '-l LANG or --language LANG' do
56
+ context "with LANG specified as 'help'" do
57
+ it "lists all known langues" do
58
+ when_parsing '-l help' do
59
+ LanguageHelpFormatter.should_receive(:list_languages).with(output_stream)
60
+ end
61
+ end
62
+ it "exits the program" do
63
+ when_parsing('--language help') { Kernel.should_receive(:exit) }
64
+ end
65
+ end
66
+ it "sets the langauge" do
67
+ after_parsing('-l en') { options[:lang].should == 'en' }
68
+ end
69
+ end
70
+
71
+ context '-f FORMAT or --format FORMAT' do
72
+ it "defaults the output for the formatter to the output stream (STDOUT)" do
73
+ after_parsing('-f pretty') { options[:formats].should == [['pretty', output_stream]] }
74
+ end
75
+ end
76
+
77
+ context '-o [FILE|DIR] or --out [FILE|DIR]' do
78
+ it "defaults the formatter to 'pretty' when not specified earlier" do
79
+ after_parsing('-o file.txt') { options[:formats].should == [['pretty', 'file.txt']] }
80
+ end
81
+ it "sets the output for the formatter defined immediatly before it" do
82
+ after_parsing('-f profile --out file.txt -f pretty -o file2.txt') do
83
+ options[:formats].should == [['profile', 'file.txt'], ['pretty', 'file2.txt']]
84
+ end
85
+ end
86
+ end
87
+
88
+ context '-t TAGS --tags TAGS' do
89
+ it "removes the @ prefix" do
90
+ after_parsing('-t @foo,bar') { options[:include_tags].should == ['foo','bar'] }
91
+ end
92
+ it "designates tags prefixed with ~ as tags to be excluded" do
93
+ after_parsing('--tags ~@foo,bar') { options[:exclude_tags].should == ['foo'] }
94
+ end
95
+ end
96
+
97
+ context '-n NAME or --name NAME' do
98
+ it "stores the provided names as regular expressions" do
99
+ after_parsing('-n foo --name bar') { options[:name_regexps].should == [/foo/,/bar/] }
100
+ end
101
+ end
102
+
103
+ context '-e PATTERN or --exclude PATTERN' do
104
+ it "stores the provided exclusions as regular expressions" do
105
+ after_parsing('-e foo --exclude bar') { options[:excludes].should == [/foo/,/bar/] }
106
+ end
107
+ end
108
+
109
+ context '-p PROFILE or --profile PROFILE' do
110
+
111
+ it "notifies the user that an individual profile is being used" do
112
+ given_cucumber_yml_defined_as({'foo' => [1,2,3]})
113
+ options.parse!(%w{--profile foo})
114
+ output_stream.string.should =~ /Using the foo profile...\n/
115
+ end
116
+
117
+ it "notifies the user when multiple profiles are being used" do
118
+ given_cucumber_yml_defined_as({'foo' => [1,2,3], 'bar' => ['v'], 'dog' => ['v']})
119
+ options.parse!(%w{--profile foo --profile bar --profile dog})
120
+ output_stream.string.should =~ /Using the foo, bar and dog profiles...\n/
121
+ end
122
+
123
+ it "notifies the user of all profiles being used, even when they are nested" do
124
+ given_cucumber_yml_defined_as('foo' => '-p bar', 'bar' => 'features')
125
+ after_parsing('-p foo') do
126
+ output_stream.string.should =~ /Using the foo and bar profiles.../
127
+ end
128
+ end
129
+
130
+ it "uses the default profile passed in during initialization if none are specified by the user" do
131
+ given_cucumber_yml_defined_as({'default' => '--require some_file'})
132
+
133
+ options = Options.new(output_stream, error_stream, :default_profile => 'default')
134
+ options.parse!(%w{--format progress})
135
+ options[:require].should include('some_file')
136
+ end
137
+
138
+ it "merges all uniq values from both cmd line and the profile" do
139
+ given_cucumber_yml_defined_as('foo' => %w[--verbose])
140
+ options.parse!(%w[--wip --profile foo])
141
+ options[:wip].should be_true
142
+ options[:verbose].should be_true
143
+ end
144
+
145
+ it "gives precendene to the origianl options' paths" do
146
+ given_cucumber_yml_defined_as('foo' => %w[features])
147
+ options.parse!(%w[my.feature -p foo])
148
+ options[:paths].should == %w[my.feature]
149
+ end
150
+
151
+ it "combines the require files of both" do
152
+ given_cucumber_yml_defined_as('bar' => %w[--require features -r dog.rb])
153
+ options.parse!(%w[--require foo.rb -p bar])
154
+ options[:require].should == %w[foo.rb features dog.rb]
155
+ end
156
+
157
+ it "combines the include_tags of both" do
158
+ given_cucumber_yml_defined_as('baz' => %w[-t bar])
159
+ options.parse!(%w[--tags foo -p baz])
160
+ options[:include_tags].should == %w[foo bar]
161
+ end
162
+
163
+ it "combines the exclude_tags of both" do
164
+ given_cucumber_yml_defined_as('baz' => %w[-t ~bar])
165
+ options.parse!(%w[--tags ~foo -p baz])
166
+ options[:exclude_tags].should == %w[foo bar]
167
+ end
168
+
169
+ it "only takes the paths from the original options, and disgregards the profiles" do
170
+ given_cucumber_yml_defined_as('baz' => %w[features])
171
+ options.parse!(%w[my.feature -p baz])
172
+ options[:paths].should == ['my.feature']
173
+ end
174
+
175
+ it "uses the paths from the profile when none are specified originally" do
176
+ given_cucumber_yml_defined_as('baz' => %w[some.feature])
177
+ options.parse!(%w[-p baz])
178
+ options[:paths].should == ['some.feature']
179
+ end
180
+
181
+ it "combines environment variables from the profile but gives precendene to cmd line args" do
182
+ given_cucumber_yml_defined_as('baz' => %w[FOO=bar CHEESE=swiss])
183
+ options.parse!(%w[-p baz CHEESE=cheddar BAR=foo])
184
+ options[:env_vars].should == {'BAR' => 'foo', 'FOO' => 'bar', 'CHEESE' => 'cheddar'}
185
+ end
186
+
187
+ it "disregards STDOUT formatter defined in profile when another is passed in (via cmd line)" do
188
+ given_cucumber_yml_defined_as({'foo' => %w[--format pretty]})
189
+ options.parse!(%w{--format progress --profile foo})
190
+ options[:formats].should == [['progress', output_stream]]
191
+ end
192
+
193
+ it "includes any non-STDOUT formatters from the profile" do
194
+ given_cucumber_yml_defined_as({'html' => %w[--format html -o features.html]})
195
+ options.parse!(%w{--format progress --profile html})
196
+ options[:formats].should == [['progress', output_stream], ['html', 'features.html']]
197
+ end
198
+
199
+ it "assumes all of the formatters defined in the profile when none are specified on cmd line" do
200
+ given_cucumber_yml_defined_as({'html' => %w[--format progress --format html -o features.html]})
201
+ options.parse!(%w{--profile html})
202
+ options[:formats].should == [['progress', output_stream], ['html', 'features.html']]
203
+ end
204
+
205
+ it "respects --quiet when defined in the profile" do
206
+ given_cucumber_yml_defined_as('foo' => '-q')
207
+ options.parse!(%w[-p foo])
208
+ options[:snippets].should be_false
209
+ options[:source].should be_false
210
+ end
211
+
212
+ end
213
+
214
+ context '-P or --no-profile' do
215
+
216
+ it "disables profiles" do
217
+ given_cucumber_yml_defined_as({'default' => '-v --require file_specified_in_default_profile.rb'})
218
+
219
+ after_parsing("-P --require some_file.rb") do
220
+ options[:require].should == ['some_file.rb']
221
+ end
222
+ end
223
+
224
+ it "notifies the user that the profiles are being disabled" do
225
+ given_cucumber_yml_defined_as({'default' => '-v'})
226
+
227
+ after_parsing("--no-profile --require some_file.rb") do
228
+ output_stream.string.should =~ /Disabling profiles.../
229
+ end
230
+ end
231
+
232
+ end
233
+
234
+ context '-b or --backtrace' do
235
+ it "turns on cucumber's full backtrace" do
236
+ when_parsing("-b") do
237
+ Exception.should_receive(:cucumber_full_backtrace=).with(true)
238
+ end
239
+ end
240
+ end
241
+
242
+ context '--version' do
243
+ it "displays Cucumber's version" do
244
+ after_parsing('--version') do
245
+ output_stream.string.should =~ /#{VERSION::STRING}/
246
+ end
247
+ end
248
+ it "exits the program" do
249
+ when_parsing('--version') { Kernel.should_receive(:exit) }
250
+ end
251
+ end
252
+
253
+ context 'environment variables (i.e. MODE=webrat)' do
254
+ it "places all of the environment variables into a hash" do
255
+ after_parsing('MODE=webrat FOO=bar') do
256
+ options[:env_vars].should == {'MODE' => 'webrat', 'FOO' => 'bar'}
257
+ end
258
+ end
259
+ end
260
+
261
+ it "assigns any extra arguments as paths to features" do
262
+ after_parsing('-f pretty my_feature.feature my_other_features') do
263
+ options[:paths].should == ['my_feature.feature', 'my_other_features']
264
+ end
265
+ end
266
+
267
+ it "does not mistake environment variables as feature paths" do
268
+ after_parsing('my_feature.feature FOO=bar') do
269
+ options[:paths].should == ['my_feature.feature']
270
+ end
271
+ end
272
+ end
273
+
274
+ describe '#expanded_args_without_drb' do
275
+ it "returns the orginal args in additon to the args from any profiles" do
276
+ given_cucumber_yml_defined_as('foo' => '-v',
277
+ 'bar' => '--wip -p baz',
278
+ 'baz' => '-r some_file.rb')
279
+ options.parse!(%w[features -p foo --profile bar])
280
+
281
+ options.expanded_args_without_drb.should == %w[features -v --wip -r some_file.rb]
282
+ end
283
+
284
+ it "removes the --drb flag so that the args can be safely passed to the drb server" do
285
+ given_cucumber_yml_defined_as('default' => 'features -f pretty --drb')
286
+ options.parse!(%w[--profile default])
287
+
288
+ options.expanded_args_without_drb.should == %w[features -f pretty]
289
+ end
290
+
291
+ it "contains the environment variables" do
292
+ options.parse!(%w[features FOO=bar])
293
+ options.expanded_args_without_drb.should == %w[features FOO=bar]
294
+ end
295
+
296
+ it "ignores the paths from the profiles if one was specified on the command line" do
297
+ given_cucumber_yml_defined_as('foo' => 'features --drb')
298
+ options.parse!(%w[some_feature.feature -p foo])
299
+ options.expanded_args_without_drb.should == %w[some_feature.feature]
300
+ end
301
+
302
+
303
+
304
+
305
+ end
306
+
307
+ end
308
+
309
+ end
310
+ end
311
+
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'yaml'
3
+
4
+ module Cucumber
5
+ module Cli
6
+ describe ProfileLoader do
7
+ it "should have all of its specs migrated from configuration_spec"
8
+ end
9
+ end
10
+ end
@@ -36,7 +36,7 @@ describe Proc do
36
36
  end
37
37
 
38
38
  if Cucumber::RUBY_1_9
39
- it "should allow varargs" do
39
+ it "should allow varargs (expecting 0+)" do
40
40
  lambda {
41
41
  Object.new.cucumber_instance_exec(true, 'foo', 1) do |*args|
42
42
  end
@@ -44,11 +44,25 @@ describe Proc do
44
44
  end
45
45
  else
46
46
  # Ruby 1.8
47
- it "should not allow varargs because Ruby 1.8 reports same arity as with no args, so we can't really tell the difference." do
47
+ it "should not allow varargs 0+ because Ruby 1.8 reports same arity as with no args, so we can't really tell the difference." do
48
48
  lambda {
49
49
  Object.new.cucumber_instance_exec(true, 'foo', 1) do |*args|
50
50
  end
51
51
  }.should raise_error(Cucumber::ArityMismatchError, "Your block takes 0 arguments, but the Regexp matched 1 argument.")
52
52
  end
53
53
  end
54
+
55
+ it "should allow varargs (expecting 1+)" do
56
+ lambda {
57
+ Object.new.cucumber_instance_exec(true, 'foo', 1) do |arg,*args|
58
+ end
59
+ }.should_not raise_error(Cucumber::ArityMismatchError)
60
+ end
61
+
62
+ it "should raise ArityMismatchError for too few required args when using varargs (expecting 1+)" do
63
+ lambda {
64
+ Object.new.cucumber_instance_exec(true, nil) do |arg,*args|
65
+ end
66
+ }.should raise_error(Cucumber::ArityMismatchError, "Your block takes 1+ arguments, but the Regexp matched 0 arguments.")
67
+ end
54
68
  end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'cucumber/formatter/html'
3
+
4
+ module Cucumber
5
+ module Formatter
6
+ describe Html do
7
+ before(:each) do
8
+ @out = StringIO.new
9
+ @html = Html.new(mock("step mother"), @out, {})
10
+ end
11
+
12
+ it "should not raise an error when visiting a blank feature name" do
13
+ lambda { @html.visit_feature_name("") }.should_not raise_error
14
+ end
15
+ end
16
+ end
17
+ end
18
+
@@ -17,7 +17,7 @@ module Cucumber
17
17
  describe "visiting a table cell value without a status" do
18
18
  it "should take the status from the last run step" do
19
19
  @progress.visit_step_result('', '', nil, :failed, nil, 10, nil)
20
- @progress.visit_table_cell_value('value', 10, nil)
20
+ @progress.visit_table_cell_value('value', nil)
21
21
 
22
22
  @out.string.should == "FF"
23
23
  end
@@ -25,7 +25,7 @@ module Cucumber
25
25
 
26
26
  describe "visiting a table cell which is a table header" do
27
27
  it "should not output anything" do
28
- @progress.visit_table_cell_value('value', 10, :skipped_param)
28
+ @progress.visit_table_cell_value('value', :skipped_param)
29
29
 
30
30
  @out.string.should == ""
31
31
  end
@@ -45,4 +45,4 @@ module Cucumber
45
45
  end
46
46
  end
47
47
  end
48
- end
48
+ end