cucumber 3.2.0 → 4.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 +4 -4
- data/CHANGELOG.md +166 -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 +3 -2
- data/lib/cucumber/runtime/support_code.rb +13 -15
- data/lib/cucumber/runtime/user_interface.rb +6 -16
- data/lib/cucumber/runtime.rb +54 -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 +221 -77
- 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
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,29 @@ 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
|
-
build_hook_step(
|
20
|
+
def after_step_hook(id, test_step, location, &block)
|
21
|
+
raise ArgumentError if test_step.hook?
|
22
|
+
build_hook_step(id, location, block, AfterStepHook, Core::Test::Action)
|
23
23
|
end
|
24
24
|
|
25
|
-
def around_hook(
|
25
|
+
def around_hook(&block)
|
26
26
|
Core::Test::AroundHook.new(&block)
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
def build_hook_step(
|
31
|
+
def build_hook_step(id, location, block, hook_type, action_type)
|
32
32
|
action = action_type.new(location, &block)
|
33
33
|
hook = hook_type.new(action.location)
|
34
|
-
Core::Test::
|
34
|
+
Core::Test::HookStep.new(id, hook.text, location, action)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -135,7 +135,7 @@ module Cucumber
|
|
135
135
|
def raise_error
|
136
136
|
table = DataTable.from([[]])
|
137
137
|
table.instance_variable_set :@cell_matrix, cell_matrix
|
138
|
-
raise Different
|
138
|
+
raise Different, table if should_raise?
|
139
139
|
end
|
140
140
|
|
141
141
|
def should_raise?
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'cucumber/gherkin/data_table_parser'
|
5
5
|
require 'cucumber/gherkin/formatter/escaping'
|
6
|
-
require 'cucumber/core/ast/describes_itself'
|
7
6
|
require 'cucumber/multiline_argument/data_table/diff_matrices'
|
8
7
|
|
9
8
|
module Cucumber
|
@@ -28,19 +27,21 @@ module Cucumber
|
|
28
27
|
# This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
|
29
28
|
#
|
30
29
|
class DataTable
|
31
|
-
include Core::Ast::DescribesItself
|
32
|
-
|
33
30
|
def self.default_arg_name #:nodoc:
|
34
31
|
'table'
|
35
32
|
end
|
36
33
|
|
34
|
+
def describe_to(visitor, *args)
|
35
|
+
visitor.legacy_table(self, *args)
|
36
|
+
end
|
37
|
+
|
37
38
|
class << self
|
38
|
-
def from(data
|
39
|
+
def from(data)
|
39
40
|
case data
|
40
41
|
when Array
|
41
|
-
from_array(data
|
42
|
+
from_array(data)
|
42
43
|
when String
|
43
|
-
parse(data
|
44
|
+
parse(data)
|
44
45
|
else
|
45
46
|
raise ArgumentError, 'expected data to be a String or an Array.'
|
46
47
|
end
|
@@ -48,15 +49,15 @@ module Cucumber
|
|
48
49
|
|
49
50
|
private
|
50
51
|
|
51
|
-
def parse(text
|
52
|
+
def parse(text)
|
52
53
|
builder = Builder.new
|
53
54
|
parser = Cucumber::Gherkin::DataTableParser.new(builder)
|
54
55
|
parser.parse(text)
|
55
|
-
from_array(builder.rows
|
56
|
+
from_array(builder.rows)
|
56
57
|
end
|
57
58
|
|
58
|
-
def from_array(data
|
59
|
-
new Core::
|
59
|
+
def from_array(data)
|
60
|
+
new Core::Test::DataTable.new(data)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
@@ -71,18 +72,17 @@ module Cucumber
|
|
71
72
|
@rows << row
|
72
73
|
end
|
73
74
|
|
74
|
-
def eof
|
75
|
-
end
|
75
|
+
def eof; end
|
76
76
|
end
|
77
77
|
|
78
|
-
NULL_CONVERSIONS = Hash.new(
|
78
|
+
NULL_CONVERSIONS = Hash.new(strict: false, proc: ->(cell_value) { cell_value }).freeze
|
79
79
|
|
80
|
-
# @param data [Core::
|
80
|
+
# @param data [Core::Test::DataTable] the data for the table
|
81
81
|
# @param conversion_procs [Hash] see map_columns!
|
82
82
|
# @param header_mappings [Hash] see map_headers!
|
83
83
|
# @param header_conversion_proc [Proc] see map_headers!
|
84
84
|
def initialize(data, conversion_procs = NULL_CONVERSIONS.dup, header_mappings = {}, header_conversion_proc = nil)
|
85
|
-
raise ArgumentError, 'data must be a Core::
|
85
|
+
raise ArgumentError, 'data must be a Core::Test::DataTable' unless data.is_a? Core::Test::DataTable
|
86
86
|
ast_table = data
|
87
87
|
# Verify that it's square
|
88
88
|
ast_table.transpose
|
@@ -111,7 +111,7 @@ module Cucumber
|
|
111
111
|
# registered with #map_column! and #map_headers!.
|
112
112
|
#
|
113
113
|
def dup
|
114
|
-
self.class.new(Core::
|
114
|
+
self.class.new(Core::Test::DataTable.new(raw), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
115
115
|
end
|
116
116
|
|
117
117
|
# Returns a new, transposed table. Example:
|
@@ -126,7 +126,7 @@ module Cucumber
|
|
126
126
|
# | 4 | 2 |
|
127
127
|
#
|
128
128
|
def transpose
|
129
|
-
self.class.new(Core::
|
129
|
+
self.class.new(Core::Test::DataTable.new(raw.transpose), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
130
130
|
end
|
131
131
|
|
132
132
|
# Converts this table into an Array of Hash where the keys of each
|
@@ -160,7 +160,7 @@ module Cucumber
|
|
160
160
|
#
|
161
161
|
def symbolic_hashes
|
162
162
|
@symbolic_hashes ||=
|
163
|
-
|
163
|
+
hashes.map do |string_hash|
|
164
164
|
Hash[string_hash.map { |a, b| [symbolize_key(a), b] }]
|
165
165
|
end
|
166
166
|
end
|
@@ -180,7 +180,7 @@ module Cucumber
|
|
180
180
|
def rows_hash
|
181
181
|
return @rows_hash if @rows_hash
|
182
182
|
verify_table_width(2)
|
183
|
-
@rows_hash =
|
183
|
+
@rows_hash = transpose.hashes[0]
|
184
184
|
end
|
185
185
|
|
186
186
|
# Gets the raw data of this table. For example, a Table built from
|
@@ -200,7 +200,7 @@ module Cucumber
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def column_names #:nodoc:
|
203
|
-
@
|
203
|
+
@column_names ||= cell_matrix[0].map(&:value)
|
204
204
|
end
|
205
205
|
|
206
206
|
def rows
|
@@ -269,7 +269,7 @@ module Cucumber
|
|
269
269
|
|
270
270
|
# Returns a new Table where the headers are redefined. See #map_headers!
|
271
271
|
def map_headers(mappings = {}, &block)
|
272
|
-
self.class.new(Core::
|
272
|
+
self.class.new(Core::Test::DataTable.new(raw), @conversion_procs.dup, mappings, block)
|
273
273
|
end
|
274
274
|
|
275
275
|
# Change how #hashes converts column values. The +column_name+ argument identifies the column
|
@@ -286,15 +286,15 @@ module Cucumber
|
|
286
286
|
#
|
287
287
|
def map_column!(column_name, strict = true, &conversion_proc)
|
288
288
|
# TODO: Remove this method for 2.0
|
289
|
-
@conversion_procs[column_name.to_s] = { :
|
289
|
+
@conversion_procs[column_name.to_s] = { strict: strict, proc: conversion_proc }
|
290
290
|
self
|
291
291
|
end
|
292
292
|
|
293
293
|
# Returns a new Table with an additional column mapping. See #map_column!
|
294
294
|
def map_column(column_name, strict = true, &conversion_proc)
|
295
295
|
conversion_procs = @conversion_procs.dup
|
296
|
-
conversion_procs[column_name.to_s] = { :
|
297
|
-
self.class.new(Core::
|
296
|
+
conversion_procs[column_name.to_s] = { strict: strict, proc: conversion_proc }
|
297
|
+
self.class.new(Core::Test::DataTable.new(raw), conversion_procs, @header_mappings.dup, @header_conversion_proc)
|
298
298
|
end
|
299
299
|
|
300
300
|
# Compares +other_table+ to self. If +other_table+ contains columns
|
@@ -352,9 +352,13 @@ module Cucumber
|
|
352
352
|
end
|
353
353
|
end
|
354
354
|
|
355
|
-
def to_hash
|
356
|
-
|
357
|
-
|
355
|
+
def to_hash
|
356
|
+
cells_rows.map { |cells| cells.map(&:value) }
|
357
|
+
end
|
358
|
+
|
359
|
+
def cells_to_hash(cells) #:nodoc:
|
360
|
+
hash = Hash.new do |hash_inner, key|
|
361
|
+
hash_inner[key.to_s] if key.is_a?(Symbol)
|
358
362
|
end
|
359
363
|
column_names.each_with_index do |column_name, column_index|
|
360
364
|
hash[column_name] = cells.value(column_index)
|
@@ -367,19 +371,21 @@ module Cucumber
|
|
367
371
|
end
|
368
372
|
|
369
373
|
def verify_column(column_name) #:nodoc:
|
370
|
-
raise %
|
374
|
+
raise %(The column named "#{column_name}" does not exist) unless raw[0].include?(column_name)
|
371
375
|
end
|
372
376
|
|
373
377
|
def verify_table_width(width) #:nodoc:
|
374
|
-
raise %
|
378
|
+
raise %(The table must have exactly #{width} columns) unless raw[0].size == width
|
375
379
|
end
|
376
380
|
|
377
|
-
|
381
|
+
# TODO: remove the below function if it's not actually being used.
|
382
|
+
# Nothing else in this repo calls it.
|
383
|
+
def text?(text) #:nodoc:
|
378
384
|
raw.flatten.compact.detect { |cell_value| cell_value.index(text) }
|
379
385
|
end
|
380
386
|
|
381
387
|
def cells_rows #:nodoc:
|
382
|
-
@rows ||= cell_matrix.map do |cell_row|
|
388
|
+
@rows ||= cell_matrix.map do |cell_row| # rubocop:disable Naming/MemoizedInstanceVariableName
|
383
389
|
Cells.new(self, cell_row)
|
384
390
|
end
|
385
391
|
end
|
@@ -399,26 +405,48 @@ module Cucumber
|
|
399
405
|
end
|
400
406
|
|
401
407
|
def to_s(options = {}) #:nodoc:
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
|
406
|
-
io = StringIO.new
|
407
|
-
|
408
|
-
c = Cucumber::Term::ANSIColor.coloring?
|
409
|
-
Cucumber::Term::ANSIColor.coloring = options[:color]
|
410
|
-
runtime = Struct.new(:configuration).new(Configuration.new)
|
411
|
-
formatter = Formatter::Pretty.new(runtime, io, options)
|
412
|
-
formatter.instance_variable_set('@indent', options[:indent])
|
413
|
-
Formatter::LegacyApi::Ast::MultilineArg.for(self).accept(Formatter::Fanout.new([formatter]))
|
414
|
-
Cucumber::Term::ANSIColor.coloring = c
|
415
|
-
io.rewind
|
416
|
-
s = "\n" + io.read + (' ' * (options[:indent] - 2))
|
417
|
-
s
|
408
|
+
indentation = options.key?(:indent) ? options[:indent] : 2
|
409
|
+
prefixes = options.key?(:prefixes) ? options[:prefixes] : TO_S_PREFIXES
|
410
|
+
DataTablePrinter.new(self, indentation, prefixes).to_s
|
418
411
|
end
|
419
412
|
|
420
|
-
|
421
|
-
|
413
|
+
class DataTablePrinter #:nodoc:
|
414
|
+
include Cucumber::Gherkin::Formatter::Escaping
|
415
|
+
attr_reader :data_table, :indentation, :prefixes
|
416
|
+
private :data_table, :indentation, :prefixes
|
417
|
+
|
418
|
+
def initialize(data_table, indentation, prefixes)
|
419
|
+
@data_table = data_table
|
420
|
+
@indentation = indentation
|
421
|
+
@prefixes = prefixes
|
422
|
+
end
|
423
|
+
|
424
|
+
def to_s
|
425
|
+
leading_row = "\n"
|
426
|
+
end_indentation = indentation - 2
|
427
|
+
trailing_row = "\n" + (' ' * end_indentation)
|
428
|
+
table_rows = data_table.cell_matrix.map { |row| format_row(row) }
|
429
|
+
leading_row + table_rows.join("\n") + trailing_row
|
430
|
+
end
|
431
|
+
|
432
|
+
private
|
433
|
+
|
434
|
+
def format_row(row)
|
435
|
+
row_start = (' ' * indentation) + '| '
|
436
|
+
row_end = '|'
|
437
|
+
cells = row.map.with_index do |cell, i|
|
438
|
+
format_cell(cell, data_table.col_width(i))
|
439
|
+
end
|
440
|
+
row_start + cells.join('| ') + row_end
|
441
|
+
end
|
442
|
+
|
443
|
+
def format_cell(cell, col_width)
|
444
|
+
cell_text = escape_cell(cell.value.to_s)
|
445
|
+
cell_text_width = cell_text.unpack('U*').length
|
446
|
+
padded_text = cell_text + (' ' * (col_width - cell_text_width))
|
447
|
+
prefix = prefixes[cell.status]
|
448
|
+
"#{prefix}#{padded_text} "
|
449
|
+
end
|
422
450
|
end
|
423
451
|
|
424
452
|
def columns #:nodoc:
|
@@ -446,7 +474,11 @@ module Cucumber
|
|
446
474
|
|
447
475
|
def create_cell_matrix(ast_table) #:nodoc:
|
448
476
|
ast_table.raw.map do |raw_row|
|
449
|
-
line =
|
477
|
+
line = begin
|
478
|
+
raw_row.line
|
479
|
+
rescue StandardError
|
480
|
+
-1
|
481
|
+
end
|
450
482
|
raw_row.map do |raw_cell|
|
451
483
|
Cell.new(raw_cell, self, line)
|
452
484
|
end
|
@@ -476,22 +508,20 @@ module Cucumber
|
|
476
508
|
end
|
477
509
|
|
478
510
|
@header_mappings.each_pair do |pre, post|
|
479
|
-
mapped_cells = header_cells.
|
511
|
+
mapped_cells = header_cells.reject { |cell| cell.value.match(pre).nil? }
|
480
512
|
raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
|
481
513
|
raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map(&:value).inspect}" if mapped_cells.length > 1
|
482
514
|
mapped_cells[0].value = post
|
483
|
-
if @conversion_procs.key?(pre)
|
484
|
-
@conversion_procs[post] = @conversion_procs.delete(pre)
|
485
|
-
end
|
515
|
+
@conversion_procs[post] = @conversion_procs.delete(pre) if @conversion_procs.key?(pre)
|
486
516
|
end
|
487
517
|
end
|
488
518
|
|
489
519
|
def clear_cache! #:nodoc:
|
490
|
-
@hashes = @rows_hash = @
|
520
|
+
@hashes = @rows_hash = @column_names = @rows = @columns = nil
|
491
521
|
end
|
492
522
|
|
493
523
|
def ensure_table(table_or_array) #:nodoc:
|
494
|
-
return table_or_array if DataTable
|
524
|
+
return table_or_array if DataTable == table_or_array.class
|
495
525
|
DataTable.from(table_or_array)
|
496
526
|
end
|
497
527
|
|
@@ -507,7 +537,8 @@ module Cucumber
|
|
507
537
|
attr_reader :exception
|
508
538
|
|
509
539
|
def initialize(table, cells)
|
510
|
-
@table
|
540
|
+
@table = table
|
541
|
+
@cells = cells
|
511
542
|
end
|
512
543
|
|
513
544
|
def accept(visitor)
|
@@ -524,7 +555,7 @@ module Cucumber
|
|
524
555
|
end
|
525
556
|
|
526
557
|
def to_hash #:nodoc:
|
527
|
-
@to_hash ||= @table.
|
558
|
+
@to_hash ||= @table.cells_to_hash(self)
|
528
559
|
end
|
529
560
|
|
530
561
|
def value(n) #:nodoc:
|
@@ -563,19 +594,21 @@ module Cucumber
|
|
563
594
|
attr_accessor :status, :value
|
564
595
|
|
565
596
|
def initialize(value, table, line)
|
566
|
-
@value
|
597
|
+
@value = value
|
598
|
+
@table = table
|
599
|
+
@line = line
|
567
600
|
end
|
568
601
|
|
569
602
|
def inspect!
|
570
603
|
@value = "(i) #{value.inspect}"
|
571
604
|
end
|
572
605
|
|
573
|
-
def ==(
|
574
|
-
SurplusCell
|
606
|
+
def ==(other)
|
607
|
+
SurplusCell == other.class || value == other.value
|
575
608
|
end
|
576
609
|
|
577
|
-
def eql?(
|
578
|
-
self ==
|
610
|
+
def eql?(other)
|
611
|
+
self == other
|
579
612
|
end
|
580
613
|
|
581
614
|
def hash
|
@@ -593,7 +626,7 @@ module Cucumber
|
|
593
626
|
:comment
|
594
627
|
end
|
595
628
|
|
596
|
-
def ==(
|
629
|
+
def ==(_other)
|
597
630
|
true
|
598
631
|
end
|
599
632
|
|
@@ -12,10 +12,10 @@ module Cucumber
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def from(argument, location = nil, content_type = nil)
|
15
|
-
location ||= Core::
|
15
|
+
location ||= Core::Test::Location.of_caller
|
16
16
|
case argument
|
17
17
|
when String
|
18
|
-
builder.doc_string(Core::
|
18
|
+
builder.doc_string(Core::Test::DocString.new(argument, content_type))
|
19
19
|
when Array
|
20
20
|
location = location.on_line(argument.first.line..argument.last.line)
|
21
21
|
builder.data_table(argument.map(&:cells), location)
|
@@ -52,11 +52,9 @@ module Cucumber
|
|
52
52
|
end
|
53
53
|
|
54
54
|
class None
|
55
|
-
def append_to(array)
|
56
|
-
end
|
55
|
+
def append_to(array); end
|
57
56
|
|
58
|
-
def describe_to(visitor)
|
59
|
-
end
|
57
|
+
def describe_to(visitor); end
|
60
58
|
end
|
61
59
|
end
|
62
60
|
end
|
data/lib/cucumber/platform.rb
CHANGED
@@ -7,7 +7,7 @@ require 'cucumber/core/platform'
|
|
7
7
|
|
8
8
|
module Cucumber
|
9
9
|
unless defined?(Cucumber::VERSION)
|
10
|
-
VERSION = File.read(File.expand_path('
|
10
|
+
VERSION = File.read(File.expand_path('version', __dir__)).strip
|
11
11
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
12
12
|
LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
13
13
|
RAILS = defined?(Rails)
|
@@ -18,8 +18,8 @@ module Cucumber
|
|
18
18
|
attr_accessor :use_full_backtrace
|
19
19
|
|
20
20
|
# @private
|
21
|
-
def file_mode(
|
22
|
-
"#{
|
21
|
+
def file_mode(mode, encoding = 'UTF-8')
|
22
|
+
"#{mode}:#{encoding}"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
self.use_full_backtrace = false
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -38,8 +38,8 @@ module Cucumber
|
|
38
38
|
attr_reader :args
|
39
39
|
|
40
40
|
def initialize(libs, cucumber_opts, feature_files)
|
41
|
-
raise 'libs must be an Array when running in-process' unless Array
|
42
|
-
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) }
|
43
43
|
@args = (
|
44
44
|
cucumber_opts +
|
45
45
|
feature_files
|
@@ -65,11 +65,11 @@ module Cucumber
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def load_path
|
68
|
-
[format('"
|
68
|
+
[format('"%<path>s"', path: @libs.join(File::PATH_SEPARATOR))]
|
69
69
|
end
|
70
70
|
|
71
71
|
def quoted_binary(cucumber_bin)
|
72
|
-
[format('"
|
72
|
+
[format('"%<path>s"', path: cucumber_bin)]
|
73
73
|
end
|
74
74
|
|
75
75
|
def use_bundler
|
@@ -98,9 +98,7 @@ module Cucumber
|
|
98
98
|
|
99
99
|
def run
|
100
100
|
sh cmd.join(' ') do |ok, res|
|
101
|
-
|
102
|
-
exit res.exitstatus
|
103
|
-
end
|
101
|
+
exit res.exitstatus unless ok
|
104
102
|
end
|
105
103
|
end
|
106
104
|
end
|
@@ -113,9 +111,9 @@ module Cucumber
|
|
113
111
|
|
114
112
|
# Extra options to pass to the cucumber binary. Can be overridden by the CUCUMBER_OPTS environment variable.
|
115
113
|
# It's recommended to pass an Array, but if it's a String it will be #split by ' '.
|
116
|
-
|
114
|
+
attr_reader :cucumber_opts
|
117
115
|
def cucumber_opts=(opts) #:nodoc:
|
118
|
-
@cucumber_opts = String
|
116
|
+
@cucumber_opts = String == opts.class ? opts.split(' ') : opts
|
119
117
|
end
|
120
118
|
|
121
119
|
# Whether or not to fork a new ruby interpreter. Defaults to true. You may gain
|
@@ -134,12 +132,16 @@ module Cucumber
|
|
134
132
|
# Note that this attribute has no effect if you don't run in forked mode.
|
135
133
|
attr_accessor :bundler
|
136
134
|
|
135
|
+
# Name of the running task
|
136
|
+
attr_reader :task_name
|
137
|
+
|
137
138
|
# Define Cucumber Rake task
|
138
139
|
def initialize(task_name = 'cucumber', desc = 'Run Cucumber features')
|
139
|
-
@task_name
|
140
|
+
@task_name = task_name
|
141
|
+
@desc = desc
|
140
142
|
@fork = true
|
141
143
|
@libs = ['lib']
|
142
|
-
@rcov_opts = %w
|
144
|
+
@rcov_opts = %w[--rails --exclude osx\/objc,gems\/]
|
143
145
|
yield self if block_given?
|
144
146
|
@binary = binary.nil? ? Cucumber::BINARY : File.expand_path(binary)
|
145
147
|
define_task
|
@@ -154,18 +156,16 @@ module Cucumber
|
|
154
156
|
|
155
157
|
def runner(_task_args = nil) #:nodoc:
|
156
158
|
cucumber_opts = [(ENV['CUCUMBER_OPTS'] ? ENV['CUCUMBER_OPTS'].split(/\s+/) : nil) || cucumber_opts_with_profile]
|
157
|
-
if
|
158
|
-
return ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files)
|
159
|
-
end
|
159
|
+
return ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files) if fork
|
160
160
|
InProcessCucumberRunner.new(libs, cucumber_opts, feature_files)
|
161
161
|
end
|
162
162
|
|
163
163
|
def cucumber_opts_with_profile #:nodoc:
|
164
|
-
Array(cucumber_opts).concat
|
164
|
+
Array(cucumber_opts).concat(Array(@profile).flat_map { |p| ['--profile', p] })
|
165
165
|
end
|
166
166
|
|
167
167
|
def feature_files #:nodoc:
|
168
|
-
make_command_line_safe(FileList[
|
168
|
+
make_command_line_safe(FileList[ENV['FEATURE'] || []])
|
169
169
|
end
|
170
170
|
|
171
171
|
def make_command_line_safe(list)
|
@@ -9,16 +9,17 @@ module Spec #:nodoc:
|
|
9
9
|
# will fail when running cucumber)
|
10
10
|
class OptionParser < ::OptionParser #:nodoc:
|
11
11
|
NEUTERED_RSPEC = Object.new
|
12
|
-
def NEUTERED_RSPEC.method_missing(
|
12
|
+
def NEUTERED_RSPEC.method_missing(_method, *_args) # rubocop:disable Style/MissingRespondToMissing
|
13
|
+
self || super
|
14
|
+
end
|
13
15
|
|
14
|
-
def self.method_added(
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
@__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
|
21
21
|
end
|
22
|
+
@__neutering_rspec = false
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -15,45 +15,12 @@ module Cucumber
|
|
15
15
|
# the passed / failed / undefined / skipped status of
|
16
16
|
# the test case.
|
17
17
|
#
|
18
|
-
# The test case might come from a regular Scenario or
|
19
|
-
# a Scenario outline. You can call the `#outline?`
|
20
|
-
# predicate to find out. If it's from an outline,
|
21
|
-
# you get a couple of extra methods.
|
22
18
|
module RunningTestCase
|
23
19
|
def self.new(test_case)
|
24
|
-
|
20
|
+
TestCase.new(test_case)
|
25
21
|
end
|
26
22
|
|
27
|
-
class
|
28
|
-
def initialize(test_case)
|
29
|
-
@test_case = test_case
|
30
|
-
test_case.describe_source_to(self)
|
31
|
-
end
|
32
|
-
|
33
|
-
def feature(feature)
|
34
|
-
end
|
35
|
-
|
36
|
-
def scenario(_scenario)
|
37
|
-
@factory = Scenario
|
38
|
-
end
|
39
|
-
|
40
|
-
def scenario_outline(_scenario)
|
41
|
-
@factory = ScenarioOutlineExample
|
42
|
-
end
|
43
|
-
|
44
|
-
def examples_table(examples_table)
|
45
|
-
end
|
46
|
-
|
47
|
-
def examples_table_row(row)
|
48
|
-
end
|
49
|
-
|
50
|
-
def running_test_case
|
51
|
-
@factory.new(@test_case)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
private_constant :Builder
|
55
|
-
|
56
|
-
class Scenario < SimpleDelegator
|
23
|
+
class TestCase < SimpleDelegator
|
57
24
|
def initialize(test_case, result = Core::Test::Result::Unknown.new)
|
58
25
|
@test_case = test_case
|
59
26
|
@result = result
|
@@ -85,27 +52,9 @@ module Cucumber
|
|
85
52
|
tags.map &:name
|
86
53
|
end
|
87
54
|
|
88
|
-
def outline?
|
89
|
-
false
|
90
|
-
end
|
91
|
-
|
92
55
|
def with_result(result)
|
93
56
|
self.class.new(@test_case, result)
|
94
57
|
end
|
95
58
|
end
|
96
|
-
|
97
|
-
class ScenarioOutlineExample < Scenario
|
98
|
-
def outline?
|
99
|
-
true
|
100
|
-
end
|
101
|
-
|
102
|
-
def scenario_outline
|
103
|
-
self
|
104
|
-
end
|
105
|
-
|
106
|
-
def cell_values
|
107
|
-
source.last.values
|
108
|
-
end
|
109
|
-
end
|
110
59
|
end
|
111
60
|
end
|