cucumber 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/History.txt +81 -0
  2. data/Manifest.txt +30 -9
  3. data/README.txt +1 -2
  4. data/bin/cucumber +1 -1
  5. data/examples/calculator/README.txt +5 -0
  6. data/examples/calculator/Rakefile +1 -2
  7. data/examples/calculator/features/addition.feature +1 -0
  8. data/examples/chinese_simplified_calculator/Rakefile +6 -0
  9. data/examples/chinese_simplified_calculator/features/addition.feature +17 -0
  10. data/examples/chinese_simplified_calculator/features/steps/calculator_steps.rb +24 -0
  11. data/examples/chinese_simplified_calculator/lib/calculator.rb +10 -0
  12. data/examples/java/features/steps/hello_steps.rb +1 -1
  13. data/examples/swedish_calculator/Rakefile +5 -0
  14. data/examples/swedish_calculator/features/steps/kalkulator_steps.rb +22 -0
  15. data/examples/swedish_calculator/features/summering.feature +17 -0
  16. data/examples/swedish_calculator/lib/kalkulator.rb +11 -0
  17. data/examples/tickets/Rakefile +8 -1
  18. data/examples/tickets/cucumber.yml +2 -0
  19. data/examples/tickets/features/steps/tickets_steps.rb +15 -0
  20. data/examples/tickets/features/tickets.feature +12 -1
  21. data/gem_tasks/treetop.rake +35 -23
  22. data/lib/cucumber.rb +1 -0
  23. data/lib/cucumber/cli.rb +19 -5
  24. data/lib/cucumber/core_ext/proc.rb +8 -5
  25. data/lib/cucumber/executor.rb +7 -1
  26. data/lib/cucumber/formatters.rb +1 -1
  27. data/lib/cucumber/formatters/html_formatter.rb +6 -3
  28. data/lib/cucumber/formatters/pretty_formatter.rb +29 -7
  29. data/lib/cucumber/formatters/profile_formatter.rb +92 -0
  30. data/lib/cucumber/languages.yml +39 -12
  31. data/lib/cucumber/model.rb +1 -0
  32. data/lib/cucumber/model/table.rb +28 -0
  33. data/lib/cucumber/rails/world.rb +1 -3
  34. data/lib/cucumber/rake/task.rb +1 -1
  35. data/lib/cucumber/tree/feature.rb +8 -2
  36. data/lib/cucumber/tree/scenario.rb +23 -6
  37. data/lib/cucumber/tree/step.rb +5 -4
  38. data/lib/cucumber/treetop_parser/feature.treetop.erb +54 -12
  39. data/lib/cucumber/treetop_parser/feature_da.rb +415 -74
  40. data/lib/cucumber/treetop_parser/feature_de.rb +415 -74
  41. data/lib/cucumber/treetop_parser/feature_en.rb +415 -74
  42. data/lib/cucumber/treetop_parser/feature_es.rb +415 -74
  43. data/lib/cucumber/treetop_parser/feature_et.rb +415 -74
  44. data/lib/cucumber/treetop_parser/feature_fr.rb +415 -74
  45. data/lib/cucumber/treetop_parser/feature_nl.rb +1593 -0
  46. data/lib/cucumber/treetop_parser/feature_no.rb +415 -74
  47. data/lib/cucumber/treetop_parser/feature_pt.rb +415 -74
  48. data/lib/cucumber/treetop_parser/feature_ru.rb +415 -74
  49. data/lib/cucumber/treetop_parser/feature_se.rb +419 -78
  50. data/lib/cucumber/treetop_parser/feature_zh-CN.rb +1593 -0
  51. data/lib/cucumber/version.rb +1 -1
  52. data/{generators → rails_generators}/cucumber/cucumber_generator.rb +0 -0
  53. data/{generators → rails_generators}/cucumber/templates/common_webrat.rb +1 -10
  54. data/{generators → rails_generators}/cucumber/templates/cucumber +0 -0
  55. data/{generators → rails_generators}/cucumber/templates/cucumber.rake +0 -0
  56. data/{generators → rails_generators}/cucumber/templates/env.rb +0 -0
  57. data/{generators → rails_generators}/feature/feature_generator.rb +0 -0
  58. data/{generators → rails_generators}/feature/templates/feature.erb +1 -0
  59. data/{generators → rails_generators}/feature/templates/steps.erb +0 -0
  60. data/spec/cucumber/cli_spec.rb +11 -3
  61. data/spec/cucumber/core_ext/proc_spec.rb +6 -0
  62. data/spec/cucumber/formatters/html_formatter_spec.rb +16 -1
  63. data/spec/cucumber/formatters/pretty_formatter_spec.rb +54 -25
  64. data/spec/cucumber/formatters/profile_formatter_spec.rb +193 -0
  65. data/spec/cucumber/model/table_spec.rb +20 -0
  66. data/spec/cucumber/rails/stubs/mini_rails.rb +17 -0
  67. data/spec/cucumber/rails/stubs/test_help.rb +1 -0
  68. data/spec/cucumber/rails/world_spec.rb +11 -0
  69. data/spec/cucumber/tree/feature_spec.rb +12 -0
  70. data/spec/cucumber/tree/scenario_spec.rb +22 -0
  71. data/spec/cucumber/tree/step_spec.rb +12 -2
  72. data/spec/cucumber/treetop_parser/empty_scenario.feature +1 -1
  73. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +18 -0
  74. data/spec/cucumber/treetop_parser/fit_scenario.feature +1 -0
  75. data/spec/cucumber/treetop_parser/multiline_steps.feature +13 -0
  76. data/spec/cucumber/treetop_parser/multiple_tables.feature +2 -0
  77. data/spec/cucumber/treetop_parser/test_dos.feature +1 -0
  78. data/spec/cucumber/treetop_parser/with_comments.feature +6 -2
  79. metadata +34 -12
  80. data/examples/calculator/cucumber.yml +0 -1
