cucumber 10.2.0 → 11.1.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -8
  3. data/VERSION +1 -1
  4. data/lib/cucumber/cli/configuration.rb +1 -1
  5. data/lib/cucumber/cli/main.rb +22 -0
  6. data/lib/cucumber/cli/options.rb +3 -18
  7. data/lib/cucumber/cli/profile_loader.rb +2 -2
  8. data/lib/cucumber/cli/rerun_file.rb +1 -1
  9. data/lib/cucumber/cli.rb +3 -0
  10. data/lib/cucumber/configuration.rb +33 -24
  11. data/lib/cucumber/events/base.rb +25 -0
  12. data/lib/cucumber/events/envelope.rb +29 -2
  13. data/lib/cucumber/events/gherkin_source_parsed.rb +12 -3
  14. data/lib/cucumber/events/gherkin_source_read.rb +11 -3
  15. data/lib/cucumber/events/hook_test_step_created.rb +12 -2
  16. data/lib/cucumber/events/step_activated.rb +13 -7
  17. data/lib/cucumber/events/step_definition_registered.rb +12 -4
  18. data/lib/cucumber/events/test_case_created.rb +11 -3
  19. data/lib/cucumber/events/test_case_finished.rb +12 -4
  20. data/lib/cucumber/events/test_case_ready.rb +10 -4
  21. data/lib/cucumber/events/test_case_started.rb +11 -2
  22. data/lib/cucumber/events/test_run_finished.rb +10 -3
  23. data/lib/cucumber/events/test_run_hook_finished.rb +19 -0
  24. data/lib/cucumber/events/test_run_hook_started.rb +20 -0
  25. data/lib/cucumber/events/test_run_started.rb +11 -2
  26. data/lib/cucumber/events/test_step_created.rb +12 -2
  27. data/lib/cucumber/events/test_step_finished.rb +12 -2
  28. data/lib/cucumber/events/test_step_started.rb +11 -2
  29. data/lib/cucumber/events/undefined_parameter_type.rb +11 -3
  30. data/lib/cucumber/events.rb +2 -0
  31. data/lib/cucumber/filters/fire_before_all_hooks.rb +36 -0
  32. data/lib/cucumber/filters/randomizer.rb +5 -5
  33. data/lib/cucumber/filters/reverser.rb +41 -0
  34. data/lib/cucumber/filters.rb +1 -12
  35. data/lib/cucumber/formatter/ansicolor.rb +3 -0
  36. data/lib/cucumber/formatter/console.rb +15 -7
  37. data/lib/cucumber/formatter/console_issues.rb +5 -5
  38. data/lib/cucumber/formatter/duration_extractor.rb +2 -0
  39. data/lib/cucumber/formatter/fail_fast.rb +3 -4
  40. data/lib/cucumber/formatter/global_hooks_summary.rb +36 -0
  41. data/lib/cucumber/formatter/html.rb +1 -3
  42. data/lib/cucumber/formatter/json.rb +5 -3
  43. data/lib/cucumber/formatter/junit.rb +5 -34
  44. data/lib/cucumber/formatter/message.rb +8 -4
  45. data/lib/cucumber/formatter/message_builder.rb +249 -143
  46. data/lib/cucumber/formatter/pretty.rb +2 -5
  47. data/lib/cucumber/formatter/progress.rb +1 -2
  48. data/lib/cucumber/formatter/rerun.rb +80 -30
  49. data/lib/cucumber/formatter/usage.rb +2 -3
  50. data/lib/cucumber/formatter.rb +3 -0
  51. data/lib/cucumber/glue/proto_world.rb +6 -4
  52. data/lib/cucumber/glue/registry_and_more.rb +122 -20
  53. data/lib/cucumber/glue.rb +3 -0
  54. data/lib/cucumber/multiline_argument/data_table.rb +0 -11
  55. data/lib/cucumber/platform.rb +2 -2
  56. data/lib/cucumber/query.rb +273 -0
  57. data/lib/cucumber/rake/forked_cucumber_runner.rb +57 -0
  58. data/lib/cucumber/rake/in_process_cucumber_runner.rb +27 -0
  59. data/lib/cucumber/rake/task.rb +36 -106
  60. data/lib/cucumber/rake.rb +3 -0
  61. data/lib/cucumber/repository.rb +136 -0
  62. data/lib/cucumber/rspec/disable_option_parser.rb +3 -3
  63. data/lib/cucumber/runtime/user_interface.rb +2 -2
  64. data/lib/cucumber/runtime.rb +29 -9
  65. data/lib/cucumber/step_match.rb +1 -1
  66. data/lib/cucumber.rb +2 -13
  67. metadata +33 -30
  68. data/lib/cucumber/formatter/errors.rb +0 -9
  69. data/lib/cucumber/formatter/query/hook_by_test_step.rb +0 -34
  70. data/lib/cucumber/formatter/query/pickle_by_test.rb +0 -28
  71. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +0 -28
  72. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +0 -42
  73. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +0 -44
  74. data/lib/cucumber/formatter/query/test_run_started.rb +0 -17
  75. data/lib/cucumber/step_definition_light.rb +0 -29
