cucumber 3.1.2 → 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 +5 -5
- data/CHANGELOG.md +1780 -1146
- data/CONTRIBUTING.md +224 -61
- data/README.md +144 -22
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +46 -53
- data/lib/cucumber/cli/configuration.rb +28 -6
- data/lib/cucumber/cli/main.rb +12 -12
- data/lib/cucumber/cli/options.rb +103 -77
- data/lib/cucumber/cli/profile_loader.rb +49 -26
- data/lib/cucumber/configuration.rb +44 -29
- data/lib/cucumber/constantize.rb +2 -5
- data/lib/cucumber/deprecate.rb +31 -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 +13 -0
- data/lib/cucumber/events/step_activated.rb +2 -1
- data/lib/cucumber/events/test_case_created.rb +13 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_step_created.rb +13 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
- data/lib/cucumber/events.rb +14 -7
- data/lib/cucumber/file_specs.rb +6 -6
- data/lib/cucumber/filters/activate_steps.rb +5 -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 +2 -4
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +40 -52
- data/lib/cucumber/formatter/ast_lookup.rb +163 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -8
- data/lib/cucumber/formatter/console.rb +69 -69
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +6 -3
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +3 -1
- data/lib/cucumber/formatter/errors.rb +6 -0
- data/lib/cucumber/formatter/fanout.rb +2 -0
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +147 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/interceptor.rb +11 -30
- data/lib/cucumber/formatter/io.rb +55 -13
- data/lib/cucumber/formatter/json.rb +115 -122
- data/lib/cucumber/formatter/junit.rb +72 -55
- data/lib/cucumber/formatter/message.rb +23 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +360 -153
- data/lib/cucumber/formatter/progress.rb +30 -32
- data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -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 +40 -0
- data/lib/cucumber/formatter/rerun.rb +22 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +8 -6
- data/lib/cucumber/formatter/summary.rb +16 -8
- data/lib/cucumber/formatter/unicode.rb +15 -17
- data/lib/cucumber/formatter/url_reporter.rb +17 -0
- data/lib/cucumber/formatter/usage.rb +17 -14
- data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +19 -0
- data/lib/cucumber/glue/hook.rb +34 -11
- data/lib/cucumber/glue/invoke_in_world.rb +13 -18
- data/lib/cucumber/glue/proto_world.rb +37 -44
- data/lib/cucumber/glue/registry_and_more.rb +71 -12
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +42 -20
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +11 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +2 -2
- data/lib/cucumber/multiline_argument/data_table.rb +97 -64
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +3 -3
- data/lib/cucumber/rake/task.rb +16 -18
- data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
- data/lib/cucumber/rspec/doubles.rb +3 -5
- data/lib/cucumber/running_test_case.rb +2 -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/step_hooks.rb +6 -2
- data/lib/cucumber/runtime/support_code.rb +13 -15
- data/lib/cucumber/runtime/user_interface.rb +6 -16
- data/lib/cucumber/runtime.rb +77 -59
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +12 -17
- data/lib/cucumber/step_match_search.rb +2 -1
- data/lib/cucumber/term/ansicolor.rb +9 -9
- data/lib/cucumber/term/banner.rb +56 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +1 -1
- metadata +272 -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,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
-
require 'cucumber/core/
|
4
|
+
require 'cucumber/core/test/doc_string'
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
class Runtime
|
@@ -15,11 +15,13 @@ module Cucumber
|
|
15
15
|
attr_reader :support_code
|
16
16
|
|
17
17
|
def initialize(support_code, user_interface)
|
18
|
-
@support_code
|
18
|
+
@support_code = support_code
|
19
|
+
@user_interface = user_interface
|
19
20
|
end
|
20
21
|
|
21
22
|
def_delegators :@user_interface,
|
22
23
|
:embed,
|
24
|
+
:attach,
|
23
25
|
:ask,
|
24
26
|
:puts,
|
25
27
|
:features_paths,
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module Cucumber
|
4
4
|
class Runtime
|
5
5
|
class StepHooks
|
6
|
-
def initialize(hooks)
|
6
|
+
def initialize(id_generator, hooks, event_bus)
|
7
7
|
@hooks = hooks
|
8
|
+
@id_generator = id_generator
|
9
|
+
@event_bus = event_bus
|
8
10
|
end
|
9
11
|
|
10
12
|
def apply(test_steps)
|
@@ -18,7 +20,9 @@ module Cucumber
|
|
18
20
|
def after_step_hooks(test_step)
|
19
21
|
@hooks.map do |hook|
|
20
22
|
action = ->(*args) { hook.invoke('AfterStep', [args, test_step]) }
|
21
|
-
Hooks.after_step_hook(
|
23
|
+
hook_step = Hooks.after_step_hook(@id_generator.new_id, test_step, hook.location, &action)
|
24
|
+
@event_bus.hook_test_step_created(hook_step, hook)
|
25
|
+
hook_step
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -22,19 +22,15 @@ module Cucumber
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def step(step)
|
25
|
-
location = Core::
|
25
|
+
location = Core::Test::Location.of_caller
|
26
26
|
@support_code.invoke_dynamic_step(step[:text], multiline_arg(step, location))
|
27
27
|
end
|
28
28
|
|
29
29
|
def multiline_arg(step, location)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
MultilineArgument.from(argument[:content], location, argument[:content_type])
|
35
|
-
else
|
36
|
-
MultilineArgument::DataTable.from(argument[:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
|
37
|
-
end
|
30
|
+
if !step[:doc_string].nil?
|
31
|
+
MultilineArgument.from(step[:doc_string][:content], location, step[:doc_string][:content_type])
|
32
|
+
elsif !step[:data_table].nil?
|
33
|
+
MultilineArgument::DataTable.from(step[:data_table][:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
|
38
34
|
else
|
39
35
|
MultilineArgument.from(nil)
|
40
36
|
end
|
@@ -62,8 +58,8 @@ module Cucumber
|
|
62
58
|
# Given I have 8 cukes in my belly
|
63
59
|
# Then I should not be thirsty
|
64
60
|
# })
|
65
|
-
def invoke_dynamic_steps(steps_text,
|
66
|
-
parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self),
|
61
|
+
def invoke_dynamic_steps(steps_text, iso_code, _location)
|
62
|
+
parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self), iso_code)
|
67
63
|
parser.parse(steps_text)
|
68
64
|
end
|
69
65
|
|
@@ -108,26 +104,28 @@ module Cucumber
|
|
108
104
|
def find_after_step_hooks(test_case)
|
109
105
|
scenario = RunningTestCase.new(test_case)
|
110
106
|
hooks = registry.hooks_for(:after_step, scenario)
|
111
|
-
StepHooks.new hooks
|
107
|
+
StepHooks.new(@configuration.id_generator, hooks, @configuration.event_bus)
|
112
108
|
end
|
113
109
|
|
114
110
|
def apply_before_hooks(test_case)
|
111
|
+
return test_case if test_case.test_steps.empty?
|
115
112
|
scenario = RunningTestCase.new(test_case)
|
116
113
|
hooks = registry.hooks_for(:before, scenario)
|
117
|
-
BeforeHooks.new(hooks, scenario).apply_to(test_case)
|
114
|
+
BeforeHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
|
118
115
|
end
|
119
116
|
|
120
117
|
def apply_after_hooks(test_case)
|
118
|
+
return test_case if test_case.test_steps.empty?
|
121
119
|
scenario = RunningTestCase.new(test_case)
|
122
120
|
hooks = registry.hooks_for(:after, scenario)
|
123
|
-
AfterHooks.new(hooks, scenario).apply_to(test_case)
|
121
|
+
AfterHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
|
124
122
|
end
|
125
123
|
|
126
124
|
def find_around_hooks(test_case)
|
127
125
|
scenario = RunningTestCase.new(test_case)
|
128
126
|
|
129
127
|
registry.hooks_for(:around, scenario).map do |hook|
|
130
|
-
Hooks.around_hook
|
128
|
+
Hooks.around_hook do |run_scenario|
|
131
129
|
hook.invoke('Around', scenario, &run_scenario)
|
132
130
|
end
|
133
131
|
end
|
@@ -7,14 +7,6 @@ module Cucumber
|
|
7
7
|
module UserInterface
|
8
8
|
attr_writer :visitor
|
9
9
|
|
10
|
-
# Output +messages+ alongside the formatted output.
|
11
|
-
# This is an alternative to using Kernel#puts - it will display
|
12
|
-
# nicer, and in all outputs (in case you use several formatters)
|
13
|
-
#
|
14
|
-
def puts(*messages)
|
15
|
-
@visitor.puts(*messages)
|
16
|
-
end
|
17
|
-
|
18
10
|
# Suspends execution and prompts +question+ to the console (STDOUT).
|
19
11
|
# An operator (manual tester) can then enter a line of text and hit
|
20
12
|
# <ENTER>. The entered text is returned, and both +question+ and
|
@@ -48,20 +40,18 @@ module Cucumber
|
|
48
40
|
# be a path to a file, or if it's an image it may also be a Base64 encoded image.
|
49
41
|
# The embedded data may or may not be ignored, depending on what kind of formatter(s) are active.
|
50
42
|
#
|
51
|
-
def
|
52
|
-
@visitor.
|
43
|
+
def attach(src, media_type)
|
44
|
+
@visitor.attach(src, media_type)
|
53
45
|
end
|
54
46
|
|
55
47
|
private
|
56
48
|
|
57
49
|
def mri_gets(timeout_seconds)
|
58
|
-
|
59
|
-
|
60
|
-
STDIN.gets
|
61
|
-
end
|
62
|
-
rescue Timeout::Error
|
63
|
-
nil
|
50
|
+
Timeout.timeout(timeout_seconds) do
|
51
|
+
STDIN.gets
|
64
52
|
end
|
53
|
+
rescue Timeout::Error
|
54
|
+
nil
|
65
55
|
end
|
66
56
|
|
67
57
|
def jruby_gets(timeout_seconds)
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require 'fileutils'
|
5
|
-
require 'multi_json'
|
6
4
|
require 'cucumber/configuration'
|
5
|
+
require 'cucumber/create_meta'
|
6
|
+
require 'cucumber/deprecate'
|
7
7
|
require 'cucumber/load_path'
|
8
8
|
require 'cucumber/formatter/duration'
|
9
9
|
require 'cucumber/file_specs'
|
10
10
|
require 'cucumber/filters'
|
11
11
|
require 'cucumber/formatter/fanout'
|
12
12
|
require 'cucumber/gherkin/i18n'
|
13
|
+
require 'cucumber/glue/registry_wrapper'
|
13
14
|
require 'cucumber/step_match_search'
|
15
|
+
require 'cucumber/messages'
|
16
|
+
require 'sys/uname'
|
14
17
|
|
15
18
|
module Cucumber
|
16
19
|
module FixRuby21Bug9285
|
@@ -19,8 +22,8 @@ module Cucumber
|
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
22
|
-
class FileException <
|
23
|
-
|
25
|
+
class FileException < RuntimeError
|
26
|
+
attr_reader :path
|
24
27
|
|
25
28
|
def initialize(original_exception, path)
|
26
29
|
super(original_exception)
|
@@ -31,7 +34,7 @@ module Cucumber
|
|
31
34
|
class FileNotFoundException < FileException
|
32
35
|
end
|
33
36
|
|
34
|
-
class FeatureFolderNotFoundException <
|
37
|
+
class FeatureFolderNotFoundException < RuntimeError
|
35
38
|
def initialize(path)
|
36
39
|
@path = path
|
37
40
|
end
|
@@ -54,7 +57,6 @@ module Cucumber
|
|
54
57
|
def initialize(configuration = Configuration.default)
|
55
58
|
@configuration = Configuration.new(configuration)
|
56
59
|
@support_code = SupportCode.new(self, @configuration)
|
57
|
-
@results = Formatter::LegacyApi::Results.new
|
58
60
|
end
|
59
61
|
|
60
62
|
# Allows you to take an existing runtime and change its configuration
|
@@ -65,15 +67,23 @@ module Cucumber
|
|
65
67
|
|
66
68
|
require 'cucumber/wire/plugin'
|
67
69
|
def run!
|
70
|
+
@configuration.notify :envelope, Cucumber::Messages::Envelope.new(
|
71
|
+
meta: Cucumber::CreateMeta.create_meta('cucumber-ruby', Cucumber::VERSION)
|
72
|
+
)
|
73
|
+
|
68
74
|
load_step_definitions
|
69
|
-
install_wire_plugin
|
70
75
|
fire_after_configuration_hook
|
76
|
+
fire_install_plugin_hook
|
77
|
+
install_wire_plugin
|
78
|
+
fire_before_all_hook unless dry_run?
|
71
79
|
# TODO: can we remove this state?
|
72
80
|
self.visitor = report
|
73
81
|
|
74
82
|
receiver = Test::Runner.new(@configuration.event_bus)
|
75
|
-
compile features, receiver, filters
|
83
|
+
compile features, receiver, filters, @configuration.event_bus
|
76
84
|
@configuration.notify :test_run_finished
|
85
|
+
|
86
|
+
fire_after_all_hook unless dry_run?
|
77
87
|
end
|
78
88
|
|
79
89
|
def features_paths
|
@@ -84,14 +94,6 @@ module Cucumber
|
|
84
94
|
@configuration.dry_run?
|
85
95
|
end
|
86
96
|
|
87
|
-
def scenarios(status = nil)
|
88
|
-
@results.scenarios(status)
|
89
|
-
end
|
90
|
-
|
91
|
-
def steps(status = nil)
|
92
|
-
@results.steps(status)
|
93
|
-
end
|
94
|
-
|
95
97
|
def unmatched_step_definitions
|
96
98
|
@support_code.unmatched_step_definitions
|
97
99
|
end
|
@@ -107,16 +109,27 @@ module Cucumber
|
|
107
109
|
# Returns Ast::DocString for +string_without_triple_quotes+.
|
108
110
|
#
|
109
111
|
def doc_string(string_without_triple_quotes, content_type = '', _line_offset = 0)
|
110
|
-
|
111
|
-
Core::Ast::DocString.new(string_without_triple_quotes, content_type, location)
|
112
|
+
Core::Test::DocString.new(string_without_triple_quotes, content_type)
|
112
113
|
end
|
113
114
|
|
114
115
|
private
|
115
116
|
|
116
|
-
def fire_after_configuration_hook #:nodoc
|
117
|
+
def fire_after_configuration_hook #:nodoc:
|
117
118
|
@support_code.fire_hook(:after_configuration, @configuration)
|
118
119
|
end
|
119
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
|
+
|
120
133
|
require 'cucumber/core/gherkin/document'
|
121
134
|
def features
|
122
135
|
@features ||= feature_files.map do |path|
|
@@ -143,14 +156,12 @@ module Cucumber
|
|
143
156
|
end
|
144
157
|
|
145
158
|
def initialize(path)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
raise FeatureFolderNotFoundException.new(path)
|
153
|
-
end
|
159
|
+
@file = File.new(path)
|
160
|
+
set_encoding
|
161
|
+
rescue Errno::EACCES => e
|
162
|
+
raise FileNotFoundException.new(e, File.expand_path(path))
|
163
|
+
rescue Errno::ENOENT
|
164
|
+
raise FeatureFolderNotFoundException, path
|
154
165
|
end
|
155
166
|
|
156
167
|
def read
|
@@ -162,7 +173,7 @@ module Cucumber
|
|
162
173
|
def set_encoding
|
163
174
|
@file.each do |line|
|
164
175
|
if ENCODING_PATTERN =~ line
|
165
|
-
@file.set_encoding
|
176
|
+
@file.set_encoding Regexp.last_match(1)
|
166
177
|
break
|
167
178
|
end
|
168
179
|
break unless COMMENT_OR_EMPTY_LINE_PATTERN =~ line
|
@@ -171,16 +182,16 @@ module Cucumber
|
|
171
182
|
end
|
172
183
|
end
|
173
184
|
|
174
|
-
require 'cucumber/formatter/legacy_api/adapter'
|
175
|
-
require 'cucumber/formatter/legacy_api/runtime_facade'
|
176
|
-
require 'cucumber/formatter/legacy_api/results'
|
177
185
|
require 'cucumber/formatter/ignore_missing_messages'
|
178
186
|
require 'cucumber/formatter/fail_fast'
|
187
|
+
require 'cucumber/formatter/publish_banner_printer'
|
179
188
|
require 'cucumber/core/report/summary'
|
189
|
+
|
180
190
|
def report
|
181
191
|
return @report if @report
|
182
192
|
reports = [summary_report] + formatters
|
183
193
|
reports << fail_fast_report if @configuration.fail_fast?
|
194
|
+
reports << publish_banner_printer unless @configuration.publish_quiet?
|
184
195
|
@report ||= Formatter::Fanout.new(reports)
|
185
196
|
end
|
186
197
|
|
@@ -192,41 +203,32 @@ module Cucumber
|
|
192
203
|
@fail_fast_report ||= Formatter::FailFast.new(@configuration)
|
193
204
|
end
|
194
205
|
|
206
|
+
def publish_banner_printer
|
207
|
+
@publish_banner_printer ||= Formatter::PublishBannerPrinter.new(@configuration)
|
208
|
+
end
|
209
|
+
|
195
210
|
def formatters
|
196
211
|
@formatters ||=
|
197
|
-
@configuration.formatter_factories do |factory, formatter_options, path_or_io
|
198
|
-
create_formatter(factory, formatter_options, path_or_io
|
212
|
+
@configuration.formatter_factories do |factory, formatter_options, path_or_io|
|
213
|
+
create_formatter(factory, formatter_options, path_or_io)
|
199
214
|
end
|
200
215
|
end
|
201
216
|
|
202
|
-
def create_formatter(factory, formatter_options, path_or_io
|
203
|
-
if
|
204
|
-
if
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
return factory.new(@configuration.with_options(out_stream: path_or_io))
|
211
|
-
end
|
217
|
+
def create_formatter(factory, formatter_options, path_or_io)
|
218
|
+
if accept_options?(factory)
|
219
|
+
return factory.new(@configuration, formatter_options) if path_or_io.nil?
|
220
|
+
factory.new(@configuration.with_options(out_stream: path_or_io),
|
221
|
+
formatter_options)
|
222
|
+
else
|
223
|
+
return factory.new(@configuration) if path_or_io.nil?
|
224
|
+
factory.new(@configuration.with_options(out_stream: path_or_io))
|
212
225
|
end
|
213
|
-
results = Formatter::LegacyApi::Results.new
|
214
|
-
runtime_facade = Formatter::LegacyApi::RuntimeFacade.new(results, @support_code, @configuration)
|
215
|
-
formatter = factory.new(runtime_facade, path_or_io, cli_options)
|
216
|
-
Formatter::LegacyApi::Adapter.new(
|
217
|
-
Formatter::IgnoreMissingMessages.new(formatter),
|
218
|
-
results, @configuration
|
219
|
-
)
|
220
226
|
end
|
221
227
|
|
222
228
|
def accept_options?(factory)
|
223
229
|
factory.instance_method(:initialize).arity > 1
|
224
230
|
end
|
225
231
|
|
226
|
-
def legacy_formatter?(factory)
|
227
|
-
factory.instance_method(:initialize).arity > 2
|
228
|
-
end
|
229
|
-
|
230
232
|
def failure?
|
231
233
|
if @configuration.wip?
|
232
234
|
summary_report.test_cases.total_passed > 0
|
@@ -237,7 +239,7 @@ module Cucumber
|
|
237
239
|
public :failure?
|
238
240
|
|
239
241
|
require 'cucumber/core/test/filters'
|
240
|
-
def filters
|
242
|
+
def filters # rubocop:disable Metrics/AbcSize
|
241
243
|
tag_expressions = @configuration.tag_expressions
|
242
244
|
name_regexps = @configuration.name_regexps
|
243
245
|
tag_limits = @configuration.tag_limits
|
@@ -250,14 +252,18 @@ module Cucumber
|
|
250
252
|
# TODO: can we just use Glue::RegistryAndMore's step definitions directly?
|
251
253
|
step_match_search = StepMatchSearch.new(@support_code.registry.method(:step_matches), @configuration)
|
252
254
|
filters << Filters::ActivateSteps.new(step_match_search, @configuration)
|
253
|
-
@configuration.filters.each
|
254
|
-
|
255
|
-
end
|
255
|
+
@configuration.filters.each { |filter| filters << filter }
|
256
|
+
|
256
257
|
unless configuration.dry_run?
|
257
258
|
filters << Filters::ApplyAfterStepHooks.new(@support_code)
|
258
259
|
filters << Filters::ApplyBeforeHooks.new(@support_code)
|
259
260
|
filters << Filters::ApplyAfterHooks.new(@support_code)
|
260
261
|
filters << Filters::ApplyAroundHooks.new(@support_code)
|
262
|
+
end
|
263
|
+
|
264
|
+
filters << Filters::BroadcastTestCaseReadyEvent.new(@configuration)
|
265
|
+
|
266
|
+
unless configuration.dry_run?
|
261
267
|
filters << Filters::BroadcastTestRunStartedEvent.new(@configuration)
|
262
268
|
filters << Filters::Quit.new
|
263
269
|
filters << Filters::Retry.new(@configuration)
|
@@ -273,7 +279,19 @@ module Cucumber
|
|
273
279
|
end
|
274
280
|
|
275
281
|
def install_wire_plugin
|
276
|
-
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)
|
277
295
|
end
|
278
296
|
|
279
297
|
def log
|
@@ -9,11 +9,12 @@ module Cucumber
|
|
9
9
|
attr_reader :regexp_source, :location
|
10
10
|
|
11
11
|
def initialize(regexp_source, location)
|
12
|
-
@regexp_source
|
12
|
+
@regexp_source = regexp_source
|
13
|
+
@location = location
|
13
14
|
end
|
14
15
|
|
15
|
-
def eql?(
|
16
|
-
regexp_source ==
|
16
|
+
def eql?(other)
|
17
|
+
regexp_source == other.regexp_source && location == other.location
|
17
18
|
end
|
18
19
|
|
19
20
|
def hash
|
@@ -8,8 +8,8 @@ module Cucumber
|
|
8
8
|
@support_code.load_files_from_paths(configuration.autoload_code_paths)
|
9
9
|
end
|
10
10
|
|
11
|
-
def to_json
|
12
|
-
@support_code.step_definitions.map(&:to_hash).to_json
|
11
|
+
def to_json(obj = nil)
|
12
|
+
@support_code.step_definitions.map(&:to_hash).to_json(obj)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/cucumber/step_match.rb
CHANGED
@@ -9,7 +9,9 @@ module Cucumber
|
|
9
9
|
|
10
10
|
def initialize(step_definition, step_name, step_arguments)
|
11
11
|
raise "step_arguments can't be nil (but it can be an empty array)" if step_arguments.nil?
|
12
|
-
@step_definition
|
12
|
+
@step_definition = step_definition
|
13
|
+
@name_to_match = step_name
|
14
|
+
@step_arguments = step_arguments
|
13
15
|
end
|
14
16
|
|
15
17
|
def args
|
@@ -21,12 +23,12 @@ module Cucumber
|
|
21
23
|
|
22
24
|
def activate(test_step)
|
23
25
|
test_step.with_action(@step_definition.location) do
|
24
|
-
invoke(MultilineArgument.from_core(test_step.
|
26
|
+
invoke(MultilineArgument.from_core(test_step.multiline_arg))
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
30
|
def invoke(multiline_arg)
|
29
|
-
all_args =
|
31
|
+
all_args = args
|
30
32
|
multiline_arg.append_to(all_args)
|
31
33
|
@step_definition.invoke(all_args)
|
32
34
|
end
|
@@ -46,7 +48,7 @@ module Cucumber
|
|
46
48
|
#
|
47
49
|
# lambda { |param| "[#{param}]" }
|
48
50
|
#
|
49
|
-
def format_args(format =
|
51
|
+
def format_args(format = ->(a) { a }, &proc)
|
50
52
|
replace_arguments(@name_to_match, @step_arguments, format, &proc)
|
51
53
|
end
|
52
54
|
|
@@ -75,7 +77,7 @@ module Cucumber
|
|
75
77
|
|
76
78
|
replacement = if block_given?
|
77
79
|
yield(group.value)
|
78
|
-
elsif Proc
|
80
|
+
elsif Proc == format.class
|
79
81
|
format.call(group.value)
|
80
82
|
else
|
81
83
|
format % group.value
|
@@ -91,17 +93,11 @@ module Cucumber
|
|
91
93
|
def inspect #:nodoc:
|
92
94
|
"#<#{self.class}: #{location}>"
|
93
95
|
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def deep_clone_args
|
98
|
-
Marshal.load( Marshal.dump( args ) )
|
99
|
-
end
|
100
96
|
end
|
101
97
|
|
102
98
|
class SkippingStepMatch
|
103
99
|
def activate(test_step)
|
104
|
-
|
100
|
+
test_step.with_action { raise Core::Test::Result::Skipped }
|
105
101
|
end
|
106
102
|
end
|
107
103
|
|
@@ -123,8 +119,7 @@ module Cucumber
|
|
123
119
|
end
|
124
120
|
|
125
121
|
def file_colon_line
|
126
|
-
|
127
|
-
@step.file_colon_line
|
122
|
+
location.to_s
|
128
123
|
end
|
129
124
|
|
130
125
|
def backtrace_line
|
@@ -132,7 +127,7 @@ module Cucumber
|
|
132
127
|
end
|
133
128
|
|
134
129
|
def text_length
|
135
|
-
@step.
|
130
|
+
@step.text.length
|
136
131
|
end
|
137
132
|
|
138
133
|
def step_arguments
|
@@ -141,7 +136,7 @@ module Cucumber
|
|
141
136
|
|
142
137
|
def activate(test_step)
|
143
138
|
# noop
|
144
|
-
|
139
|
+
test_step
|
145
140
|
end
|
146
141
|
end
|
147
142
|
|
@@ -151,7 +146,7 @@ module Cucumber
|
|
151
146
|
end
|
152
147
|
|
153
148
|
def activate(test_step)
|
154
|
-
|
149
|
+
test_step.with_action { raise @error }
|
155
150
|
end
|
156
151
|
end
|
157
152
|
end
|
@@ -35,7 +35,7 @@ module Cucumber
|
|
35
35
|
[:on_magenta, 45],
|
36
36
|
[:on_cyan, 46],
|
37
37
|
[:on_white, 47]
|
38
|
-
]
|
38
|
+
].freeze
|
39
39
|
|
40
40
|
ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
|
41
41
|
# :startdoc:
|
@@ -54,8 +54,9 @@ module Cucumber
|
|
54
54
|
end
|
55
55
|
self.coloring = true
|
56
56
|
|
57
|
+
# rubocop:disable Security/Eval
|
57
58
|
ATTRIBUTES.each do |c, v|
|
58
|
-
eval
|
59
|
+
eval <<-END_EVAL, binding, __FILE__, __LINE__ + 1
|
59
60
|
def #{c}(string = nil)
|
60
61
|
result = String.new
|
61
62
|
result << "\e[#{v}m" if Cucumber::Term::ANSIColor.coloring?
|
@@ -71,23 +72,23 @@ module Cucumber
|
|
71
72
|
result << "\e[0m" if Cucumber::Term::ANSIColor.coloring?
|
72
73
|
result
|
73
74
|
end
|
74
|
-
|
75
|
+
END_EVAL
|
75
76
|
end
|
77
|
+
# rubocop:enable Security/Eval
|
76
78
|
|
77
79
|
# Regular expression that is used to scan for ANSI-sequences while
|
78
80
|
# uncoloring strings.
|
79
81
|
COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/
|
80
82
|
|
81
83
|
def self.included(klass)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
84
|
+
return unless klass == String
|
85
|
+
ATTRIBUTES.delete(:clear)
|
86
|
+
ATTRIBUTE_NAMES.delete(:clear)
|
86
87
|
end
|
87
88
|
|
88
89
|
# Returns an uncolored version of the string, that is all
|
89
90
|
# ANSI-sequences are stripped from the string.
|
90
|
-
def uncolored(string = nil)
|
91
|
+
def uncolored(string = nil)
|
91
92
|
if block_given?
|
92
93
|
yield.gsub(COLORED_REGEXP, '')
|
93
94
|
elsif string
|
@@ -105,7 +106,6 @@ module Cucumber
|
|
105
106
|
def attributes
|
106
107
|
ATTRIBUTE_NAMES
|
107
108
|
end
|
108
|
-
extend self
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'cucumber/term/ansicolor'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Term
|
5
|
+
module Banner
|
6
|
+
def display_banner(lines, io, border_modifiers = nil)
|
7
|
+
BannerMaker.new.display_banner(lines, io, border_modifiers || %i[green bold])
|
8
|
+
end
|
9
|
+
|
10
|
+
class BannerMaker
|
11
|
+
include Term::ANSIColor
|
12
|
+
|
13
|
+
def display_banner(lines, io, border_modifiers)
|
14
|
+
lines = lines.split("\n") if lines.is_a? String
|
15
|
+
longest_line_length = lines.map { |line| line_length(line) }.max
|
16
|
+
|
17
|
+
io.puts apply_modifiers("┌#{'─' * (longest_line_length + 2)}┐", border_modifiers)
|
18
|
+
lines.map do |line|
|
19
|
+
padding = ' ' * (longest_line_length - line_length(line))
|
20
|
+
io.puts "#{apply_modifiers('│', border_modifiers)} #{display_line(line)}#{padding} #{apply_modifiers('│', border_modifiers)}"
|
21
|
+
end
|
22
|
+
io.puts apply_modifiers("└#{'─' * (longest_line_length + 2)}┘", border_modifiers)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def display_line(line)
|
28
|
+
line.is_a?(Array) ? line.map { |span| display_span(span) }.join : line
|
29
|
+
end
|
30
|
+
|
31
|
+
def display_span(span)
|
32
|
+
return apply_modifiers(span.shift, span) if span.is_a?(Array)
|
33
|
+
span
|
34
|
+
end
|
35
|
+
|
36
|
+
def apply_modifiers(str, modifiers)
|
37
|
+
display = str
|
38
|
+
modifiers.each { |modifier| display = send(modifier, display) }
|
39
|
+
display
|
40
|
+
end
|
41
|
+
|
42
|
+
def line_length(line)
|
43
|
+
if line.is_a?(Array)
|
44
|
+
line.map { |span| span_length(span) }.sum
|
45
|
+
else
|
46
|
+
line.length
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def span_length(span)
|
51
|
+
span.is_a?(Array) ? span[0].length : span.length
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|