@@ -2,7 +2,7 @@ module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 7
5
+ TINY = 8
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -13,7 +13,7 @@ When /^I fill in "(.*)" with "(.*)"$/ do |field, value|
13
13
  fills_in(field, :with => value)
14
14
  end
15
15
 
16
- When /^I select "(.*)" from "(.*)"$/ do |field, value|
16
+ When /^I select "(.*)" from "(.*)"$/ do |value, field|
17
17
  selects(value, :from => field)
18
18
  end
19
19
 
@@ -33,15 +33,6 @@ When /^I attach the file at "(.*)" to "(.*)" $/ do |path, field|
33
33
  attaches_file(field, path)
34
34
  end
35
35
 
36
- When /^I go to (.*)$/ do |page|
37
- visits case page
38
- when "the home page"
39
- "/"
40
- else
41
- raise "Can't find mapping from \"#{page}\" to a path"
42
- end
43
- end
44
-
45
36
  Then /^I should see "(.*)"$/ do |text|
46
37
  response.body.should =~ /#{text}/m
47
38
  end
@@ -22,6 +22,7 @@ Feature: Manage <%= plural_name %>
22
22
  When I delete the first <%= singular_name %>
23
23
  Then there should be 3 <%= plural_name %> left
24
24
 
25
+ More Examples:
25
26
  | initial | after |
26
27
  | 100 | 99 |
27
28
  | 1 | 0 |
@@ -15,7 +15,8 @@ module Cucumber
15
15
  :require => ['from/yml'],
16
16
  :dry_run => false,
17
17
  :lang => 'en',
18
- :source => true
18
+ :source => true,
19
+ :out => STDOUT
19
20
  }
20
21
  end
21
22
 
@@ -31,16 +32,23 @@ module Cucumber
31
32
  :require => ['from/yml'],
32
33
  :dry_run => false,
33
34
  :lang => 'en',
34
- :source => true
35
+ :source => true,
36
+ :out => STDOUT
35
37
  }