@@ -1,12 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/events'
3
+ require_relative 'base'
4
4
 
5
5
  module Cucumber
6
6
  module Events
7
7
  # Event fired when a TestStep is created from a PickleStep
8
- class TestStepCreated < Core::Event.new(:test_step, :pickle_step)
8
+ class TestStepCreated < Base
9
9
  attr_reader :test_step, :pickle_step
10
+
11
+ def self.event_id
12
+ :test_step_created
13
+ end
14
+
15
+ def initialize(test_step, pickle_step)
16
+ @test_step = test_step
17
+ @pickle_step = pickle_step
18
+ super()
19
+ end
10
20
  end
11
21
  end
12
22
  end
@@ -1,16 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/events'
3
+ require_relative 'base'
4
4
 
5
5
  module Cucumber
6
6
  module Events
7
7
  # Signals that a {Cucumber::Core::Test::Step} has finished executing
8
- class TestStepFinished < Core::Events::TestStepFinished
8
+ class TestStepFinished < Base
9
9
  # @return [Cucumber::Core::Test::Step] the test step that was executed
10
10
  attr_reader :test_step
11
11
 
12
12
  # @return [Cucumber::Core::Test::Result] the result of running the {Cucumber::Core::Test::Step}
13
13
  attr_reader :result
14
+
15
+ def self.event_id
16
+ :test_step_finished
17
+ end
18
+
19
+ def initialize(test_step, result)
20
+ @test_step = test_step
21
+ @result = result
22
+ super()
23
+ end
14
24
  end
15
25
  end
16
26
  end
@@ -1,13 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/events'
3
+ require_relative 'base'
4
4
 
5
5
  module Cucumber
6
6
  module Events
7
7
  # Signals that a {Cucumber::Core::Test::Step} is about to be executed
8
- class TestStepStarted < Core::Events::TestStepStarted
8
+ class TestStepStarted < Base
9
9
  # @return [Cucumber::Core::Test::Step] the test step to be executed
10
10
  attr_reader :test_step
11
+
12
+ def self.event_id
13
+ :test_step_started
14
+ end
15
+
16
+ def initialize(test_step)
17
+ @test_step = test_step
18
+ super()
19
+ end
11
20
  end
12
21
  end
13
22
  end
@@ -1,11 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/core/events'
4
-
5
3
  module Cucumber
6
4
  module Events
7
- class UndefinedParameterType < Core::Event.new(:type_name, :expression)
5
+ class UndefinedParameterType < Base
8
6
  attr_reader :type_name, :expression
7
+
8
+ def self.event_id
9
+ :undefined_parameter_type
10
+ end
11
+
12
+ def initialize(type_name, expression)
13
+ @type_name = type_name
14
+ @expression = expression
15
+ super()
16
+ end
9
17
  end
10
18
  end
11
19
  end
@@ -34,6 +34,8 @@ module Cucumber
34
34
  TestCaseStarted,
35
35
  TestCaseReady,
