cucumber 3.2.0 → 4.0.0.rc.1

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 (90) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +61 -18
  3. data/CONTRIBUTING.md +1 -0
  4. data/bin/cucumber +1 -1
  5. data/lib/autotest/cucumber_mixin.rb +42 -39
  6. data/lib/cucumber/cli/configuration.rb +4 -4
  7. data/lib/cucumber/cli/main.rb +11 -12
  8. data/lib/cucumber/cli/options.rb +56 -69
  9. data/lib/cucumber/cli/profile_loader.rb +32 -20
  10. data/lib/cucumber/configuration.rb +20 -21
  11. data/lib/cucumber/constantize.rb +2 -5
  12. data/lib/cucumber/deprecate.rb +5 -5
  13. data/lib/cucumber/errors.rb +4 -6
  14. data/lib/cucumber/events.rb +1 -0
  15. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  16. data/lib/cucumber/events/step_activated.rb +2 -1
  17. data/lib/cucumber/file_specs.rb +6 -6
  18. data/lib/cucumber/filters/activate_steps.rb +5 -3
  19. data/lib/cucumber/filters/prepare_world.rb +5 -9
  20. data/lib/cucumber/filters/quit.rb +1 -3
  21. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
  22. data/lib/cucumber/formatter/ansicolor.rb +40 -45
  23. data/lib/cucumber/formatter/ast_lookup.rb +160 -0
  24. data/lib/cucumber/formatter/backtrace_filter.rb +5 -7
  25. data/lib/cucumber/formatter/console.rb +28 -59
  26. data/lib/cucumber/formatter/console_counts.rb +4 -9
  27. data/lib/cucumber/formatter/console_issues.rb +6 -3
  28. data/lib/cucumber/formatter/duration_extractor.rb +1 -1
  29. data/lib/cucumber/formatter/fanout.rb +2 -0
  30. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  31. data/lib/cucumber/formatter/interceptor.rb +5 -7
  32. data/lib/cucumber/formatter/io.rb +8 -14
  33. data/lib/cucumber/formatter/json.rb +93 -117
  34. data/lib/cucumber/formatter/junit.rb +55 -57
  35. data/lib/cucumber/formatter/pretty.rb +346 -152
  36. data/lib/cucumber/formatter/progress.rb +28 -32
  37. data/lib/cucumber/formatter/rerun.rb +22 -4
  38. data/lib/cucumber/formatter/stepdefs.rb +1 -2
  39. data/lib/cucumber/formatter/steps.rb +2 -3
  40. data/lib/cucumber/formatter/summary.rb +16 -8
  41. data/lib/cucumber/formatter/unicode.rb +15 -17
  42. data/lib/cucumber/formatter/usage.rb +9 -8
  43. data/lib/cucumber/gherkin/data_table_parser.rb +8 -6
  44. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
  45. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
  46. data/lib/cucumber/gherkin/steps_parser.rb +7 -8
  47. data/lib/cucumber/glue/dsl.rb +1 -1
  48. data/lib/cucumber/glue/hook.rb +16 -9
  49. data/lib/cucumber/glue/invoke_in_world.rb +13 -18
  50. data/lib/cucumber/glue/proto_world.rb +14 -16
  51. data/lib/cucumber/glue/registry_and_more.rb +7 -9
  52. data/lib/cucumber/glue/snippet.rb +21 -20
  53. data/lib/cucumber/glue/step_definition.rb +14 -15
  54. data/lib/cucumber/glue/world_factory.rb +1 -1
  55. data/lib/cucumber/hooks.rb +11 -11
  56. data/lib/cucumber/multiline_argument.rb +4 -6
  57. data/lib/cucumber/multiline_argument/data_table.rb +88 -59
  58. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
  59. data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
  60. data/lib/cucumber/platform.rb +3 -3
  61. data/lib/cucumber/rake/task.rb +13 -16
  62. data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
  63. data/lib/cucumber/running_test_case.rb +2 -53
  64. data/lib/cucumber/runtime.rb +27 -57
  65. data/lib/cucumber/runtime/after_hooks.rb +3 -3
  66. data/lib/cucumber/runtime/before_hooks.rb +3 -3
  67. data/lib/cucumber/runtime/for_programming_languages.rb +3 -2
  68. data/lib/cucumber/runtime/step_hooks.rb +1 -1
  69. data/lib/cucumber/runtime/support_code.rb +10 -12
  70. data/lib/cucumber/runtime/user_interface.rb +4 -6
  71. data/lib/cucumber/step_definition_light.rb +4 -3
  72. data/lib/cucumber/step_match.rb +12 -11
  73. data/lib/cucumber/step_match_search.rb +2 -1
  74. data/lib/cucumber/term/ansicolor.rb +9 -9
  75. data/lib/cucumber/version +1 -1
  76. metadata +37 -28
  77. data/lib/cucumber/formatter/cucumber.css +0 -286
  78. data/lib/cucumber/formatter/cucumber.sass +0 -247
  79. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  80. data/lib/cucumber/formatter/html.rb +0 -611
  81. data/lib/cucumber/formatter/html_builder.rb +0 -121
  82. data/lib/cucumber/formatter/http_io.rb +0 -146
  83. data/lib/cucumber/formatter/inline-js.js +0 -30
  84. data/lib/cucumber/formatter/jquery-min.js +0 -154
  85. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  86. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  87. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  88. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  89. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  90. data/lib/cucumber/step_argument.rb +0 -25
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ class AstLookup
6
+ def initialize(config)
7
+ @gherkin_documents = {}
8
+ @test_case_lookups = {}
9
+ @test_step_lookups = {}
10
+ @step_keyword_lookups = {}
11
+ config.on_event :gherkin_source_parsed, &method(:on_gherkin_source_parsed)
12
+ end
13
+
14
+ def on_gherkin_source_parsed(event)
15
+ @gherkin_documents[event.gherkin_document[:uri]] = event.gherkin_document
16
+ end
17
+
18
+ def gherkin_document(uri)
19
+ @gherkin_documents[uri]
20
+ end
21
+
22
+ def scenario_source(test_case)
23
+ uri = test_case.location.file
24
+ @test_case_lookups[uri] ||= TestCaseLookupBuilder.new(gherkin_document(uri)).lookup_hash
25
+ @test_case_lookups[uri][test_case.location.lines.max]
26
+ end
27
+
28
+ def step_source(test_step)
29
+ uri = test_step.location.file
30
+ @test_step_lookups[uri] ||= TestStepLookupBuilder.new(gherkin_document(uri)).lookup_hash
31
+ @test_step_lookups[uri][test_step.location.lines.min]
32
+ end
33
+
34
+ def snippet_step_keyword(test_step)
35
+ uri = test_step.location.file
36
+ document = gherkin_document(uri)
37
+ dialect = ::Gherkin::Dialect.for(document[:feature][:language])
38
+ given_when_then_keywords = [dialect.given_keywords, dialect.when_keywords, dialect.then_keywords].flatten.uniq.reject { |kw| kw == '* ' }
39
+ keyword_lookup = step_keyword_lookup(uri)
40
+ keyword = nil
41
+ node = keyword_lookup[test_step.location.lines.min]
42
+ while keyword.nil?
43
+ if given_when_then_keywords.include?(node.keyword)
44
+ keyword = node.keyword
45
+ break
46
+ end
47
+ break if node.previous_node.nil?
48
+ node = node.previous_node
49
+ end
50
+ keyword = dialect.given_keywords.reject { |kw| kw == '* ' }[0] if keyword.nil?
51
+ keyword = Cucumber::Gherkin::I18n.code_keyword_for(keyword)
52
+ keyword
53
+ end
54
+
55
+ ScenarioSource = Struct.new(:type, :scenario)
56
+
57
+ ScenarioOutlineSource = Struct.new(:type, :scenario_outline, :examples, :row)
58
+
59
+ StepSource = Struct.new(:type, :step)
60
+
61
+ private
62
+
63
+ def step_keyword_lookup(uri)
64
+ @step_keyword_lookups[uri] ||= KeywordLookupBuilder.new(gherkin_document(uri)).lookup_hash
65
+ end
66
+
67
+ class TestCaseLookupBuilder
68
+ attr_reader :lookup_hash
69
+
70
+ def initialize(gherkin_document)
71
+ @lookup_hash = {}
72
+ process_scenario_container(gherkin_document[:feature])
73
+ end
74
+
75
+ private
76
+
77
+ def process_scenario_container(container)
78
+ container[:children].each do |child|
79
+ if !child[:rule].nil?
80
+ process_scenario_container(child[:rule])
81
+ elsif !child[:scenario].nil?
82
+ if child[:scenario][:examples].empty?
83
+ @lookup_hash[child[:scenario][:location][:line]] = ScenarioSource.new(:Scenario, child[:scenario])
84
+
85
+ else
86
+ child[:scenario][:examples].each do |examples|
87
+ examples[:table_body].each do |row|
88
+ @lookup_hash[row[:location][:line]] = ScenarioOutlineSource.new(:ScenarioOutline, child[:scenario], examples, row)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ class TestStepLookupBuilder
98
+ attr_reader :lookup_hash
99
+
100
+ def initialize(gherkin_document)
101
+ @lookup_hash = {}
102
+ process_scenario_container(gherkin_document[:feature])
103
+ end
104
+
105
+ private
106
+
107
+ def process_scenario_container(container)
108
+ container[:children].each do |child|
109
+ if !child[:rule].nil?
110
+ process_scenario_container(child[:rule])
111
+ elsif !child[:scenario].nil?
112
+ child[:scenario][:steps].each do |step|
113
+ @lookup_hash[step[:location][:line]] = StepSource.new(:Step, step)
114
+ end
115
+ elsif !child[:background].nil?
116
+ child[:background][:steps].each do |step|
117
+ @lookup_hash[step[:location][:line]] = StepSource.new(:Step, step)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ KeywordSearchNode = Struct.new(:keyword, :previous_node)
125
+
126
+ class KeywordLookupBuilder
127
+ attr_reader :lookup_hash
128
+
129
+ def initialize(gherkin_document)
130
+ @lookup_hash = {}
131
+ process_scenario_container(gherkin_document[:feature], nil)
132
+ end
133
+
134
+ private
135
+
136
+ def process_scenario_container(container, original_previous_node)
137
+ container[:children].each do |child|
138
+ previous_node = original_previous_node
139
+ if !child[:rule].nil?
140
+ process_scenario_container(child[:rule], original_previous_node)
141
+ elsif !child[:scenario].nil?
142
+ child[:scenario][:steps].each do |step|
143
+ node = KeywordSearchNode.new(step[:keyword], previous_node)
144
+ @lookup_hash[step[:location][:line]] = node
145
+ previous_node = node
146
+ end
147
+ elsif !child[:background].nil?
148
+ child[:background][:steps].each do |step|
149
+ node = KeywordSearchNode.new(step[:keyword], previous_node)
150
+ @lookup_hash[step[:location][:line]] = node
151
+ previous_node = node
152
+ original_previous_node = previous_node
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -4,7 +4,7 @@ require 'cucumber/platform'
4
4
 
