cucumber 0.10.3 → 0.10.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/History.txt +21 -8
  2. data/cucumber.gemspec +5 -5
  3. data/examples/sinatra/features/support/env.rb +1 -1
  4. data/examples/v8/features/fibonacci.feature +1 -1
  5. data/examples/watir/features/step_definitions/search_steps.rb +1 -1
  6. data/features/json_formatter.feature +1 -2
  7. data/features/transforms.feature +2 -2
  8. data/fixtures/junit/features/scenario_outline.feature +9 -0
  9. data/fixtures/tickets/features.html +1 -1
  10. data/gem_tasks/sdoc.rake +1 -1
  11. data/legacy_features/announce.feature +48 -60
  12. data/legacy_features/bug_371.feature +2 -2
  13. data/legacy_features/bug_600.feature +10 -4
  14. data/legacy_features/html_formatter/a.html +2 -2
  15. data/legacy_features/junit_formatter.feature +30 -1
  16. data/legacy_features/profiles.feature +1 -1
  17. data/legacy_features/step_definitions/cucumber_steps.rb +4 -0
  18. data/lib/cucumber/ast.rb +1 -1
  19. data/lib/cucumber/ast/{py_string.rb → doc_string.rb} +6 -6
  20. data/lib/cucumber/ast/tree_walker.rb +4 -4
  21. data/lib/cucumber/formatter/console.rb +20 -18
  22. data/lib/cucumber/formatter/cucumber.css +2 -2
  23. data/lib/cucumber/formatter/cucumber.sass +13 -13
  24. data/lib/cucumber/formatter/html.rb +23 -23
  25. data/lib/cucumber/formatter/junit.rb +5 -1
  26. data/lib/cucumber/formatter/pdf.rb +6 -6
  27. data/lib/cucumber/formatter/pretty.rb +5 -5
  28. data/lib/cucumber/parser/gherkin_builder.rb +2 -2
  29. data/lib/cucumber/platform.rb +1 -1
  30. data/lib/cucumber/rake/task.rb +13 -1
  31. data/lib/cucumber/rb_support/rb_language.rb +1 -1
  32. data/lib/cucumber/rb_support/rb_world.rb +24 -16
  33. data/lib/cucumber/runtime.rb +1 -1
  34. data/lib/cucumber/runtime/for_programming_languages.rb +3 -3
  35. data/lib/cucumber/runtime/support_code.rb +1 -1
  36. data/lib/cucumber/runtime/user_interface.rb +12 -11
  37. data/lib/cucumber/step_match.rb +1 -1
  38. data/spec/cucumber/ast/doc_string_spec.rb +40 -0
  39. data/spec/cucumber/ast/feature_factory.rb +2 -2
  40. data/spec/cucumber/ast/feature_spec.rb +1 -1
  41. data/spec/cucumber/ast/step_spec.rb +2 -2
  42. data/spec/cucumber/formatter/junit_spec.rb +1 -0
  43. data/spec/cucumber/rb_support/rb_language_spec.rb +1 -1
  44. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +3 -3
  45. metadata +14 -13
  46. data/spec/cucumber/ast/py_string_spec.rb +0 -40
@@ -132,4 +132,33 @@ can't convert .* into String \(TypeError\)
132
132
  And STDERR should match