36
36
  TestRunFinished,
37
+ TestRunHookFinished,
38
+ TestRunHookStarted,
37
39
  TestRunStarted,
38
40
  TestStepCreated,
39
41
  TestStepFinished,
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cucumber
4
+ module Filters
5
+ # Executes all BeforeAll hooks and ONLY if they were all
6
+ # successful pass on all the `TestCase` objects down the filter chain
7
+ class FireBeforeAllHooks < Core::Filter.new(:config)
8
+ def initialize(support_code, receiver = nil)
9
+ super
10
+ @support_code = support_code
11
+ @test_cases = []
12
+ end
13
+
14
+ def test_case(test_case)
15
+ @test_cases << test_case
16
+ self
17
+ end
18
+
19
+ def done
20
+ if fire_before_all_hook
21
+ @test_cases.map do |test_case|
22
+ test_case.describe_to(@receiver)
23
+ end
24
+ end
25
+ receiver.done
26
+ self
27
+ end
28
+
29
+ private
30
+
31
+ def fire_before_all_hook
32
+ @support_code.fire_hook(:before_all)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -6,6 +6,9 @@ module Cucumber
6
6
  module Filters
7
7
  # Batches up all test cases, randomizes them, and then sends them on
8
8
  class Randomizer
9
+ attr_reader :seed
10
+ private :seed
11
+
9
12
  def initialize(seed, receiver = nil)
10
13
  @receiver = receiver
11
14
  @test_cases = []
@@ -26,7 +29,7 @@ module Cucumber
26
29
  end
27
30
 
28
31
  def with_receiver(receiver)
29
- self.class.new(@seed, receiver)
32
+ self.class.new(seed, receiver)
30
33
  end
31
34
 
32
35
  private
@@ -34,12 +37,9 @@ module Cucumber
34
37
  def shuffled_test_cases
35
38
  digester = Digest::SHA2.new(256)
36
39
  @test_cases.map.with_index
37
- .sort_by { |_, index| digester.digest((@seed + index).to_s) }
40
+ .sort_by { |_, index| digester.digest((seed + index).to_s) }
38
41
  .map { |test_case, _| test_case }
39
42
  end
40
-
41
- attr_reader :seed
42
- private :seed
43
43
  end
44
44
  end
45
45
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/sha2'
4
+
5
+ module Cucumber
6
+ module Filters
7
+ # Reverses the order of test cases
8
+ class Reverser
9
+ attr_reader :seed
10
+ private :seed
11
+
12
+ def initialize(receiver = nil)
13
+ @receiver = receiver
14
+ @test_cases = []
15
+ end
16
+
17
+ def test_case(test_case)
18
+ @test_cases << test_case
19
+ self
20
+ end
21
+
22
+ def done
23
+ reversed_test_cases.each do |test_case|
24
+ test_case.describe_to(@receiver)
25
+ end
26
+ @receiver.done
27
+ self
28
+ end
29
+
30
+ def with_receiver(receiver)
31
+ self.class.new(receiver)
32
+ end
33
+
34
+ private
35
+
36
+ def reversed_test_cases
37
+ @test_cases.reverse
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,14 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cucumber/filters/activate_steps'
4
- require 'cucumber/filters/apply_after_step_hooks'
5
- require 'cucumber/filters/apply_before_hooks'
6
- require 'cucumber/filters/apply_after_hooks'
7
- require 'cucumber/filters/apply_around_hooks'
8
- require 'cucumber/filters/broadcast_test_run_started_event'
9
- require 'cucumber/filters/prepare_world'
10
- require 'cucumber/filters/quit'
11
- require 'cucumber/filters/randomizer'
12
- require 'cucumber/filters/retry'
13
- require 'cucumber/filters/tag_limits'
14
- require 'cucumber/filters/broadcast_test_case_ready_event'
3
+ Dir["#{File.dirname(__FILE__)}/filters/*.rb"].map(&method(:require))
@@ -47,6 +47,8 @@ module Cucumber
47
47
  # * <tt>flaky_param</tt> - defaults to <tt>yellow,bold</tt>