5
5
  module Cucumber
6
6
  module Formatter
7
- @backtrace_filters = %w(
7
+ @backtrace_filters = %w[
8
8
  /vendor/rails
9
9
  lib/cucumber
10
10
  bin/cucumber:
@@ -15,11 +15,9 @@ module Cucumber
15
15
  .gem/ruby
16
16
  lib/ruby/
17
17
  bin/bundle
18
- )
18
+ ]
19
19
 
20
- if ::Cucumber::JRUBY
21
- @backtrace_filters << 'org/jruby/'
22
- end
20
+ @backtrace_filters << 'org/jruby/' if ::Cucumber::JRUBY
23
21
 
24
22
  BACKTRACE_FILTER_PATTERNS = Regexp.new(@backtrace_filters.join('|'))
25
23
 
@@ -31,7 +29,7 @@ module Cucumber
31
29
  def exception
32
30
  return @exception if ::Cucumber.use_full_backtrace
33
31
 
34
- pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m
32
+ pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m # rubocop:disable Style/RegexpLiteral
35
33
  backtrace = @exception.backtrace.map { |line| line.gsub(pwd_pattern, './') }
36
34
 
37
35
  filtered = (backtrace || []).reject do |line|
@@ -41,7 +39,7 @@ module Cucumber
41
39
  if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
