casecumber 1.0.2.1 → 1.2.1.cb2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/.rvmrc +1 -1
  2. data/.travis.yml +13 -6
  3. data/Gemfile +2 -0
  4. data/History.md +139 -0
  5. data/LICENSE +1 -1
  6. data/README.md +19 -4
  7. data/cucumber.gemspec +16 -29
  8. data/cucumber.yml +3 -3
  9. data/examples/i18n/README.textile +1 -16
  10. data/features/.cucumber/stepdefs.json +612 -0
  11. data/features/backtraces.feature +36 -0
  12. data/features/doc_strings.feature +73 -0
  13. data/features/drb_server_integration.feature +63 -0
  14. data/features/formatter_step_file_colon_line.feature +46 -0
  15. data/features/json_formatter.feature +137 -137
  16. data/features/nested_steps.feature +60 -0
  17. data/features/rerun_formatter.feature +35 -0
  18. data/features/run_specific_scenarios.feature +47 -0
  19. data/features/step_definitions/cucumber-features/cucumber_ruby_mappings.rb +32 -3
  20. data/features/step_definitions/cucumber_steps.rb +15 -0
  21. data/features/step_definitions/drb_steps.rb +3 -0
  22. data/features/support/env.rb +4 -0
  23. data/features/support/feature_factory.rb +50 -0
  24. data/gem_tasks/cucumber.rake +15 -8
  25. data/gem_tasks/yard.rake +18 -0
  26. data/legacy_features/call_steps_from_stepdefs.feature +1 -1
  27. data/legacy_features/cucumber_cli.feature +0 -7
  28. data/legacy_features/default_snippets.feature +3 -2
  29. data/legacy_features/junit_formatter.feature +60 -10
  30. data/legacy_features/language_help.feature +17 -15
  31. data/legacy_features/snippets_when_using_star_keyword.feature +3 -2
  32. data/legacy_features/step_definitions/cucumber_steps.rb +1 -1
  33. data/legacy_features/support/env.rb +1 -1
  34. data/legacy_features/wire_protocol.feature +1 -1
  35. data/lib/cucumber/ast/background.rb +11 -0
  36. data/lib/cucumber/ast/doc_string.rb +10 -29
  37. data/lib/cucumber/ast/feature.rb +6 -2
  38. data/lib/cucumber/ast/feature_element.rb +7 -3
  39. data/lib/cucumber/ast/multiline_argument.rb +30 -0
  40. data/lib/cucumber/ast/outline_table.rb +20 -12
  41. data/lib/cucumber/ast/step.rb +1 -1
  42. data/lib/cucumber/ast/step_invocation.rb +2 -15
  43. data/lib/cucumber/ast/table.rb +67 -38
  44. data/lib/cucumber/ast/tags.rb +7 -7
  45. data/lib/cucumber/ast/tree_walker.rb +5 -5
  46. data/lib/cucumber/cli/configuration.rb +4 -0
  47. data/lib/cucumber/cli/main.rb +1 -0
  48. data/lib/cucumber/cli/options.rb +29 -10
  49. data/lib/cucumber/constantize.rb +1 -1
  50. data/lib/cucumber/core_ext/disable_mini_and_test_unit_autorun.rb +24 -10
  51. data/lib/cucumber/formatter/ansicolor.rb +8 -13
  52. data/lib/cucumber/formatter/console.rb +3 -2
  53. data/lib/cucumber/formatter/cucumber.css +7 -1
  54. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +6 -2
  55. data/lib/cucumber/formatter/html.rb +14 -8
  56. data/lib/cucumber/formatter/interceptor.rb +62 -0
  57. data/lib/cucumber/formatter/json.rb +0 -12
  58. data/lib/cucumber/formatter/junit.rb +31 -15
  59. data/lib/cucumber/formatter/pretty.rb +3 -3
  60. data/lib/cucumber/formatter/progress.rb +1 -1
  61. data/lib/cucumber/formatter/rerun.rb +31 -8
  62. data/lib/cucumber/formatter/usage.rb +1 -1
  63. data/lib/cucumber/js_support/js_language.rb +1 -1
  64. data/lib/cucumber/js_support/js_snippets.rb +1 -1
  65. data/lib/cucumber/language_support/language_methods.rb +0 -4
  66. data/lib/cucumber/parser/gherkin_builder.rb +13 -14
  67. data/lib/cucumber/platform.rb +1 -1
  68. data/lib/cucumber/py_support/py_language.rb +3 -7
  69. data/lib/cucumber/rb_support/rb_dsl.rb +15 -8
  70. data/lib/cucumber/rb_support/rb_language.rb +3 -17
  71. data/lib/cucumber/rb_support/rb_step_definition.rb +17 -5
  72. data/lib/cucumber/rb_support/rb_transform.rb +5 -2
  73. data/lib/cucumber/rb_support/rb_world.rb +9 -5
  74. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +3 -3
  75. data/lib/cucumber/runtime/results.rb +2 -2
  76. data/lib/cucumber/runtime/support_code.rb +14 -19
  77. data/lib/cucumber/runtime.rb +40 -2
  78. data/lib/cucumber/step_match.rb +3 -4
  79. data/lib/cucumber/term/ansicolor.rb +118 -0
  80. data/lib/cucumber/wire_support/wire_protocol/requests.rb +7 -5
  81. data/lib/cucumber/wire_support/wire_protocol.rb +0 -1
  82. data/lib/cucumber.rb +2 -1
  83. data/spec/cucumber/ast/doc_string_spec.rb +2 -2
  84. data/spec/cucumber/ast/feature_factory.rb +4 -3
  85. data/spec/cucumber/ast/scenario_outline_spec.rb +1 -2
  86. data/spec/cucumber/ast/step_spec.rb +1 -1
  87. data/spec/cucumber/ast/table_spec.rb +61 -27
  88. data/spec/cucumber/cli/configuration_spec.rb +12 -6
  89. data/spec/cucumber/cli/main_spec.rb +2 -2
  90. data/spec/cucumber/cli/options_spec.rb +9 -3
  91. data/spec/cucumber/constantize_spec.rb +16 -0
  92. data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
  93. data/spec/cucumber/formatter/html_spec.rb +4 -3
  94. data/spec/cucumber/formatter/interceptor_spec.rb +111 -0
  95. data/spec/cucumber/formatter/junit_spec.rb +36 -20
  96. data/spec/cucumber/formatter/progress_spec.rb +2 -2
  97. data/spec/cucumber/rb_support/rb_language_spec.rb +5 -5
  98. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +20 -4
  99. data/spec/cucumber/rb_support/rb_transform_spec.rb +6 -2
  100. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +7 -3
  101. data/spec/cucumber/runtime/results_spec.rb +81 -0
  102. data/spec/cucumber/step_match_spec.rb +8 -4
  103. data/spec/spec_helper.rb +15 -1
  104. metadata +68 -128
  105. data/.gitignore +0 -26
  106. data/.gitmodules +0 -3
  107. data/.yardopts +0 -0
  108. data/Gemfile.lock +0 -115
  109. data/examples/i18n/de/.gitignore +0 -1
  110. data/examples/i18n/en/.gitignore +0 -1
  111. data/examples/i18n/eo/.gitignore +0 -1
  112. data/examples/i18n/fi/.gitignore +0 -1
  113. data/examples/i18n/hu/.gitignore +0 -1
  114. data/examples/i18n/id/.gitignore +0 -1
  115. data/examples/i18n/ja/.gitignore +0 -1
  116. data/examples/i18n/ko/.gitignore +0 -1
  117. data/examples/i18n/lt/.gitignore +0 -1
  118. data/examples/i18n/pl/.gitignore +0 -1
  119. data/examples/i18n/sk/.gitignore +0 -1
  120. data/examples/i18n/tr/.gitignore +0 -1
  121. data/examples/i18n/zh-TW/.gitignore +0 -1
  122. data/examples/python/lib/.gitignore +0 -1
  123. data/examples/ruby2python/lib/.gitignore +0 -1
  124. data/examples/watir/.gitignore +0 -2
  125. data/fixtures/self_test/.gitignore +0 -1
  126. data/lib/cucumber/formatter/pdf.rb +0 -244
  127. data/lib/cucumber/step_argument.rb +0 -9
