cucumber 0.9.4 → 0.10.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 (107) hide show
  1. data/Gemfile +1 -1
  2. data/History.txt +16 -0
  3. data/bin/cucumber +7 -1
  4. data/cucumber.gemspec +5 -4
  5. data/cucumber.yml +1 -1
  6. data/examples/sinatra/features/support/env.rb +1 -4
  7. data/features/background.feature +284 -95
  8. data/features/custom_formatter.feature +3 -73
  9. data/features/execute_with_tag_filter.feature +63 -0
  10. data/features/{negative_tagged_hooks.feature → hooks.feature} +5 -6
  11. data/features/json_formatter.feature +161 -245
  12. data/features/stats_formatters.feature +70 -0
  13. data/features/step_definitions/cucumber_steps.rb +5 -163
  14. data/features/support/env.rb +23 -149
  15. data/features/{tag_logic.feature → tagged_hooks.feature} +11 -52
  16. data/gem_tasks/{features.rake → cucumber.rake} +6 -1
  17. data/{features → legacy_features}/announce.feature +0 -0
  18. data/{features → legacy_features}/api/list_step_defs_as_json.feature +0 -0
  19. data/{features → legacy_features}/api/run_cli_main_with_existing_runtime.feature +0 -0
  20. data/{features → legacy_features}/around_hooks.feature +0 -0
  21. data/{features → legacy_features}/bug_371.feature +0 -0
  22. data/{features → legacy_features}/bug_464.feature +0 -0
  23. data/{features → legacy_features}/bug_475.feature +0 -0
  24. data/{features → legacy_features}/bug_585_tab_indentation.feature +0 -0
  25. data/{features → legacy_features}/bug_600.feature +0 -0
  26. data/{features → legacy_features}/call_steps_from_stepdefs.feature +0 -0
  27. data/{features → legacy_features}/cucumber_cli.feature +9 -9
  28. data/{features → legacy_features}/cucumber_cli_outlines.feature +0 -0
  29. data/{features → legacy_features}/default_snippets.feature +0 -0
  30. data/{features → legacy_features}/diffing.feature +0 -0
  31. data/{features → legacy_features}/drb_server_integration.feature +0 -0
  32. data/{features → legacy_features}/exception_in_after_block.feature +0 -0
  33. data/{features → legacy_features}/exception_in_after_step_block.feature +0 -0
  34. data/{features → legacy_features}/exception_in_before_block.feature +0 -0
  35. data/{features → legacy_features}/exclude_files.feature +0 -0
  36. data/{features → legacy_features}/expand.feature +0 -0
  37. data/{features → legacy_features}/html_formatter.feature +0 -0
  38. data/{features → legacy_features}/html_formatter/a.html +0 -0
  39. data/{features → legacy_features}/junit_formatter.feature +0 -0
  40. data/{features → legacy_features}/language_from_header.feature +0 -0
  41. data/{features → legacy_features}/language_help.feature +0 -0
  42. data/{features → legacy_features}/listener_debugger_formatter.feature +0 -0
  43. data/legacy_features/multiline_names.feature +44 -0
  44. data/{features → legacy_features}/post_configuration_hook.feature +0 -0
  45. data/{features → legacy_features}/profiles.feature +0 -0
  46. data/{features → legacy_features}/rake_task.feature +0 -0
  47. data/{features → legacy_features}/report_called_undefined_steps.feature +0 -0
  48. data/{features → legacy_features}/rerun_formatter.feature +0 -0
  49. data/{features → legacy_features}/simplest.feature +0 -0
  50. data/{features → legacy_features}/snippet.feature +0 -0
  51. data/{features → legacy_features}/snippets_when_using_star_keyword.feature +0 -0
  52. data/legacy_features/step_definitions/cucumber_steps.rb +168 -0
  53. data/{features → legacy_features}/step_definitions/extra_steps.rb +0 -0
  54. data/{features → legacy_features}/step_definitions/simplest_steps.rb +0 -0
  55. data/{features → legacy_features}/step_definitions/wire_steps.rb +1 -0
  56. data/legacy_features/support/env.rb +157 -0
  57. data/{features → legacy_features}/support/env.rb.simplest +0 -0
  58. data/{features → legacy_features}/support/fake_wire_server.rb +0 -0
  59. data/{features → legacy_features}/table_diffing.feature +0 -0
  60. data/{features → legacy_features}/table_mapping.feature +0 -0
  61. data/{features → legacy_features}/transform.feature +0 -0
  62. data/{features → legacy_features}/unicode_table.feature +0 -0
  63. data/{features → legacy_features}/wire_protocol.feature +1 -1
  64. data/{features → legacy_features}/wire_protocol_table_diffing.feature +0 -0
  65. data/{features → legacy_features}/wire_protocol_tags.feature +0 -0
  66. data/{features → legacy_features}/wire_protocol_timeouts.feature +0 -0
  67. data/{features → legacy_features}/work_in_progress.feature +0 -0
  68. data/lib/cucumber/ast/examples.rb +5 -0
  69. data/lib/cucumber/ast/feature.rb +5 -0
  70. data/lib/cucumber/ast/feature_element.rb +5 -0
  71. data/lib/cucumber/ast/scenario_outline.rb +9 -4
  72. data/lib/cucumber/ast/step.rb +5 -0
  73. data/lib/cucumber/ast/step_invocation.rb +4 -0
  74. data/lib/cucumber/ast/table.rb +3 -3
  75. data/lib/cucumber/ast/tree_walker.rb +1 -39
  76. data/lib/cucumber/cli/main.rb +1 -6
  77. data/lib/cucumber/cli/options.rb +1 -2
  78. data/lib/cucumber/formatter/ansicolor.rb +2 -4
  79. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +84 -0
  80. data/lib/cucumber/formatter/gpretty.rb +24 -0
  81. data/lib/cucumber/formatter/html.rb +1 -1
  82. data/lib/cucumber/formatter/io.rb +2 -4
  83. data/lib/cucumber/formatter/json.rb +15 -152
  84. data/lib/cucumber/formatter/json_pretty.rb +5 -6
  85. data/lib/cucumber/formatter/unicode.rb +41 -20
  86. data/lib/cucumber/parser/gherkin_builder.rb +7 -1
  87. data/lib/cucumber/platform.rb +1 -1
  88. data/lib/cucumber/step_match.rb +5 -1
  89. data/spec/cucumber/ast/scenario_outline_spec.rb +11 -8
  90. data/spec/cucumber/ast/table_spec.rb +6 -1
  91. data/spec/cucumber/cli/main_spec.rb +4 -1
  92. metadata +105 -132
  93. data/features/multiline_names.feature +0 -44
  94. data/features/usage_and_stepdefs_formatter.feature +0 -169
  95. data/fixtures/json/features/pystring.feature +0 -8
  96. data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +0 -12
  97. data/fixtures/self_test/features/background/background_with_name.feature +0 -7
  98. data/fixtures/self_test/features/background/failing_background.feature +0 -12
  99. data/fixtures/self_test/features/background/failing_background_after_success.feature +0 -11
  100. data/fixtures/self_test/features/background/multiline_args_background.feature +0 -32
  101. data/fixtures/self_test/features/background/passing_background.feature +0 -10
  102. data/fixtures/self_test/features/background/pending_background.feature +0 -10
  103. data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +0 -16
  104. data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +0 -16
  105. data/lib/cucumber/formatter/color_io.rb +0 -23
  106. data/lib/cucumber/formatter/tag_cloud.rb +0 -35
  107. data/spec/cucumber/formatter/color_io_spec.rb +0 -29