133
133
  """
134
134
  You \*must\* specify \-\-out DIR for the junit formatter
135
- """
135
+ """
136
+
137
+ Scenario: one feature, one scenario outline, two examples: one passing, one failing
138
+ When I run cucumber --format junit --out tmp/ features/scenario_outline.feature
139
+ Then it should fail with
140
+ """
141
+
142
+ """
143
+ And "fixtures/junit/tmp/TEST-scenario_outline.xml" with junit duration "0.005" should contain
144
+ """
145
+ <?xml version="1.0" encoding="UTF-8"?>
146
+ <testsuite errors="0" failures="1" name="Scenario outlines" skipped="0" tests="2" time="0.005">
147
+ <testcase classname="Scenario outlines.Using scenario outlines" name="Using scenario outlines (outline example : | passing |)" time="0.005">
148
+ </testcase>
149
+ <testcase classname="Scenario outlines.Using scenario outlines" name="Using scenario outlines (outline example : | failing |)" time="0.005">
150
+ <failure message="failed Using scenario outlines (outline example : | failing |)" type="failed">
151
+ <![CDATA[Scenario Outline: Using scenario outlines
152
+
153
+ Example row: | failing |
154
+
155
+ Message:
156
+ ]]>
157
+ <![CDATA[ (RuntimeError)
158
+ features/scenario_outline.feature:4:in `Given a <type> scenario']]>
159
+ </failure>
160
+ </testcase>
161
+ </testsuite>
162
+
163
+ """
164
+
@@ -4,7 +4,7 @@ Feature: Profiles
4
4
  These named arguments are called profiles and the yml file should be in the root of your project.
5
5
  Any cucumber argument is valid in a profile. To see all the available flags type 'cucumber --help'
6
6
  For more information about profiles please see the wiki:
7
- http://wiki.github.com/aslakhellesoy/cucumber/cucumberyml
7
+ http://wiki.github.com/cucumber/cucumber/cucumber.yml
8
8
 
9
9
  Background: Basic App
10
10
  Given a standard Cucumber project directory structure
@@ -78,6 +78,10 @@ Then /^it should (fail|pass) with$/ do |success, output|
78
78
  Then("it should #{success}")
79
79
  end
80
80
 
81
+ Then /^the output should contain "([^"]*)"$/ do |text|
82
+ last_stdout.should include(text)
83
+ end
84
+
81
85
  Then /^the output should contain:?$/ do |text|
82
86
  last_stdout.should include(text)
83
87
  end
data/lib/cucumber/ast.rb CHANGED
@@ -9,7 +9,7 @@ require 'cucumber/ast/step_collection'
9
9
  require 'cucumber/ast/step'
10
10
  require 'cucumber/ast/table'
11
11
  require 'cucumber/ast/tags'
12
- require 'cucumber/ast/py_string'
12
+ require 'cucumber/ast/doc_string'
13
13
  require 'cucumber/ast/outline_table'
14
14
  require 'cucumber/ast/examples'
15
15
  require 'cucumber/ast/visitor'
@@ -8,7 +8,7 @@ module Cucumber
8
8
  # Cucumber sandwich
9
9
  # """
10
10
  #
11
- # The text between the pair of <tt>"""</tt> is stored inside a PyString,
11
+ # The text between the pair of <tt>"""</tt> is stored inside a DocString,
12
12
  # which is yielded to the StepDefinition block as the last argument.
13
13
  #
14
14
  # The StepDefinition can then access the String via the #to_s method. In the
@@ -16,7 +16,7 @@ module Cucumber
16
16
  #
17
17
  # Note how the indentation from the source is stripped away.
18
18
  #
19
- class PyString #:nodoc:
19
+ class DocString #:nodoc:
20
20
  class Builder
21
21
  attr_reader :string
22
22
 
@@ -24,7 +24,7 @@ module Cucumber
24
24
  @string = ''
25
25
  end
26
26
 
27
- def py_string(string, line_number)
27
+ def doc_string(string, line_number)
28
28
  @string = string
29
29
  end
30
30
 
@@ -55,7 +55,7 @@ module Cucumber
55
55
 
56
56
  def accept(visitor)
57
57
  return if Cucumber.wants_to_quit
58
- visitor.visit_py_string(@string)
58
+ visitor.visit_doc_string(@string)
59
59
  end
60
60
 
61
61
  def arguments_replaced(arguments) #:nodoc:
@@ -64,7 +64,7 @@ module Cucumber
64
64
  value ||= ''
65
65
  string = string.gsub(name, value)
66
66
  end
67
- PyString.new(string)
67
+ DocString.new(string)
68
68
  end
69
69
 
70
70
  def has_text?(text)
@@ -73,7 +73,7 @@ module Cucumber
73
73
 
74
74
  # For testing only
75
75
  def to_sexp #:nodoc:
76
- [:py_string, to_step_definition_arg]
76
+ [:doc_string, to_step_definition_arg]
77
77
  end
78
78
  end
79
79
  end
@@ -122,7 +122,7 @@ module Cucumber
122
122
  broadcast(exception, status)
123
123
  end
124
124
 
125
- def visit_py_string(string)
125
+ def visit_doc_string(string)
126
126
  broadcast(string)
127
127
  end
128
128
 
@@ -142,9 +142,9 @@ module Cucumber
142
142
  broadcast(value, status)
143
143
  end
144
144
 
145
- # Print +announcement+. This method can be called from within StepDefinitions.
146
- def announce(announcement)
147
- broadcast(announcement)
145
+ # Print +messages+. This method can be called from within StepDefinitions.
146
+ def puts(*messages)
147
+ broadcast(*messages)
148
148
  end
149
149
 
150
150
  # Embed +file+ of +mime_type+ in the formatter. This method can be called from within StepDefinitions.
@@ -26,9 +26,9 @@ module Cucumber
26
26
  format_string(line, status)
27
27
  end
28
28
 
29
- def format_string(string, status)
29
+ def format_string(o, status)
30
30
  fmt = format_for(status)
31
- string.split("\n").map do |line|
31
+ o.to_s.split("\n").map do |line|
32
32
  if Proc === fmt
33
33
  fmt.call(line)
34
34
  else
@@ -131,39 +131,41 @@ module Cucumber
131
131
  # no-op
132
132
  end
133
133
 
134
- #define @delayed_announcements = [] in your Formatter if you want to
134
+ #define @delayed_messages = [] in your Formatter if you want to
135
135
  #activate this feature
136
- def announce(announcement)
137
- if @delayed_announcements
138
- @delayed_announcements << announcement
136
+ def puts(*messages)
137
+ if @delayed_messages
138
+ @delayed_messages += messages
139
139
  else
140
140
  if @io
141
141
  @io.puts
142
- @io.puts(format_string(announcement, :tag))
142
+ messages.each do |message|
143
+ @io.puts(format_string(message, :tag))
144
+ end
143
145
  @io.flush
144
146
  end
145
147
  end
146
148
  end
147
149
 
148
- def print_announcements()
149
- @delayed_announcements.each {|ann| print_announcement(ann)}
150
- empty_announcements
150
+ def print_messages
151
+ @delayed_messages.each {|message| print_message(message)}
152
+ empty_messages
151
153
  end
152
154
 
153
- def print_table_row_announcements
154
- return if @delayed_announcements.empty?
155
- @io.print(format_string(@delayed_announcements.join(', '), :tag).indent(2))
155
+ def print_table_row_messages
156
+ return if @delayed_messages.empty?
157
+ @io.print(format_string(@delayed_messages.join(', '), :tag).indent(2))
156
158
  @io.flush
157
- empty_announcements
159
+ empty_messages
158
160
  end
159
161
 
160
- def print_announcement(announcement)
161
- @io.puts(format_string(announcement, :tag).indent(@indent))
162
+ def print_message(message)
163
+ @io.puts(format_string(message, :tag).indent(@indent))
162
164
  @io.flush
163
165
  end
164
166
 
165
- def empty_announcements
166
- @delayed_announcements = []
167
+ def empty_messages
168
+ @delayed_messages = []
167
169
  end
168
170
 
169
171
  private
@@ -133,7 +133,7 @@ body {
133
133
  background: #fcfb98;
134
134
  color: #131313;
135
135
  }
136
- .cucumber table td.announcement, td table td.announcement, th table td.announcement {
136
+ .cucumber table td.message, td table td.message, th table td.message {
137
137
  border-left: 5px solid aqua;
138
138
  border-bottom: 1px solid aqua;
139
139
  background: #e0ffff;
@@ -185,7 +185,7 @@ body {
185
185
  background: #fcfb98;
186
186
  color: #131313;
187
187
  }
188
- .cucumber ol li.announcement, td ol li.announcement, th ol li.announcement {
188
+ .cucumber ol li.message, td ol li.message, th ol li.message {
189
189
  border-left: 5px solid aqua;
190
190
  border-bottom: 1px solid aqua;
191
191
  background: #e0ffff;
@@ -24,9 +24,9 @@ $undefined: #fcfb98
24
24
  $undefined_border: #faf834
25
25
  $undefined_text: #131313
26
26
 
27
- $announcement: #e0ffff
28
- $announcement_border: aqua
29
- $announcement_text: #001111
27
+ $message: #e0ffff
28
+ $message_border: aqua
29
+ $message_text: #001111
30
30
 
31
31
  body
32
32
  font-size: 0px
@@ -136,11 +136,11 @@ body
136
136
  border-bottom: $step_bottom $undefined_border
137
137
  background: $undefined
138
138
  color: $undefined_text
139
- td.announcement
140
- border-left: $step_left $announcement_border
141
- border-bottom: $step_bottom $announcement_border
142
- background: $announcement
143
- color: $announcement_text
139
+ td.message
140
+ border-left: $step_left $message_border
141
+ border-bottom: $step_bottom $message_border
142
+ background: $message
143
+ color: $message_text
144
144
  ol
145
145
  list-style: none
146
146
  margin: 0px
@@ -178,11 +178,11 @@ body
178
178
  border-bottom: $step_bottom $undefined_border
179
179
  background: $undefined
180
180
  color: $undefined_text
181
- li.announcement
182
- border-left: $step_left $announcement_border
183
- border-bottom: $step_bottom $announcement_border
184
- background: $announcement
185
- color: $announcement_text
181
+ li.message
182
+ border-left: $step_left $message_border
183
+ border-bottom: $step_bottom $message_border
184
+ background: $message
185
+ color: $message_text
186
186
  margin-left: 10px
187
187
  #summary
188
188
  margin: 0px
@@ -20,21 +20,21 @@ module Cucumber
20
20
  @scenario_number = 0
21
21
  @step_number = 0
22
22
  @header_red = nil
23
- @delayed_announcements = []
23
+ @delayed_messages = []
24
24
  end
25
25
 
26
- def embed(file, mime_type, label)
26
+ def embed(src, mime_type, label)
27
27
  case(mime_type)
28
28
  when /^image\/(png|gif|jpg|jpeg)/
29
- embed_image(file, label)
29
+ embed_image(src, label)
30
30
  end
31
31
  end
32
32
 
33
- def embed_image(file, label)
33
+ def embed_image(src, label)
34
34
  id = file.hash
35
35
  @builder.span(:class => 'embed') do |pre|
36
36
  pre << %{<a href="" onclick="img=document.getElementById('#{id}'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false">#{label}</a><br>&nbsp;
37
- <img id="#{id}" style="display: none" src="#{file}"/>}
37
+ <img id="#{id}" style="display: none" src="#{src}"/>}
38
38
  end
39
39
  end
40
40
 
@@ -249,7 +249,7 @@ module Cucumber
249
249
  end
250
250
  end
251
251
  @builder << '</li>'
252
- print_announcements
252
+ print_messages
253
253
  end
254
254
 
255
255
  def step_name(keyword, step_match, status, source_indent, background)
@@ -286,7 +286,7 @@ module Cucumber
286
286
  end
287
287
  end
288
288
 
289
- def py_string(string)
289
+ def doc_string(string)
290
290
  return if @hide_this_step
291
291
  @builder.pre(:class => 'val') do |pre|
292
292
  @builder << string.gsub("\n", '&#x000A;')
@@ -303,7 +303,7 @@ module Cucumber
303
303
 
304
304
  def after_table_row(table_row)
305
305
  return if @hide_this_step
306
- print_table_row_announcements
306
+ print_table_row_messages
307
307
  @builder << '</tr>'
308
308
  if table_row.exception
309
309
  @builder.tr do
@@ -333,35 +333,35 @@ module Cucumber
333
333
  @col_index += 1
334
334
  end
335
335
 
336
- def announce(announcement)
337
- @delayed_announcements << announcement
338
- #@builder.pre(announcement, :class => 'announcement')
336
+ def puts(message)
337
+ @delayed_messages << message
338
+ #@builder.pre(message, :class => 'message')
339
339
  end
340
340
 
341
- def print_announcements
342
- return if @delayed_announcements.empty?
341
+ def print_messages
342
+ return if @delayed_messages.empty?
343
343
 
344
344
  #@builder.ol do
345
- @delayed_announcements.each do |ann|
346
- @builder.li(:class => 'step announcement') do
345
+ @delayed_messages.each do |ann|
346
+ @builder.li(:class => 'step message') do
347
347
  @builder << ann
348
348
  end
349
349
  end
350
350
  #end
351
- empty_announcements
351
+ empty_messages
352
352
  end
353
353
 
354
- def print_table_row_announcements
355
- return if @delayed_announcements.empty?
354
+ def print_table_row_messages
355
+ return if @delayed_messages.empty?
356
356
 
357
- @builder.td(:class => 'announcement') do
358
- @builder << @delayed_announcements.join(", ")
357
+ @builder.td(:class => 'message') do
358
+ @builder << @delayed_messages.join(", ")
359
359
  end
360
- empty_announcements
360
+ empty_messages
361
361
  end
362
362
 
363
- def empty_announcements
364
- @delayed_announcements = []
363
+ def empty_messages
364
+ @delayed_messages = []
365
365
  end
366
366
 
367
367
  protected
@@ -26,6 +26,10 @@ module Cucumber
26
26
  @time = 0
27
27
  end
28
28
 
29
+ def before_feature_element(feature_element)
30
+ @in_examples = Ast::ScenarioOutline === feature_element
31
+ end
32
+
29
33
  def after_feature(feature)
30
34
  @testsuite = OrderedXmlMarkup.new( :indent => 2 )
31
35
  @testsuite.instruct!
@@ -92,7 +96,7 @@ module Cucumber
92
96
  end
93
97
 
94
98
  def after_table_row(table_row)
95
- return unless @in_examples
99
+ return unless @in_examples and Cucumber::Ast::OutlineTable::ExampleRow === table_row
96
100
  duration = Time.now - @table_start
97
101
  unless @header_row
98
102
  name_suffix = " (outline example : #{table_row.name})"
@@ -28,9 +28,9 @@ module Cucumber
28
28
  @file = ensure_file(path_or_io, "pdf")
29
29
 
30
30
  if(options[:dry_run])
31
- @status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK, :announced => GREY}
31
+ @status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK, :putsd => GREY}
32
32
  else
33
- @status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202', :announced => GREY}
33
+ @status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202', :putsd => GREY}
34
34
  end
35
35
 
36
36
  @pdf = Prawn::Document.new
@@ -71,9 +71,9 @@ module Cucumber
71
71
  end
72
72
  end
73
73
 
74
- def announce(announcement)
75
- @pdf.fill_color(@status_colors[:announced])
76
- @pdf.text announcement, :size => 10
74
+ def puts(message)
75
+ @pdf.fill_color(@status_colors[:putsd])
76
+ @pdf.text message, :size => 10
77
77
  @pdf.fill_color BLACK
78
78
  end
79
79
 
@@ -172,7 +172,7 @@ module Cucumber
172
172
  end
173
173
  end
174
174
 
175
- def before_py_string(string)
175
+ def before_doc_string(string)
176
176
  return if @hide_this_step
177
177
  s = %{"""\n#{string}\n"""}.indent(10)
178
178
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}
@@ -25,7 +25,7 @@ module Cucumber
25
25
  @exceptions = []
26
26
  @indent = 0
27
27
  @prefixes = options[:prefixes] || {}
28
- @delayed_announcements = []
28
+ @delayed_messages = []
29
29
  end
30
30
 
31
31
  def after_features(features)
@@ -101,7 +101,7 @@ module Cucumber
101
101
  end
102
102
 
103
103
  def examples_name(keyword, name)
104
- puts unless @visiting_first_example_name
104
+ @io.puts unless @visiting_first_example_name
105
105
  @visiting_first_example_name = false
106
106
  names = name.strip.empty? ? [name.strip] : name.split("\n")
107
107
  @io.puts(" #{keyword}: #{names[0]}")
@@ -150,10 +150,10 @@ module Cucumber
150
150
  source_indent = nil unless @options[:source]
151
151
  name_to_report = format_step(keyword, step_match, status, source_indent)
152
152
  @io.puts(name_to_report.indent(@scenario_indent + 2))
153
- print_announcements
153
+ print_messages
154
154
  end
155
155
 
156
- def py_string(string)
156
+ def doc_string(string)
157
157
  return if @hide_this_step
158
158
  s = %{"""\n#{string}\n"""}.indent(@indent)
159
159
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}.join("\n")
@@ -184,7 +184,7 @@ module Cucumber
184
184
 
185
185
  def after_table_row(table_row)
186
186
  return if !@table || @hide_this_step
187
- print_table_row_announcements
187
+ print_table_row_messages
188
188
  @io.puts
189
189
  if table_row.exception && !@exceptions.include?(table_row.exception)
190
190
  print_exception(table_row.exception, table_row.status, @indent)