cucumber 3.1.2 → 8.0.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1880 -1146
- data/CONTRIBUTING.md +220 -61
- data/README.md +143 -22
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +49 -53
- data/lib/autotest/discover.rb +3 -2
- data/lib/cucumber/cli/configuration.rb +32 -7
- data/lib/cucumber/cli/main.rb +16 -15
- data/lib/cucumber/cli/options.rb +111 -79
- data/lib/cucumber/cli/profile_loader.rb +45 -26
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/configuration.rb +47 -31
- data/lib/cucumber/constantize.rb +3 -6
- data/lib/cucumber/deprecate.rb +32 -7
- data/lib/cucumber/errors.rb +5 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
- data/lib/cucumber/events/hook_test_step_created.rb +12 -0
- data/lib/cucumber/events/step_activated.rb +0 -5
- data/lib/cucumber/events/step_definition_registered.rb +0 -5
- data/lib/cucumber/events/test_case_created.rb +12 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_run_finished.rb +2 -1
- data/lib/cucumber/events/test_step_created.rb +12 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +9 -0
- data/lib/cucumber/events.rb +15 -8
- data/lib/cucumber/file_specs.rb +8 -7
- data/lib/cucumber/filters/activate_steps.rb +6 -3
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/filters/prepare_world.rb +5 -9
- data/lib/cucumber/filters/quit.rb +1 -3
- data/lib/cucumber/filters/tag_limits/verifier.rb +3 -7
- data/lib/cucumber/filters/tag_limits.rb +1 -3
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +74 -86
- data/lib/cucumber/formatter/ast_lookup.rb +163 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -7
- data/lib/cucumber/formatter/console.rb +76 -68
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +12 -4
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +4 -1
- data/lib/cucumber/formatter/errors.rb +7 -0
- data/lib/cucumber/formatter/fanout.rb +3 -1
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +152 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -2
- data/lib/cucumber/formatter/interceptor.rb +11 -30
- data/lib/cucumber/formatter/io.rb +57 -13
- data/lib/cucumber/formatter/json.rb +119 -124
- data/lib/cucumber/formatter/junit.rb +75 -55
- data/lib/cucumber/formatter/message.rb +23 -0
- data/lib/cucumber/formatter/message_builder.rb +256 -0
- data/lib/cucumber/formatter/pretty.rb +370 -153
- data/lib/cucumber/formatter/progress.rb +31 -32
- data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +32 -0
- data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
- data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +42 -0
- data/lib/cucumber/formatter/rerun.rb +24 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +8 -6
- data/lib/cucumber/formatter/summary.rb +17 -8
- data/lib/cucumber/formatter/unicode.rb +18 -20
- data/lib/cucumber/formatter/url_reporter.rb +17 -0
- data/lib/cucumber/formatter/usage.rb +18 -15
- data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +14 -18
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +29 -15
- data/lib/cucumber/glue/hook.rb +37 -11
- data/lib/cucumber/glue/invoke_in_world.rb +17 -22
- data/lib/cucumber/glue/proto_world.rb +47 -53
- data/lib/cucumber/glue/registry_and_more.rb +62 -17
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +48 -23
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +12 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +4 -3
- data/lib/cucumber/multiline_argument/data_table.rb +143 -123
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +5 -5
- data/lib/cucumber/rake/task.rb +34 -25
- data/lib/cucumber/rspec/disable_option_parser.rb +15 -11
- data/lib/cucumber/rspec/doubles.rb +3 -5
- data/lib/cucumber/running_test_case.rb +3 -53
- data/lib/cucumber/runtime/after_hooks.rb +8 -4
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
- data/lib/cucumber/runtime/meta_message_builder.rb +106 -0
- data/lib/cucumber/runtime/step_hooks.rb +6 -2
- data/lib/cucumber/runtime/support_code.rb +16 -15
- data/lib/cucumber/runtime/user_interface.rb +10 -19
- data/lib/cucumber/runtime.rb +78 -76
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +17 -20
- data/lib/cucumber/step_match_search.rb +5 -3
- data/lib/cucumber/term/ansicolor.rb +72 -48
- data/lib/cucumber/term/banner.rb +57 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +3 -2
- data/lib/simplecov_setup.rb +1 -1
- metadata +279 -81
- data/lib/cucumber/core_ext/string.rb +0 -11
- data/lib/cucumber/events/gherkin_source_parsed.rb~ +0 -14
- data/lib/cucumber/formatter/ast_lookup.rb~ +0 -9
- data/lib/cucumber/formatter/cucumber.css +0 -286
- data/lib/cucumber/formatter/cucumber.sass +0 -247
- data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
- data/lib/cucumber/formatter/html_builder.rb +0 -121
- data/lib/cucumber/formatter/inline-js.js +0 -30
- data/lib/cucumber/formatter/jquery-min.js +0 -154
- data/lib/cucumber/formatter/json_pretty.rb +0 -11
- data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
- data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
- data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
- data/lib/cucumber/step_argument.rb +0 -25
@@ -1,253 +1,470 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'gherkin/dialect'
|
4
5
|
require 'cucumber/formatter/console'
|
5
6
|
require 'cucumber/formatter/io'
|
6
7
|
require 'cucumber/gherkin/formatter/escaping'
|
7
8
|
require 'cucumber/formatter/console_counts'
|
8
9
|
require 'cucumber/formatter/console_issues'
|
10
|
+
require 'cucumber/formatter/duration_extractor'
|
11
|
+
require 'cucumber/formatter/backtrace_filter'
|
12
|
+
require 'cucumber/formatter/ast_lookup'
|
9
13
|
|
10
14
|
module Cucumber
|
11
15
|
module Formatter
|
12
16
|
# The formatter used for <tt>--format pretty</tt> (the default formatter).
|
13
17
|
#
|
14
|
-
# This formatter prints
|
15
|
-
# just prettier. That means with proper indentation and alignment of table columns.
|
18
|
+
# This formatter prints the result of the feature executions to plain text - exactly how they were parsed.
|
16
19
|
#
|
17
20
|
# If the output is STDOUT (and not a file), there are bright colours to watch too.
|
18
21
|
#
|
19
|
-
class Pretty
|
22
|
+
class Pretty # rubocop:disable Metrics/ClassLength
|
20
23
|
include FileUtils
|
21
24
|
include Console
|
22
25
|
include Io
|
23
26
|
include Cucumber::Gherkin::Formatter::Escaping
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@
|
31
|
-
@
|
32
|
-
@
|
33
|
-
@delayed_messages = []
|
34
|
-
@previous_step_keyword = nil
|
27
|
+
attr_reader :config, :options, :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case, :in_scenario_outline, :print_background_steps
|
28
|
+
private :config, :options
|
29
|
+
private :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
|
30
|
+
private :in_scenario_outline, :print_background_steps
|
31
|
+
|
32
|
+
def initialize(config)
|
33
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
34
|
+
@config = config
|
35
|
+
@options = config.to_hash
|
35
36
|
@snippets_input = []
|
36
|
-
@
|
37
|
-
@
|
37
|
+
@undefined_parameter_types = []
|
38
|
+
@total_duration = 0
|
39
|
+
@exceptions = []
|
40
|
+
@gherkin_sources = {}
|
41
|
+
@step_matches = {}
|
42
|
+
@ast_lookup = AstLookup.new(config)
|
43
|
+
@counts = ConsoleCounts.new(config)
|
44
|
+
@issues = ConsoleIssues.new(config, @ast_lookup)
|
45
|
+
@first_feature = true
|
46
|
+
@current_feature_uri = ''
|
47
|
+
@current_scenario_outline = nil
|
48
|
+
@current_examples = nil
|
49
|
+
@current_test_case = nil
|
50
|
+
@in_scenario_outline = false
|
51
|
+
@print_background_steps = false
|
52
|
+
@test_step_output = []
|
53
|
+
@passed_test_cases = []
|
54
|
+
@source_indent = 0
|
55
|
+
@next_comment_to_be_printed = 0
|
56
|
+
|
57
|
+
bind_events(config)
|
58
|
+
end
|
59
|
+
|
60
|
+
def bind_events(config)
|
61
|
+
config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
|
62
|
+
config.on_event :step_activated, &method(:on_step_activated)
|
63
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
64
|
+
config.on_event :test_step_started, &method(:on_test_step_started)
|
65
|
+
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
66
|
+
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
67
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
68
|
+
config.on_event :undefined_parameter_type, &method(:collect_undefined_parameter_type_names)
|
69
|
+
end
|
70
|
+
|
71
|
+
def on_gherkin_source_read(event)
|
72
|
+
@gherkin_sources[event.path] = event.body
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_step_activated(event)
|
76
|
+
test_step, step_match = *event.attributes
|
77
|
+
@step_matches[test_step.to_s] = step_match
|
78
|
+
end
|
79
|
+
|
80
|
+
def on_test_case_started(event)
|
81
|
+
if !same_feature_as_previous_test_case?(event.test_case.location)
|
82
|
+
if first_feature?
|
83
|
+
@first_feature = false
|
84
|
+
print_profile_information
|
85
|
+
else
|
86
|
+
print_comments(gherkin_source.split("\n").length, 0)
|
87
|
+
@io.puts
|
88
|
+
end
|
89
|
+
@current_feature_uri = event.test_case.location.file
|
90
|
+
@exceptions = []
|
91
|
+
print_feature_data
|
92
|
+
if feature_has_background?
|
93
|
+
print_background_data
|
94
|
+
@print_background_steps = true
|
95
|
+
@in_scenario_outline = false
|
96
|
+
end
|
97
|
+
else
|
98
|
+
@print_background_steps = false
|
99
|
+
end
|
100
|
+
@current_test_case = event.test_case
|
101
|
+
print_step_header(current_test_case) unless print_background_steps
|
38
102
|
end
|
39
103
|
|
40
|
-
def
|
41
|
-
|
104
|
+
def on_test_step_started(event)
|
105
|
+
return if event.test_step.hook?
|
106
|
+
|
107
|
+
print_step_header(current_test_case) if first_step_after_printing_background_steps?(event.test_step)
|
42
108
|
end
|
43
109
|
|
44
|
-
def
|
45
|
-
|
110
|
+
def on_test_step_finished(event)
|
111
|
+
collect_snippet_data(event.test_step, @ast_lookup) if event.result.undefined?
|
112
|
+
return if in_scenario_outline && !options[:expand]
|
113
|
+
|
114
|
+
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
115
|
+
print_step_data(event.test_step, event.result) if print_step_data?(event, exception_to_be_printed)
|
116
|
+
print_step_output
|
117
|
+
return unless exception_to_be_printed
|
118
|
+
|
119
|
+
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
120
|
+
@exceptions << exception_to_be_printed
|
46
121
|
end
|
47
122
|
|
48
|
-
def
|
49
|
-
@
|
50
|
-
@
|
123
|
+
def on_test_case_finished(event)
|
124
|
+
@total_duration += DurationExtractor.new(event.result).result_duration
|
125
|
+
@passed_test_cases << event.test_case if config.wip? && event.result.passed?
|
126
|
+
if in_scenario_outline && !options[:expand]
|
127
|
+
print_row_data(event.test_case, event.result)
|
128
|
+
else
|
129
|
+
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
130
|
+
return unless exception_to_be_printed
|
131
|
+
|
132
|
+
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
133
|
+
@exceptions << exception_to_be_printed
|
134
|
+
end
|
51
135
|
end
|
52
136
|
|
53
|
-
def
|
54
|
-
|
55
|
-
@io.
|
137
|
+
def on_test_run_finished(_event)
|
138
|
+
print_comments(gherkin_source.split("\n").length, 0) unless current_feature_uri.empty?
|
139
|
+
@io.puts
|
140
|
+
print_summary
|
56
141
|
end
|
57
142
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
143
|
+
def attach(src, media_type)
|
144
|
+
return unless media_type == 'text/x.cucumber.log+plain'
|
145
|
+
|
146
|
+
@test_step_output.push src
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def find_exception_to_be_printed(result)
|
152
|
+
return nil if result.ok?(options[:strict])
|
153
|
+
|
154
|
+
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
155
|
+
exception = result.failed? ? result.exception : result
|
156
|
+
return nil if @exceptions.include?(exception)
|
157
|
+
|
158
|
+
exception
|
159
|
+
end
|
160
|
+
|
161
|
+
def calculate_source_indent(test_case)
|
162
|
+
scenario = scenario_source(test_case).scenario
|
163
|
+
@source_indent = calculate_source_indent_for_ast_node(scenario)
|
164
|
+
end
|
165
|
+
|
166
|
+
def calculate_source_indent_for_ast_node(ast_node)
|
167
|
+
indent = 4 + ast_node.keyword.length
|
168
|
+
indent += 1 + ast_node.name.length
|
169
|
+
ast_node.steps.each do |step|
|
170
|
+
step_indent = 5 + step.keyword.length + step.text.length
|
171
|
+
indent = step_indent if step_indent > indent
|
62
172
|
end
|
173
|
+
indent
|
63
174
|
end
|
64
175
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
176
|
+
def calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
|
177
|
+
indent = 7 + scenario_keyword.length
|
178
|
+
indent += 2 + expanded_name.length
|
179
|
+
test_case.test_steps.each do |step|
|
180
|
+
if !step.hook? && step.location.lines.max >= test_case.location.lines.max
|
181
|
+
step_indent = 9 + test_step_keyword(step).length + step.text.length
|
182
|
+
indent = step_indent if step_indent > indent
|
183
|
+
end
|
184
|
+
end
|
185
|
+
indent
|
70
186
|
end
|
71
187
|
|
72
|
-
def
|
73
|
-
@io.puts(
|
74
|
-
@
|
75
|
-
@io.flush
|
188
|
+
def print_step_output
|
189
|
+
@test_step_output.each { |message| @io.puts(indent(format_string(message, :tag), 6)) }
|
190
|
+
@test_step_output = []
|
76
191
|
end
|
77
192
|
|
78
|
-
def
|
79
|
-
@
|
80
|
-
@scenario_indent = 2
|
193
|
+
def first_feature?
|
194
|
+
@first_feature
|
81
195
|
end
|
82
196
|
|
83
|
-
def
|
84
|
-
|
85
|
-
@io.puts
|
86
|
-
@io.flush
|
197
|
+
def same_feature_as_previous_test_case?(location)
|
198
|
+
location.file == current_feature_uri
|
87
199
|
end
|
88
200
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
201
|
+
def feature_has_background?
|
202
|
+
feature_children = gherkin_document.feature.children
|
203
|
+
return false if feature_children.empty?
|
204
|
+
|
205
|
+
!feature_children.first.background.nil?
|
93
206
|
end
|
94
207
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
208
|
+
def print_step_header(test_case)
|
209
|
+
if from_scenario_outline?(test_case)
|
210
|
+
@in_scenario_outline = true
|
211
|
+
unless same_outline_as_previous_test_case?(test_case)
|
212
|
+
@current_scenario_outline = scenario_source(test_case).scenario_outline
|
213
|
+
@io.puts
|
214
|
+
print_outline_data(current_scenario_outline)
|
215
|
+
end
|
216
|
+
unless same_examples_as_previous_test_case?(test_case)
|
217
|
+
@current_examples = scenario_source(test_case).examples
|
218
|
+
@io.puts
|
219
|
+
print_examples_data(current_examples)
|
220
|
+
end
|
221
|
+
print_expanded_row_data(current_test_case) if options[:expand]
|
222
|
+
else
|
223
|
+
@in_scenario_outline = false
|
224
|
+
@current_scenario_outline = nil
|
225
|
+
@current_examples = nil
|
226
|
+
@io.puts
|
227
|
+
@source_indent = calculate_source_indent(current_test_case)
|
228
|
+
print_scenario_data(test_case)
|
229
|
+
end
|
100
230
|
end
|
101
231
|
|
102
|
-
def
|
103
|
-
|
232
|
+
def same_outline_as_previous_test_case?(test_case)
|
233
|
+
scenario_source(test_case).scenario_outline == current_scenario_outline
|
104
234
|
end
|
105
235
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
236
|
+
def same_examples_as_previous_test_case?(test_case)
|
237
|
+
scenario_source(test_case).examples == current_examples
|
238
|
+
end
|
239
|
+
|
240
|
+
def from_scenario_outline?(test_case)
|
241
|
+
scenario = scenario_source(test_case)
|
242
|
+
scenario.type != :Scenario
|
243
|
+
end
|
244
|
+
|
245
|
+
def first_step_after_printing_background_steps?(test_step)
|
246
|
+
return false unless print_background_steps
|
247
|
+
return false unless test_step.location.lines.max >= current_test_case.location.lines.max
|
248
|
+
|
249
|
+
@print_background_steps = false
|
250
|
+
true
|
110
251
|
end
|
111
252
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
|
253
|
+
def print_feature_data
|
254
|
+
feature = gherkin_document.feature
|
255
|
+
print_language_comment(feature.location.line)
|
256
|
+
print_comments(feature.location.line, 0)
|
257
|
+
print_tags(feature.tags, 0)
|
258
|
+
print_feature_line(feature)
|
259
|
+
print_description(feature.description)
|
116
260
|
@io.flush
|
117
|
-
@indent = 6
|
118
|
-
@scenario_indent = 6
|
119
261
|
end
|
120
262
|
|
121
|
-
def
|
122
|
-
|
263
|
+
def print_language_comment(feature_line)
|
264
|
+
gherkin_source.split("\n")[0..feature_line].each do |line|
|
265
|
+
@io.puts(format_string(line, :comment)) if /# *language *:/ =~ line
|
266
|
+
end
|
123
267
|
end
|
124
268
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
269
|
+
def print_comments(up_to_line, indent_amount)
|
270
|
+
comments = gherkin_document.comments
|
271
|
+
return if comments.empty? || comments.length <= @next_comment_to_be_printed
|
272
|
+
|
273
|
+
comments[@next_comment_to_be_printed..].each do |comment|
|
274
|
+
if comment.location.line <= up_to_line
|
275
|
+
@io.puts(indent(format_string(comment.text.strip, :comment), indent_amount))
|
276
|
+
@next_comment_to_be_printed += 1
|
277
|
+
end
|
278
|
+
break if @next_comment_to_be_printed >= comments.length
|
279
|
+
end
|
128
280
|
end
|
129
281
|
|
130
|
-
def
|
131
|
-
|
282
|
+
def print_tags(tags, indent_amount)
|
283
|
+
return if !tags || tags.empty?
|
284
|
+
|
285
|
+
@io.puts(indent(tags.map { |tag| format_string(tag.name, :tag) }.join(' '), indent_amount))
|
132
286
|
end
|
133
287
|
|
134
|
-
def
|
135
|
-
|
136
|
-
@indent = 6
|
137
|
-
print_messages
|
288
|
+
def print_feature_line(feature)
|
289
|
+
print_keyword_name(feature.keyword, feature.name, 0)
|
138
290
|
end
|
139
291
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
@exceptions << exception
|
292
|
+
def print_keyword_name(keyword, name, indent_amount, location = nil)
|
293
|
+
line = "#{keyword}:"
|
294
|
+
line += " #{name}"
|
295
|
+
@io.print(indent(line, indent_amount))
|
296
|
+
if location && options[:source]
|
297
|
+
line_comment = indent(format_string("# #{location}", :comment), @source_indent - line.length - indent_amount)
|
298
|
+
@io.print(line_comment)
|
148
299
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
300
|
+
@io.puts
|
301
|
+
end
|
302
|
+
|
303
|
+
def print_description(description)
|
304
|
+
return unless description
|
305
|
+
|
306
|
+
description.split("\n").each do |line|
|
307
|
+
@io.puts(line)
|
152
308
|
end
|
153
|
-
@status = status
|
154
309
|
end
|
155
310
|
|
156
|
-
def
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
311
|
+
def print_background_data
|
312
|
+
@io.puts
|
313
|
+
background = gherkin_document.feature.children.first.background
|
314
|
+
@source_indent = calculate_source_indent_for_ast_node(background) if options[:source]
|
315
|
+
print_comments(background.location.line, 2)
|
316
|
+
print_background_line(background)
|
317
|
+
print_description(background.description)
|
318
|
+
@io.flush
|
319
|
+
end
|
320
|
+
|
321
|
+
def print_background_line(background)
|
322
|
+
print_keyword_name(background.keyword, background.name, 2, "#{current_feature_uri}:#{background.location.line}")
|
162
323
|
end
|
163
324
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
325
|
+
def print_scenario_data(test_case)
|
326
|
+
scenario = scenario_source(test_case).scenario
|
327
|
+
print_comments(scenario.location.line, 2)
|
328
|
+
print_tags(scenario.tags, 2)
|
329
|
+
print_scenario_line(scenario, test_case.location)
|
330
|
+
print_description(scenario.description)
|
169
331
|
@io.flush
|
170
332
|
end
|
171
333
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
175
|
-
|
334
|
+
def print_scenario_line(scenario, location = nil)
|
335
|
+
print_keyword_name(scenario.keyword, scenario.name, 2, location)
|
336
|
+
end
|
337
|
+
|
338
|
+
def print_step_data?(event, exception_to_be_printed)
|
339
|
+
!event.test_step.hook? && (
|
340
|
+
print_background_steps ||
|
341
|
+
event.test_step.location.lines.max >= current_test_case.location.lines.max ||
|
342
|
+
exception_to_be_printed
|
343
|
+
)
|
344
|
+
end
|
345
|
+
|
346
|
+
def print_step_data(test_step, result)
|
347
|
+
base_indent = options[:expand] && in_scenario_outline ? 8 : 4
|
348
|
+
step_keyword = test_step_keyword(test_step)
|
349
|
+
indent = options[:source] ? @source_indent - step_keyword.length - test_step.text.length - base_indent : nil
|
350
|
+
print_comments(test_step.location.lines.max, base_indent)
|
351
|
+
name_to_report = format_step(step_keyword, @step_matches.fetch(test_step.to_s) { NoStepMatch.new(test_step, test_step.text) }, result.to_sym, indent)
|
352
|
+
@io.puts(indent(name_to_report, base_indent))
|
353
|
+
print_multiline_argument(test_step, result, base_indent + 2) unless options[:no_multiline]
|
176
354
|
@io.flush
|
177
355
|
end
|
178
356
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
357
|
+
def test_step_keyword(test_step)
|
358
|
+
step = step_source(test_step).step
|
359
|
+
step.keyword
|
182
360
|
end
|
183
361
|
|
184
|
-
def
|
185
|
-
@
|
362
|
+
def step_source(test_step)
|
363
|
+
@ast_lookup.step_source(test_step)
|
186
364
|
end
|
187
365
|
|
188
|
-
def
|
189
|
-
|
190
|
-
@col_index = 0
|
191
|
-
@io.print ' |'.indent(@indent - 2)
|
366
|
+
def scenario_source(test_case)
|
367
|
+
@ast_lookup.scenario_source(test_case)
|
192
368
|
end
|
193
369
|
|
194
|
-
def
|
195
|
-
|
196
|
-
print_table_row_messages
|
197
|
-
@io.puts
|
198
|
-
if table_row.exception && !@exceptions.include?(table_row.exception)
|
199
|
-
print_exception(table_row.exception, table_row.status, @indent)
|
200
|
-
end
|
370
|
+
def gherkin_source
|
371
|
+
@gherkin_sources[current_feature_uri]
|
201
372
|
end
|
202
373
|
|
203
|
-
def
|
204
|
-
|
205
|
-
@col_index += 1
|
374
|
+
def gherkin_document
|
375
|
+
@ast_lookup.gherkin_document(current_feature_uri)
|
206
376
|
end
|
207
377
|
|
208
|
-
def
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
@io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Cucumber::Term::ANSIColor.reset(' |'))
|
216
|
-
@io.flush
|
378
|
+
def print_multiline_argument(test_step, result, indent)
|
379
|
+
step = step_source(test_step).step
|
380
|
+
if !step.doc_string.nil?
|
381
|
+
print_doc_string(step.doc_string.content, result.to_sym, indent)
|
382
|
+
elsif !step.data_table.nil?
|
383
|
+
print_data_table(step.data_table, result.to_sym, indent)
|
384
|
+
end
|
217
385
|
end
|
218
386
|
|
219
|
-
def
|
220
|
-
|
387
|
+
def print_data_table(data_table, status, indent_amount)
|
388
|
+
data_table.rows.each do |row|
|
389
|
+
print_comments(row.location.line, indent_amount)
|
390
|
+
@io.puts indent(format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status), indent_amount)
|
391
|
+
end
|
221
392
|
end
|
222
393
|
|
223
|
-
def
|
224
|
-
|
394
|
+
def print_outline_data(scenario_outline) # rubocop:disable Metrics/AbcSize
|
395
|
+
print_comments(scenario_outline.location.line, 2)
|
396
|
+
print_tags(scenario_outline.tags, 2)
|
397
|
+
@source_indent = calculate_source_indent_for_ast_node(scenario_outline) if options[:source]
|
398
|
+
print_scenario_line(scenario_outline, "#{current_feature_uri}:#{scenario_outline.location.line}")
|
399
|
+
print_description(scenario_outline.description)
|
400
|
+
scenario_outline.steps.each do |step|
|
401
|
+
print_comments(step.location.line, 4)
|
402
|
+
step_line = " #{step.keyword}#{step.text}"
|
403
|
+
@io.print(format_string(step_line, :skipped))
|
404
|
+
if options[:source]
|
405
|
+
comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
|
406
|
+
@io.print(indent(comment_line, @source_indent - step_line.length))
|
407
|
+
end
|
408
|
+
@io.puts
|
409
|
+
next if options[:no_multiline]
|
410
|
+
|
411
|
+
print_doc_string(step.doc_string.content, :skipped, 6) unless step.doc_string.nil?
|
412
|
+
print_data_table(step.data_table, :skipped, 6) unless step.data_table.nil?
|
413
|
+
end
|
414
|
+
@io.flush
|
225
415
|
end
|
226
416
|
|
227
|
-
|
417
|
+
def print_doc_string(content, status, indent_amount)
|
418
|
+
s = indent(%("""\n#{content}\n"""), indent_amount)
|
419
|
+
s = s.split("\n").map { |l| l =~ /^\s+$/ ? '' : l }.join("\n")
|
420
|
+
@io.puts(format_string(s, status))
|
421
|
+
end
|
228
422
|
|
229
|
-
def
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
@io.
|
423
|
+
def print_examples_data(examples)
|
424
|
+
print_comments(examples.location.line, 4)
|
425
|
+
print_tags(examples.tags, 4)
|
426
|
+
print_keyword_name(examples.keyword, examples.name, 4)
|
427
|
+
print_description(examples.description)
|
428
|
+
unless options[:expand]
|
429
|
+
print_comments(examples.table_header.location.line, 6)
|
430
|
+
@io.puts(indent(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip, 6))
|
237
431
|
end
|
432
|
+
@io.flush
|
433
|
+
end
|
434
|
+
|
435
|
+
def print_row_data(test_case, result)
|
436
|
+
print_comments(test_case.location.lines.max, 6)
|
437
|
+
@io.print(indent(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym), 6))
|
438
|
+
@io.print(indent(format_string(@test_step_output.join(', '), :tag), 2)) unless @test_step_output.empty?
|
439
|
+
@test_step_output = []
|
238
440
|
@io.puts
|
239
|
-
|
441
|
+
if result.failed? || result.pending?
|
442
|
+
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
443
|
+
exception = result.failed? ? result.exception : result
|
444
|
+
unless @exceptions.include?(exception)
|
445
|
+
print_exception(exception, result.to_sym, 6)
|
446
|
+
@exceptions << exception
|
447
|
+
end
|
448
|
+
end
|
240
449
|
@io.flush
|
241
450
|
end
|
242
451
|
|
243
|
-
def
|
244
|
-
|
452
|
+
def print_expanded_row_data(test_case)
|
453
|
+
feature = gherkin_document.feature
|
454
|
+
language_code = feature.language || 'en'
|
455
|
+
language = ::Gherkin::Dialect.for(language_code)
|
456
|
+
scenario_keyword = language.scenario_keywords[0]
|
457
|
+
row = scenario_source(test_case).row
|
458
|
+
expanded_name = "| #{row.cells.map(&:value).join(' | ')} |"
|
459
|
+
@source_indent = calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
|
460
|
+
@io.puts
|
461
|
+
print_keyword_name(scenario_keyword, expanded_name, 6, test_case.location)
|
245
462
|
end
|
246
463
|
|
247
|
-
def print_summary
|
248
|
-
print_statistics(
|
249
|
-
print_snippets(
|
250
|
-
print_passing_wip(@
|
464
|
+
def print_summary
|
465
|
+
print_statistics(@total_duration, config, @counts, @issues)
|
466
|
+
print_snippets(options)
|
467
|
+
print_passing_wip(config, @passed_test_cases, @ast_lookup)
|
251
468
|
end
|
252
469
|
end
|
253
470
|
end
|