@@ -296,7 +296,7 @@ Feature: Wire Protocol
296
296
  | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[]] |
297
297
  | ["snippet_text",{"step_keyword":"Given","multiline_arg_class":"","step_name":"we're all wired"}] | ["success","foo()\n bar;\nbaz"] |
298
298
  | ["begin_scenario"] | ["success"] |
299
- | ["end_scenario"] | ["success"] |
299
+ | ["end_scenario"] | ["success"] |
300
300
  When I run cucumber -f pretty
301
301
  Then STDERR should be empty
302
302
  And it should pass with
@@ -7,6 +7,11 @@ module Cucumber
7
7
  @comment, @keyword, @name, @outline_table = comment, keyword, name, outline_table
8
8
  end
9
9
 
10
+ attr_reader :gherkin_statement
11
+ def gherkin_statement(statement=nil)
12
+ @gherkin_statement ||= statement
13
+ end
14
+
10
15
  def accept(visitor)
11
16
  return if Cucumber.wants_to_quit
12
17
  visitor.visit_comment(@comment) unless @comment.empty?
@@ -11,6 +11,11 @@ module Cucumber
11
11
  @background, @comment, @tags, @keyword, @name, @feature_elements = background, comment, tags, keyword, name.strip, feature_elements
12
12
  end
