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
@@ -16,26 +16,19 @@ Could not find profile: '#{profile}'
|
|
16
16
|
|
17
17
|
Defined profiles in cucumber.yml:
|
18
18
|
* #{cucumber_yml.keys.sort.join("\n * ")}
|
19
|
-
|
19
|
+
END_OF_ERROR
|
20
20
|
end
|
21
21
|
|
22
22
|
args_from_yml = cucumber_yml[profile] || ''
|
23
23
|
|
24
|
-
require 'shellwords'
|
25
|
-
|
26
24
|
case args_from_yml
|
27
25
|
when String
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
placeholder = 'pseudo_unique_backslash_placeholder'
|
33
|
-
sanitized_line = args_from_yml.gsub('\\', placeholder)
|
34
|
-
|
35
|
-
args_from_yml = Shellwords.shellwords(sanitized_line).collect { |argument| argument.gsub(placeholder, '\\') }
|
36
|
-
else
|
37
|
-
args_from_yml = Shellwords.shellwords(args_from_yml)
|
26
|
+
if args_from_yml =~ /^\s*$/
|
27
|
+
raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was blank." \
|
28
|
+
" Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n"
|
38
29
|
end
|
30
|
+
|
31
|
+
args_from_yml = processed_shellwords(args_from_yml)
|
39
32
|
when Array
|
40
33
|
raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was empty. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml.empty?
|
41
34
|
else
|
@@ -45,7 +38,7 @@ Defined profiles in cucumber.yml:
|
|
45
38
|
args_from_yml
|
46
39
|
end
|
47
40
|
|
48
|
-
def
|
41
|
+
def profile?(profile)
|
49
42
|
cucumber_yml.key?(profile)
|
50
43
|
end
|
51
44
|
|
@@ -58,29 +51,43 @@ Defined profiles in cucumber.yml:
|
|
58
51
|
# Loads the profile, processing it through ERB and YAML, and returns it as a hash.
|
59
52
|
def cucumber_yml
|
60
53
|
return @cucumber_yml if @cucumber_yml
|
61
|
-
|
62
|
-
|
54
|
+
|
55
|
+
ensure_configuration_file_exists
|
56
|
+
process_configuration_file_with_erb
|
57
|
+
load_configuration
|
58
|
+
|
59
|
+
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
60
|
+
raise(YmlLoadError, 'cucumber.yml was found, but was blank or malformed. ' \
|
61
|
+
"Please refer to cucumber's documentation on correct profile usage.\n")
|
63
62
|
end
|
64
63
|
|
64
|
+
@cucumber_yml
|
65
|
+
end
|
66
|
+
|
67
|
+
def ensure_configuration_file_exists
|
68
|
+
return if cucumber_yml_defined?
|
69
|
+
|
70
|
+
raise(ProfilesNotDefinedError, "cucumber.yml was not found. Current directory is #{Dir.pwd}." \
|
71
|
+
"Please refer to cucumber's documentation on defining profiles in cucumber.yml. You must define" \
|
72
|
+
"a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_configuration_file_with_erb
|
65
76
|
require 'erb'
|
66
|
-
require 'yaml'
|
67
77
|
begin
|
68
|
-
@cucumber_erb = ERB.new(IO.read(cucumber_file),
|
78
|
+
@cucumber_erb = ERB.new(IO.read(cucumber_file), trim_mode: '%').result(binding)
|
69
79
|
rescue StandardError
|
70
|
-
raise(YmlLoadError, "cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage.\n#{
|
80
|
+
raise(YmlLoadError, "cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage.\n#{$ERROR_INFO.inspect}")
|
71
81
|
end
|
82
|
+
end
|
72
83
|
|
84
|
+
def load_configuration
|
85
|
+
require 'yaml'
|
73
86
|
begin
|
74
|
-
@cucumber_yml = YAML.load(@cucumber_erb)
|
87
|
+
@cucumber_yml = YAML.load(@cucumber_erb) # rubocop:disable Security/YAMLLoad
|
75
88
|
rescue StandardError
|
76
89
|
raise(YmlLoadError, "cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
|
77
90
|
end
|
78
|
-
|
79
|
-
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
80
|
-
raise(YmlLoadError, "cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentation on correct profile usage.\n")
|
81
|
-
end
|
82
|
-
|
83
|
-
return @cucumber_yml
|
84
91
|
end
|
85
92
|
|
86
93
|
# Locates cucumber.yml file. The file can end in .yml or .yaml,
|
@@ -89,6 +96,18 @@ Defined profiles in cucumber.yml:
|
|
89
96
|
def cucumber_file
|
90
97
|
@cucumber_file ||= Dir.glob('{,.config/,config/}cucumber{.yml,.yaml}').first
|
91
98
|
end
|
99
|
+
|
100
|
+
def processed_shellwords(args_from_yml)
|
101
|
+
require 'shellwords'
|
102
|
+
|
103
|
+
return Shellwords.shellwords(args_from_yml) unless Cucumber::WINDOWS
|
104
|
+
|
105
|
+
# Shellwords treats backslash as an escape character so we have to mask it out temporarily
|
106
|
+
placeholder = 'pseudo_unique_backslash_placeholder'
|
107
|
+
sanitized_line = args_from_yml.gsub('\\', placeholder)
|
108
|
+
|
109
|
+
Shellwords.shellwords(sanitized_line).collect { |argument| argument.gsub(placeholder, '\\') }
|
110
|
+
end
|
92
111
|
end
|
93
112
|
end
|
94
113
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'cucumber/constantize'
|
4
4
|
require 'cucumber/cli/rerun_file'
|
5
5
|
require 'cucumber/events'
|
6
|
+
require 'cucumber/messages'
|
6
7
|
require 'cucumber/core/event_bus'
|
7
8
|
require 'cucumber/core/test/result'
|
8
9
|
require 'forwardable'
|
@@ -54,13 +55,21 @@ module Cucumber
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def seed
|
57
|
-
|
58
|
+
@options[:seed]
|
58
59
|
end
|
59
60
|
|
60
61
|
def dry_run?
|
61
62
|
@options[:dry_run]
|
62
63
|
end
|
63
64
|
|
65
|
+
def publish_enabled?
|
66
|
+
@options[:publish_enabled]
|
67
|
+
end
|
68
|
+
|
69
|
+
def publish_quiet?
|
70
|
+
@options[:publish_quiet]
|
71
|
+
end
|
72
|
+
|
64
73
|
def fail_fast?
|
65
74
|
@options[:fail_fast]
|
66
75
|
end
|
@@ -167,10 +176,14 @@ module Cucumber
|
|
167
176
|
end
|
168
177
|
|
169
178
|
def support_to_load
|
170
|
-
support_files = all_files_to_load.select { |f| f =~
|
171
|
-
|
179
|
+
support_files = all_files_to_load.select { |f| f =~ /\/support\// }
|
180
|
+
|
181
|
+
# env_files are separated from other_files so we can ensure env files
|
182
|
+
# load first.
|
183
|
+
#
|
184
|
+
env_files = support_files.select { |f| f =~ /\/support\/env\..*/ }
|
172
185
|
other_files = support_files - env_files
|
173
|
-
|
186
|
+
env_files.reverse + other_files.reverse
|
174
187
|
end
|
175
188
|
|
176
189
|
def all_files_to_load
|
@@ -180,27 +193,24 @@ module Cucumber
|
|
180
193
|
File.directory?(path) ? Dir["#{path}/**/*"] : path
|
181
194
|
end.flatten.uniq
|
182
195
|
remove_excluded_files_from(files)
|
183
|
-
files.
|
196
|
+
files.select! { |f| File.file?(f) }
|
184
197
|
files.reject! { |f| File.extname(f) == '.feature' }
|
185
198
|
files.reject! { |f| f =~ /^http/ }
|
186
199
|
files.sort
|
187
200
|
end
|
188
201
|
|
189
202
|
def step_defs_to_load
|
190
|
-
all_files_to_load.reject { |f| f =~
|
203
|
+
all_files_to_load.reject { |f| f =~ /\/support\// }
|
191
204
|
end
|
192
205
|
|
193
206
|
def formatter_factories
|
194
207
|
formats.map do |format, formatter_options, path_or_io|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
rescue Exception => e
|
202
|
-
raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
|
203
|
-
end
|
208
|
+
factory = formatter_class(format)
|
209
|
+
yield factory,
|
210
|
+
formatter_options,
|
211
|
+
path_or_io
|
212
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
213
|
+
raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
|
204
214
|
end
|
205
215
|
end
|
206
216
|
|
@@ -239,26 +249,31 @@ module Cucumber
|
|
239
249
|
@options[:event_bus]
|
240
250
|
end
|
241
251
|
|
252
|
+
def id_generator
|
253
|
+
@id_generator ||= Cucumber::Messages::IdGenerator::UUID.new
|
254
|
+
end
|
255
|
+
|
242
256
|
private
|
243
257
|
|
244
258
|
def default_options
|
245
259
|
{
|
246
|
-
:
|
247
|
-
:
|
248
|
-
:
|
249
|
-
:
|
250
|
-
:
|
251
|
-
:
|
252
|
-
:
|
253
|
-
:
|
254
|
-
:
|
255
|
-
:
|
256
|
-
:
|
257
|
-
:
|
258
|
-
:
|
259
|
-
:
|
260
|
-
:
|
261
|
-
:
|
260
|
+
autoload_code_paths: ['features/support', 'features/step_definitions'],
|
261
|
+
filters: [],
|
262
|
+
strict: Cucumber::Core::Test::Result::StrictConfiguration.new,
|
263
|
+
require: [],
|
264
|
+
dry_run: false,
|
265
|
+
publish_quiet: false,
|
266
|
+
fail_fast: false,
|
267
|
+
formats: [],
|
268
|
+
excludes: [],
|
269
|
+
tag_expressions: [],
|
270
|
+
name_regexps: [],
|
271
|
+
env_vars: {},
|
272
|
+
diff_enabled: true,
|
273
|
+
snippets: true,
|
274
|
+
source: true,
|
275
|
+
duration: true,
|
276
|
+
event_bus: Cucumber::Events.make_event_bus
|
262
277
|
}
|
263
278
|
end
|
264
279
|
|
@@ -268,6 +283,7 @@ module Cucumber
|
|
268
283
|
|
269
284
|
def with_default_features_path(paths)
|
270
285
|
return default_features_paths if paths.empty?
|
286
|
+
|
271
287
|
paths
|
272
288
|
end
|
273
289
|
|
data/lib/cucumber/constantize.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'cucumber/platform'
|
4
4
|
module Cucumber
|
5
|
-
module Constantize
|
5
|
+
module Constantize # :nodoc:
|
6
6
|
def constantize(camel_cased_word)
|
7
7
|
try = 0
|
8
8
|
begin
|
@@ -17,11 +17,8 @@ module Cucumber
|
|
17
17
|
constant
|
18
18
|
rescue NameError => e
|
19
19
|
require underscore(camel_cased_word)
|
20
|
-
if try < 2
|
21
|
-
|
22
|
-
else
|
23
|
-
raise e
|
24
|
-
end
|
20
|
+
retry if try < 2
|
21
|
+
raise e
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
data/lib/cucumber/deprecate.rb
CHANGED
@@ -5,23 +5,48 @@ require 'cucumber/gherkin/formatter/ansi_escapes'
|
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
module Deprecate
|
8
|
-
|
9
|
-
|
8
|
+
class AnsiString
|
9
|
+
include Cucumber::Gherkin::Formatter::AnsiEscapes
|
10
|
+
|
11
|
+
def self.failure_message(message)
|
12
|
+
AnsiString.new.failure_message(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def failure_message(message)
|
16
|
+
failed + message + reset
|
17
|
+
end
|
18
|
+
end
|
10
19
|
|
20
|
+
class CliOption
|
21
|
+
def self.deprecate(stream, option, message, remove_after_version)
|
22
|
+
return if stream.nil?
|
23
|
+
|
24
|
+
stream.puts(
|
25
|
+
AnsiString.failure_message(
|
26
|
+
"\nWARNING: #{option} is deprecated" \
|
27
|
+
" and will be removed after version #{remove_after_version}.\n#{message}.\n"
|
28
|
+
)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module ForUsers
|
11
34
|
def self.call(message, method, remove_after_version)
|
12
|
-
|
35
|
+
$stderr.puts AnsiString.failure_message(
|
36
|
+
"\nWARNING: ##{method} is deprecated" \
|
37
|
+
" and will be removed after version #{remove_after_version}. #{message}.\n" \
|
38
|
+
"(Called from #{caller(3..3).first})"
|
39
|
+
)
|
13
40
|
end
|
14
41
|
end
|
15
42
|
|
16
43
|
module ForDevelopers
|
17
44
|
def self.call(_message, _method, remove_after_version)
|
18
|
-
if Cucumber::VERSION
|
19
|
-
raise "This method is due for removal after version #{remove_after_version}"
|
20
|
-
end
|
45
|
+
raise "This method is due for removal after version #{remove_after_version}" if Cucumber::VERSION >= remove_after_version
|
21
46
|
end
|
22
47
|
end
|
23
48
|
|
24
|
-
STRATEGY = $
|
49
|
+
STRATEGY = $PROGRAM_NAME =~ /rspec$/ ? ForDevelopers : ForUsers
|
25
50
|
end
|
26
51
|
|
27
52
|
def self.deprecate(*args)
|
data/lib/cucumber/errors.rb
CHANGED
@@ -6,14 +6,12 @@ module Cucumber
|
|
6
6
|
# Raised when there is no matching StepDefinition for a step.
|
7
7
|
class Undefined < Core::Test::Result::Undefined
|
8
8
|
def self.from(result, step_name)
|
9
|
-
if result.is_a?(self)
|
10
|
-
return result.with_message(with_prefix(result.message))
|
11
|
-
end
|
9
|
+
return result.with_message(with_prefix(result.message)) if result.is_a?(self)
|
12
10
|
|
13
11
|
begin
|
14
|
-
raise self
|
15
|
-
rescue =>
|
16
|
-
|
12
|
+
raise self, with_prefix(step_name)
|
13
|
+
rescue StandardError => e
|
14
|
+
e
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
@@ -37,7 +35,7 @@ module Cucumber
|
|
37
35
|
# Raised when a step matches 2 or more StepDefinitions
|
38
36
|
class Ambiguous < StandardError
|
39
37
|
def initialize(step_name, step_definitions, used_guess)
|
40
|
-
message = String.new
|
38
|
+
message = String.new # rubocop:disable Style/EmptyLiteral
|
41
39
|
message << "Ambiguous match of \"#{step_name}\":\n\n"
|
42
40
|
message << step_definitions.map(&:backtrace_line).join("\n")
|
43
41
|
message << "\n\n"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'cucumber/core/events'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Events
|
5
|
+
# Fired after we've parsed the contents of a feature file
|
6
|
+
class GherkinSourceParsed < Core::Event.new(:gherkin_document)
|
7
|
+
# The Gherkin Ast
|
8
|
+
attr_reader :gherkin_document
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/core/events'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Events
|
7
|
+
# Event fired when a step is created from a hook
|
8
|
+
class HookTestStepCreated < Core::Event.new(:test_step, :hook)
|
9
|
+
attr_reader :test_step, :hook
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/core/events'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Events
|
7
|
+
# Event fired when a Test::Case is created from a Pickle
|
8
|
+
class TestCaseCreated < Core::Event.new(:test_case, :pickle)
|
9
|
+
attr_reader :test_case, :pickle
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/core/events'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Events
|
7
|
+
# Event fired when a Test::Case is ready to be ran (matching has been done, hooks added etc)
|
8
|
+
class TestCaseReady < Core::Event.new(:test_case)
|
9
|
+
attr_reader :test_case
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/core/events'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Events
|
7
|
+
# Event fired when a TestStep is created from a PickleStep
|
8
|
+
class TestStepCreated < Core::Event.new(:test_step, :pickle_step)
|
9
|
+
attr_reader :test_step, :pickle_step
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/cucumber/events.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
Dir[File.dirname(__FILE__)
|
3
|
+
Dir["#{File.dirname(__FILE__)}/events/*.rb"].map(&method(:require))
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
# Events tell you what's happening while Cucumber runs your features.
|
@@ -11,7 +11,7 @@ module Cucumber
|
|
11
11
|
# To subscribe to an event, use {Cucumber::Configuration#on_event}
|
12
12
|
#
|
13
13
|
# @example
|
14
|
-
#
|
14
|
+
# InstallPlugin do |config|
|
15
15
|
# config.on_event :test_case_finished do |event|
|
16
16
|
# puts event.result
|
17
17
|
# end
|
@@ -24,15 +24,22 @@ module Cucumber
|
|
24
24
|
|
25
25
|
def self.registry
|
26
26
|
Core::Events.build_registry(
|
27
|
-
|
27
|
+
GherkinSourceParsed,
|
28
|
+
GherkinSourceRead,
|
29
|
+
HookTestStepCreated,
|
30
|
+
StepActivated,
|
31
|
+
StepDefinitionRegistered,
|
32
|
+
TestCaseCreated,
|
28
33
|
TestCaseFinished,
|
34
|
+
TestCaseStarted,
|
35
|
+
TestCaseReady,
|
36
|
+
TestRunFinished,
|
37
|
+
TestRunStarted,
|
38
|
+
TestStepCreated,
|
29
39
|
TestStepFinished,
|
30
40
|
TestStepStarted,
|
31
|
-
|
32
|
-
|
33
|
-
TestRunFinished,
|
34
|
-
GherkinSourceRead,
|
35
|
-
TestRunStarted
|
41
|
+
Envelope,
|
42
|
+
UndefinedParameterType
|
36
43
|
)
|
37
44
|
end
|
38
45
|
end
|
data/lib/cucumber/file_specs.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cucumber'
|
4
|
-
require 'cucumber/core/
|
4
|
+
require 'cucumber/core/test/location'
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
class FileSpecs
|
8
|
-
FILE_COLON_LINE_PATTERN = /^([\w\W]*?)(?::([\d:]+))?$/
|
8
|
+
FILE_COLON_LINE_PATTERN = /^([\w\W]*?)(?::([\d:]+))?$/ # :nodoc:
|
9
9
|
|
10
10
|
def initialize(file_specs)
|
11
11
|
Cucumber.logger.debug("Features:\n")
|
12
|
-
@file_specs = file_specs.map { |
|
12
|
+
@file_specs = file_specs.map { |spec| FileSpec.new(spec) }
|
13
13
|
Cucumber.logger.debug("\n")
|
14
14
|
end
|
15
15
|
|
@@ -22,8 +22,8 @@ module Cucumber
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class FileSpec
|
25
|
-
def initialize(
|
26
|
-
@file, @lines = *FILE_COLON_LINE_PATTERN.match(
|
25
|
+
def initialize(spec)
|
26
|
+
@file, @lines = *FILE_COLON_LINE_PATTERN.match(spec).captures
|
27
27
|
Cucumber.logger.debug(" * #{@file}\n")
|
28
28
|
@lines = String(@lines).split(':').map { |line| Integer(line) }
|
29
29
|
end
|
@@ -31,8 +31,9 @@ module Cucumber
|
|
31
31
|
attr_reader :file
|
32
32
|
|
33
33
|
def locations
|
34
|
-
return [Core::
|
35
|
-
|
34
|
+
return [Core::Test::Location.new(@file)] if @lines.empty?
|
35
|
+
|
36
|
+
@lines.map { |line| Core::Test::Location.new(@file, line) }
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
@@ -26,7 +26,7 @@ module Cucumber
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def new_test_steps
|
29
|
-
@original_test_case.test_steps.map(&
|
29
|
+
@original_test_case.test_steps.map(&method(:attempt_to_activate))
|
30
30
|
end
|
31
31
|
|
32
32
|
def attempt_to_activate(test_step)
|
@@ -39,17 +39,20 @@ module Cucumber
|
|
39
39
|
|
40
40
|
class FindMatch
|
41
41
|
def initialize(step_match_search, configuration, test_step)
|
42
|
-
@step_match_search
|
42
|
+
@step_match_search = step_match_search
|
43
|
+
@configuration = configuration
|
44
|
+
@test_step = test_step
|
43
45
|
end
|
44
46
|
|
45
47
|
def result
|
46
48
|
begin
|
47
|
-
return NoStepMatch.new(test_step
|
49
|
+
return NoStepMatch.new(test_step, test_step.text) unless matches.any?
|
48
50
|
rescue Cucumber::Ambiguous => e
|
49
51
|
return AmbiguousStepMatch.new(e)
|
50
52
|
end
|
51
53
|
configuration.notify :step_activated, test_step, match
|
52
54
|
return SkippingStepMatch.new if configuration.dry_run?
|
55
|
+
|
53
56
|
match
|
54
57
|
end
|
55
58
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Filters
|
5
|
+
class BroadcastTestCaseReadyEvent < Core::Filter.new(:config)
|
6
|
+
def test_case(test_case)
|
7
|
+
config.notify :test_case_ready, test_case
|
8
|
+
test_case.describe_to(receiver)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cucumber/core/filter'
|
4
|
-
require 'cucumber/core/
|
4
|
+
require 'cucumber/core/test/location'
|
5
5
|
require 'cucumber/running_test_case'
|
6
6
|
|
7
7
|
module Cucumber
|
@@ -13,23 +13,19 @@ module Cucumber
|
|
13
13
|
|
14
14
|
class CaseFilter
|
15
15
|
def initialize(runtime, original_test_case)
|
16
|
-
@runtime
|
16
|
+
@runtime = runtime
|
17
|
+
@original_test_case = original_test_case
|
17
18
|
end
|
18
19
|
|
19
20
|
def test_case
|
20
|
-
init_scenario = Cucumber::Hooks.around_hook
|
21
|
+
init_scenario = Cucumber::Hooks.around_hook do |continue|
|
21
22
|
@runtime.begin_scenario(scenario)
|
22
23
|
continue.call
|
23
24
|
@runtime.end_scenario(scenario)
|
24
25
|
end
|
25
26
|
around_hooks = [init_scenario] + @original_test_case.around_hooks
|
26
27
|
|
27
|
-
|
28
|
-
empty_hook_location = Cucumber::Core::Ast::Location.from_source_location(*empty_hook.source_location)
|
29
|
-
default_hook = Cucumber::Hooks.before_hook(@original_test_case.source, empty_hook_location, &empty_hook)
|
30
|
-
steps = [default_hook] + @original_test_case.test_steps
|
31
|
-
|
32
|
-
@original_test_case.with_around_hooks(around_hooks).with_steps(steps)
|
28
|
+
@original_test_case.with_around_hooks(around_hooks).with_steps(@original_test_case.test_steps)
|
33
29
|
end
|
34
30
|
|
35
31
|
private
|