cucumber 6.1.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +256 -166
- data/CONTRIBUTING.md +217 -52
- data/README.md +133 -13
- data/lib/cucumber/cli/options.rb +1 -1
- data/lib/cucumber/events.rb +1 -1
- data/lib/cucumber/formatter/ansicolor.rb +0 -7
- data/lib/cucumber/formatter/console.rb +11 -3
- data/lib/cucumber/formatter/message.rb +2 -1
- data/lib/cucumber/formatter/message_builder.rb +8 -8
- data/lib/cucumber/formatter/pretty.rb +19 -18
- data/lib/cucumber/formatter/publish_banner_printer.rb +1 -1
- data/lib/cucumber/formatter/steps.rb +5 -2
- data/lib/cucumber/formatter/usage.rb +6 -4
- data/lib/cucumber/gherkin/data_table_parser.rb +1 -1
- data/lib/cucumber/gherkin/steps_parser.rb +1 -1
- data/lib/cucumber/glue/dsl.rb +19 -0
- data/lib/cucumber/glue/registry_and_more.rb +29 -0
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/step_definition.rb +3 -4
- data/lib/cucumber/runtime.rb +32 -2
- data/lib/cucumber/version +1 -1
- metadata +40 -40
- data/lib/cucumber/core_ext/string.rb +0 -11
@@ -181,7 +181,7 @@ module Cucumber
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def print_step_output
|
184
|
-
@test_step_output.each { |message| @io.puts(format_string(message, :tag)
|
184
|
+
@test_step_output.each { |message| @io.puts(indent(format_string(message, :tag), 6)) }
|
185
185
|
@test_step_output = []
|
186
186
|
end
|
187
187
|
|
@@ -259,33 +259,34 @@ module Cucumber
|
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
262
|
-
def print_comments(up_to_line,
|
262
|
+
def print_comments(up_to_line, indent_amount)
|
263
263
|
comments = gherkin_document.comments
|
264
264
|
return if comments.empty? || comments.length <= @next_comment_to_be_printed
|
265
265
|
comments[@next_comment_to_be_printed..-1].each do |comment|
|
266
266
|
if comment.location.line <= up_to_line
|
267
|
-
@io.puts(format_string(comment.text.strip, :comment)
|
267
|
+
@io.puts(indent(format_string(comment.text.strip, :comment), indent_amount))
|
268
268
|
@next_comment_to_be_printed += 1
|
269
269
|
end
|
270
270
|
break if @next_comment_to_be_printed >= comments.length
|
271
271
|
end
|
272
272
|
end
|
273
273
|
|
274
|
-
def print_tags(tags,
|
274
|
+
def print_tags(tags, indent_amount)
|
275
275
|
return if !tags || tags.empty?
|
276
|
-
|
276
|
+
|
277
|
+
@io.puts(indent(tags.map { |tag| format_string(tag.name, :tag) }.join(' '), indent_amount))
|
277
278
|
end
|
278
279
|
|
279
280
|
def print_feature_line(feature)
|
280
281
|
print_keyword_name(feature.keyword, feature.name, 0)
|
281
282
|
end
|
282
283
|
|
283
|
-
def print_keyword_name(keyword, name,
|
284
|
+
def print_keyword_name(keyword, name, indent_amount, location = nil)
|
284
285
|
line = "#{keyword}:"
|
285
286
|
line += " #{name}"
|
286
|
-
@io.print(
|
287
|
+
@io.print(indent(line, indent_amount))
|
287
288
|
if location && options[:source]
|
288
|
-
line_comment = format_string("# #{location}", :comment)
|
289
|
+
line_comment = indent(format_string("# #{location}", :comment), @source_indent - line.length - indent_amount)
|
289
290
|
@io.print(line_comment)
|
290
291
|
end
|
291
292
|
@io.puts
|
@@ -339,7 +340,7 @@ module Cucumber
|
|
339
340
|
indent = options[:source] ? @source_indent - step_keyword.length - test_step.text.length - base_indent : nil
|
340
341
|
print_comments(test_step.location.lines.max, base_indent)
|
341
342
|
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)
|
342
|
-
@io.puts(
|
343
|
+
@io.puts(indent(name_to_report, base_indent))
|
343
344
|
print_multiline_argument(test_step, result, base_indent + 2) unless options[:no_multiline]
|
344
345
|
@io.flush
|
345
346
|
end
|
@@ -374,10 +375,10 @@ module Cucumber
|
|
374
375
|
end
|
375
376
|
end
|
376
377
|
|
377
|
-
def print_data_table(data_table, status,
|
378
|
+
def print_data_table(data_table, status, indent_amount)
|
378
379
|
data_table.rows.each do |row|
|
379
|
-
print_comments(row.location.line,
|
380
|
-
@io.puts format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status)
|
380
|
+
print_comments(row.location.line, indent_amount)
|
381
|
+
@io.puts indent(format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status), indent_amount)
|
381
382
|
end
|
382
383
|
end
|
383
384
|
|
@@ -393,7 +394,7 @@ module Cucumber
|
|
393
394
|
@io.print(format_string(step_line, :skipped))
|
394
395
|
if options[:source]
|
395
396
|
comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
|
396
|
-
@io.print(
|
397
|
+
@io.print(indent(comment_line, @source_indent - step_line.length))
|
397
398
|
end
|
398
399
|
@io.puts
|
399
400
|
next if options[:no_multiline]
|
@@ -403,8 +404,8 @@ module Cucumber
|
|
403
404
|
@io.flush
|
404
405
|
end
|
405
406
|
|
406
|
-
def print_doc_string(content, status,
|
407
|
-
s = %("""\n#{content}\n""")
|
407
|
+
def print_doc_string(content, status, indent_amount)
|
408
|
+
s = indent(%("""\n#{content}\n"""), indent_amount)
|
408
409
|
s = s.split("\n").map { |l| l =~ /^\s+$/ ? '' : l }.join("\n")
|
409
410
|
@io.puts(format_string(s, status))
|
410
411
|
end
|
@@ -416,15 +417,15 @@ module Cucumber
|
|
416
417
|
print_description(examples.description)
|
417
418
|
unless options[:expand]
|
418
419
|
print_comments(examples.table_header.location.line, 6)
|
419
|
-
@io.puts(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip
|
420
|
+
@io.puts(indent(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip, 6))
|
420
421
|
end
|
421
422
|
@io.flush
|
422
423
|
end
|
423
424
|
|
424
425
|
def print_row_data(test_case, result)
|
425
426
|
print_comments(test_case.location.lines.max, 6)
|
426
|
-
@io.print(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym)
|
427
|
-
@io.print(format_string(@test_step_output.join(', '), :tag)
|
427
|
+
@io.print(indent(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym), 6))
|
428
|
+
@io.print(indent(format_string(@test_step_output.join(', '), :tag), 2)) unless @test_step_output.empty?
|
428
429
|
@test_step_output = []
|
429
430
|
@io.puts
|
430
431
|
if result.failed? || result.pending?
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'cucumber/formatter/console'
|
4
|
+
|
3
5
|
module Cucumber
|
4
6
|
module Formatter
|
5
7
|
# The formatter used for <tt>--format steps</tt>
|
6
8
|
class Steps
|
9
|
+
include Console
|
7
10
|
def initialize(runtime, path_or_io, options)
|
8
11
|
@io = ensure_io(path_or_io, nil)
|
9
12
|
@options = options
|
@@ -24,8 +27,8 @@ module Cucumber
|
|
24
27
|
sources = @step_definition_files[step_definition_file]
|
25
28
|
source_indent = source_indent(sources)
|
26
29
|
sources.sort.each do |file_colon_line, regexp_source|
|
27
|
-
@io.print
|
28
|
-
@io.print " # #{file_colon_line}"
|
30
|
+
@io.print indent(regexp_source, 2)
|
31
|
+
@io.print indent(" # #{file_colon_line}", source_indent - regexp_source.unpack('U*').length)
|
29
32
|
@io.puts
|
30
33
|
end
|
31
34
|
@io.puts
|
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'cucumber/formatter/progress'
|
4
4
|
require 'cucumber/step_definition_light'
|
5
|
+
require 'cucumber/formatter/console'
|
5
6
|
|
6
7
|
module Cucumber
|
7
8
|
module Formatter
|
8
9
|
class Usage < Progress
|
10
|
+
include Console
|
9
11
|
class StepDefKey < StepDefinitionLight
|
10
12
|
attr_accessor :mean_duration, :status
|
11
13
|
end
|
@@ -87,8 +89,8 @@ module Cucumber
|
|
87
89
|
@io.print format_string(format('%<duration>.7f', duration: stepdef_key.mean_duration), :skipped) + ' ' unless config.dry_run?
|
88
90
|
@io.print format_string(stepdef_key.regexp_source, stepdef_key.status)
|
89
91
|
if config.source?
|
90
|
-
|
91
|
-
line_comment = " # #{stepdef_key.location}"
|
92
|
+
indent_amount = max_length - stepdef_key.regexp_source.unpack('U*').length
|
93
|
+
line_comment = indent(" # #{stepdef_key.location}", indent_amount)
|
92
94
|
@io.print(format_string(line_comment, :comment))
|
93
95
|
end
|
94
96
|
@io.puts
|
@@ -100,8 +102,8 @@ module Cucumber
|
|
100
102
|
@io.print format_string(format('%<duration>.7f', duration: step[:duration]), :skipped) + ' ' unless config.dry_run?
|
101
103
|
@io.print format_step(step[:keyword], step[:step_match], step[:status], nil)
|
102
104
|
if config.source?
|
103
|
-
|
104
|
-
line_comment = " # #{step[:location]}"
|
105
|
+
indent_amount = max_length - (step[:keyword].unpack('U*').length + step[:step_match].format_args.unpack('U*').length)
|
106
|
+
line_comment = indent(" # #{step[:location]}", indent_amount)
|
105
107
|
@io.print(format_string(line_comment, :comment))
|
106
108
|
end
|
107
109
|
@io.puts
|
@@ -15,7 +15,7 @@ module Cucumber
|
|
15
15
|
messages = ::Gherkin.from_source('dummy', feature_header + text, gherkin_options)
|
16
16
|
|
17
17
|
messages.each do |message|
|
18
|
-
gherkin_document = message.gherkin_document.
|
18
|
+
gherkin_document = message.gherkin_document.to_h unless message.gherkin_document.nil?
|
19
19
|
end
|
20
20
|
|
21
21
|
return if gherkin_document.nil?
|
@@ -17,7 +17,7 @@ module Cucumber
|
|
17
17
|
messages = ::Gherkin.from_source('dummy', feature_header(dialect) + text, gherkin_options)
|
18
18
|
|
19
19
|
messages.each do |message|
|
20
|
-
gherkin_document = message.gherkin_document.
|
20
|
+
gherkin_document = message.gherkin_document.to_h unless message.gherkin_document.nil?
|
21
21
|
end
|
22
22
|
|
23
23
|
@builder.steps(gherkin_document[:feature][:children][0][:scenario][:steps])
|
data/lib/cucumber/glue/dsl.rb
CHANGED
@@ -109,10 +109,29 @@ module Cucumber
|
|
109
109
|
|
110
110
|
# Registers a proc that will run after Cucumber is configured. You can register as
|
111
111
|
# as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
|
112
|
+
#
|
113
|
+
# DEPRECATED: please use InstallPlugin or BeforeAll instead
|
112
114
|
def AfterConfiguration(&proc)
|
113
115
|
Dsl.register_rb_hook('after_configuration', [], proc)
|
114
116
|
end
|
115
117
|
|
118
|
+
# Registers a proc that will run after Cucumber is configured in order to install an external plugin.
|
119
|
+
def InstallPlugin(&proc)
|
120
|
+
Dsl.register_rb_hook('install_plugin', [], proc)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Registers a proc that will run before the execution of the scenarios.
|
124
|
+
# Use it for your final set-ups
|
125
|
+
def BeforeAll(&proc)
|
126
|
+
Dsl.register_rb_hook('before_all', [], proc)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Registers a proc that will run after the execution of the scenarios.
|
130
|
+
# Use it for your final clean-ups
|
131
|
+
def AfterAll(&proc)
|
132
|
+
Dsl.register_rb_hook('after_all', [], proc)
|
133
|
+
end
|
134
|
+
|
116
135
|
# Registers a new Ruby StepDefinition. This method is aliased
|
117
136
|
# to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
|
118
137
|
# also to the i18n translations whenever a feature of a
|
@@ -4,6 +4,7 @@ require 'cucumber/cucumber_expressions/parameter_type_registry'
|
|
4
4
|
require 'cucumber/cucumber_expressions/cucumber_expression'
|
5
5
|
require 'cucumber/cucumber_expressions/regular_expression'
|
6
6
|
require 'cucumber/cucumber_expressions/cucumber_expression_generator'
|
7
|
+
require 'cucumber/deprecate'
|
7
8
|
require 'cucumber/glue/dsl'
|
8
9
|
require 'cucumber/glue/snippet'
|
9
10
|
require 'cucumber/glue/hook'
|
@@ -135,11 +136,31 @@ module Cucumber
|
|
135
136
|
end
|
136
137
|
|
137
138
|
def after_configuration(configuration)
|
139
|
+
deprecate_after_configuration_hook if hooks[:after_configuration].any?
|
140
|
+
|
138
141
|
hooks[:after_configuration].each do |hook|
|
139
142
|
hook.invoke('AfterConfiguration', configuration)
|
140
143
|
end
|
141
144
|
end
|
142
145
|
|
146
|
+
def install_plugin(configuration, registry)
|
147
|
+
hooks[:install_plugin].each do |hook|
|
148
|
+
hook.invoke('InstallPlugin', [configuration, registry])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def before_all
|
153
|
+
hooks[:before_all].each do |hook|
|
154
|
+
hook.invoke('BeforeAll', [])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def after_all
|
159
|
+
hooks[:after_all].each do |hook|
|
160
|
+
hook.invoke('AfterAll', [])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
143
164
|
def add_hook(phase, hook)
|
144
165
|
hooks[phase.to_sym] << hook
|
145
166
|
hook
|
@@ -207,6 +228,14 @@ module Cucumber
|
|
207
228
|
def hooks
|
208
229
|
@hooks ||= Hash.new { |h, k| h[k] = [] }
|
209
230
|
end
|
231
|
+
|
232
|
+
def deprecate_after_configuration_hook
|
233
|
+
Cucumber.deprecate(
|
234
|
+
'See https://github.com/cucumber/cucumber-ruby/blob/main/UPGRADING.md#upgrading-to-710 for more info',
|
235
|
+
' AfterConfiguration hook',
|
236
|
+
'8.0.0'
|
237
|
+
)
|
238
|
+
end
|
210
239
|
end
|
211
240
|
|
212
241
|
def self.backtrace_line(proc, name)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Glue
|
5
|
+
##
|
6
|
+
# This class wraps some internals methods to expose them to external plugins.
|
7
|
+
class RegistryWrapper
|
8
|
+
def initialize(registry)
|
9
|
+
@registry = registry
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Creates a new CucumberExpression from the given +string_or_regexp+.
|
14
|
+
#
|
15
|
+
# If +string_or_regexp+ is a string, it will return a new CucumberExpression::CucumberExpression
|
16
|
+
#
|
17
|
+
# If +string_or_regexp+ is a regexp, it will return a new CucumberExpressions::RegularExpression
|
18
|
+
#
|
19
|
+
# An ArgumentError is raised if +string_or_regexp+ is not a string or a regexp
|
20
|
+
def create_expression(string_or_regexp)
|
21
|
+
@registry.create_expression(string_or_regexp)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Return the current execution environment - AKA an isntance of World
|
26
|
+
def current_world
|
27
|
+
@registry.current_world
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cucumber/step_match'
|
4
|
-
require 'cucumber/core_ext/string'
|
5
4
|
require 'cucumber/glue/invoke_in_world'
|
6
5
|
|
7
6
|
module Cucumber
|
@@ -77,7 +76,7 @@ module Cucumber
|
|
77
76
|
Cucumber::Messages::Envelope.new(
|
78
77
|
step_definition: Cucumber::Messages::StepDefinition.new(
|
79
78
|
id: id,
|
80
|
-
pattern: Cucumber::Messages::
|
79
|
+
pattern: Cucumber::Messages::StepDefinitionPattern.new(
|
81
80
|
source: expression.source.to_s,
|
82
81
|
type: expression_type
|
83
82
|
),
|
@@ -92,8 +91,8 @@ module Cucumber
|
|
92
91
|
end
|
93
92
|
|
94
93
|
def expression_type
|
95
|
-
return Cucumber::Messages::
|
96
|
-
Cucumber::Messages::
|
94
|
+
return Cucumber::Messages::StepDefinitionPatternType::CUCUMBER_EXPRESSION if expression.is_a?(CucumberExpressions::CucumberExpression)
|
95
|
+
Cucumber::Messages::StepDefinitionPatternType::REGULAR_EXPRESSION
|
97
96
|
end
|
98
97
|
|
99
98
|
# @api private
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -3,12 +3,14 @@
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'cucumber/configuration'
|
5
5
|
require 'cucumber/create_meta'
|
6
|
+
require 'cucumber/deprecate'
|
6
7
|
require 'cucumber/load_path'
|
7
8
|
require 'cucumber/formatter/duration'
|
8
9
|
require 'cucumber/file_specs'
|
9
10
|
require 'cucumber/filters'
|
10
11
|
require 'cucumber/formatter/fanout'
|
11
12
|
require 'cucumber/gherkin/i18n'
|
13
|
+
require 'cucumber/glue/registry_wrapper'
|
12
14
|
require 'cucumber/step_match_search'
|
13
15
|
require 'cucumber/messages'
|
14
16
|
require 'sys/uname'
|
@@ -70,14 +72,18 @@ module Cucumber
|
|
70
72
|
)
|
71
73
|
|
72
74
|
load_step_definitions
|
73
|
-
install_wire_plugin
|
74
75
|
fire_after_configuration_hook
|
76
|
+
fire_install_plugin_hook
|
77
|
+
install_wire_plugin
|
78
|
+
fire_before_all_hook unless dry_run?
|
75
79
|
# TODO: can we remove this state?
|
76
80
|
self.visitor = report
|
77
81
|
|
78
82
|
receiver = Test::Runner.new(@configuration.event_bus)
|
79
83
|
compile features, receiver, filters, @configuration.event_bus
|
80
84
|
@configuration.notify :test_run_finished
|
85
|
+
|
86
|
+
fire_after_all_hook unless dry_run?
|
81
87
|
end
|
82
88
|
|
83
89
|
def features_paths
|
@@ -112,6 +118,18 @@ module Cucumber
|
|
112
118
|
@support_code.fire_hook(:after_configuration, @configuration)
|
113
119
|
end
|
114
120
|
|
121
|
+
def fire_install_plugin_hook #:nodoc:
|
122
|
+
@support_code.fire_hook(:install_plugin, @configuration, registry_wrapper)
|
123
|
+
end
|
124
|
+
|
125
|
+
def fire_before_all_hook #:nodoc:
|
126
|
+
@support_code.fire_hook(:before_all)
|
127
|
+
end
|
128
|
+
|
129
|
+
def fire_after_all_hook #:nodoc:
|
130
|
+
@support_code.fire_hook(:after_all)
|
131
|
+
end
|
132
|
+
|
115
133
|
require 'cucumber/core/gherkin/document'
|
116
134
|
def features
|
117
135
|
@features ||= feature_files.map do |path|
|
@@ -261,7 +279,19 @@ module Cucumber
|
|
261
279
|
end
|
262
280
|
|
263
281
|
def install_wire_plugin
|
264
|
-
Cucumber::Wire::Plugin.
|
282
|
+
return if Cucumber::Wire::Plugin.installed?
|
283
|
+
return unless @configuration.all_files_to_load.any? { |f| f =~ /\.wire$/ }
|
284
|
+
|
285
|
+
Cucumber::Wire::Plugin.new(@configuration, registry_wrapper).install
|
286
|
+
Cucumber.deprecate(
|
287
|
+
'See https://github.com/cucumber/cucumber-ruby/blob/main/UPGRADING.md#upgrading-to-710 for more info',
|
288
|
+
' built-in usage of the wire protocol',
|
289
|
+
'8.0.0'
|
290
|
+
)
|
291
|
+
end
|
292
|
+
|
293
|
+
def registry_wrapper
|
294
|
+
Cucumber::Glue::RegistryWrapper.new(@support_code.registry)
|
265
295
|
end
|
266
296
|
|
267
297
|
def log
|
data/lib/cucumber/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
7.1.0
|