13
13
 
14
+ attr_reader :gherkin_statement
15
+ def gherkin_statement(statement=nil)
16
+ @gherkin_statement ||= statement
17
+ end
18
+
14
19
  def init
15
20
  @background.feature = self if @background
16
21
  @background.init if @background
@@ -6,6 +6,11 @@ module Cucumber
6
6
  module FeatureElement #:nodoc:
7
7
  attr_accessor :feature
8
8
 
9
+ attr_reader :gherkin_statement, :raw_steps
10
+ def gherkin_statement(statement=nil)
11
+ @gherkin_statement ||= statement
12
+ end
13
+
9
14
  def add_step(step)
10
15
  @raw_steps << step
11
16
  end
@@ -24,8 +24,8 @@ module Cucumber
24
24
  @background, @comment, @tags, @line, @keyword, @name, @raw_steps, @example_sections = background, comment, tags, line, keyword, name, raw_steps, example_sections
25
25
  end
26
26
 
27
- def add_examples(example_section)
28
- @example_sections << example_section
27
+ def add_examples(example_section, gherkin_examples)
28
+ @example_sections << [example_section, gherkin_examples]
29
29
  end
30
30
 
31
31
  def init
@@ -33,7 +33,10 @@ module Cucumber
33
33
  attach_steps(@raw_steps)
34
34
  @steps = StepCollection.new(@raw_steps)
35
35
 
36
- @examples_array = @example_sections.map do |example_section|
36
+ @examples_array = @example_sections.map do |example_section_and_gherkin_examples|
37
+ example_section = example_section_and_gherkin_examples[0]
38
+ gherkin_examples = example_section_and_gherkin_examples[1]
39
+
37
40
  examples_comment = example_section[0]
38
41
  examples_line = example_section[1]
39
42
  examples_keyword = example_section[2]
@@ -41,7 +44,9 @@ module Cucumber
41
44
  examples_matrix = example_section[4]
42
45
 
43
46
  examples_table = OutlineTable.new(examples_matrix, self)
44
- Examples.new(examples_comment, examples_line, examples_keyword, examples_name, examples_table)
47
+ ex = Examples.new(examples_comment, examples_line, examples_keyword, examples_name, examples_table)
48
+ ex.gherkin_statement(gherkin_examples)
49
+ ex
45
50
  end
46
51
 
47
52
  @examples_array.extend(ExamplesArray)
@@ -14,6 +14,11 @@ module Cucumber
14
14
  @line, @keyword, @name, @multiline_arg = line, keyword, name, multiline_arg
15
15
  end
16
16
 
17
+ attr_reader :gherkin_statement
18
+ def gherkin_statement(statement=nil)
19
+ @gherkin_statement ||= statement
20
+ end
21
+
17
22
  def background?
