cucumber 0.9.4 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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