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
@@ -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'
|
@@ -28,7 +29,7 @@ module Cucumber
|
|
28
29
|
# Raised if there are 2 or more World blocks.
|
29
30
|
class MultipleWorld < StandardError
|
30
31
|
def initialize(first_proc, second_proc)
|
31
|
-
message = String.new
|
32
|
+
message = String.new # rubocop:disable Style/EmptyLiteral
|
32
33
|
message << "You can only pass a proc to #World once, but it's happening\n"
|
33
34
|
message << "in 2 places:\n\n"
|
34
35
|
message << Glue.backtrace_line(first_proc, 'World') << "\n"
|
@@ -53,7 +54,8 @@ module Cucumber
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def initialize(runtime, configuration)
|
56
|
-
@runtime
|
57
|
+
@runtime = runtime
|
58
|
+
@configuration = configuration
|
57
59
|
@step_definitions = []
|
58
60
|
Glue::Dsl.rb_language = self
|
59
61
|
@world_proc = @world_modules = nil
|
@@ -63,32 +65,42 @@ module Cucumber
|
|
63
65
|
end
|
64
66
|
|
65
67
|
def step_matches(name_to_match)
|
66
|
-
@step_definitions.
|
68
|
+
@step_definitions.each_with_object([]) do |step_definition, result|
|
67
69
|
if (arguments = step_definition.arguments_from(name_to_match))
|
68
70
|
result << StepMatch.new(step_definition, name_to_match, arguments)
|
69
71
|
end
|
70
|
-
result
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
def register_rb_hook(phase, tag_expressions, proc)
|
75
|
-
add_hook(phase, Hook.new(self, tag_expressions, proc))
|
75
|
+
def register_rb_hook(phase, tag_expressions, proc, name: nil)
|
76
|
+
hook = add_hook(phase, Hook.new(@configuration.id_generator.new_id, self, tag_expressions, proc, name: name))
|
77
|
+
@configuration.notify :envelope, hook.to_envelope
|
78
|
+
hook
|
76
79
|
end
|
77
80
|
|
78
81
|
def define_parameter_type(parameter_type)
|
82
|
+
@configuration.notify :envelope, parameter_type_envelope(parameter_type)
|
83
|
+
|
79
84
|
@parameter_type_registry.define_parameter_type(parameter_type)
|
80
85
|
end
|
81
86
|
|
82
87
|
def register_rb_step_definition(string_or_regexp, proc_or_sym, options)
|
83
|
-
step_definition = StepDefinition.new(self, string_or_regexp, proc_or_sym, options)
|
88
|
+
step_definition = StepDefinition.new(@configuration.id_generator.new_id, self, string_or_regexp, proc_or_sym, options)
|
84
89
|
@step_definitions << step_definition
|
85
90
|
@configuration.notify :step_definition_registered, step_definition
|
91
|
+
@configuration.notify :envelope, step_definition.to_envelope
|
86
92
|
step_definition
|
93
|
+
rescue Cucumber::CucumberExpressions::UndefinedParameterTypeError => e
|
94
|
+
# TODO: add a way to extract the parameter type directly from the error.
|
95
|
+
type_name = e.message.match(/^Undefined parameter type ['|{](.*)['|}].?$/)[1]
|
96
|
+
|
97
|
+
@configuration.notify :undefined_parameter_type, type_name, string_or_regexp
|
87
98
|
end
|
88
99
|
|
89
100
|
def build_rb_world_factory(world_modules, namespaced_world_modules, proc)
|
90
101
|
if proc
|
91
102
|
raise MultipleWorld.new(@world_proc, proc) if @world_proc
|
103
|
+
|
92
104
|
@world_proc = proc
|
93
105
|
end
|
94
106
|
@world_modules ||= []
|
@@ -96,15 +108,20 @@ module Cucumber
|
|
96
108
|
|
97
109
|
@namespaced_world_modules ||= Hash.new { |h, k| h[k] = [] }
|
98
110
|
namespaced_world_modules.each do |namespace, world_module|
|
99
|
-
unless @namespaced_world_modules[namespace].include?(world_module)
|
100
|
-
@namespaced_world_modules[namespace] << world_module
|
101
|
-
end
|
111
|
+
@namespaced_world_modules[namespace] << world_module unless @namespaced_world_modules[namespace].include?(world_module)
|
102
112
|
end
|
103
113
|
end
|
104
114
|
|
105
115
|
def load_code_file(code_file)
|
106
116
|
return unless File.extname(code_file) == '.rb'
|
107
|
-
|
117
|
+
|
118
|
+
# This will cause self.add_step_definition, self.add_hook, and self.define_parameter_type to be called from Glue::Dsl
|
119
|
+
|
120
|
+
if Cucumber.use_legacy_autoloader
|
121
|
+
load File.expand_path(code_file)
|
122
|
+
else
|
123
|
+
require File.expand_path(code_file)
|
124
|
+
end
|
108
125
|
end
|
109
126
|
|
110
127
|
def begin_scenario(test_case)
|
@@ -119,9 +136,21 @@ module Cucumber
|
|
119
136
|
@current_world = nil
|
120
137
|
end
|
121
138
|
|
122
|
-
def
|
123
|
-
hooks[:
|
124
|
-
hook.invoke('
|
139
|
+
def install_plugin(configuration, registry)
|
140
|
+
hooks[:install_plugin].each do |hook|
|
141
|
+
hook.invoke('InstallPlugin', [configuration, registry])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def before_all
|
146
|
+
hooks[:before_all].each do |hook|
|
147
|
+
hook.invoke('BeforeAll', [])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def after_all
|
152
|
+
hooks[:after_all].each do |hook|
|
153
|
+
hook.invoke('AfterAll', [])
|
125
154
|
end
|
126
155
|
end
|
127
156
|
|
@@ -134,7 +163,7 @@ module Cucumber
|
|
134
163
|
@hooks = nil
|
135
164
|
end
|
136
165
|
|
137
|
-
def hooks_for(phase, scenario)
|
166
|
+
def hooks_for(phase, scenario) # :nodoc:
|
138
167
|
hooks[phase.to_sym].select { |hook| scenario.accept_hook?(hook) }
|
139
168
|
end
|
140
169
|
|
@@ -153,7 +182,8 @@ module Cucumber
|
|
153
182
|
def create_expression(string_or_regexp)
|
154
183
|
return CucumberExpressions::CucumberExpression.new(string_or_regexp, @parameter_type_registry) if string_or_regexp.is_a?(String)
|
155
184
|
return CucumberExpressions::RegularExpression.new(string_or_regexp, @parameter_type_registry) if string_or_regexp.is_a?(Regexp)
|
156
|
-
|
185
|
+
|
186
|
+
raise ArgumentError, 'Expression must be a String or Regexp'
|
157
187
|
end
|
158
188
|
|
159
189
|
def self.cli_snippet_type_options
|
@@ -166,6 +196,21 @@ module Cucumber
|
|
166
196
|
|
167
197
|
private
|
168
198
|
|
199
|
+
def parameter_type_envelope(parameter_type)
|
200
|
+
# TODO: should me moved to Cucumber::Expression::ParameterType#to_envelope ?
|
201
|
+
# Note: that would mean that cucumber-expression would depend on cucumber-messages
|
202
|
+
|
203
|
+
Cucumber::Messages::Envelope.new(
|
204
|
+
parameter_type: Cucumber::Messages::ParameterType.new(
|
205
|
+
id: @configuration.id_generator.new_id,
|
206
|
+
name: parameter_type.name,
|
207
|
+
regular_expressions: parameter_type.regexps.map(&:to_s),
|
208
|
+
prefer_for_regular_expression_match: parameter_type.prefer_for_regexp_match?,
|
209
|
+
use_for_snippets: parameter_type.use_for_snippets?
|
210
|
+
)
|
211
|
+
)
|
212
|
+
end
|
213
|
+
|
169
214
|
def available_step_definition_hash
|
170
215
|
@available_step_definition_hash ||= {}
|
171
216
|
end
|
@@ -180,7 +225,7 @@ module Cucumber
|
|
180
225
|
end
|
181
226
|
|
182
227
|
def self.backtrace_line(proc, name)
|
183
|
-
location = Cucumber::Core::
|
228
|
+
location = Cucumber::Core::Test::Location.from_source_location(*proc.source_location)
|
184
229
|
"#{location}:in `#{name}'"
|
185
230
|
end
|
186
231
|
end
|
@@ -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
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Cucumber
|
4
4
|
module Glue
|
5
5
|
module Snippet
|
6
|
-
ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)']
|
6
|
+
ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)'].freeze
|
7
7
|
|
8
8
|
class Generator
|
9
9
|
def self.register_on(configuration)
|
@@ -42,7 +42,7 @@ module Cucumber
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.cli_option_string(type, cucumber_expression_generator)
|
45
|
-
format('
|
45
|
+
format('%<type>-7s: %<description>-28s e.g. %<example>s', type: type, description: description, example: example(cucumber_expression_generator))
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -61,7 +61,7 @@ module Cucumber
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def do_block
|
64
|
-
do_block = String.new
|
64
|
+
do_block = String.new # rubocop:disable Style/EmptyLiteral
|
65
65
|
do_block << "do#{parameters}\n"
|
66
66
|
multiline_argument.append_comment_to(do_block)
|
67
67
|
do_block << " pending # Write code here that turns the phrase above into concrete actions\n"
|
@@ -72,11 +72,15 @@ module Cucumber
|
|
72
72
|
def parameters
|
73
73
|
block_args = (0...number_of_arguments).map { |n| "arg#{n + 1}" }
|
74
74
|
multiline_argument.append_block_parameter_to(block_args)
|
75
|
-
block_args.empty? ? '' : " |#{block_args.join(
|
75
|
+
block_args.empty? ? '' : " |#{block_args.join(', ')}|"
|
76
76
|
end
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
class << self
|
79
|
+
private
|
80
|
+
|
81
|
+
def example(cucumber_expression_generator)
|
82
|
+
new(cucumber_expression_generator, 'Given', 'I have 2 cukes', MultilineArgument::None.new).step
|
83
|
+
end
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
@@ -87,11 +91,11 @@ module Cucumber
|
|
87
91
|
|
88
92
|
def to_s
|
89
93
|
header = generated_expressions.each_with_index.map do |expr, i|
|
90
|
-
prefix = i
|
91
|
-
"#{prefix}#{code_keyword}(
|
94
|
+
prefix = i.zero? ? '' : '# '
|
95
|
+
"#{prefix}#{code_keyword}('#{expr.source}') do#{parameters(expr)}"
|
92
96
|
end.join("\n")
|
93
97
|
|
94
|
-
body = String.new
|
98
|
+
body = String.new # rubocop:disable Style/EmptyLiteral
|
95
99
|
multiline_argument.append_comment_to(body)
|
96
100
|
body << " pending # Write code here that turns the phrase above into concrete actions\n"
|
97
101
|
body << 'end'
|
@@ -102,7 +106,7 @@ module Cucumber
|
|
102
106
|
def parameters(expr)
|
103
107
|
parameter_names = expr.parameter_names
|
104
108
|
multiline_argument.append_block_parameter_to(parameter_names)
|
105
|
-
parameter_names.empty? ? '' : " |#{parameter_names.join(
|
109
|
+
parameter_names.empty? ? '' : " |#{parameter_names.join(', ')}|"
|
106
110
|
end
|
107
111
|
|
108
112
|
def self.description
|
@@ -141,11 +145,11 @@ module Cucumber
|
|
141
145
|
end
|
142
146
|
|
143
147
|
SNIPPET_TYPES = {
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:
|
148
|
-
}
|
148
|
+
cucumber_expression: CucumberExpression,
|
149
|
+
regexp: Regexp,
|
150
|
+
classic: Classic,
|
151
|
+
percent: Percent
|
152
|
+
}.freeze
|
149
153
|
|
150
154
|
module MultilineArgumentSnippet
|
151
155
|
def self.new(multiline_argument)
|
@@ -170,11 +174,10 @@ module Cucumber
|
|
170
174
|
|
171
175
|
class DocString
|
172
176
|
def append_block_parameter_to(array)
|
173
|
-
array << '
|
177
|
+
array << 'doc_string'
|
174
178
|
end
|
175
179
|
|
176
|
-
def append_comment_to(string)
|
177
|
-
end
|
180
|
+
def append_comment_to(string); end
|
178
181
|
end
|
179
182
|
|
180
183
|
class DataTable
|
@@ -192,11 +195,9 @@ module Cucumber
|
|
192
195
|
end
|
193
196
|
|
194
197
|
class None
|
195
|
-
def append_block_parameter_to(array)
|
196
|
-
end
|
198
|
+
def append_block_parameter_to(array); end
|
197
199
|
|
198
|
-
def append_comment_to(string)
|
199
|
-
end
|
200
|
+
def append_comment_to(string); end
|
200
201
|
end
|
201
202
|
end
|
202
203
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cucumber/step_match'
|
4
|
-
require 'cucumber/step_argument'
|
5
|
-
require 'cucumber/core_ext/string'
|
6
4
|
require 'cucumber/glue/invoke_in_world'
|
7
5
|
|
8
6
|
module Cucumber
|
@@ -25,9 +23,10 @@ module Cucumber
|
|
25
23
|
end
|
26
24
|
|
27
25
|
class << self
|
28
|
-
def new(registry, string_or_regexp, proc_or_sym, options)
|
26
|
+
def new(id, registry, string_or_regexp, proc_or_sym, options)
|
29
27
|
raise MissingProc if proc_or_sym.nil?
|
30
|
-
|
28
|
+
|
29
|
+
super id, registry, registry.create_expression(string_or_regexp), create_proc(proc_or_sym, options)
|
31
30
|
end
|
32
31
|
|
33
32
|
private
|
@@ -35,6 +34,7 @@ module Cucumber
|
|
35
34
|
def create_proc(proc_or_sym, options)
|
36
35
|
return proc_or_sym if proc_or_sym.is_a?(Proc)
|
37
36
|
raise ArgumentError unless proc_or_sym.is_a?(Symbol)
|
37
|
+
|
38
38
|
message = proc_or_sym
|
39
39
|
target_proc = parse_target_proc_from(options)
|
40
40
|
patch_location_onto lambda { |*args|
|
@@ -44,33 +44,62 @@ module Cucumber
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def patch_location_onto(block)
|
47
|
-
location = Core::
|
47
|
+
location = Core::Test::Location.of_caller(5)
|
48
48
|
block.define_singleton_method(:source_location) { [location.file, location.line] }
|
49
49
|
block
|
50
50
|
end
|
51
51
|
|
52
52
|
def parse_target_proc_from(options)
|
53
|
-
return
|
53
|
+
return -> { self } unless options.key?(:on)
|
54
|
+
|
54
55
|
target = options[:on]
|
55
56
|
case target
|
56
57
|
when Proc
|
57
58
|
target
|
58
59
|
when Symbol
|
59
|
-
|
60
|
+
-> { send(target) }
|
60
61
|
else
|
61
|
-
|
62
|
+
-> { raise ArgumentError, 'Target must be a symbol or a proc' }
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
|
-
attr_reader :expression, :registry
|
67
|
+
attr_reader :id, :expression, :registry
|
67
68
|
|
68
|
-
def initialize(registry, expression, proc)
|
69
|
+
def initialize(id, registry, expression, proc)
|
69
70
|
raise 'No regexp' if expression.is_a?(Regexp)
|
70
|
-
|
71
|
+
|
72
|
+
@id = id
|
73
|
+
@registry = registry
|
74
|
+
@expression = expression
|
75
|
+
@proc = proc
|
71
76
|
# @registry.available_step_definition(regexp_source, location)
|
72
77
|
end
|
73
78
|
|
79
|
+
def to_envelope
|
80
|
+
Cucumber::Messages::Envelope.new(
|
81
|
+
step_definition: Cucumber::Messages::StepDefinition.new(
|
82
|
+
id: id,
|
83
|
+
pattern: Cucumber::Messages::StepDefinitionPattern.new(
|
84
|
+
source: expression.source.to_s,
|
85
|
+
type: expression_type
|
86
|
+
),
|
87
|
+
source_reference: Cucumber::Messages::SourceReference.new(
|
88
|
+
uri: location.file,
|
89
|
+
location: Cucumber::Messages::Location.new(
|
90
|
+
line: location.lines.first
|
91
|
+
)
|
92
|
+
)
|
93
|
+
)
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def expression_type
|
98
|
+
return Cucumber::Messages::StepDefinitionPatternType::CUCUMBER_EXPRESSION if expression.is_a?(CucumberExpressions::CucumberExpression)
|
99
|
+
|
100
|
+
Cucumber::Messages::StepDefinitionPatternType::REGULAR_EXPRESSION
|
101
|
+
end
|
102
|
+
|
74
103
|
# @api private
|
75
104
|
def to_hash
|
76
105
|
type = expression.is_a?(CucumberExpressions::RegularExpression) ? 'regular expression' : 'cucumber expression'
|
@@ -92,26 +121,22 @@ module Cucumber
|
|
92
121
|
end
|
93
122
|
|
94
123
|
# @api private
|
95
|
-
def ==(
|
96
|
-
expression.source ==
|
124
|
+
def ==(other)
|
125
|
+
expression.source == other.expression.source
|
97
126
|
end
|
98
127
|
|
99
128
|
# @api private
|
100
129
|
def arguments_from(step_name)
|
101
|
-
|
102
|
-
# @registry.invoked_step_definition(regexp_source, location) if args
|
103
|
-
args
|
130
|
+
@expression.match(step_name)
|
104
131
|
end
|
105
132
|
|
106
133
|
# @api private
|
107
134
|
# TODO: inline this and step definition just be a value object
|
108
135
|
def invoke(args)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
raise e
|
114
|
-
end
|
136
|
+
InvokeInWorld.cucumber_instance_exec_in(@registry.current_world, true, @expression.to_s, *args, &@proc)
|
137
|
+
rescue ArityMismatchError => e
|
138
|
+
e.backtrace.unshift(backtrace_line)
|
139
|
+
raise e
|
115
140
|
end
|
116
141
|
|
117
142
|
# @api private
|
@@ -131,7 +156,7 @@ module Cucumber
|
|
131
156
|
|
132
157
|
# The source location where the step definition can be found
|
133
158
|
def location
|
134
|
-
@location ||= Cucumber::Core::
|
159
|
+
@location ||= Cucumber::Core::Test::Location.from_source_location(*@proc.source_location)
|
135
160
|
end
|
136
161
|
|
137
162
|
# @api private
|
data/lib/cucumber/hooks.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'pathname'
|
4
|
-
require 'cucumber/core/
|
4
|
+
require 'cucumber/core/test/location'
|
5
5
|
require 'cucumber/core/test/around_hook'
|
6
6
|
|
7
7
|
module Cucumber
|
@@ -9,29 +9,30 @@ module Cucumber
|
|
9
9
|
# source for test steps
|
10
10
|
module Hooks
|
11
11
|
class << self
|
12
|
-
def before_hook(
|
13
|
-
build_hook_step(
|
12
|
+
def before_hook(id, location, &block)
|
13
|
+
build_hook_step(id, location, block, BeforeHook, Core::Test::UnskippableAction)
|
14
14
|
end
|
15
15
|
|
16
|
-
def after_hook(
|
17
|
-
build_hook_step(
|
16
|
+
def after_hook(id, location, &block)
|
17
|
+
build_hook_step(id, location, block, AfterHook, Core::Test::UnskippableAction)
|
18
18
|
end
|
19
19
|
|
20
|
-
def after_step_hook(
|
21
|
-
raise ArgumentError
|
22
|
-
|
20
|
+
def after_step_hook(id, test_step, location, &block)
|
21
|
+
raise ArgumentError if test_step.hook?
|
22
|
+
|
23
|
+
build_hook_step(id, location, block, AfterStepHook, Core::Test::Action)
|
23
24
|
end
|
24
25
|
|
25
|
-
def around_hook(
|
26
|
+
def around_hook(&block)
|
26
27
|
Core::Test::AroundHook.new(&block)
|
27
28
|
end
|
28
29
|
|
29
30
|
private
|
30
31
|
|
31
|
-
def build_hook_step(
|
32
|
+
def build_hook_step(id, location, block, hook_type, action_type)
|
32
33
|
action = action_type.new(location, &block)
|
33
34
|
hook = hook_type.new(action.location)
|
34
|
-
Core::Test::
|
35
|
+
Core::Test::HookStep.new(id, hook.text, location, action)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cucumber
|
2
2
|
module MultilineArgument
|
3
3
|
class DataTable
|
4
|
-
class DiffMatrices
|
4
|
+
class DiffMatrices # :nodoc:
|
5
5
|
attr_accessor :cell_matrix, :other_table_cell_matrix, :options
|
6
6
|
|
7
7
|
def initialize(cell_matrix, other_table_cell_matrix, options)
|
@@ -95,7 +95,7 @@ module Cucumber
|
|
95
95
|
def changes
|
96
96
|
require 'diff/lcs'
|
97
97
|
diffable_cell_matrix = cell_matrix.dup.extend(::Diff::LCS)
|
98
|
-
diffable_cell_matrix.diff(other_table_cell_matrix).flatten
|
98
|
+
diffable_cell_matrix.diff(other_table_cell_matrix).flatten(1)
|
99
99
|
end
|
100
100
|
|
101
101
|
def inspect_rows(missing_row, inserted_row)
|
@@ -113,6 +113,7 @@ module Cucumber
|
|
113
113
|
row_index = row_indices.index(i)
|
114
114
|
row = cell_matrix[row_index] if row_index
|
115
115
|
next unless row
|
116
|
+
|
116
117
|
(original_width..padded_width).each do |col_index|
|
117
118
|
surplus_cell = other_row[col_index]
|
118
119
|
row[col_index].value = surplus_cell.value if row[col_index]
|
@@ -135,7 +136,7 @@ module Cucumber
|
|
135
136
|
def raise_error
|
136
137
|
table = DataTable.from([[]])
|
137
138
|
table.instance_variable_set :@cell_matrix, cell_matrix
|
138
|
-
raise Different
|
139
|
+
raise Different, table if should_raise?
|
139
140
|
end
|
140
141
|
|
141
142
|
def should_raise?
|