48
48
  # * <tt>failed</tt> - defaults to <tt>red</tt>
49
49
  # * <tt>failed_param</tt> - defaults to <tt>red,bold</tt>
50
+ # * <tt>ambiguous</tt> - defaults to <tt>red</tt>
51
+ # * <tt>abmiguous_param</tt> - defaults to <tt>red,bold</tt>
50
52
  # * <tt>passed</tt> - defaults to <tt>green</tt>
51
53
  # * <tt>passed_param</tt> - defaults to <tt>green,bold</tt>
52
54
  # * <tt>outline</tt> - defaults to <tt>cyan</tt>
@@ -72,6 +74,7 @@ module Cucumber
72
74
  'pending' => 'yellow',
73
75
  'flaky' => 'yellow',
74
76
  'failed' => 'red',
77
+ 'ambiguous' => 'red',
75
78
  'passed' => 'green',
76
79
  'outline' => 'cyan',
77
80
  'skipped' => 'cyan',
@@ -116,11 +116,11 @@ module Cucumber
116
116
  def collect_snippet_data(test_step, ast_lookup)
117
117
  # collect snippet data for undefined steps
118
118
  keyword = ast_lookup.snippet_step_keyword(test_step)
119
- @snippets_input << Console::SnippetData.new(keyword, test_step)
119
+ snippets_input << Console::SnippetData.new(keyword, test_step)
120
120
  end
121
121
 
122
122
  def collect_undefined_parameter_type_names(undefined_parameter_type)
123
- @undefined_parameter_types << undefined_parameter_type.type_name
123
+ undefined_parameter_types << undefined_parameter_type.type_name
124
124
  end
125
125
 
126
126
  def print_snippets(options)
@@ -129,9 +129,9 @@ module Cucumber
129
129
  snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
130
130
  snippet_text(step_keyword, step_name, multiline_arg)
131
131
  end
132
- do_print_snippets(snippet_text_proc) unless @snippets_input.empty?
132
+ do_print_snippets(snippet_text_proc) unless snippets_input.empty?
133
133
 
134
- @undefined_parameter_types.map do |type_name|
134
+ undefined_parameter_types.map do |type_name|
135
135
  do_print_undefined_parameter_type_snippet(type_name)
136
136
  end
137
137
  end
@@ -169,7 +169,7 @@ module Cucumber
169
169
  end
170
170
  end
171
171
 
172
- def attach(src, media_type, filename)
172
+ def attach(src, media_type, filename, _streamed_file)
173
173
  return unless media_type == 'text/x.cucumber.log+plain'
174
174
  return unless @io
175
175
 
@@ -249,11 +249,19 @@ module Cucumber
249
249
 
250
250
  def snippet_text(step_keyword, step_name, multiline_arg)
251
251
  keyword = Cucumber::Gherkin::I18n.code_keyword_for(step_keyword).strip
252
- config.snippet_generators.map do |generator|
253
- generator.call(keyword, step_name, multiline_arg, config.snippet_type)
252
+ @config.snippet_generators.map do |generator|
253
+ generator.call(keyword, step_name, multiline_arg, @config.snippet_type)
254
254
  end.join("\n")
255
255
  end
256
256
 
257
+ def snippets_input
258
+ @snippets_input ||= []
259
+ end
260
+
261
+ def undefined_parameter_types
262
+ @undefined_parameter_types ||= []
263
+ end
264
+
257
265
  class SnippetData
258
266
  attr_reader :actual_keyword, :step
259
267
 
@@ -10,6 +10,7 @@ module Cucumber
10
10
  def initialize(config, ast_lookup = AstLookup.new(config))
11
11
  @previous_test_case = nil
12
12
  @issues = Hash.new { |h, k| h[k] = [] }
13
+ @global_hooks_summary = GlobalHooksSummary.new(config)
13
14
  @config = config
14
15
  @config.on_event(:test_case_finished) do |event|
15
16
  if event.test_case != @previous_test_case
@@ -24,14 +25,13 @@ module Cucumber
24
25
  end
25
26
 