36
38
  end
37
39
 
38
- it "should accept source option" do
40
+ it "should accept --no-source option" do
39
41
  cli = CLI.new
40
42
  cli.parse_options!(%w{--no-source})
41
43
 
42
44
  cli.options[:source].should be_false
43
45
  end
46
+
47
+ it "should accept --out option" do
48
+ cli = CLI.new
49
+ File.should_receive(:open).with('jalla.txt', 'w')
50
+ cli.parse_options!(%w{--out jalla.txt})
51
+ end
44
52
 
45
53
  end
46
54
  end
@@ -34,6 +34,12 @@ module Cucumber
34
34
  proc.call_in(Object.new, 1)
35
35
  }.should raise_error(Cucumber::ArityMismatchError, "expected 2 block argument(s), got 1")
36
36
  end
37
+
38
+ it "should remove extraneous path info for file" do
39
+ proc = lambda {|a,b|}
40
+ proc.extend CallIn
41
+ proc.file_colon_line.should == "spec/cucumber/core_ext/proc_spec.rb:39"
42
+ end
37
43
  end
38
44
  end
39
45
  end
@@ -41,7 +41,8 @@ module Cucumber
41
41
  @features << p.parse_feature(f)
42
42
  end
43
43
  @io = StringIO.new
44
- @formatter = HtmlFormatter.new(@io)
44
+ step_mother = mock('step mother')
45
+ @formatter = HtmlFormatter.new(@io, step_mother)
45
46
  @me = MiniExecutor.new(@formatter)
46
47
  end
47
48
 
@@ -54,6 +55,20 @@ module Cucumber
54
55
  #File.open(expected_html, 'w') {|io| io.write(@io.string)}
55
56
  @io.string.should eql(IO.read(expected_html))
56
57
  end
58
+
59
+ it "should render FIT table headers" do
60
+ scenario = mock('scenario', :name => 'test', :accept => nil)
61
+ row_scenario = mock('row scenario', :name => 'test', :accept => nil)
62
+ scenario.stub!(:table_header).and_return(['test', 'fit', 'headers'])
63
+
64
+ @formatter.visit_regular_scenario(scenario)
65
+ @formatter.visit_row_scenario(row_scenario)
66
+
67
+ ['test', 'fit' ,'headers'].each do |column_header|
68
+ @io.string.should include(column_header)
69
+ end
70
+ end
71
+
57
72
  end
58
73
  end
59
74
  end
@@ -12,6 +12,16 @@ module Cucumber
12
12
  :error => nil,
13
13
  :row? => false}.merge(stubs))
14
14
  end
15
+
16
+ def mock_scenario(stubs={})
17
+ stub('scenario', {
18
+ :name => 'test',
19
+ :row? => false }.merge(stubs))
20
+ end
21
+
22
+ def mock_feature(stubs={})
23
+ stub("feature", stubs)
24
+ end
15
25
 
16
26
  def mock_error(stubs={})
