cucumber 3.2.0 → 4.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 +192 -19
- data/CONTRIBUTING.md +2 -18
- data/README.md +4 -5
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +34 -39
- data/lib/cucumber/cli/configuration.rb +5 -5
- data/lib/cucumber/cli/main.rb +12 -12
- data/lib/cucumber/cli/options.rb +62 -71
- data/lib/cucumber/cli/profile_loader.rb +49 -26
- data/lib/cucumber/configuration.rb +31 -23
- 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 +13 -6
- 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 -45
- data/lib/cucumber/formatter/ast_lookup.rb +165 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
- data/lib/cucumber/formatter/console.rb +58 -66
- 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 +1 -1
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/interceptor.rb +8 -28
- data/lib/cucumber/formatter/io.rb +1 -1
- data/lib/cucumber/formatter/json.rb +101 -115
- data/lib/cucumber/formatter/junit.rb +56 -56
- data/lib/cucumber/formatter/message.rb +22 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +359 -153
- data/lib/cucumber/formatter/progress.rb +30 -32
- 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 +2 -3
- data/lib/cucumber/formatter/summary.rb +16 -8
- data/lib/cucumber/formatter/unicode.rb +15 -17
- data/lib/cucumber/formatter/usage.rb +11 -10
- 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 +1 -1
- 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 +42 -33
- data/lib/cucumber/glue/registry_and_more.rb +42 -12
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +42 -19
- 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 +1 -1
- 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 -16
- data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
- 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 +34 -58
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +12 -11
- data/lib/cucumber/step_match_search.rb +2 -1
- data/lib/cucumber/term/ansicolor.rb +9 -9
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +1 -1
- metadata +251 -81
- 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
@@ -0,0 +1,13 @@
|
|
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
|
10
|
+
attr_reader :hook
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
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
|
10
|
+
attr_reader :pickle
|
11
|
+
end
|
12
|
+
end
|
13
|
+
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,13 @@
|
|
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
|
10
|
+
attr_reader :pickle_step
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/cucumber/events.rb
CHANGED
@@ -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,7 +1,7 @@
|
|
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
|
@@ -9,7 +9,7 @@ module Cucumber
|
|
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,8 @@ module Cucumber
|
|
31
31
|
attr_reader :file
|
32
32
|
|
33
33
|
def locations
|
34
|
-
return [Core::
|
35
|
-
@lines.map { |line| Core::
|
34
|
+
return [Core::Test::Location.new(@file)] if @lines.empty?
|
35
|
+
@lines.map { |line| Core::Test::Location.new(@file, line) }
|
36
36
|
end
|
37
37
|
end
|
38
38
|
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,12 +39,14 @@ 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
|
@@ -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
|
@@ -17,10 +17,8 @@ module Cucumber
|
|
17
17
|
|
18
18
|
def collect_breaches(test_case_index)
|
19
19
|
tag_limits.reduce([]) do |breaches, (tag_name, limit)|
|
20
|
-
breaches.tap do |
|
21
|
-
if test_case_index.count_by_tag_name(tag_name) > limit
|
22
|
-
breaches << Breach.new(tag_name, limit, test_case_index.locations_of_tag_name(tag_name))
|
23
|
-
end
|
20
|
+
breaches.tap do |breach|
|
21
|
+
breach << Breach.new(tag_name, limit, test_case_index.locations_of_tag_name(tag_name)) if test_case_index.count_by_tag_name(tag_name) > limit
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
data/lib/cucumber/filters.rb
CHANGED
@@ -55,20 +55,18 @@ module Cucumber
|
|
55
55
|
include Cucumber::Term::ANSIColor
|
56
56
|
|
57
57
|
ALIASES = Hash.new do |h, k|
|
58
|
-
if k.to_s =~ /(.*)_param/
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
'tag' => 'cyan'
|
71
|
-
})
|
58
|
+
h[Regexp.last_match(1)] + ',bold' if k.to_s =~ /(.*)_param/
|
59
|
+
end.merge(
|
60
|
+
'undefined' => 'yellow',
|
61
|
+
'pending' => 'yellow',
|
62
|
+
'flaky' => 'yellow',
|
63
|
+
'failed' => 'red',
|
64
|
+
'passed' => 'green',
|
65
|
+
'outline' => 'cyan',
|
66
|
+
'skipped' => 'cyan',
|
67
|
+
'comment' => 'grey',
|
68
|
+
'tag' => 'cyan'
|
69
|
+
)
|
72
70
|
|
73
71
|
if ENV['CUCUMBER_COLORS'] # Example: export CUCUMBER_COLORS="passed=red:failed=yellow"
|
74
72
|
ENV['CUCUMBER_COLORS'].split(':').each do |pair|
|
@@ -89,45 +87,42 @@ module Cucumber
|
|
89
87
|
# red(bold(string, &proc)) + red
|
90
88
|
# end
|
91
89
|
ALIASES.each_key do |method_name|
|
92
|
-
|
93
|
-
|
90
|
+
next if method_name =~ /.*_param/
|
91
|
+
code = <<-COLOR
|
94
92
|
def #{method_name}(string=nil, &proc)
|
95
|
-
#{ALIASES[method_name].split(
|
93
|
+
#{ALIASES[method_name].split(',').join('(') + '(string, &proc' + ')' * ALIASES[method_name].split(',').length}
|
96
94
|
end
|
97
95
|
# This resets the colour to the non-param colour
|
98
96
|
def #{method_name}_param(string=nil, &proc)
|
99
|
-
#{ALIASES[method_name + '_param'].split(
|
97
|
+
#{ALIASES[method_name + '_param'].split(',').join('(') + '(string, &proc' + ')' * ALIASES[method_name + '_param'].split(',').length} + #{ALIASES[method_name].split(',').join(' + ')}
|
100
98
|
end
|
101
|
-
|
102
|
-
|
103
|
-
end
|
99
|
+
COLOR
|
100
|
+
eval(code) # rubocop:disable Security/Eval
|
104
101
|
end
|
105
102
|
|
106
103
|
def self.define_grey #:nodoc:
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
define_real_grey
|
130
|
-
end
|
104
|
+
gem 'genki-ruby-terminfo'
|
105
|
+
require 'terminfo'
|
106
|
+
case TermInfo.default_object.tigetnum('colors')
|
107
|
+
when 0
|
108
|
+
raise "Your terminal doesn't support colours."
|
109
|
+
when 1
|
110
|
+
::Cucumber::Term::ANSIColor.coloring = false
|
111
|
+
alias_method :grey, :white
|
112
|
+
when 2..8
|
113
|
+
alias_method :grey, :white # rubocop:disable Lint/DuplicateMethods
|
114
|
+
else
|
115
|
+
define_real_grey
|
116
|
+
end
|
117
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
118
|
+
if e.class.name == 'TermInfo::TermInfoError'
|
119
|
+
STDERR.puts '*** WARNING ***'
|
120
|
+
STDERR.puts "You have the genki-ruby-terminfo gem installed, but you haven't set your TERM variable."
|
121
|
+
STDERR.puts 'Try setting it to TERM=xterm-256color to get grey colour in output.'
|
122
|
+
STDERR.puts "\n"
|
123
|
+
alias_method :grey, :white
|
124
|
+
else
|
125
|
+
define_real_grey
|
131
126
|
end
|
132
127
|
end
|
133
128
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Formatter
|
5
|
+
class AstLookup
|
6
|
+
def initialize(config)
|
7
|
+
@gherkin_documents = {}
|
8
|
+
@test_case_lookups = {}
|
9
|
+
@test_step_lookups = {}
|
10
|
+
@step_keyword_lookups = {}
|
11
|
+
config.on_event :gherkin_source_parsed, &method(:on_gherkin_source_parsed)
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_gherkin_source_parsed(event)
|
15
|
+
@gherkin_documents[event.gherkin_document.uri] = event.gherkin_document
|
16
|
+
end
|
17
|
+
|
18
|
+
def gherkin_document(uri)
|
19
|
+
@gherkin_documents[uri]
|
20
|
+
end
|
21
|
+
|
22
|
+
def scenario_source(test_case)
|
23
|
+
uri = test_case.location.file
|
24
|
+
@test_case_lookups[uri] ||= TestCaseLookupBuilder.new(gherkin_document(uri)).lookup_hash
|
25
|
+
@test_case_lookups[uri][test_case.location.lines.max]
|
26
|
+
end
|
27
|
+
|
28
|
+
def step_source(test_step)
|
29
|
+
uri = test_step.location.file
|
30
|
+
@test_step_lookups[uri] ||= TestStepLookupBuilder.new(gherkin_document(uri)).lookup_hash
|
31
|
+
@test_step_lookups[uri][test_step.location.lines.min]
|
32
|
+
end
|
33
|
+
|
34
|
+
def snippet_step_keyword(test_step)
|
35
|
+
uri = test_step.location.file
|
36
|
+
document = gherkin_document(uri)
|
37
|
+
dialect = ::Gherkin::Dialect.for(document.feature.language)
|
38
|
+
given_when_then_keywords = [dialect.given_keywords, dialect.when_keywords, dialect.then_keywords].flatten.uniq.reject { |kw| kw == '* ' }
|
39
|
+
keyword_lookup = step_keyword_lookup(uri)
|
40
|
+
keyword = nil
|
41
|
+
node = keyword_lookup[test_step.location.lines.min]
|
42
|
+
while keyword.nil?
|
43
|
+
if given_when_then_keywords.include?(node.keyword)
|
44
|
+
keyword = node.keyword
|
45
|
+
break
|
46
|
+
end
|
47
|
+
break if node.previous_node.nil?
|
48
|
+
node = node.previous_node
|
49
|
+
end
|
50
|
+
keyword = dialect.given_keywords.reject { |kw| kw == '* ' }[0] if keyword.nil?
|
51
|
+
keyword = Cucumber::Gherkin::I18n.code_keyword_for(keyword)
|
52
|
+
keyword
|
53
|
+
end
|
54
|
+
|
55
|
+
ScenarioSource = Struct.new(:type, :scenario)
|
56
|
+
|
57
|
+
ScenarioOutlineSource = Struct.new(:type, :scenario_outline, :examples, :row)
|
58
|
+
|
59
|
+
StepSource = Struct.new(:type, :step)
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def step_keyword_lookup(uri)
|
64
|
+
@step_keyword_lookups[uri] ||= KeywordLookupBuilder.new(gherkin_document(uri)).lookup_hash
|
65
|
+
end
|
66
|
+
|
67
|
+
class TestCaseLookupBuilder
|
68
|
+
attr_reader :lookup_hash
|
69
|
+
|
70
|
+
def initialize(gherkin_document)
|
71
|
+
@lookup_hash = {}
|
72
|
+
process_scenario_container(gherkin_document.feature)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def process_scenario_container(container)
|
78
|
+
container.children.each do |child|
|
79
|
+
if child.respond_to?(:rule) && child.rule
|
80
|
+
process_scenario_container(child.rule)
|
81
|
+
elsif child.respond_to?(:scenario) && child.scenario
|
82
|
+
process_scenario(child)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def process_scenario(child)
|
88
|
+
if child.scenario.examples.empty?
|
89
|
+
@lookup_hash[child.scenario.location.line] = ScenarioSource.new(:Scenario, child.scenario)
|
90
|
+
else
|
91
|
+
child.scenario.examples.each do |examples|
|
92
|
+
examples.table_body.each do |row|
|
93
|
+
@lookup_hash[row.location.line] = ScenarioOutlineSource.new(:ScenarioOutline, child.scenario, examples, row)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class TestStepLookupBuilder
|
101
|
+
attr_reader :lookup_hash
|
102
|
+
|
103
|
+
def initialize(gherkin_document)
|
104
|
+
@lookup_hash = {}
|
105
|
+
process_scenario_container(gherkin_document.feature)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def process_scenario_container(container)
|
111
|
+
container.children.each do |child|
|
112
|
+
if child.respond_to?(:rule) && child.rule
|
113
|
+
process_scenario_container(child.rule)
|
114
|
+
elsif child.respond_to?(:scenario) && child.scenario
|
115
|
+
child.scenario.steps.each do |step|
|
116
|
+
@lookup_hash[step.location.line] = StepSource.new(:Step, step)
|
117
|
+
end
|
118
|
+
elsif !child.background.nil?
|
119
|
+
child.background.steps.each do |step|
|
120
|
+
@lookup_hash[step.location.line] = StepSource.new(:Step, step)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
KeywordSearchNode = Struct.new(:keyword, :previous_node)
|
128
|
+
|
129
|
+
class KeywordLookupBuilder
|
130
|
+
attr_reader :lookup_hash
|
131
|
+
|
132
|
+
def initialize(gherkin_document)
|
133
|
+
@lookup_hash = {}
|
134
|
+
process_scenario_container(gherkin_document.feature, nil)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
140
|
+
def process_scenario_container(container, original_previous_node)
|
141
|
+
container.children.each do |child|
|
142
|
+
previous_node = original_previous_node
|
143
|
+
if child.respond_to?(:rule) && child.rule
|
144
|
+
process_scenario_container(child.rule, original_previous_node)
|
145
|
+
elsif child.respond_to?(:scenario) && child.scenario
|
146
|
+
child.scenario.steps.each do |step|
|
147
|
+
node = KeywordSearchNode.new(step.keyword, previous_node)
|
148
|
+
@lookup_hash[step.location.line] = node
|
149
|
+
previous_node = node
|
150
|
+
end
|
151
|
+
elsif child.respond_to?(:background) && child.background
|
152
|
+
child.background.steps.each do |step|
|
153
|
+
node = KeywordSearchNode.new(step.keyword, previous_node)
|
154
|
+
@lookup_hash[step.location.line] = node
|
155
|
+
previous_node = node
|
156
|
+
original_previous_node = previous_node
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -4,22 +4,23 @@ require 'cucumber/platform'
|
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
module Formatter
|
7
|
-
@backtrace_filters = %w
|
7
|
+
@backtrace_filters = %w[
|
8
8
|
/vendor/rails
|
9
9
|
lib/cucumber
|
10
10
|
bin/cucumber:
|
11
11
|
lib/rspec
|
12
12
|
gems/
|
13
|
+
site_ruby/
|
13
14
|
minitest
|
14
15
|
test/unit
|
15
16
|
.gem/ruby
|
16
|
-
lib/ruby/
|
17
17
|
bin/bundle
|
18
|
-
|
18
|
+
]
|
19
19
|
|
20
|
-
if ::
|
21
|
-
|
22
|
-
|
20
|
+
@backtrace_filters << RbConfig::CONFIG['rubyarchdir'] if RbConfig::CONFIG['rubyarchdir']
|
21
|
+
@backtrace_filters << RbConfig::CONFIG['rubylibdir'] if RbConfig::CONFIG['rubylibdir']
|
22
|
+
|
23
|
+
@backtrace_filters << 'org/jruby/' if ::Cucumber::JRUBY
|
23
24
|
|
24
25
|
BACKTRACE_FILTER_PATTERNS = Regexp.new(@backtrace_filters.join('|'))
|
25
26
|
|
@@ -31,7 +32,7 @@ module Cucumber
|
|
31
32
|
def exception
|
32
33
|
return @exception if ::Cucumber.use_full_backtrace
|
33
34
|
|
34
|
-
pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m
|
35
|
+
pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m # rubocop:disable Style/RegexpLiteral
|
35
36
|
backtrace = @exception.backtrace.map { |line| line.gsub(pwd_pattern, './') }
|
36
37
|
|
37
38
|
filtered = (backtrace || []).reject do |line|
|
@@ -41,7 +42,7 @@ module Cucumber
|
|
41
42
|
if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
|
42
43
|
# Strip off file locations
|
43
44
|
filtered = filtered.map do |line|
|
44
|
-
line =~ /(.*):in `/ ?
|
45
|
+
line =~ /(.*):in `/ ? Regexp.last_match(1) : line
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|