26
27
  def to_s
27
- return if @issues.empty?
28
-
29
- result = Core::Test::Result::TYPES.map { |type| scenario_listing(type, @issues[type]) }
30
- result.flatten.join("\n")
28
+ test_case_result = @issues.empty? ? [] : Core::Test::Result::TYPES.map { |type| scenario_listing(type, @issues[type]) }
29
+ global_hooks_result = @global_hooks_summary.ok? ? [] : @global_hooks_summary.exception_listing
30
+ [test_case_result + global_hooks_result].flatten.join("\n")
31
31
  end
32
32
 
33
33
  def any?
34
- @issues.any?
34
+ @issues.any? || !@global_hooks_summary.ok?
35
35
  end
36
36
 
37
37
  private
@@ -14,6 +14,8 @@ module Cucumber
14
14
 
15
15
  def failed(*) end
16
16
 
17
+ def ambiguous(*) end
18
+
17
19
  def undefined(*) end
18
20
 
19
21
  def skipped(*) end
@@ -9,11 +9,10 @@ module Cucumber
9
9
  def initialize(configuration)
10
10
  @previous_test_case = nil
11
11
  configuration.on_event :test_case_finished do |event|
12
- test_case, result = *event.attributes
13
- if test_case != @previous_test_case
12
+ if event.test_case != @previous_test_case
14
13
  @previous_test_case = event.test_case
15
- Cucumber.wants_to_quit = true unless result.ok?(strict: configuration.strict)
16
- elsif result.passed?
14
+ Cucumber.wants_to_quit = true unless event.result.ok?(strict: configuration.strict)
15
+ elsif event.result.passed?
17
16
  Cucumber.wants_to_quit = false
18
17
  end
19
18
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cucumber/formatter/io'
4
+ require 'cucumber/formatter/console'
5
+ require 'cucumber/formatter/console_counts'
6
+ require 'cucumber/formatter/console_issues'
7
+ require 'cucumber/core/test/result'
8
+ require 'cucumber/formatter/ast_lookup'
9
+
10
+ module Cucumber
11
+ module Formatter
12
+ # AllHookSummary formatter, keep track of failures in Before/AfterAll hooks
13
+ class GlobalHooksSummary
14
+ include Console
15
+
16
+ def initialize(config)
17
+ @config = config
18
+ @all_hook_failures = []
19
+
20
+ @config.on_event :test_run_hook_finished do |event|
21
+ @all_hook_failures << event unless event.test_result.ok?
22
+ end
23
+ end
24
+
25
+ def ok?
26
+ @all_hook_failures.empty?
27
+ end
28
+
29
+ def exception_listing
30
+ [format_string('Global hook failures:', :failed)] + @all_hook_failures.map do |event|
31
+ format_string("#{event.hook.location} # #{event.test_result.exception} (#{event.test_result.exception.class})", :failed)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -7,17 +7,15 @@ require 'cucumber/formatter/message_builder'
7
7
  module Cucumber
8
8
  module Formatter
9
9
  class HTML < MessageBuilder
10
- include Io
11
-
12
10
  def initialize(config)
13
11
  @io = ensure_io(config.out_stream, config.error_stream)
14
12
  @html_formatter = Cucumber::HTMLFormatter::Formatter.new(@io)
15
13
  @html_formatter.write_pre_message
16
-
17
14
  super(config)
18
15
  end
19
16
 
20
17
  def output_envelope(envelope)
18
+ @repository.update(envelope)
21
19
  @html_formatter.write_message(envelope)
22
20
  @html_formatter.write_post_message if envelope.test_run_finished
23
21
  end
@@ -65,7 +65,8 @@ module Cucumber
65
65
  end
66
66
 
67
67
  def on_test_step_finished(event)
68
- test_step, result = *event.attributes
68
+ test_step = event.test_step
69
+ result = event.result
69
70
  result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
70
71
  return if internal_hook?(test_step)
71
72
 
@@ -76,7 +77,8 @@ module Cucumber
76
77
  def on_test_case_finished(event)
77
78
  feature_elements << @test_case_hash if @in_background