17
27
  stub('error', {
@@ -35,47 +45,66 @@ module Cucumber
35
45
 
36
46
  describe "show source option true" do
37
47
 
48
+ before(:each) do
49
+ @io = StringIO.new
50
+ step_mother = mock('step_mother')
51
+ @formatter = PrettyFormatter.new @io, step_mother, :source => true
52
+ end
53
+
38
54
  %w{passed failed skipped}.each do |result|
39
55
  it "should display step source for passed step" do
40
- io = StringIO.new
41
-
42
- step_mother = mock('step_mother')
43
- formatter = PrettyFormatter.new io, step_mother, :source => true
44
- formatter.send("step_#{result}".to_sym, mock_step(:regexp_args_proc => [nil, nil, mock_proc], :error => StandardError.new, :padding_length => 2), nil, nil)
56
+ @formatter.send("step_#{result}".to_sym, mock_step(:regexp_args_proc => [nil, nil, mock_proc], :error => StandardError.new, :padding_length => 2), nil, nil)
45
57
 
46
- io.string.should include("Given formatted yes # steps/example_steps.rb:11")
58
+ @io.string.should include("Given formatted yes # steps/example_steps.rb:11")
47
59
  end
48
60
  end
61
+
62
+ it "should display feature file and line for pending step" do
63
+ @formatter.step_pending(mock_step(:name => 'test', :file => 'features/example.feature', :line => 5, :padding_length => 2), nil, nil)
64
+
65
+ @io.string.should include("Given test # features/example.feature:5")
66
+ end
49
67
 
50
- it "should align step comments" do
51
- io = StringIO.new
68
+ it "should display file and line for scenario" do
69
+ @formatter.scenario_executing(mock_scenario(:name => "title", :file => 'features/example.feature', :line => 2 , :padding_length => 2))
52
70
 
71
+ @io.string.should include("Scenario: title # features/example.feature:2")
72
+ end
73
+
74
+ it "should display file for feature" do
75
+ @formatter.visit_feature(mock_feature(:file => 'features/example.feature', :padding_length => 2))
76
+ @formatter.header_executing("Feature: test\n In order to ...\n As a ...\n I want to ...\n")
77
+
78
+ @io.string.should include("Feature: test # features/example.feature\n")
79
+ @io.string.should include("In order to ...\n")
80
+ @io.string.should include("As a ...\n")
81
+ @io.string.should include("I want to ...\n")
82
+ end
83
+
84
+ it "should align step comments" do
53
85
  step_1 = mock_step(:regexp_args_proc => [nil, nil, mock_proc], :format => "1", :padding_length => 10)
54
86
  step_4 = mock_step(:regexp_args_proc => [nil, nil, mock_proc], :format => "4444", :padding_length => 7)
55
87
  step_9 = mock_step(:regexp_args_proc => [nil, nil, mock_proc], :format => "999999999", :padding_length => 2)
56
-
57
- step_mother = mock('step_mother')
58
- formatter = PrettyFormatter.new io, step_mother, :source => true
59
88
 
60
- formatter.step_passed(step_1, nil, nil)
61
- formatter.step_passed(step_4, nil, nil)
62
- formatter.step_passed(step_9, nil, nil)
89
+ @formatter.step_passed(step_1, nil, nil)
90
+ @formatter.step_passed(step_4, nil, nil)
91
+ @formatter.step_passed(step_9, nil, nil)
63
92
 
64
- io.string.should include("Given 1 # steps/example_steps.rb:11")
65
- io.string.should include("Given 4444 # steps/example_steps.rb:11")
66
- io.string.should include("Given 999999999 # steps/example_steps.rb:11")
93
+ @io.string.should include("Given 1 # steps/example_steps.rb:11")
94
+ @io.string.should include("Given 4444 # steps/example_steps.rb:11")
95
+ @io.string.should include("Given 999999999 # steps/example_steps.rb:11")
67
96
  end
68
-
69
- it "should NOT display step source for pending step" do
70
- io = StringIO.new
71
- step_mother = mock('step_mother')
97
+
98
+ it "should align step comments with respect to their scenario's comment" do
99
+ step = mock_step(:regexp_args_proc => [nil, nil, mock_proc], :error => StandardError.new, :padding_length => 6)
72
100
 
73
- formatter = PrettyFormatter.new io, step_mother, :source => true
74
- formatter.step_pending(mock_step(:regexp_args_proc => [nil, nil, mock_proc]), nil, nil)
101
+ @formatter.scenario_executing(mock_scenario(:name => "very long title", :file => 'features/example.feature', :line => 5, :steps => [step], :padding_length => 2))
102
+ @formatter.step_passed(step, nil, nil)
75
103
 
76
- io.string.should_not include("steps/example_steps.rb:11")
104
+ @io.string.should include("Scenario: very long title # features/example.feature:5")
105
+ @io.string.should include(" Given formatted yes # steps/example_steps.rb:11")
77
106
  end
78
-
107
+
79
108
  end
80
109
  end
81
110
  end
@@ -0,0 +1,193 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Cucumber
4
+ module Formatters
5
+ describe ProfileFormatter do
6
+ attr_reader :io, :formatter
7
+
8
+ def mock_proc(stubs={})
9
+ stub(Proc, {:to_comment_line => '# steps/example_steps.rb:11'}.merge(stubs))
10
+ end
11
+
12
+ def mock_step(stubs={})
13
+ stub('step', {:keyword => 'Given',
14
+ :actual_keyword => 'Given',
15
+ :format => 'test',
16
+ :row? => false,
17
+ :file => 'test.feature',
18
+ :line => 5,
19
+ :regexp_args_proc => [nil, nil, mock_proc]}.merge(stubs))
20
+ end
21
+
22
+ before(:each) do
23
+ @io = StringIO.new
24
+ step_mother = stub('step_mother')
25
+ @formatter = ProfileFormatter.new(io, step_mother)
26
+ end
27
+
28
+ it "should print a heading" do
29
+ formatter.visit_features(nil)
30
+
31
+ io.string.should eql("Profiling enabled.\n")
32
+ end
33
+
34
+ it "should record the current time when starting a new step" do
35
+ now = Time.now
36
+ Time.stub!(:now).and_return(now)
37
+ formatter.step_executing('should foo', nil, nil)
38
+
39
+ formatter.instance_variable_get("@step_time").should == now
40
+ end
41
+
42
+ describe "grouping recorded passed steps" do
43
+
44
+ before(:each) do
45
+ now = Time.now
46
+ formatter.instance_variable_set("@step_time", now)
47
+ Time.stub!(:now).and_return(now, now)
48
+ end
49
+
50
+ it "should group by regular expressions and actual keyword" do
51
+ step_1 = mock_step(:actual_keyword => 'Given')
52
+ step_2 = mock_step(:actual_keyword => 'Given')
53
+
54
+ formatter.step_passed(step_1, /nihon/, nil)
55
+ formatter.step_passed(step_2, /ichiban/, nil)
56
+
57
+ step_times = formatter.instance_variable_get("@step_times")
58
+
59
+ step_times.has_key?('Given /nihon/').should be_true
60
+ step_times.has_key?('Given /ichiban/').should be_true
61
+ end
62
+
63
+ it "should use a previous step's keyword when recording row steps" do
64
+ step = mock_step(:actual_keyword => 'Given')
65
+ step_row = mock_step(:row? => true)
66
+
67
+ formatter.step_passed(step, /nihon/, [])
68
+ formatter.step_passed(step_row, /nihon/, [])
69
+
70
+ step_times = formatter.instance_variable_get("@step_times")
71
+
72
+ step_times['Given /nihon/'].length.should == 2
73
+ end
74
+
75
+ end
76
+
77
+ it "should correctly record a passed step" do
78
+ formatter.step_executing(nil, nil, nil)
79
+ formatter.step_passed(mock_step(:format => 'she doth teach the torches to burn bright', :actual_keyword => 'Given'), nil, nil)
80
+ formatter.dump
81
+
82
+ io.string.should include('Given she doth teach the torches to burn bright')
83
+ end
84
+
85
+ it "should correctly record a passed step row" do
86
+ formatter.step_executing(nil, nil, nil)
87
+ formatter.step_passed(mock_step(:row? => true), /example/, ['fitty'])
88
+ formatter.dump
89
+
90
+ io.string.should include('fitty')
91
+ end
92
+
93
+ it "should calculate the mean step execution time" do
94
+ now = Time.now
95
+ Time.stub!(:now).and_return(now, now+5, now, now+1)
96
+
97
+ 2.times do
98
+ formatter.step_executing(mock_step, nil, nil)
99
+ formatter.step_passed(mock_step, nil, nil)
100
+ end
101
+
102
+ formatter.dump
103
+
104
+ io.string.should include('3.0000000')
105
+ end
106
+
107
+ it "should display file and line comment for step invocation" do
108
+ step = mock_step(:format => 'test', :actual_keyword => 'Given', :file => 'test.feature', :line => 5)
109
+
110
+ formatter.step_executing(step, nil, nil)
111
+ formatter.step_passed(step, nil, nil)
112
+ formatter.dump
113
+
114
+ @io.string.should include("# test.feature:5")
115
+ end
116
+
117
+ it "should display file and line comment for step definition" do
118
+ step = mock_step(:format => 'test', :actual_keyword => 'Given',
119
+ :regexp_args_proc => [/test/, nil, mock_proc(:to_comment_line => '# steps/example_steps.rb:11')])
120
+
121
+ formatter.step_executing(step, nil, nil)
122
+ formatter.step_passed(step, nil, nil)
123
+ formatter.dump
124
+
125
+ @io.string.should include("# steps/example_steps.rb:11")
126
+ end
127
+
128
+ it "should show the performance times of the step invocations for a step definition" do
129
+ now = Time.now
130
+ Time.stub!(:now).and_return(now, now+5, now, now+1)
131
+
132
+ step = mock_step(:format => 'step invocation', :actual_keyword => 'Given')
133
+
134
+ 2.times do
135
+ formatter.step_executing(step, /example/, nil)
136
+ formatter.step_passed(step, /example/, nil)
137
+ end
138
+
139
+ formatter.dump
140
+
141
+ io.string.should include("3.0000000 Given /example/")
142
+ io.string.should include("5.0000000 Given step invocation")
143
+ io.string.should include("1.0000000 Given step invocation")
144
+ end
145
+
146
+ it "should sort the step invocations in descending order" do
147
+ now = Time.now
148
+ Time.stub!(:now).and_return(now, now+1, now, now+5)
149
+
150
+ step = mock_step(:format => 'step invocation', :actual_keyword => 'Given')
151
+
152
+ 2.times do
153
+ formatter.step_executing(step, /example 1/, nil)
154
+ formatter.step_passed(step, /example 1/, nil)
155
+ end
156
+
157
+ formatter.dump
158
+ io_string_lines = io.string.split("\n")
159
+
160
+ io_string_lines.at(-2).should include('5.0000000')
161
+ io_string_lines.at(-1).should include('1.0000000')
162
+ end
163
+
164
+ it "should print the top average 10 step results" do
165
+ formatter.instance_variable_set("@step_time", Time.now)
166
+
167
+ 11.times do |test_number|
168
+ step_regexp = Regexp.new "unique_test_#{test_number}"
169
+ formatter.step_passed(mock_step(:format => 'test', :actual_keyword => 'Given',
170
+ :regexp_args_proc => [step_regexp, nil, mock_proc]), step_regexp, nil)
171
+ end
172
+
173
+ formatter.dump
174
+
175
+ io.string.scan(/unique_test_\d+/).length.should == 10
176
+ end
177
+
178
+ it "should print the top 5 step invocations for step definition" do
179
+ formatter.instance_variable_set("@step_time", Time.now)
180
+ step_definition_put = 1
181
+
182
+ 10.times do |test_number|
183
+ formatter.step_passed(mock_step(:format => 'please invocate me', :actual_keyword => 'Given'), nil, nil)
184
+ end
185
+
186
+ formatter.dump
187
+
188
+ io.string.scan(/please invocate me/).length.should == 5
189
+ end
190
+
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Cucumber
4
+ module Model
5
+ describe Table do
6
+ it "should convert into hash-array" do
7
+ raw = [
8
+ %w{name gender},
9
+ %w{aslak male},
10
+ %w{patty female},
11
+ ]
12
+ ha = Table.new(raw).hashes
13
+ ha.should == [
14
+ {'name' => 'aslak', 'gender' => 'male'},
15
+ {'name' => 'patty', 'gender' => 'female'}
16
+ ]
17
+ end
18
+ end
19
+ end
20
+ end