18
23
  false
19
24
  end
@@ -187,6 +187,10 @@ module Cucumber
187
187
  @step.language
188
188
  end
189
189
 
190
+ def gherkin_statement
191
+ @step.gherkin_statement
192
+ end
193
+
190
194
  def to_sexp
191
195
  [:step_invocation, @step.line, @step.keyword, @name, (@multiline_arg.nil? ? nil : @multiline_arg.to_sexp)].compact
192
196
  end
@@ -276,8 +276,8 @@ module Cucumber
276
276
  # end
277
277
  #
278
278
  def map_column!(column_name, strict=true, &conversion_proc)
279
- verify_column(column_name) if strict
280
- @conversion_procs[column_name] = conversion_proc
279
+ verify_column(column_name.to_s) if strict
280
+ @conversion_procs[column_name.to_s] = conversion_proc
281
281
  end
282
282
 
283
283
  # Compares +other_table+ to self. If +other_table+ contains columns
@@ -685,4 +685,4 @@ module Cucumber
685
685
  end
686
686
  end
687
687
  end
688
- end
688
+ end
@@ -171,48 +171,10 @@ module Cucumber
171
171
  def send_to_all(message, *args)
172
172
  @listeners.each do |listener|
173
173
  if listener.respond_to?(message)
174
- if legacy_listener?(listener)
175
- warn_legacy(listener)
176
- legacy_invoke(listener, message, *args)
177
- else
178
- listener.__send__(message, *args)
179
- end
174
+ listener.__send__(message, *args)
180
175
  end
181
176
  end
182
177
  end
183
-
184
- def legacy_listener?(listener)
185
- listener.respond_to?(:feature_name) &&
186
- (listener.method(:feature_name) rescue false) &&
187
- listener.method(:feature_name).arity == 1
188
- end
189
-
190
- def warn_legacy(listener)
191
- @warned_listeners ||= []
192
- unless @warned_listeners.index(listener)
193
- warn("#{listener.class} is using a deprecated formatter API. Starting with Cucumber 0.7.0 the signatures\n" +
194
- "that have changed are:\n" +
195
- " feature_name(keyword, name) # Two arguments. The keyword argument will not contain a colon.\n" +
196
- " scenario_name(keyword, name, file_colon_line, source_indent) # The keyword argument will not contain a colon.\n" +
197
- " examples_name(keyword, name) # The keyword argument will not contain a colon.\n"
198
- )
199
- end
200
- @warned_listeners << listener
201
- end
202
-
203
- def legacy_invoke(listener, message, *args)
204
- case message.to_sym
205
- when :feature_name
206
- listener.feature_name("#{args[0]}: #{args[1]}")
207
- when :scenario_name, :examples_name
208
- args_with_colon = args.dup
209
- args_with_colon[0] += ':'
210
- listener.__send__(message, *args_with_colon)
211
- else
212
- listener.__send__(message, *args)
213
- end
214
- end
215
-
216
178
  def extract_method_name_from(call_stack)