42
40
  # Strip off file locations
43
41
  filtered = filtered.map do |line|
44
- line =~ /(.*):in `/ ? $1 : line
42
+ line =~ /(.*):in `/ ? Regexp.last_match(1) : line
45
43
  end
46
44
  end
47
45
 
@@ -46,7 +46,7 @@ module Cucumber
46
46
  def format_string(o, status)
47
47
  fmt = format_for(status)
48
48
  o.to_s.split("\n").map do |line|
49
- if Proc === fmt
49
+ if Proc == fmt.class
50
50
  fmt.call(line)
51
51
  else
52
52
  fmt % line
@@ -54,10 +54,6 @@ module Cucumber
54
54
  end.join("\n")
55
55
  end
56
56
 
57
- def print_steps(status)
58
- print_elements(runtime.steps(status), status, 'steps')
59
- end
60
-
61
57
  def print_elements(elements, status, kind)
62
58
  return if elements.empty?
63
59
 
@@ -109,26 +105,23 @@ module Cucumber
109
105
  end
110
106
 
111
107
  # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10655
112
- def linebreaks(s, max)
113
- return s unless max && max > 0
114
- s.gsub(/.{1,#{max}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }.rstrip
108
+ def linebreaks(msg, max)
109
+ return msg unless max && max > 0
110
+ msg.gsub(/.{1,#{max}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }.rstrip
115
111
  end
116
112
 
117
- def collect_snippet_data(test_step, result)
113
+ def collect_snippet_data(test_step, ast_lookup)
118
114
  # collect snippet data for undefined steps
119
- return if hook?(test_step)
120
- keyword = test_step.source.last.actual_keyword(@previous_step_keyword)
121
- @previous_step_keyword = keyword
122
- return unless result.undefined?
123
- @snippets_input << Console::SnippetData.new(keyword, test_step.source.last)
115
+ keyword = ast_lookup.snippet_step_keyword(test_step)
116
+ @snippets_input << Console::SnippetData.new(keyword, test_step)
124
117
  end
125
118
 
126
119
  def print_snippets(options)
127
120
  return unless options[:snippets]
128
- return if runtime.steps(:undefined).empty?
121
+ return if @snippets_input.empty?
129
122
 
130
123
  snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
131
- runtime.snippet_text(step_keyword, step_name, multiline_arg)
124
+ snippet_text(step_keyword, step_name, multiline_arg)
132
125
  end
133
126
  do_print_snippets(snippet_text_proc)
134
127
  end
@@ -146,10 +139,14 @@ module Cucumber
146
139
  @io.flush
147
140
  end
148
141
 
149
- def print_passing_wip(options)
150
- return unless options[:wip]
151
- passed_messages = element_messages(runtime.scenarios(:passed), :passed)
152
- do_print_passing_wip(passed_messages)
142
+ def print_passing_wip(config, passed_test_cases, ast_lookup)
143
+ return unless config.wip?
144
+ messages = passed_test_cases.map do |test_case|
145
+ scenario_source = ast_lookup.scenario_source(test_case)
146
+ keyword = scenario_source.type == :Scenario ? scenario_source.scenario[:keyword] : scenario_source.scenario_outline[:keyword]
147
+ linebreaks("#{test_case.location.on_line(test_case.location.lines.max)}:in `#{keyword}: #{test_case.name}'", ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
148
+ end
149
+ do_print_passing_wip(messages)
153
150
  end
154
151
 
155
152
  def do_print_passing_wip(passed_messages)
@@ -165,51 +162,26 @@ module Cucumber
165
162
  # no-op
166
163
  end
167
164
 
168
- # define @delayed_messages = [] in your Formatter if you want to
169
- # activate this feature
170
165
  def puts(*messages)
171
- if @delayed_messages
172
- @delayed_messages += messages
173
- else
174
- if @io
175
- @io.puts
176
- messages.each do |message|
177
- @io.puts(format_string(message, :tag))
178
- end
179
- @io.flush
180
- end
166
+ return unless @io
167
+ @io.puts
168
+ messages.each do |message|
169
+ @io.puts(format_string(message, :tag))
181
170
  end
182
- end
183
-
184
- def print_messages
185
- @delayed_messages.each { |message| print_message(message) }
186
- empty_messages
187
- end
188
-
189
- def print_table_row_messages
190
- return if @delayed_messages.empty?
191
- @io.print(format_string(@delayed_messages.join(', '), :tag).indent(2))
192
- @io.flush
193
- empty_messages
194
- end
195
-
196
- def print_message(message)
197
- @io.puts(format_string(message, :tag).indent(@indent))
198
171
  @io.flush
199
172
  end
200
173
 
201
- def empty_messages
202
- @delayed_messages = []
203
- end
204
-
205
174
  def print_profile_information
206
175
  return if @options[:skip_profile_information] || @options[:profiles].nil? || @options[:profiles].empty?
207
176
  do_print_profile_information(@options[:profiles])
208
177
  end
209
178
 
210
179
  def do_print_profile_information(profiles)
211
- profiles_sentence = profiles.size == 1 ? profiles.first :
212
- "#{profiles[0...-1].join(', ')} and #{profiles.last}"
180
+ profiles_sentence = if profiles.size == 1
181
+ profiles.first
182
+ else
183
+ "#{profiles[0...-1].join(', ')} and #{profiles.last}"
184
+ end
213
185
 
214
186
  @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size > 1}..."
215
187
  end
@@ -225,10 +197,6 @@ module Cucumber
225
197
  fmt
226
198
  end
227
199
 
228
- def hook?(test_step)
229
- not test_step.source.last.respond_to?(:actual_keyword)
230
- end
231
-
232
200
  def element_messages(elements, status)
233
201
  elements.map do |element|
234
202
  if status == :failed
@@ -249,7 +217,8 @@ module Cucumber
249
217
  class SnippetData
250
218
  attr_reader :actual_keyword, :step
251
219
  def initialize(actual_keyword, step)
252
- @actual_keyword, @step = actual_keyword, step
220
+ @actual_keyword = actual_keyword
221
+ @step = step
253
222
  end
254
223
  end
255
224
  end
@@ -29,15 +29,10 @@ module Cucumber
29
29
  end
30
30
 
31
31
  def status_counts(summary)
32
- counts = Core::Test::Result::TYPES.map do |status|
33
- count = summary.total(status)
34
- [status, count]
35
- end.select do |status, count|
36
- count > 0
37
- end.map do |status, count|
38
- format_string("#{count} #{status}", status)
39
- end
40
- "(#{counts.join(", ")})" if counts.any?
32
+ counts = Core::Test::Result::TYPES.map { |status| [status, summary.total(status)] }
33
+ counts = counts.select { |_status, count| count > 0 }
34
+ counts = counts.map { |status, count| format_string("#{count} #{status}", status) }
35
+ "(#{counts.join(', ')})" if counts.any?
41
36
  end
42
37
  end
43
38
  end
@@ -5,7 +5,7 @@ module Cucumber
5
5
  class ConsoleIssues
6
6
  include Console
7
7
 
8
- def initialize(config)
8
+ def initialize(config, ast_lookup = AstLookup.new(config))
9
9
  @previous_test_case = nil
10
10
  @issues = Hash.new { |h, k| h[k] = [] }
11
11
  @config = config
@@ -18,6 +18,7 @@ module Cucumber
18
18
  @issues[:failed].delete(event.test_case)
19
19
  end
20
20
  end
21
+ @ast_lookup = ast_lookup
21
22
  end
22
23
 
23
24
  def to_s
@@ -35,8 +36,10 @@ module Cucumber
35
36
  def scenario_listing(type, test_cases)
36
37
  return [] if test_cases.empty?
37
38
  [format_string("#{type_heading(type)} Scenarios:", type)] + test_cases.map do |test_case|
38
- source = @config.source? ? format_string(" # #{test_case.keyword}: #{test_case.name}", :comment) : ''
39
- format_string("cucumber #{profiles_string}" + test_case.location, type) + source
39
+ scenario_source = @ast_lookup.scenario_source(test_case)
40
+ keyword = scenario_source.type == :Scenario ? scenario_source.scenario[:keyword] : scenario_source.scenario_outline[:keyword]
41
+ source = @config.source? ? format_string(" # #{keyword}: #{test_case.name}", :comment) : ''
42
+ format_string("cucumber #{profiles_string}#{test_case.location.file}:#{test_case.location.lines.max}", type) + source
40
43
  end
41
44
  end
42
45
 
@@ -22,7 +22,7 @@ module Cucumber
22
22
  def exception(*) end
23
23
 
24
24
  def duration(duration, *)
25
- duration.tap { |duration| @result_duration = duration.nanoseconds / 10**9.0 }
25
+ duration.tap { |dur| @result_duration = dur.nanoseconds / 10**9.0 }
26
26
  end
27
27
  end
28
28
  end
@@ -13,6 +13,8 @@ module Cucumber
13
13
  end
14
14
 
15
15
  def method_missing(message, *args)
16
+ super unless recipients
17
+
16
18
  recipients.each do |recipient|
17
19
  recipient.send(message, *args) if recipient.respond_to?(message)
18
20
  end
@@ -8,7 +8,7 @@ module Cucumber
8
8
  end
9
9
 
10
10
  def method_missing(message, *args)
11
- @receiver.send(message, *args) if @receiver.respond_to?(message)
11
+ @receiver.respond_to?(message) ? @receiver.send(message, *args) : super
12
12
  end
13
13
 
14
14
  def respond_to_missing?(name, include_private = false)
@@ -43,17 +43,15 @@ module Cucumber
43
43
  end
44
44
 
45
45
  def method_missing(method, *args, &blk)
46
- @pipe.send(method, *args, &blk)
46
+ @pipe.send(method, *args, &blk) || super
47
47
  end
48
48
 
49
- def respond_to?(method, include_private = false)
49
+ def respond_to_missing?(method, include_private = false)
50
50
  super || @pipe.respond_to?(method, include_private)
51
51
  end
52
52
 
53
53
  def self.validate_pipe(pipe)
54
- unless [:stdout, :stderr].include? pipe
55
- raise ArgumentError, '#wrap only accepts :stderr or :stdout'
56
- end
54
+ raise ArgumentError, '#wrap only accepts :stderr or :stdout' unless %i[stdout stderr].include? pipe
57
55
  end
58
56
 
59
57
  def self.unwrap!(pipe)
@@ -75,10 +73,10 @@ module Cucumber
75
73
 
76
74
  case pipe
77
75
  when :stderr
78
- $stderr = self.new($stderr)
76
+ $stderr = new($stderr)
79
77
  return $stderr
80
78
  when :stdout
81
- $stdout = self.new($stdout)
79
+ $stdout = new($stdout)
82
80
  return $stdout
83
81
  end
84
82
  end