cucumber 3.0.2 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +216 -17
- data/CONTRIBUTING.md +4 -21
- data/README.md +8 -10
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber.rb +1 -0
- data/lib/autotest/cucumber_mixin.rb +35 -39
- data/lib/autotest/cucumber_rails.rb +1 -0
- data/lib/autotest/cucumber_rails_rspec.rb +1 -0
- data/lib/autotest/cucumber_rails_rspec2.rb +1 -0
- data/lib/autotest/cucumber_rspec.rb +1 -0
- data/lib/autotest/cucumber_rspec2.rb +1 -0
- data/lib/autotest/discover.rb +1 -0
- data/lib/cucumber.rb +2 -1
- data/lib/cucumber/cli/configuration.rb +6 -5
- data/lib/cucumber/cli/main.rb +14 -14
- data/lib/cucumber/cli/options.rb +113 -116
- data/lib/cucumber/cli/profile_loader.rb +50 -29
- data/lib/cucumber/cli/rerun_file.rb +1 -0
- data/lib/cucumber/configuration.rb +38 -29
- data/lib/cucumber/constantize.rb +8 -10
- data/lib/cucumber/core_ext/string.rb +1 -0
- data/lib/cucumber/deprecate.rb +32 -8
- data/lib/cucumber/encoding.rb +2 -1
- data/lib/cucumber/errors.rb +6 -7
- data/lib/cucumber/events.rb +14 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
- data/lib/cucumber/events/gherkin_source_read.rb +1 -4
- data/lib/cucumber/events/hook_test_step_created.rb +13 -0
- data/lib/cucumber/events/step_activated.rb +6 -6
- data/lib/cucumber/events/step_definition_registered.rb +4 -8
- data/lib/cucumber/events/test_case_created.rb +13 -0
- data/lib/cucumber/events/test_case_finished.rb +0 -4
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_case_started.rb +0 -4
- data/lib/cucumber/events/test_run_finished.rb +2 -3
- data/lib/cucumber/events/test_run_started.rb +2 -4
- data/lib/cucumber/events/test_step_created.rb +13 -0
- data/lib/cucumber/events/test_step_finished.rb +0 -4
- data/lib/cucumber/events/test_step_started.rb +1 -5
- data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
- data/lib/cucumber/file_specs.rb +7 -6
- data/lib/cucumber/filters.rb +2 -0
- data/lib/cucumber/filters/activate_steps.rb +6 -4
- data/lib/cucumber/filters/apply_after_hooks.rb +1 -0
- data/lib/cucumber/filters/apply_after_step_hooks.rb +1 -0
- data/lib/cucumber/filters/apply_around_hooks.rb +1 -0
- data/lib/cucumber/filters/apply_before_hooks.rb +1 -0
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/filters/broadcast_test_run_started_event.rb +2 -1
- data/lib/cucumber/filters/gated_receiver.rb +1 -2
- data/lib/cucumber/filters/prepare_world.rb +6 -13
- data/lib/cucumber/filters/quit.rb +3 -6
- data/lib/cucumber/filters/randomizer.rb +6 -7
- data/lib/cucumber/filters/retry.rb +2 -2
- data/lib/cucumber/filters/tag_limits.rb +2 -2
- data/lib/cucumber/filters/tag_limits/test_case_index.rb +1 -2
- data/lib/cucumber/filters/tag_limits/verifier.rb +3 -6
- data/lib/cucumber/formatter/ansicolor.rb +33 -37
- data/lib/cucumber/formatter/ast_lookup.rb +165 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -10
- data/lib/cucumber/formatter/console.rb +65 -74
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +9 -6
- data/lib/cucumber/formatter/duration.rb +2 -1
- data/lib/cucumber/formatter/duration_extractor.rb +4 -2
- data/lib/cucumber/formatter/errors.rb +6 -0
- data/lib/cucumber/formatter/fail_fast.rb +9 -6
- data/lib/cucumber/formatter/fanout.rb +3 -3
- data/lib/cucumber/formatter/html.rb +11 -602
- data/lib/cucumber/formatter/http_io.rb +146 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -3
- data/lib/cucumber/formatter/interceptor.rb +11 -18
- data/lib/cucumber/formatter/io.rb +18 -11
- data/lib/cucumber/formatter/json.rb +102 -109
- data/lib/cucumber/formatter/junit.rb +73 -68
- data/lib/cucumber/formatter/message.rb +22 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +360 -153
- data/lib/cucumber/formatter/progress.rb +31 -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 +23 -4
- data/lib/cucumber/formatter/stepdefs.rb +2 -2
- data/lib/cucumber/formatter/steps.rb +4 -5
- data/lib/cucumber/formatter/summary.rb +17 -9
- data/lib/cucumber/formatter/unicode.rb +16 -18
- data/lib/cucumber/formatter/usage.rb +30 -26
- data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +83 -86
- data/lib/cucumber/gherkin/formatter/escaping.rb +13 -12
- data/lib/cucumber/gherkin/i18n.rb +1 -0
- data/lib/cucumber/gherkin/steps_parser.rb +18 -8
- data/lib/cucumber/glue/dsl.rb +2 -1
- data/lib/cucumber/glue/hook.rb +35 -11
- data/lib/cucumber/glue/invoke_in_world.rb +15 -20
- data/lib/cucumber/glue/proto_world.rb +47 -39
- data/lib/cucumber/glue/registry_and_more.rb +54 -23
- data/lib/cucumber/glue/snippet.rb +24 -27
- data/lib/cucumber/glue/step_definition.rb +51 -28
- data/lib/cucumber/glue/world_factory.rb +1 -3
- data/lib/cucumber/hooks.rb +24 -14
- data/lib/cucumber/load_path.rb +1 -0
- data/lib/cucumber/multiline_argument.rb +6 -8
- data/lib/cucumber/multiline_argument/data_table.rb +106 -73
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +8 -11
- data/lib/cucumber/multiline_argument/doc_string.rb +2 -1
- data/lib/cucumber/platform.rb +4 -3
- data/lib/cucumber/project_initializer.rb +1 -1
- data/lib/cucumber/rake/task.rb +21 -18
- data/lib/cucumber/rspec/disable_option_parser.rb +10 -8
- data/lib/cucumber/rspec/doubles.rb +1 -0
- data/lib/cucumber/running_test_case.rb +4 -54
- data/lib/cucumber/runtime.rb +57 -61
- data/lib/cucumber/runtime/after_hooks.rb +9 -4
- data/lib/cucumber/runtime/before_hooks.rb +9 -4
- data/lib/cucumber/runtime/for_programming_languages.rb +12 -9
- data/lib/cucumber/runtime/step_hooks.rb +5 -2
- data/lib/cucumber/runtime/support_code.rb +16 -22
- data/lib/cucumber/runtime/user_interface.rb +8 -19
- data/lib/cucumber/step_definition_light.rb +6 -4
- data/lib/cucumber/step_definitions.rb +3 -2
- data/lib/cucumber/step_match.rb +20 -18
- data/lib/cucumber/step_match_search.rb +9 -9
- data/lib/cucumber/term/ansicolor.rb +39 -39
- data/lib/cucumber/unit.rb +1 -0
- data/lib/cucumber/version +1 -1
- data/lib/simplecov_setup.rb +1 -0
- metadata +214 -127
- 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 -41
- data/lib/cucumber/formatter/html_builder.rb +0 -120
- 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 -10
- 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 -24
@@ -26,7 +26,7 @@ module Cucumber
|
|
26
26
|
@original_header = other_table_cell_matrix[0]
|
27
27
|
pad_and_match
|
28
28
|
@padded_width = cell_matrix[0].length
|
29
|
-
@row_indices = Array.new(other_table_cell_matrix.length) {|n| n}
|
29
|
+
@row_indices = Array.new(other_table_cell_matrix.length) { |n| n }
|
30
30
|
end
|
31
31
|
|
32
32
|
# Pads two cell matrices to same column width and matches columns according to header value.
|
@@ -38,19 +38,19 @@ module Cucumber
|
|
38
38
|
matched_cols = []
|
39
39
|
|
40
40
|
header_values.each_with_index do |v, i|
|
41
|
-
mapped_index = unmatched_cols.index{|unmapped_col| unmapped_col.first == v}
|
41
|
+
mapped_index = unmatched_cols.index { |unmapped_col| unmapped_col.first == v }
|
42
42
|
if mapped_index
|
43
43
|
matched_cols << unmatched_cols.delete_at(mapped_index)
|
44
44
|
else
|
45
45
|
mark_as_missing(cols[i])
|
46
|
-
empty_col = ensure_2d(other_table_cell_matrix).collect {SurplusCell.new(nil, self, -1)}
|
46
|
+
empty_col = ensure_2d(other_table_cell_matrix).collect { SurplusCell.new(nil, self, -1) }
|
47
47
|
empty_col.first.value = v
|
48
48
|
matched_cols << empty_col
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
unmatched_cols.each do
|
53
|
-
empty_col = cell_matrix.collect {SurplusCell.new(nil, self, -1)}
|
53
|
+
empty_col = cell_matrix.collect { SurplusCell.new(nil, self, -1) }
|
54
54
|
cols << empty_col
|
55
55
|
end
|
56
56
|
|
@@ -68,7 +68,6 @@ module Cucumber
|
|
68
68
|
array[0].is_a?(Array) ? array : [array]
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
71
|
def perform_diff
|
73
72
|
inserted = 0
|
74
73
|
missing = 0
|
@@ -77,13 +76,13 @@ module Cucumber
|
|
77
76
|
changes.each do |change|
|
78
77
|
if change.action == '-'
|
79
78
|
@missing_row_pos = change.position + inserted
|
80
|
-
cell_matrix[missing_row_pos].each{|cell| cell.status = :undefined}
|
79
|
+
cell_matrix[missing_row_pos].each { |cell| cell.status = :undefined }
|
81
80
|
row_indices.insert(missing_row_pos, nil)
|
82
81
|
missing += 1
|
83
82
|
else # '+'
|
84
83
|
@insert_row_pos = change.position + missing
|
85
84
|
inserted_row = change.element
|
86
|
-
inserted_row.each{|cell| cell.status = :comment}
|
85
|
+
inserted_row.each { |cell| cell.status = :comment }
|
87
86
|
cell_matrix.insert(insert_row_pos, inserted_row)
|
88
87
|
row_indices[insert_row_pos] = nil
|
89
88
|
inspect_rows(cell_matrix[missing_row_pos], inserted_row) if last_change == '-'
|
@@ -109,7 +108,6 @@ module Cucumber
|
|
109
108
|
end
|
110
109
|
end
|
111
110
|
|
112
|
-
|
113
111
|
def fill_in_missing_values
|
114
112
|
other_table_cell_matrix.each_with_index do |other_row, i|
|
115
113
|
row_index = row_indices.index(i)
|
@@ -123,7 +121,7 @@ module Cucumber
|
|
123
121
|
end
|
124
122
|
|
125
123
|
def missing_col
|
126
|
-
cell_matrix[0].find{|cell| cell.status == :undefined}
|
124
|
+
cell_matrix[0].find { |cell| cell.status == :undefined }
|
127
125
|
end
|
128
126
|
|
129
127
|
def surplus_col
|
@@ -134,11 +132,10 @@ module Cucumber
|
|
134
132
|
cell_matrix[0] != original_header
|
135
133
|
end
|
136
134
|
|
137
|
-
|
138
135
|
def raise_error
|
139
136
|
table = DataTable.from([[]])
|
140
137
|
table.instance_variable_set :@cell_matrix, cell_matrix
|
141
|
-
raise Different
|
138
|
+
raise Different, table if should_raise?
|
142
139
|
end
|
143
140
|
|
144
141
|
def should_raise?
|
data/lib/cucumber/platform.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Detect the platform we're running on so we can tweak behaviour
|
3
4
|
# in various places.
|
4
5
|
require 'rbconfig'
|
@@ -6,7 +7,7 @@ require 'cucumber/core/platform'
|
|
6
7
|
|
7
8
|
module Cucumber
|
8
9
|
unless defined?(Cucumber::VERSION)
|
9
|
-
VERSION = File.read(File.expand_path('
|
10
|
+
VERSION = File.read(File.expand_path('version', __dir__)).strip
|
10
11
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
11
12
|
LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
12
13
|
RAILS = defined?(Rails)
|
@@ -17,8 +18,8 @@ module Cucumber
|
|
17
18
|
attr_accessor :use_full_backtrace
|
18
19
|
|
19
20
|
# @private
|
20
|
-
def file_mode(
|
21
|
-
"#{
|
21
|
+
def file_mode(mode, encoding = 'UTF-8')
|
22
|
+
"#{mode}:#{encoding}"
|
22
23
|
end
|
23
24
|
end
|
24
25
|
self.use_full_backtrace = false
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'cucumber/platform'
|
3
4
|
require 'cucumber/gherkin/formatter/ansi_escapes'
|
4
5
|
begin
|
5
6
|
# Support Rake > 0.8.7
|
6
7
|
require 'rake/dsl_definition'
|
8
|
+
# rubocop:disable Lint/HandleExceptions
|
7
9
|
rescue LoadError
|
10
|
+
# rubocop:enable Lint/HandleExceptions
|
8
11
|
end
|
9
12
|
|
10
13
|
module Cucumber
|
@@ -35,8 +38,8 @@ module Cucumber
|
|
35
38
|
attr_reader :args
|
36
39
|
|
37
40
|
def initialize(libs, cucumber_opts, feature_files)
|
38
|
-
raise 'libs must be an Array when running in-process' unless Array
|
39
|
-
libs.
|
41
|
+
raise 'libs must be an Array when running in-process' unless Array == libs.class
|
42
|
+
libs.reverse_each { |lib| $LOAD_PATH.unshift(lib) }
|
40
43
|
@args = (
|
41
44
|
cucumber_opts +
|
42
45
|
feature_files
|
@@ -62,11 +65,11 @@ module Cucumber
|
|
62
65
|
end
|
63
66
|
|
64
67
|
def load_path
|
65
|
-
[format('"
|
68
|
+
[format('"%<path>s"', path: @libs.join(File::PATH_SEPARATOR))]
|
66
69
|
end
|
67
70
|
|
68
71
|
def quoted_binary(cucumber_bin)
|
69
|
-
[format('"
|
72
|
+
[format('"%<path>s"', path: cucumber_bin)]
|
70
73
|
end
|
71
74
|
|
72
75
|
def use_bundler
|
@@ -82,7 +85,7 @@ module Cucumber
|
|
82
85
|
def cmd
|
83
86
|
if use_bundler
|
84
87
|
[
|
85
|
-
Cucumber::RUBY_BINARY,'-S', 'bundle', 'exec', 'cucumber',
|
88
|
+
Cucumber::RUBY_BINARY, '-S', 'bundle', 'exec', 'cucumber',
|
86
89
|
@cucumber_opts, @feature_files
|
87
90
|
].flatten
|
88
91
|
else
|
@@ -95,9 +98,7 @@ module Cucumber
|
|
95
98
|
|
96
99
|
def run
|
97
100
|
sh cmd.join(' ') do |ok, res|
|
98
|
-
|
99
|
-
exit res.exitstatus
|
100
|
-
end
|
101
|
+
exit res.exitstatus unless ok
|
101
102
|
end
|
102
103
|
end
|
103
104
|
end
|
@@ -110,9 +111,9 @@ module Cucumber
|
|
110
111
|
|
111
112
|
# Extra options to pass to the cucumber binary. Can be overridden by the CUCUMBER_OPTS environment variable.
|
112
113
|
# It's recommended to pass an Array, but if it's a String it will be #split by ' '.
|
113
|
-
|
114
|
+
attr_reader :cucumber_opts
|
114
115
|
def cucumber_opts=(opts) #:nodoc:
|
115
|
-
@cucumber_opts = String
|
116
|
+
@cucumber_opts = String == opts.class ? opts.split(' ') : opts
|
116
117
|
end
|
117
118
|
|
118
119
|
# Whether or not to fork a new ruby interpreter. Defaults to true. You may gain
|
@@ -131,12 +132,16 @@ module Cucumber
|
|
131
132
|
# Note that this attribute has no effect if you don't run in forked mode.
|
132
133
|
attr_accessor :bundler
|
133
134
|
|
135
|
+
# Name of the running task
|
136
|
+
attr_reader :task_name
|
137
|
+
|
134
138
|
# Define Cucumber Rake task
|
135
139
|
def initialize(task_name = 'cucumber', desc = 'Run Cucumber features')
|
136
|
-
@task_name
|
140
|
+
@task_name = task_name
|
141
|
+
@desc = desc
|
137
142
|
@fork = true
|
138
143
|
@libs = ['lib']
|
139
|
-
@rcov_opts = %w
|
144
|
+
@rcov_opts = %w[--rails --exclude osx\/objc,gems\/]
|
140
145
|
yield self if block_given?
|
141
146
|
@binary = binary.nil? ? Cucumber::BINARY : File.expand_path(binary)
|
142
147
|
define_task
|
@@ -151,22 +156,20 @@ module Cucumber
|
|
151
156
|
|
152
157
|
def runner(_task_args = nil) #:nodoc:
|
153
158
|
cucumber_opts = [(ENV['CUCUMBER_OPTS'] ? ENV['CUCUMBER_OPTS'].split(/\s+/) : nil) || cucumber_opts_with_profile]
|
154
|
-
if
|
155
|
-
return ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files)
|
156
|
-
end
|
159
|
+
return ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files) if fork
|
157
160
|
InProcessCucumberRunner.new(libs, cucumber_opts, feature_files)
|
158
161
|
end
|
159
162
|
|
160
163
|
def cucumber_opts_with_profile #:nodoc:
|
161
|
-
Array(cucumber_opts).concat
|
164
|
+
Array(cucumber_opts).concat(Array(@profile).flat_map { |p| ['--profile', p] })
|
162
165
|
end
|
163
166
|
|
164
167
|
def feature_files #:nodoc:
|
165
|
-
make_command_line_safe(FileList[
|
168
|
+
make_command_line_safe(FileList[ENV['FEATURE'] || []])
|
166
169
|
end
|
167
170
|
|
168
171
|
def make_command_line_safe(list)
|
169
|
-
list.map{|string| string.gsub(' ', '\ ')}
|
172
|
+
list.map { |string| string.gsub(' ', '\ ') }
|
170
173
|
end
|
171
174
|
end
|
172
175
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'optparse'
|
3
4
|
|
4
5
|
module Spec #:nodoc:
|
@@ -8,16 +9,17 @@ module Spec #:nodoc:
|
|
8
9
|
# will fail when running cucumber)
|
9
10
|
class OptionParser < ::OptionParser #:nodoc:
|
10
11
|
NEUTERED_RSPEC = Object.new
|
11
|
-
def NEUTERED_RSPEC.method_missing(
|
12
|
+
def NEUTERED_RSPEC.method_missing(_method, *_args) # rubocop:disable Style/MissingRespondToMissing
|
13
|
+
self || super
|
14
|
+
end
|
12
15
|
|
13
|
-
def self.method_added(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
@__neutering_rspec = false
|
16
|
+
def self.method_added(method)
|
17
|
+
return if @__neutering_rspec
|
18
|
+
@__neutering_rspec = true
|
19
|
+
define_method(method) do |*_a|
|
20
|
+
NEUTERED_RSPEC
|
20
21
|
end
|
22
|
+
@__neutering_rspec = false
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'delegate'
|
3
4
|
|
4
5
|
module Cucumber
|
5
|
-
#
|
6
|
+
# Represents the current status of a running test case.
|
6
7
|
#
|
7
8
|
# This wraps a `Cucumber::Core::Test::Case` and delegates
|
8
9
|
# many methods to that object.
|
@@ -14,45 +15,12 @@ module Cucumber
|
|
14
15
|
# the passed / failed / undefined / skipped status of
|
15
16
|
# the test case.
|
16
17
|
#
|
17
|
-
# The test case might come from a regular Scenario or
|
18
|
-
# a Scenario outline. You can call the `#outline?`
|
19
|
-
# predicate to find out. If it's from an outline,
|
20
|
-
# you get a couple of extra methods.
|
21
18
|
module RunningTestCase
|
22
19
|
def self.new(test_case)
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
class Builder
|
27
|
-
def initialize(test_case)
|
28
|
-
@test_case = test_case
|
29
|
-
test_case.describe_source_to(self)
|
30
|
-
end
|
31
|
-
|
32
|
-
def feature(feature)
|
33
|
-
end
|
34
|
-
|
35
|
-
def scenario(_scenario)
|
36
|
-
@factory = Scenario
|
37
|
-
end
|
38
|
-
|
39
|
-
def scenario_outline(_scenario)
|
40
|
-
@factory = ScenarioOutlineExample
|
41
|
-
end
|
42
|
-
|
43
|
-
def examples_table(examples_table)
|
44
|
-
end
|
45
|
-
|
46
|
-
def examples_table_row(row)
|
47
|
-
end
|
48
|
-
|
49
|
-
def running_test_case
|
50
|
-
@factory.new(@test_case)
|
51
|
-
end
|
20
|
+
TestCase.new(test_case)
|
52
21
|
end
|
53
|
-
private_constant :Builder
|
54
22
|
|
55
|
-
class
|
23
|
+
class TestCase < SimpleDelegator
|
56
24
|
def initialize(test_case, result = Core::Test::Result::Unknown.new)
|
57
25
|
@test_case = test_case
|
58
26
|
@result = result
|
@@ -84,27 +52,9 @@ module Cucumber
|
|
84
52
|
tags.map &:name
|
85
53
|
end
|
86
54
|
|
87
|
-
def outline?
|
88
|
-
false
|
89
|
-
end
|
90
|
-
|
91
55
|
def with_result(result)
|
92
56
|
self.class.new(@test_case, result)
|
93
57
|
end
|
94
58
|
end
|
95
|
-
|
96
|
-
class ScenarioOutlineExample < Scenario
|
97
|
-
def outline?
|
98
|
-
true
|
99
|
-
end
|
100
|
-
|
101
|
-
def scenario_outline
|
102
|
-
self
|
103
|
-
end
|
104
|
-
|
105
|
-
def cell_values
|
106
|
-
source.last.values
|
107
|
-
end
|
108
|
-
end
|
109
59
|
end
|
110
60
|
end
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require 'fileutils'
|
4
|
-
require 'multi_json'
|
5
4
|
require 'cucumber/configuration'
|
6
5
|
require 'cucumber/load_path'
|
7
6
|
require 'cucumber/formatter/duration'
|
@@ -10,6 +9,8 @@ require 'cucumber/filters'
|
|
10
9
|
require 'cucumber/formatter/fanout'
|
11
10
|
require 'cucumber/gherkin/i18n'
|
12
11
|
require 'cucumber/step_match_search'
|
12
|
+
require 'cucumber/messages'
|
13
|
+
require 'sys/uname'
|
13
14
|
|
14
15
|
module Cucumber
|
15
16
|
module FixRuby21Bug9285
|
@@ -18,8 +19,8 @@ module Cucumber
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
class FileException <
|
22
|
-
|
22
|
+
class FileException < RuntimeError
|
23
|
+
attr_reader :path
|
23
24
|
|
24
25
|
def initialize(original_exception, path)
|
25
26
|
super(original_exception)
|
@@ -30,7 +31,7 @@ module Cucumber
|
|
30
31
|
class FileNotFoundException < FileException
|
31
32
|
end
|
32
33
|
|
33
|
-
class FeatureFolderNotFoundException <
|
34
|
+
class FeatureFolderNotFoundException < RuntimeError
|
34
35
|
def initialize(path)
|
35
36
|
@path = path
|
36
37
|
end
|
@@ -53,7 +54,6 @@ module Cucumber
|
|
53
54
|
def initialize(configuration = Configuration.default)
|
54
55
|
@configuration = Configuration.new(configuration)
|
55
56
|
@support_code = SupportCode.new(self, @configuration)
|
56
|
-
@results = Formatter::LegacyApi::Results.new
|
57
57
|
end
|
58
58
|
|
59
59
|
# Allows you to take an existing runtime and change its configuration
|
@@ -64,6 +64,10 @@ module Cucumber
|
|
64
64
|
|
65
65
|
require 'cucumber/wire/plugin'
|
66
66
|
def run!
|
67
|
+
@configuration.notify :envelope, Cucumber::Messages::Envelope.new(
|
68
|
+
meta: make_meta
|
69
|
+
)
|
70
|
+
|
67
71
|
load_step_definitions
|
68
72
|
install_wire_plugin
|
69
73
|
fire_after_configuration_hook
|
@@ -71,7 +75,7 @@ module Cucumber
|
|
71
75
|
self.visitor = report
|
72
76
|
|
73
77
|
receiver = Test::Runner.new(@configuration.event_bus)
|
74
|
-
compile features, receiver, filters
|
78
|
+
compile features, receiver, filters, @configuration.event_bus
|
75
79
|
@configuration.notify :test_run_finished
|
76
80
|
end
|
77
81
|
|
@@ -83,14 +87,6 @@ module Cucumber
|
|
83
87
|
@configuration.dry_run?
|
84
88
|
end
|
85
89
|
|
86
|
-
def scenarios(status = nil)
|
87
|
-
@results.scenarios(status)
|
88
|
-
end
|
89
|
-
|
90
|
-
def steps(status = nil)
|
91
|
-
@results.steps(status)
|
92
|
-
end
|
93
|
-
|
94
90
|
def unmatched_step_definitions
|
95
91
|
@support_code.unmatched_step_definitions
|
96
92
|
end
|
@@ -105,14 +101,34 @@ module Cucumber
|
|
105
101
|
|
106
102
|
# Returns Ast::DocString for +string_without_triple_quotes+.
|
107
103
|
#
|
108
|
-
def doc_string(string_without_triple_quotes, content_type='', _line_offset=0)
|
109
|
-
|
110
|
-
|
104
|
+
def doc_string(string_without_triple_quotes, content_type = '', _line_offset = 0)
|
105
|
+
Core::Test::DocString.new(string_without_triple_quotes, content_type)
|
106
|
+
end
|
107
|
+
|
108
|
+
def make_meta
|
109
|
+
Cucumber::Messages::Meta.new(
|
110
|
+
protocol_version: Cucumber::Messages::VERSION,
|
111
|
+
implementation: Cucumber::Messages::Meta::Product.new(
|
112
|
+
name: 'cucumber-ruby',
|
113
|
+
version: Cucumber::VERSION
|
114
|
+
),
|
115
|
+
runtime: Cucumber::Messages::Meta::Product.new(
|
116
|
+
name: RUBY_ENGINE,
|
117
|
+
version: RUBY_VERSION
|
118
|
+
),
|
119
|
+
os: Cucumber::Messages::Meta::Product.new(
|
120
|
+
name: RbConfig::CONFIG['target_os'],
|
121
|
+
version: Sys::Uname.uname.version
|
122
|
+
),
|
123
|
+
cpu: Cucumber::Messages::Meta::Product.new(
|
124
|
+
name: RbConfig::CONFIG['target_cpu']
|
125
|
+
)
|
126
|
+
)
|
111
127
|
end
|
112
128
|
|
113
129
|
private
|
114
130
|
|
115
|
-
def fire_after_configuration_hook #:nodoc
|
131
|
+
def fire_after_configuration_hook #:nodoc:
|
116
132
|
@support_code.fire_hook(:after_configuration, @configuration)
|
117
133
|
end
|
118
134
|
|
@@ -142,14 +158,12 @@ module Cucumber
|
|
142
158
|
end
|
143
159
|
|
144
160
|
def initialize(path)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
raise FeatureFolderNotFoundException.new(path)
|
152
|
-
end
|
161
|
+
@file = File.new(path)
|
162
|
+
set_encoding
|
163
|
+
rescue Errno::EACCES => e
|
164
|
+
raise FileNotFoundException.new(e, File.expand_path(path))
|
165
|
+
rescue Errno::ENOENT
|
166
|
+
raise FeatureFolderNotFoundException, path
|
153
167
|
end
|
154
168
|
|
155
169
|
def read
|
@@ -161,7 +175,7 @@ module Cucumber
|
|
161
175
|
def set_encoding
|
162
176
|
@file.each do |line|
|
163
177
|
if ENCODING_PATTERN =~ line
|
164
|
-
@file.set_encoding
|
178
|
+
@file.set_encoding Regexp.last_match(1)
|
165
179
|
break
|
166
180
|
end
|
167
181
|
break unless COMMENT_OR_EMPTY_LINE_PATTERN =~ line
|
@@ -170,9 +184,6 @@ module Cucumber
|
|
170
184
|
end
|
171
185
|
end
|
172
186
|
|
173
|
-
require 'cucumber/formatter/legacy_api/adapter'
|
174
|
-
require 'cucumber/formatter/legacy_api/runtime_facade'
|
175
|
-
require 'cucumber/formatter/legacy_api/results'
|
176
187
|
require 'cucumber/formatter/ignore_missing_messages'
|
177
188
|
require 'cucumber/formatter/fail_fast'
|
178
189
|
require 'cucumber/core/report/summary'
|
@@ -193,38 +204,26 @@ module Cucumber
|
|
193
204
|
|
194
205
|
def formatters
|
195
206
|
@formatters ||=
|
196
|
-
@configuration.formatter_factories do |factory, formatter_options, path_or_io
|
197
|
-
create_formatter(factory, formatter_options, path_or_io
|
207
|
+
@configuration.formatter_factories do |factory, formatter_options, path_or_io|
|
208
|
+
create_formatter(factory, formatter_options, path_or_io)
|
198
209
|
end
|
199
210
|
end
|
200
211
|
|
201
|
-
def create_formatter(factory, formatter_options, path_or_io
|
202
|
-
if
|
203
|
-
if
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
return factory.new(@configuration.with_options(out_stream: path_or_io))
|
210
|
-
end
|
212
|
+
def create_formatter(factory, formatter_options, path_or_io)
|
213
|
+
if accept_options?(factory)
|
214
|
+
return factory.new(@configuration, formatter_options) if path_or_io.nil?
|
215
|
+
factory.new(@configuration.with_options(out_stream: path_or_io),
|
216
|
+
formatter_options)
|
217
|
+
else
|
218
|
+
return factory.new(@configuration) if path_or_io.nil?
|
219
|
+
factory.new(@configuration.with_options(out_stream: path_or_io))
|
211
220
|
end
|
212
|
-
results = Formatter::LegacyApi::Results.new
|
213
|
-
runtime_facade = Formatter::LegacyApi::RuntimeFacade.new(results, @support_code, @configuration)
|
214
|
-
formatter = factory.new(runtime_facade, path_or_io, cli_options)
|
215
|
-
Formatter::LegacyApi::Adapter.new(
|
216
|
-
Formatter::IgnoreMissingMessages.new(formatter),
|
217
|
-
results, @configuration)
|
218
221
|
end
|
219
222
|
|
220
223
|
def accept_options?(factory)
|
221
224
|
factory.instance_method(:initialize).arity > 1
|
222
225
|
end
|
223
226
|
|
224
|
-
def legacy_formatter?(factory)
|
225
|
-
factory.instance_method(:initialize).arity > 2
|
226
|
-
end
|
227
|
-
|
228
227
|
def failure?
|
229
228
|
if @configuration.wip?
|
230
229
|
summary_report.test_cases.total_passed > 0
|
@@ -235,7 +234,7 @@ module Cucumber
|
|
235
234
|
public :failure?
|
236
235
|
|
237
236
|
require 'cucumber/core/test/filters'
|
238
|
-
def filters
|
237
|
+
def filters # rubocop:disable Metrics/AbcSize
|
239
238
|
tag_expressions = @configuration.tag_expressions
|
240
239
|
name_regexps = @configuration.name_regexps
|
241
240
|
tag_limits = @configuration.tag_limits
|
@@ -245,17 +244,16 @@ module Cucumber
|
|
245
244
|
filters << Cucumber::Core::Test::NameFilter.new(name_regexps)
|
246
245
|
filters << Cucumber::Core::Test::LocationsFilter.new(filespecs.locations)
|
247
246
|
filters << Filters::Randomizer.new(@configuration.seed) if @configuration.randomize?
|
248
|
-
#
|
247
|
+
# TODO: can we just use Glue::RegistryAndMore's step definitions directly?
|
249
248
|
step_match_search = StepMatchSearch.new(@support_code.registry.method(:step_matches), @configuration)
|
250
249
|
filters << Filters::ActivateSteps.new(step_match_search, @configuration)
|
251
|
-
@configuration.filters.each
|
252
|
-
filters << filter
|
253
|
-
end
|
250
|
+
@configuration.filters.each { |filter| filters << filter }
|
254
251
|
unless configuration.dry_run?
|
255
252
|
filters << Filters::ApplyAfterStepHooks.new(@support_code)
|
256
253
|
filters << Filters::ApplyBeforeHooks.new(@support_code)
|
257
254
|
filters << Filters::ApplyAfterHooks.new(@support_code)
|
258
255
|
filters << Filters::ApplyAroundHooks.new(@support_code)
|
256
|
+
filters << Filters::BroadcastTestCaseReadyEvent.new(@configuration)
|
259
257
|
filters << Filters::BroadcastTestRunStartedEvent.new(@configuration)
|
260
258
|
filters << Filters::Quit.new
|
261
259
|
filters << Filters::Retry.new(@configuration)
|
@@ -271,13 +269,11 @@ module Cucumber
|
|
271
269
|
end
|
272
270
|
|
273
271
|
def install_wire_plugin
|
274
|
-
Cucumber::Wire::Plugin.new(@configuration).install if @configuration.all_files_to_load.any? {|f| f =~
|
272
|
+
Cucumber::Wire::Plugin.new(@configuration, @support_code.registry).install if @configuration.all_files_to_load.any? { |f| f =~ /\.wire$/ }
|
275
273
|
end
|
276
274
|
|
277
275
|
def log
|
278
276
|
Cucumber.logger
|
279
277
|
end
|
280
|
-
|
281
278
|
end
|
282
|
-
|
283
279
|
end
|