78
79
 
79
- _test_case, result = *event.attributes
80
+ _test_case = event.test_case
81
+ result = event.result
80
82
  result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
81
83
  add_failed_around_hook(result) if result.failed? && !@any_step_failed
82
84
  end
@@ -85,7 +87,7 @@ module Cucumber
85
87
  @io.write(JSON.pretty_generate(@feature_hashes))
86
88
  end
87
89
 
88
- def attach(src, mime_type, _filename)
90
+ def attach(src, mime_type, _filename, _streamed_file)
89
91
  if mime_type == 'text/x.cucumber.log+plain'
90
92
  test_step_output << src
91
93
  return
@@ -51,19 +51,17 @@ module Cucumber
51
51
  end
52
52
 
53
53
  def on_test_step_finished(event)
54
- test_step, result = *event.attributes
55
54
  return if @failing_test_step
56
55
 
57
- @failing_test_step = test_step unless result.ok?(strict: @config.strict)
56
+ @failing_test_step = event.test_step unless event.result.ok?(strict: @config.strict)
58
57
  end
59
58
 
60
59
  def on_test_case_finished(event)
61
- test_case, result = *event.attributes
62
- result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
63
- test_case_name = NameBuilder.new(test_case, @ast_lookup)
60
+ result = event.result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
61
+ test_case_name = NameBuilder.new(event.test_case, @ast_lookup)
64
62
  scenario = test_case_name.scenario_name
65
63
  scenario_designation = "#{scenario}#{test_case_name.name_suffix}"
66
- output = create_output_string(test_case, scenario, result, test_case_name.row_name)
64
+ output = create_output_string(event.test_case, scenario, result, test_case_name.row_name)
67
65
  build_testcase(result, scenario_designation, output)
68
66
 
69
67
  Interceptor::Pipe.unwrap! :stdout
@@ -131,7 +129,7 @@ module Cucumber
131
129
  end
132
130
 
133
131
  def build_testcase(result, scenario_designation, output)
134
- duration = ResultBuilder.new(result).test_case_duration
132
+ duration = DurationExtractor.new(result).result_duration
135
133
  @current_feature_data[:time] += duration
136
134
  classname = @current_feature_data[:feature].name
137
135
  filename = @current_feature_data[:uri]
@@ -234,32 +232,5 @@ module Cucumber
234
232
  @name_suffix = " (outline example : #{@row_name})"
235
233
  end
236
234
  end
237
-
238
- class ResultBuilder
239
- attr_reader :test_case_duration
240
-
241
- def initialize(result)
242
- @test_case_duration = 0
243
- result.describe_to(self)
244
- end
245
-
246
- def passed(*) end
247
-
248
- def failed(*) end
249
-
250
- def undefined(*) end
251
-
252
- def skipped(*) end
253
-
254
- def pending(*) end
255
-
256
- def exception(*) end
257
-
258
- def duration(duration, *)
259
- duration.tap { |dur| @test_case_duration = dur.nanoseconds / 10**9.0 }
260
- end
261
-
262
- def attach(*) end
263
- end
264
235
  end
265
236
  end
@@ -1,20 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'cucumber/formatter/io'
4
- require 'cucumber/formatter/message_builder'
4
+ require 'cucumber/query'
5
5
 
6
6
  module Cucumber
7
7
  module Formatter
8
8
  # The formatter used for <tt>--format message</tt>
9
- class Message < MessageBuilder
9
+ class Message
10
10
  include Io
11
11
 
12
12
  def initialize(config)
13
13
  @io = ensure_io(config.out_stream, config.error_stream)
14
- super(config)
14
+ @repository = Cucumber::Repository.new
15
+ @query = Cucumber::Query.new(@repository)
16
+ config.on_event :envelope, &method(:output_envelope)
15
17
  end
16
18
 
17
- def output_envelope(envelope)
19
+ def output_envelope(event)
20
+ envelope = event.envelope
21
+ @repository.update(envelope)
18
22
  @io.write(envelope.to_json)
19
23
  @io.write("\n")
20
24
  end