217
179
  call_stack[0].match(/in `(.*)'/).captures[0]
218
180
  end
@@ -9,7 +9,6 @@ require 'cucumber'
9
9
  require 'logger'
10
10
  require 'cucumber/parser'
11
11
  require 'cucumber/feature_file'
12
- require 'cucumber/formatter/color_io'
13
12
  require 'cucumber/cli/configuration'
14
13
  require 'cucumber/cli/drb_client'
15
14
 
@@ -24,11 +23,7 @@ module Cucumber
24
23
 
25
24
  def initialize(args, out_stream = STDOUT, error_stream = STDERR)
26
25
  @args = args
27
- if Cucumber::WINDOWS_MRI
28
- @out_stream = out_stream == STDOUT ? Formatter::ColorIO.new(Kernel, STDOUT) : out_stream
29
- else
30
- @out_stream = out_stream
31
- end
26
+ @out_stream = out_stream
32
27
 
33
28
  @error_stream = error_stream
34
29
  @configuration = nil
@@ -24,8 +24,7 @@ module Cucumber
24
24
  "#{INDENT}the usage formatter, except that steps are not printed."],
25
25
  'junit' => ['Cucumber::Formatter::Junit', 'Generates a report similar to Ant+JUnit.'],
26
26
  'json' => ['Cucumber::Formatter::Json', 'Prints the feature as JSON'],
27
- 'json_pretty' => ['Cucumber::Formatter::JsonPretty', 'Prints the feature as pretty JSON'],
28
- 'tag_cloud' => ['Cucumber::Formatter::TagCloud', 'Prints a tag cloud of tag usage.'],
27
+ 'json_pretty' => ['Cucumber::Formatter::JsonPretty', 'Prints the feature as prettified JSON'],
29
28
  'debug' => ['Cucumber::Formatter::Debug', 'For developing formatters - prints the calls made to the listeners.']
30
29
  }
31
30
  max = BUILTIN_FORMATS.keys.map{|s| s.length}.max
@@ -15,10 +15,8 @@ if Cucumber::IRONRUBY
15
15
  end
16
16
 
17
17
  if Cucumber::WINDOWS_MRI
18
- begin
19
- require 'Win32/Console/ANSI'
20
- rescue LoadError
21
- STDERR.puts %{*** WARNING: You must "gem install win32console" (1.2.0 or higher) to get coloured output on MRI/Windows}
18
+ unless ENV['ANSICON']
19
+ STDERR.puts %{*** WARNING: You must use ANSICON 1.31 or higher (http://adoxa.110mb.com/ansicon) to get coloured output on Windows}
22
20
  Term::ANSIColor.coloring = false
23
21
  end
24
22
  end
@@ -0,0 +1,84 @@
1
+ require 'cucumber/formatter/io'
2
+ require 'gherkin/formatter/argument'
3
+
4
+ module Cucumber
5
+ module Formatter
6
+ # Adapts Cucumber formatter events to Gherkin formatter events
7
+ # This class will disappear when Cucumber is based on Gherkin's model.
8
+ class GherkinFormatterAdapter
9
+ def initialize(gherkin_formatter, print_emtpy_match)
10
+ @gf = gherkin_formatter
11
+ @print_emtpy_match = print_emtpy_match
12
+ end
13
+
14
+ def before_features(features)
15
+ end
16
+
17
+ def before_feature(feature)
18
+ @gf.uri(feature.file)
19
+ @gf.feature(feature.gherkin_statement)
20
+ end
21
+
22
+ def before_background(background)
23
+ @outline = false
24
+ @gf.steps(background.raw_steps)
25
+ @gf.background(background.gherkin_statement)
26
+ end
27
+
28
+ def before_feature_element(feature_element)
29
+ @gf.steps(feature_element.raw_steps)
30
+ case(feature_element)
31
+ when Ast::Scenario
32
+ @outline = false
33
+ @gf.scenario(feature_element.gherkin_statement)
34
+ when Ast::ScenarioOutline
35
+ @outline = true
36
+ @gf.scenario_outline(feature_element.gherkin_statement)
37
+ else
38
+ raise "Bad type: #{feature_element.class}"
39
+ end
40
+ end
41
+
42
+ def before_step(step)
43
+ @gf.step(step.gherkin_statement)
44
+ if @print_emtpy_match
45
+ if(@outline)
46
+ match = Gherkin::Formatter::Model::Match.new(step.gherkin_statement.outline_args, nil)
47
+ else
48
+ match = Gherkin::Formatter::Model::Match.new([], nil)
49
+ end
50
+ @gf.match(match)
51
+ end
52
+ end
53
+
54
+ def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
55
+ arguments = step_match.step_arguments.map{|a| Gherkin::Formatter::Argument.new(a.byte_offset, a.val)}
56
+ location = step_match.file_colon_line
57
+ match = Gherkin::Formatter::Model::Match.new(arguments, location)
58
+ if @print_emtpy_match
59
+ # Trick the formatter to believe that's what was printed previously so we get arg highlights on #result
60
+ @gf.instance_variable_set('@match', match)
61
+ else
62
+ @gf.match(match)
63
+ end
64
+
65
+ error_message = exception ? "#{exception.message} (#{exception.class})\n#{exception.backtrace.join("\n")}" : nil
66
+ unless @outline
67
+ @gf.result(Gherkin::Formatter::Model::Result.new(status, error_message))
68
+ end
69
+ end
70
+
71
+ def before_examples(examples)
72
+ @gf.examples(examples.gherkin_statement)
73
+ end
74
+
75
+ def after_feature(feature)
76
+ @gf.eof
77
+ end
78
+
79
+ def embed(file, mime_type)
80
+ @gf.embedding(mime_type, File.read(file))
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,24 @@
1
+ require 'cucumber/formatter/gherkin_formatter_adapter'
2
+ require 'cucumber/formatter/io'
3
+ require 'gherkin/formatter/argument'
4
+ require 'gherkin/formatter/pretty_formatter'
5
+
6
+ module Cucumber
7
+ module Formatter
8
+ # The formatter used for <tt>--format gpretty</tt>
9
+ class Gpretty < GherkinFormatterAdapter
10
+ include Io
11
+
12
+ def initialize(step_mother, io, options)
13
+ @io = ensure_io(io, "json")
14
+ super(Gherkin::Formatter::PrettyFormatter.new(@io, false), true)
15
+ end
16
+
17
+ def after_feature(feature)
18
+ super
19
+ @io.puts
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -388,7 +388,7 @@ module Cucumber
388
388
  end
389
389
 
390
390
  def set_scenario_color(status)
391
- if status == :undefined
391
+ if status == :undefined or status == :pending
392
392
  set_scenario_color_pending
393
393
  end
394
394
  if status == :failed
@@ -1,11 +1,9 @@
1
- require 'cucumber/formatter/color_io'
2
-
3
1
  module Cucumber
4
2
  module Formatter
5
3
  module Io
6
4
  def ensure_io(path_or_io, name)
7
5
  return nil if path_or_io.nil?
8
- return path_or_io if ColorIO === path_or_io || path_or_io.respond_to?(:write)
6
+ return path_or_io if path_or_io.respond_to?(:write)
9
7
  file = File.open(path_or_io, Cucumber.file_mode('w'))
10
8
  at_exit do
11
9
  unless file.closed?
@@ -30,4 +28,4 @@ module Cucumber
30
28
  end
31
29
  end
32
30
  end
33
- end
31
+ end
@@ -1,166 +1,29 @@
1
- require "json"
2
- require "cucumber/formatter/io"
1
+ require 'cucumber/formatter/gherkin_formatter_adapter'
2
+ require 'cucumber/formatter/io'
3
+ require 'gherkin/formatter/argument'
4
+ require 'gherkin/formatter/json_formatter'
3
5
 
4
6
  module Cucumber
5
7
  module Formatter
6
8
  # The formatter used for <tt>--format json</tt>
7
- class Json
8
- class Error < StandardError
9
- end
10
-
9
+ class Json < GherkinFormatterAdapter
11
10
  include Io
12
11
 
13
12
  def initialize(step_mother, io, options)
14
- @io = ensure_io(io, "json")
15
- @options = options
16
- end
17
-
18
- def before_features(features)
19
- @json = {:features => []}
20
- end
21
-
22
- def before_feature(feature)
23
- @current_object = {:file => feature.file, :name => feature.name}
24
- @json[:features] << @current_object
25
- end
26
-
27
- def before_tags(tags)
28
- @current_object[:tags] = tags.tag_names.to_a
29
- end
30
-
31
- def before_background(background)
32
- background = {}
33
- @current_object[:background] = background
34
- @current_object = background
35
- end
36
-
37
- def after_background(background)
38
- @current_object = last_feature
39
- end
40
-
41
- def before_feature_element(feature_element)
42
- elements = @current_object[:elements] ||= []
43
-
44
- # change current object to the feature_element
45
- @current_object = {}
46
- elements << @current_object
47
- end
48
-
49
- def scenario_name(keyword, name, file_colon_line, source_indent)
50
- @current_object[:keyword] = keyword
51
- @current_object[:name] = name
52
- @current_object[:file_colon_line] = file_colon_line
53
- end
54
-
55
- def before_steps(steps)
56
- @current_object[:steps] = []
57
- end
58
-
59
- def before_step(step)
60
- @current_step = {}
61
- @current_object[:steps] << @current_step
13
+ @io = ensure_io(io, "json")
14
+ @obj = {'features' => []}
15
+ super(Gherkin::Formatter::JSONFormatter.new(nil), false)
62
16
  end
63
17
 
64
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
65
- if exception
66
- @current_step[:exception] = exception_hash_for(exception)
67
- end
68
- end
69
-
70
- def step_name(keyword, step_match, status, source_indent, background)
71
- @current_step[:status] = status
72
- @current_step[:keyword] = keyword
73
- @current_step[:name] = "#{step_match.name || step_match.format_args}"
74
- @current_step[:file_colon_line] = step_match.file_colon_line
75
- end
76
-
77
- def after_step(step)
78
- @current_step = nil
79
- end
80
-
81
- def before_examples(examples)
82
- @current_object[:examples] = {}
83
- end
84
-
85
- def examples_name(keyword, name)
86
- @current_object[:examples][:name] = "#{keyword} #{name}"
87
- end
88
-
89
- def before_outline_table(*args)
90
- @current_object[:examples][:table] = []
91
- end
92
-
93
- def before_table_row(row)
94
- @current_row = {:cells => []}
95
-
96
- if @current_object.member? :examples
97
- @current_object[:examples][:table] << @current_row
98
- elsif @current_step
99
- (@current_step[:table] ||= []) << @current_row
100
- else
101
- internal_error
102
- end
103
- end
104
-
105
- def table_cell_value(value, status)
106
- @current_row[:cells] << {:text => value, :status => status}
107
- end
108
-
109
- def after_table_row(row)
110
- if row.exception
111
- @current_row[:exception] = exception_hash_for(row.exception)
112
- end
113
- @current_row = nil
114
- end
115
-
116
- def py_string(string)
117
- @current_step[:py_string] = string
118
- end
119
-
120
- def after_feature_element(feature_element)
121
- # change current object back to the last feature
122
- @current_object = last_feature
18
+ def after_feature(feature)
19
+ super
20
+ @obj['features'] << @gf.gherkin_object
123
21
  end
124
22
 
125
23
  def after_features(features)
126
- @io.write json_string
127
- @io.flush
24
+ @io.write(@obj.to_json)
128
25
  end
129
-
130
- def embed(file, mime_type)
131
- obj = @current_step || @current_object
132
- obj[:embedded] ||= []
133
-
134
- obj[:embedded] << {
135
- :file => file,
136
- :mime_type => mime_type,
137
- :data => [File.read(file)].pack("m*") # base64
138
- }
139
- end
140
-
141
- private
142
-
143
- def json_string
144
- @json.to_json
145
- end
146
-
147
- def last_feature
148
- @json[:features].last
149
- end
150
-
151
- def exception_hash_for(e)
152
- {
153
- :class => e.class.name,
154
- :message => e.message,
155
- :backtrace => e.backtrace
156
- }
157
- end
158
-
159
- def internal_error
160
- raise Error, "you've found a bug in the JSON formatter!"
161
- end
162
-
163
- end # Json
164
- end # Formatter
165
- end # Cucumber
26
+ end
27
+ end
28
+ end
166
29