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.
- data/Gemfile +1 -1
- data/History.txt +16 -0
- data/bin/cucumber +7 -1
- data/cucumber.gemspec +5 -4
- data/cucumber.yml +1 -1
- data/examples/sinatra/features/support/env.rb +1 -4
- data/features/background.feature +284 -95
- data/features/custom_formatter.feature +3 -73
- data/features/execute_with_tag_filter.feature +63 -0
- data/features/{negative_tagged_hooks.feature → hooks.feature} +5 -6
- data/features/json_formatter.feature +161 -245
- data/features/stats_formatters.feature +70 -0
- data/features/step_definitions/cucumber_steps.rb +5 -163
- data/features/support/env.rb +23 -149
- data/features/{tag_logic.feature → tagged_hooks.feature} +11 -52
- data/gem_tasks/{features.rake → cucumber.rake} +6 -1
- data/{features → legacy_features}/announce.feature +0 -0
- data/{features → legacy_features}/api/list_step_defs_as_json.feature +0 -0
- data/{features → legacy_features}/api/run_cli_main_with_existing_runtime.feature +0 -0
- data/{features → legacy_features}/around_hooks.feature +0 -0
- data/{features → legacy_features}/bug_371.feature +0 -0
- data/{features → legacy_features}/bug_464.feature +0 -0
- data/{features → legacy_features}/bug_475.feature +0 -0
- data/{features → legacy_features}/bug_585_tab_indentation.feature +0 -0
- data/{features → legacy_features}/bug_600.feature +0 -0
- data/{features → legacy_features}/call_steps_from_stepdefs.feature +0 -0
- data/{features → legacy_features}/cucumber_cli.feature +9 -9
- data/{features → legacy_features}/cucumber_cli_outlines.feature +0 -0
- data/{features → legacy_features}/default_snippets.feature +0 -0
- data/{features → legacy_features}/diffing.feature +0 -0
- data/{features → legacy_features}/drb_server_integration.feature +0 -0
- data/{features → legacy_features}/exception_in_after_block.feature +0 -0
- data/{features → legacy_features}/exception_in_after_step_block.feature +0 -0
- data/{features → legacy_features}/exception_in_before_block.feature +0 -0
- data/{features → legacy_features}/exclude_files.feature +0 -0
- data/{features → legacy_features}/expand.feature +0 -0
- data/{features → legacy_features}/html_formatter.feature +0 -0
- data/{features → legacy_features}/html_formatter/a.html +0 -0
- data/{features → legacy_features}/junit_formatter.feature +0 -0
- data/{features → legacy_features}/language_from_header.feature +0 -0
- data/{features → legacy_features}/language_help.feature +0 -0
- data/{features → legacy_features}/listener_debugger_formatter.feature +0 -0
- data/legacy_features/multiline_names.feature +44 -0
- data/{features → legacy_features}/post_configuration_hook.feature +0 -0
- data/{features → legacy_features}/profiles.feature +0 -0
- data/{features → legacy_features}/rake_task.feature +0 -0
- data/{features → legacy_features}/report_called_undefined_steps.feature +0 -0
- data/{features → legacy_features}/rerun_formatter.feature +0 -0
- data/{features → legacy_features}/simplest.feature +0 -0
- data/{features → legacy_features}/snippet.feature +0 -0
- data/{features → legacy_features}/snippets_when_using_star_keyword.feature +0 -0
- data/legacy_features/step_definitions/cucumber_steps.rb +168 -0
- data/{features → legacy_features}/step_definitions/extra_steps.rb +0 -0
- data/{features → legacy_features}/step_definitions/simplest_steps.rb +0 -0
- data/{features → legacy_features}/step_definitions/wire_steps.rb +1 -0
- data/legacy_features/support/env.rb +157 -0
- data/{features → legacy_features}/support/env.rb.simplest +0 -0
- data/{features → legacy_features}/support/fake_wire_server.rb +0 -0
- data/{features → legacy_features}/table_diffing.feature +0 -0
- data/{features → legacy_features}/table_mapping.feature +0 -0
- data/{features → legacy_features}/transform.feature +0 -0
- data/{features → legacy_features}/unicode_table.feature +0 -0
- data/{features → legacy_features}/wire_protocol.feature +1 -1
- data/{features → legacy_features}/wire_protocol_table_diffing.feature +0 -0
- data/{features → legacy_features}/wire_protocol_tags.feature +0 -0
- data/{features → legacy_features}/wire_protocol_timeouts.feature +0 -0
- data/{features → legacy_features}/work_in_progress.feature +0 -0
- data/lib/cucumber/ast/examples.rb +5 -0
- data/lib/cucumber/ast/feature.rb +5 -0
- data/lib/cucumber/ast/feature_element.rb +5 -0
- data/lib/cucumber/ast/scenario_outline.rb +9 -4
- data/lib/cucumber/ast/step.rb +5 -0
- data/lib/cucumber/ast/step_invocation.rb +4 -0
- data/lib/cucumber/ast/table.rb +3 -3
- data/lib/cucumber/ast/tree_walker.rb +1 -39
- data/lib/cucumber/cli/main.rb +1 -6
- data/lib/cucumber/cli/options.rb +1 -2
- data/lib/cucumber/formatter/ansicolor.rb +2 -4
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +84 -0
- data/lib/cucumber/formatter/gpretty.rb +24 -0
- data/lib/cucumber/formatter/html.rb +1 -1
- data/lib/cucumber/formatter/io.rb +2 -4
- data/lib/cucumber/formatter/json.rb +15 -152
- data/lib/cucumber/formatter/json_pretty.rb +5 -6
- data/lib/cucumber/formatter/unicode.rb +41 -20
- data/lib/cucumber/parser/gherkin_builder.rb +7 -1
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/step_match.rb +5 -1
- data/spec/cucumber/ast/scenario_outline_spec.rb +11 -8
- data/spec/cucumber/ast/table_spec.rb +6 -1
- data/spec/cucumber/cli/main_spec.rb +4 -1
- metadata +105 -132
- data/features/multiline_names.feature +0 -44
- data/features/usage_and_stepdefs_formatter.feature +0 -169
- data/fixtures/json/features/pystring.feature +0 -8
- data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +0 -12
- data/fixtures/self_test/features/background/background_with_name.feature +0 -7
- data/fixtures/self_test/features/background/failing_background.feature +0 -12
- data/fixtures/self_test/features/background/failing_background_after_success.feature +0 -11
- data/fixtures/self_test/features/background/multiline_args_background.feature +0 -32
- data/fixtures/self_test/features/background/passing_background.feature +0 -10
- data/fixtures/self_test/features/background/pending_background.feature +0 -10
- data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +0 -16
- data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +0 -16
- data/lib/cucumber/formatter/color_io.rb +0 -23
- data/lib/cucumber/formatter/tag_cloud.rb +0 -35
- data/spec/cucumber/formatter/color_io_spec.rb +0 -29
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -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"]
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -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?
|
data/lib/cucumber/ast/feature.rb
CHANGED
|
@@ -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
|
|
@@ -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 |
|
|
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)
|
data/lib/cucumber/ast/step.rb
CHANGED
|
@@ -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
|
data/lib/cucumber/ast/table.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
data/lib/cucumber/cli/main.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
data/lib/cucumber/cli/options.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
19
|
-
|
|
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
|
+
|
|
@@ -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
|
|
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
|
|
2
|
-
require
|
|
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
|
|
15
|
-
@
|
|
16
|
-
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
127
|
-
@io.flush
|
|
24
|
+
@io.write(@obj.to_json)
|
|
128
25
|
end
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|