@@ -21,7 +21,7 @@ body {
21
21
  float: right;
22
22
  margin: 0 0 0 10px;
23
23
  }
24
- .cucumber .scenario h3, td .scenario h3, th .scenario h3 {
24
+ .cucumber .scenario h3, td .scenario h3, th .scenario h3, .background h3 {
25
25
  font-size: 11px;
26
26
  padding: 3px;
27
27
  margin: 0;
@@ -29,6 +29,12 @@ body {
29
29
  color: white;
30
30
  font-weight: bold;
31
31
  }
32
+
33
+ .background h3 {
34
+ font-size: 1.2em;
35
+ background: #666;
36
+ }
37
+
32
38
  .cucumber h1, td h1, th h1 {
33
39
  margin: 0px 10px 0px 10px;
34
40
  padding: 10px;
@@ -46,8 +46,8 @@ module Cucumber
46
46
  end
47
47
  end
48
48
 
49
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
50
- arguments = step_match.step_arguments.map{|a| Gherkin::Formatter::Argument.new(a.byte_offset, a.val)}
49
+ def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
50
+ arguments = step_match.step_arguments.map{|a| Gherkin::Formatter::Argument.new(a.offset, a.val)}
51
51
  location = step_match.file_colon_line
52
52
  match = Gherkin::Formatter::Model::Match.new(arguments, location)
53
53
  if @print_emtpy_match
@@ -71,6 +71,10 @@ module Cucumber
71
71
  @gf.eof
72
72
  end
73
73
 
74
+ def after_features(features)
75
+ @gf.done
76
+ end
77
+
74
78
  def embed(file, mime_type, label)
75
79
  data = File.read(file)
76
80
  if defined?(JRUBY_VERSION)
@@ -143,7 +143,7 @@ module Cucumber
143
143
 
144
144
  def background_name(keyword, name, file_colon_line, source_indent)
145
145
  @listing_background = true
146
- @builder.h3 do |h3|
146
+ @builder.h3(:id => "background_#{@scenario_number}") do |h3|
147
147
  @builder.span(keyword, :class => 'keyword')
148
148
  @builder.text!(' ')
149
149
  @builder.span(name, :class => 'val')
@@ -221,7 +221,7 @@ module Cucumber
221
221
  move_progress
222
222
  end
223
223
 
224
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
224
+ def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
225
225
  @step_match = step_match
226
226
  @hide_this_step = false
227
227
  if exception
@@ -241,7 +241,7 @@ module Cucumber
241
241
  @builder << "<li id='#{@step_id}' class='step #{status}'>"
242
242
  end
243
243
 
244
- def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
244
+ def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
245
245
  return if @hide_this_step
246
246
  # print snippet for undefined steps
247
247
  if status == :undefined
@@ -254,7 +254,7 @@ module Cucumber
254
254
  print_messages
255
255
  end
256
256
 
257
- def step_name(keyword, step_match, status, source_indent, background)
257
+ def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
258
258
  @step_matches ||= []
259
259
  background_in_scenario = background && !@listing_background
260
260
  @skip_step = @step_matches.index(step_match) || background_in_scenario
@@ -291,7 +291,7 @@ module Cucumber
291
291
  def doc_string(string)
292
292
  return if @hide_this_step
293
293
  @builder.pre(:class => 'val') do |pre|
294
- @builder << h(string.gsub("\n", '&#x000A;'))
294
+ @builder << h(string).gsub("\n", '&#x000A;')
295
295
  end
296
296
  end
297
297
 
@@ -311,7 +311,7 @@ module Cucumber
311
311
  @builder.tr do
312
312
  @builder.td(:colspan => @col_index.to_s, :class => 'failed') do
313
313
  @builder.pre do |pre|
314
- pre << format_exception(table_row.exception)
314
+ pre << h(format_exception(table_row.exception))
315
315
  end
316
316
  end
317
317
  end
@@ -375,8 +375,14 @@ module Cucumber
375
375
  if defined?(RAILS_ROOT) && message.include?('Exception caught')
376
376
  matches = message.match(/Showing <i>(.+)<\/i>(?:.+) #(\d+)/)
377
377
  backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"] if matches
378
- message = message.match(/<code>([^(\/)]+)<\//m)[1]
378
+ matches = message.match(/<code>([^(\/)]+)<\//m)
379
+ message = matches ? matches[1] : ""
379
380
  end
381
+
382
+ unless exception.instance_of?(RuntimeError)
383
+ message = "#{message} (#{exception.class})"
384
+ end
385
+
380
386
  @builder.pre do
381
387
  @builder.text!(message)
382
388
  end
@@ -507,7 +513,7 @@ module Cucumber
507
513
  def inline_js_content
508
514
  <<-EOF
509
515
 
510
- SCENARIOS = "h3[id^='scenario_']";
516
+ SCENARIOS = "h3[id^='scenario_'],h3[id^=background_]";
511
517
 
512
518
  $(document).ready(function() {
513
519
  $(SCENARIOS).css('cursor', 'pointer');
@@ -0,0 +1,62 @@
1
+
2
+ module Cucumber
3
+ module Formatter
4
+ module Interceptor
5
+ class Pipe
6
+ attr_reader :pipe, :buffer
7
+ def initialize(pipe)
8
+ @pipe = pipe
9
+ @buffer = []
10
+ @wrapped = true
11
+ end
12
+
13
+ def write(str)
14
+ @buffer << str if @wrapped
15
+ return @pipe.write(str)
16
+ end
17
+
18
+ def unwrap!
19
+ @wrapped = false
20
+ @pipe
21
+ end
22
+
23
+ def method_missing(method, *args, &blk)
24
+ @pipe.send(method, *args, &blk)
25
+ end
26
+
27
+ def self.validate_pipe(pipe)
28
+ unless [:stdout, :stderr].include? pipe
29
+ raise ArgumentError, '#wrap only accepts :stderr or :stdout'
30
+ end
31
+ end
32
+
33
+ def self.unwrap!(pipe)
34
+ validate_pipe pipe
35
+ wrapped = nil
36
+ case pipe
37
+ when :stdout
38
+ wrapped = $stdout
39
+ $stdout = wrapped.unwrap!
40
+ when :stderr
41
+ wrapped = $stderr
42
+ $stderr = wrapped.unwrap!
43
+ end
44
+ wrapped
45
+ end
46
+
47
+ def self.wrap(pipe)
48
+ validate_pipe pipe
49
+
50
+ case pipe
51
+ when :stderr
52
+ $stderr = self.new($stderr)
53
+ return $stderr
54
+ when :stdout
55
+ $stdout = self.new($stdout)
56
+ return $stdout
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -11,20 +11,8 @@ module Cucumber
11
11
 
12
12
  def initialize(step_mother, io, options)
13
13
  @io = ensure_io(io, "json")
14
- @io.write('{"features":[')
15
14
  super(Gherkin::Formatter::JSONFormatter.new(@io), false)
16
15
  end
17
-
18
- def before_feature(feature)
19
- super
20
- @io.write(',') if @one
21
- @one = true
22
- end
23
-
24
- def after_features(features)
25
- @io.write(']}')
26
- @io.flush
27
- end
28
16
  end
29
17
  end
30
18
  end
@@ -1,5 +1,6 @@
1
1
  require 'cucumber/formatter/ordered_xml_markup'
2
2
  require 'cucumber/formatter/io'
3
+ require 'cucumber/formatter/interceptor'
3
4
  require 'fileutils'
4
5
 
5
6
  module Cucumber
@@ -7,13 +8,13 @@ module Cucumber
7
8
  # The formatter used for <tt>--format junit</tt>
8
9
  class Junit
9
10
  include Io
10
-
11
+
11
12
  class UnNamedFeatureError < StandardError
12
13
  def initialize(feature_file)
13
14
  super("The feature in '#{feature_file}' does not have a name. The JUnit XML format requires a name for the testsuite element.")
14
15
  end
15
16
  end
16
-
17
+
17
18
  def initialize(step_mother, io, options)
18
19
  @reportdir = ensure_dir(io, "junit")
19
20
  @options = options
@@ -24,12 +25,17 @@ module Cucumber
24
25
  @failures = @errors = @tests = @skipped = 0
25
26
  @builder = OrderedXmlMarkup.new( :indent => 2 )
26
27
  @time = 0
28
+ # In order to fill out <system-err/> and <system-out/>, we need to
29
+ # intercept the $stderr and $stdout
30
+ @interceptedout = Interceptor::Pipe.wrap(:stdout)
31
+ @interceptederr = Interceptor::Pipe.wrap(:stderr)
27
32
  end
28
-
33
+
29
34
  def before_feature_element(feature_element)
30
35
  @in_examples = Ast::ScenarioOutline === feature_element
36
+ @steps_start = Time.now
31
37
  end
32
-
38
+
33
39
  def after_feature(feature)
34
40
  @testsuite = OrderedXmlMarkup.new( :indent => 2 )
35
41
  @testsuite.instruct!
@@ -41,15 +47,24 @@ module Cucumber
41
47
  :time => "%.6f" % @time,
42
48
  :name => @feature_name ) do
43
49
  @testsuite << @builder.target!
50
+ @testsuite.tag!('system-out') do
51
+ @testsuite.cdata! @interceptedout.buffer.join
52
+ end
53
+ @testsuite.tag!('system-err') do
54
+ @testsuite.cdata! @interceptederr.buffer.join
55
+ end
44
56
  end
45
57
 
46
58
  write_file(feature_result_filename(feature.file), @testsuite.target!)
59
+
60
+ Interceptor::Pipe.unwrap! :stdout
61
+ Interceptor::Pipe.unwrap! :stderr
47
62
  end
48
63
 
49
64
  def before_background(*args)
50
65
  @in_background = true
51
66
  end
52
-
67
+
53
68
  def after_background(*args)
54
69
  @in_background = false
55
70
  end
@@ -66,12 +81,11 @@ module Cucumber
66
81
  end
67
82
 
68
83
  def before_steps(steps)
69
- @steps_start = Time.now
70
84
  end
71
-
85
+
72
86
  def after_steps(steps)
73
87
  return if @in_background || @in_examples
74
-
88
+
75
89
  duration = Time.now - @steps_start
76
90
  if steps.failed?
77
91
  steps.each { |step| @output += "#{step.keyword}#{step.name}\n" }
@@ -79,12 +93,12 @@ module Cucumber
79
93
  end
80
94
  build_testcase(duration, steps.status, steps.exception)
81
95
  end
82
-
96
+
83
97
  def before_examples(*args)
84
98
  @header_row = true
85
99
  @in_examples = true
86
100
  end
87
-
101
+
88
102
  def after_examples(*args)
89
103
  @in_examples = false
90
104
  end
@@ -106,7 +120,7 @@ module Cucumber
106
120
  end
107
121
  build_testcase(duration, table_row.status, table_row.exception, name_suffix)
108
122
  end
109
-
123
+
110
124
  @header_row = false if @header_row
111
125
  end
112
126
 
@@ -114,7 +128,7 @@ module Cucumber
114
128
 
115
129
  def build_testcase(duration, status, exception = nil, suffix = "")
116
130
  @time += duration
117
- classname = "#{@feature_name}.#{@scenario}"
131
+ classname = @feature_name
118
132
  name = "#{@scenario}#{suffix}"
119
133
  pending = [:pending, :undefined].include?(status)
120
134
  passed = (status == :passed || (pending && !@options[:strict]))
@@ -131,6 +145,8 @@ module Cucumber
131
145
  @builder.skipped
132
146
  @skipped += 1
133
147
  end
148
+ @builder.tag!('system-out')
149
+ @builder.tag!('system-err')
134
150
  end
135
151
  @tests += 1
136
152
  end
@@ -138,15 +154,15 @@ module Cucumber
138
154
  def format_exception(exception)
139
155
  (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
140
156
  end
141
-
157
+
142
158
  def feature_result_filename(feature_file)
143
159
  File.join(@reportdir, "TEST-#{basename(feature_file)}.xml")
144
160
  end
145
-
161
+
146
162
  def basename(feature_file)
147
163
  File.basename(feature_file.gsub(/[\\\/]/, '-'), '.feature')
148
164
  end
149
-
165
+
150
166
  def write_file(feature_filename, data)
151
167
  File.open(feature_filename, 'w') { |file| file.write(data) }
152
168
  end
@@ -129,7 +129,7 @@ module Cucumber
129
129
  @indent = 6
130
130
  end
131
131
 
132
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
132
+ def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
133
133
  @hide_this_step = false
134
134
  if exception
135
135
  if @exceptions.include?(exception)
@@ -145,7 +145,7 @@ module Cucumber
145
145
  @status = status
146
146
  end
147
147
 
148
- def step_name(keyword, step_match, status, source_indent, background)
148
+ def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
149
149
  return if @hide_this_step
150
150
  source_indent = nil unless @options[:source]
151
151
  name_to_report = format_step(keyword, step_match, status, source_indent)
@@ -203,7 +203,7 @@ module Cucumber
203
203
  cell_text = escape_cell(value.to_s || '')
204
204
  padded = cell_text + (' ' * (width - cell_text.unpack('U*').length))
205
205
  prefix = cell_prefix(status)
206
- @io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Term::ANSIColor.reset(" |"))
206
+ @io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Cucumber::Term::ANSIColor.reset(" |"))
207
207
  @io.flush
208
208
  end
209
209
 
@@ -37,7 +37,7 @@ module Cucumber
37
37
  @exception_raised = false
38
38
  end
39
39
 
40
- def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
40
+ def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
41
41
  progress(status)
42
42
  @status = status
43
43
  end
@@ -22,9 +22,9 @@ module Cucumber
22
22
  @file_colon_lines = Hash.new{|h,k| h[k] = []}
23
23
  end
24
24
 
25
- def before_feature(*)
25
+ def before_feature(feature_element)
26
26
  @lines = []
27
- @file = nil
27
+ @file = feature_element.file
28
28
  end
29
29
 
30
30
  def after_feature(*)
@@ -46,17 +46,40 @@ module Cucumber
46
46
  end
47
47
 
48
48
  def after_feature_element(feature_element)
49
- if @rerun
50
- file, line = *feature_element.file_colon_line.split(':')
51
- @lines << line
52
- @file = file
49
+ if (@rerun || feature_element.failed?) && !(Ast::ScenarioOutline === feature_element)
50
+ @lines << feature_element.line
53
51
  end
54
52
  end
55
53
 
56
- def step_name(keyword, step_match, status, source_indent, background)
57
- @rerun = true if [:failed, :pending, :undefined].index(status)
54
+ def after_table_row(table_row)
55
+ return unless @in_examples and Cucumber::Ast::OutlineTable::ExampleRow === table_row
56
+ unless @header_row
57
+ if table_row.failed?
58
+ @rerun = true
59
+ @lines << table_row.line
60
+ end
61
+ end
62
+
63
+ @header_row = false if @header_row
64
+ end
65
+
66
+ def before_examples(*args)
67
+ @header_row = true
68
+ @in_examples = true
58
69
  end
59
70
 
71
+ def after_examples(*args)
72
+ @in_examples = false
73
+ end
74
+
75
+ def before_table_row(table_row)
76
+ return unless @in_examples
77
+ end
78
+
79
+ def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
80
+ @rerun = true if [:failed, :pending, :undefined].index(status)
81
+ end
82
+
60
83
  private
61
84
 
62
85
  def after_first_time
@@ -26,7 +26,7 @@ module Cucumber
26
26
  @duration = Time.now - @start_time
27
27
  end
28
28
 
29
- def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
29
+ def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
30
30
  if step_match.name.nil? # nil if it's from a scenario outline
31
31
  stepdef_key = StepDefKey.new(step_match.step_definition.regexp_source, step_match.step_definition.file_colon_line)
32
32
 
@@ -97,7 +97,7 @@ module Cucumber
97
97
  @arg
98
98
  end
99
99
 
100
- def byte_offset
100
+ def offset
101
101
  end
102
102
  end
103
103
 
@@ -1,7 +1,7 @@
1
1
  module Cucumber
2
2
  module JsSupport
3
3
  module JsSnippets
4
- PARAM_PATTERN = /"([^"]*)"/
4
+ PARAM_PATTERN = /"(.*?)"/
5
5
  ESCAPED_PARAM_PATTERN = '"([^\\"]*)"'
6
6
 
7
7
  def snippet_text(code_keyword, step_name, multiline_arg_class)
@@ -4,10 +4,6 @@ require 'cucumber/step_definition_light'
4
4
  module Cucumber
5
5
  module LanguageSupport
6
6
  module LanguageMethods
7
- def create_step_match(step_definition, step_name, name_to_report, step_arguments)
8
- StepMatch.new(step_definition, step_name, name_to_report, step_arguments)
9
- end
10
-
11
7
  def around(scenario)
12
8
  execute_around(scenario) do
13
9
  yield
@@ -1,5 +1,6 @@
1
1
  require 'cucumber/ast'
2
2
  require 'gherkin/rubify'
3
+ require 'cucumber/ast/multiline_argument'
3
4
 
4
5
  module Cucumber
5
6
  module Parser
@@ -17,7 +18,7 @@ module Cucumber
17
18
  @feature = Ast::Feature.new(
18
19
  nil,
19
20
  Ast::Comment.new(feature.comments.map{|comment| comment.value}.join("\n")),
20
- Ast::Tags.new(nil, feature.tags.map{|tag| tag.name}),
21
+ Ast::Tags.new(nil, feature.tags),
21
22
  feature.keyword,
22
23
  feature.name.lstrip,
23
24
  feature.description.rstrip,
@@ -46,7 +47,7 @@ module Cucumber
46
47
  scenario = Ast::Scenario.new(
47
48
  @background,
48
49
  Ast::Comment.new(statement.comments.map{|comment| comment.value}.join("\n")),
49
- Ast::Tags.new(nil, statement.tags.map{|tag| tag.name}),
50
+ Ast::Tags.new(nil, statement.tags),
50
51
  statement.line,
51
52
  statement.keyword,
52
53
  statement.name,
@@ -63,7 +64,7 @@ module Cucumber
63
64
  scenario_outline = Ast::ScenarioOutline.new(
64
65
  @background,
65
66
  Ast::Comment.new(statement.comments.map{|comment| comment.value}.join("\n")),
66
- Ast::Tags.new(nil, statement.tags.map{|tag| tag.name}),
67
+ Ast::Tags.new(nil, statement.tags),
67
68
  statement.line,
68
69
  statement.keyword,
69
70
  statement.name,
@@ -92,17 +93,15 @@ module Cucumber
92
93
  @step_container.add_examples(examples_fields, examples)
93
94
  end
94
95
 
95
- def step(step)
96
- @table_owner = Ast::Step.new(step.line, step.keyword, step.name)
97
- @table_owner.gherkin_statement(step)
98
- multiline_arg = rubify(step.multiline_arg)
99
- case(multiline_arg)
100
- when Gherkin::Formatter::Model::DocString
101
- @table_owner.multiline_arg = Ast::DocString.new(multiline_arg.value)
102
- when Array
103
- @table_owner.multiline_arg = Ast::Table.new(matrix(multiline_arg))
104
- end
105
- @step_container.add_step(@table_owner)
96
+ def step(gherkin_step)
97
+ step = Ast::Step.new(
98
+ gherkin_step.line,
99
+ gherkin_step.keyword,
100
+ gherkin_step.name,
101
+ Ast::MultilineArgument.from(gherkin_step.doc_string || gherkin_step.rows)
102
+ )
103
+ step.gherkin_statement(gherkin_step)
104
+ @step_container.add_step(step)
106
105
  end
107
106
 
108
107
  def eof
@@ -4,7 +4,7 @@ require 'rbconfig'
4
4
 
5
5
  module Cucumber
6
6
  unless defined?(Cucumber::VERSION)
7
- VERSION = '1.0.2.1'
7
+ VERSION = '1.2.1.cb2'
8
8
  BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
9
9
  LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
10
10
  JRUBY = defined?(JRUBY_VERSION)
@@ -24,10 +24,6 @@ module Cucumber
24
24
  def alias_adverbs(adverbs)
25
25
  end
26
26
 
27
- def step_definitions_for(py_file)
28
- mod = import(py_file)
29
- end
30
-
31
27
  def snippet_text(code_keyword, step_name, multiline_arg_class)
32
28
  "python snippet: #{code_keyword}, #{step_name}"
33
29
  end
@@ -35,12 +31,12 @@ module Cucumber
35
31
  def begin_scenario(scenario)
36
32
  @python_path = []
37
33
  add_to_python_path(File.dirname(__FILE__))
38
- @step_def_files.each{|f| add_to_python_path(File.dirname(f))}
34
+ @step_def_files.each { |f| add_to_python_path(File.dirname(f)) }
39
35
 
40
36
  RubyPython.start
41
37
 
42
38
  @delegate = import(File.dirname(__FILE__) + '/py_language.py')
43
- @step_def_files.each{|f| import(f)}
39
+ @step_def_files.each { |f| import(f) }
44
40
  end
45
41
 
46
42
  def end_scenario
@@ -56,7 +52,7 @@ module Cucumber
56
52
  modname = File.basename(path)[0...-File.extname(path).length]
57
53
  begin
58
54
  mod = RubyPython.import(modname)
59
- rescue PythonError => e
55
+ rescue RubyPython::PythonError => e
60
56
  # e.message << "Couldn't load #{path}\nConsider adding #{File.expand_path(File.dirname(path))} to your PYTHONPATH"
61
57
  raise e
62
58
  end
@@ -23,8 +23,8 @@ module Cucumber
23
23
  @rb_language.register_rb_transform(regexp, proc)
24
24
  end
25
25
 
26
- def register_rb_step_definition(regexp, proc)
27
- @rb_language.register_rb_step_definition(regexp, proc)
26
+ def register_rb_step_definition(regexp, proc_or_sym, options = {})
27
+ @rb_language.register_rb_step_definition(regexp, proc_or_sym, options)
28
28
  end
29
29
  end
30
30
 
@@ -98,12 +98,19 @@ module Cucumber
98
98
  # also to the i18n translations whenever a feature of a
99
99
  # new language is loaded.
100
100
  #
101
- # The +&proc+ gets executed in the context of a <tt>World</tt>
102
- # object, which is defined by #World. A new <tt>World</tt>
103
- # object is created for each scenario and is shared across
104
- # step definitions within that scenario.
105
- def register_rb_step_definition(regexp, &proc)
106
- RbDsl.register_rb_step_definition(regexp, proc)
101
+ # If provided, the +symbol+ is sent to the <tt>World</tt> object
102
+ # as defined by #World. A new <tt>World</tt> object is created
103
+ # for each scenario and is shared across step definitions within
104
+ # that scenario. If the +options+ hash contains an <tt>:on</tt>
105
+ # key, the value for this is assumed to be a proc. This proc
106
+ # will be executed in the context of the <tt>World</tt> object
107
+ # and then sent the +symbol+.
108
+ #
109
+ # If no +symbol+ if provided then the +&proc+ gets executed in
110
+ # the context of the <tt>World</tt> object.
111
+ def register_rb_step_definition(regexp, symbol = nil, options = {}, &proc)
112
+ proc_or_sym = symbol || proc
113
+ RbDsl.register_rb_step_definition(regexp, proc_or_sym, options)
107
114
  end
108
115
  end
109
116
  end
@@ -65,20 +65,6 @@ module Cucumber
65
65
  end
66
66
  end
67
67
 
68
- # Gets called for each file under features (or whatever is overridden
69
- # with --require).
70
- def step_definitions_for(rb_file) # Looks Unused - Delete?
71
- begin
72
- require rb_file # This will cause self.add_step_definition and self.add_hook to be called from RbDsl
73
- step_definitions
74
- rescue LoadError => e
75
- e.message << "\nFailed to load #{code_file}"
76
- raise e
77
- ensure
78
- @step_definitions = nil
79
- end
80
- end
81
-
82
68
  def step_matches(name_to_match, name_to_format)
83
69
  @step_definitions.map do |step_definition|
84
70
  if(arguments = step_definition.arguments_from(name_to_match))
@@ -89,7 +75,7 @@ module Cucumber
89
75
  end.compact
90
76
  end
91
77
 
92
- ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)']
78
+ ARGUMENT_PATTERNS = ['"(.*?)"', '(\d+)']
93
79
 
94
80
  def snippet_text(code_keyword, step_name, multiline_arg_class)
95
81
  snippet_pattern = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
@@ -124,8 +110,8 @@ module Cucumber
124
110
  add_transform(RbTransform.new(self, regexp, proc))
125
111
  end
126
112
 
127
- def register_rb_step_definition(regexp, proc)
128
- step_definition = RbStepDefinition.new(self, regexp, proc)
113
+ def register_rb_step_definition(regexp, proc_or_sym, options)
114
+ step_definition = RbStepDefinition.new(self, regexp, proc_or_sym, options)
129
115
  @step_definitions << step_definition
130
116
  step_definition
131
117
  end