cucumber 3.1.2 → 4.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -13
  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 +53 -62
  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 +3 -3
  33. data/lib/cucumber/formatter/json.rb +92 -110
  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 +36 -29
  77. data/lib/cucumber/events/gherkin_source_parsed.rb~ +0 -14
  78. data/lib/cucumber/formatter/ast_lookup.rb~ +0 -9
  79. data/lib/cucumber/formatter/cucumber.css +0 -286
  80. data/lib/cucumber/formatter/cucumber.sass +0 -247
  81. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  82. data/lib/cucumber/formatter/html.rb +0 -611
  83. data/lib/cucumber/formatter/html_builder.rb +0 -121
  84. data/lib/cucumber/formatter/inline-js.js +0 -30
  85. data/lib/cucumber/formatter/jquery-min.js +0 -154
  86. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  87. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  88. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  89. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  90. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  91. 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