cucumber 1.1.2 → 1.1.3
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.
- data/.rvmrc +1 -0
- data/.travis.yml +12 -2
- data/History.md +14 -0
- data/cucumber.gemspec +2 -2
- data/cucumber.yml +1 -1
- data/features/.cucumber/stepdefs.json +1159 -0
- data/features/issue_57.feature +35 -0
- data/legacy_features/wire_protocol.feature +1 -1
- data/lib/cucumber/ast/feature.rb +1 -1
- data/lib/cucumber/ast/table.rb +52 -31
- data/lib/cucumber/cli/configuration.rb +4 -0
- data/lib/cucumber/cli/main.rb +1 -0
- data/lib/cucumber/cli/options.rb +3 -0
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +1 -1
- data/lib/cucumber/formatter/html.rb +6 -1
- data/lib/cucumber/formatter/rerun.rb +30 -7
- data/lib/cucumber/js_support/js_language.rb +1 -1
- data/lib/cucumber/language_support/language_methods.rb +0 -4
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/py_support/py_language.rb +0 -4
- data/lib/cucumber/rb_support/rb_language.rb +0 -14
- data/lib/cucumber/rb_support/regexp_argument_matcher.rb +3 -3
- data/lib/cucumber/runtime.rb +39 -2
- data/lib/cucumber/step_match.rb +3 -3
- data/lib/cucumber/wire_support/wire_protocol.rb +0 -1
- data/lib/cucumber/wire_support/wire_protocol/requests.rb +3 -1
- data/spec/cucumber/ast/table_spec.rb +13 -0
- data/spec/cucumber/cli/main_spec.rb +1 -1
- data/spec/cucumber/constantize_spec.rb +12 -0
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +2 -2
- metadata +54 -68
- data/.gitignore +0 -27
- data/examples/i18n/de/.gitignore +0 -1
- data/examples/i18n/en/.gitignore +0 -1
- data/examples/i18n/eo/.gitignore +0 -1
- data/examples/i18n/fi/.gitignore +0 -1
- data/examples/i18n/hu/.gitignore +0 -1
- data/examples/i18n/id/.gitignore +0 -1
- data/examples/i18n/ja/.gitignore +0 -1
- data/examples/i18n/ko/.gitignore +0 -1
- data/examples/i18n/lt/.gitignore +0 -1
- data/examples/i18n/pl/.gitignore +0 -1
- data/examples/i18n/sk/.gitignore +0 -1
- data/examples/i18n/tr/.gitignore +0 -1
- data/examples/i18n/zh-TW/.gitignore +0 -1
- data/examples/python/lib/.gitignore +0 -1
- data/examples/ruby2python/lib/.gitignore +0 -1
- data/examples/watir/.gitignore +0 -2
- data/fixtures/self_test/.gitignore +0 -1
- data/lib/cucumber/step_argument.rb +0 -9
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Rerun formatter: Test for Issue #57
|
2
|
+
details see https://github.com/cucumber/cucumber/issues/57
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given a file named "features/one_passing_one_failing.feature" with:
|
6
|
+
"""
|
7
|
+
Feature: One passing example, one failing example
|
8
|
+
|
9
|
+
Scenario Outline:
|
10
|
+
Given a <certain> step
|
11
|
+
|
12
|
+
Examples:
|
13
|
+
|certain|
|
14
|
+
|passing|
|
15
|
+
|failing|
|
16
|
+
|
17
|
+
"""
|
18
|
+
And a file named "features/step_definitions/steps.rb" with:
|
19
|
+
"""
|
20
|
+
Given /a passing step/ do
|
21
|
+
#does nothing
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /a failing step/ do
|
25
|
+
fail
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
|
29
|
+
Scenario: Handle examples with the rerun formatter
|
30
|
+
When I run cucumber "features/one_passing_one_failing.feature -r features -f rerun"
|
31
|
+
Then it should fail with:
|
32
|
+
"""
|
33
|
+
features/one_passing_one_failing.feature:9
|
34
|
+
"""
|
35
|
+
|
data/lib/cucumber/ast/feature.rb
CHANGED
@@ -8,7 +8,7 @@ module Cucumber
|
|
8
8
|
|
9
9
|
attr_accessor :language
|
10
10
|
attr_writer :features, :background
|
11
|
-
attr_reader :file
|
11
|
+
attr_reader :file, :feature_elements
|
12
12
|
|
13
13
|
def initialize(background, comment, tags, keyword, title, description, feature_elements)
|
14
14
|
@background, @comment, @tags, @keyword, @title, @description, @feature_elements = background, comment, tags, keyword, title, description, feature_elements
|
data/lib/cucumber/ast/table.rb
CHANGED
@@ -51,7 +51,7 @@ module Cucumber
|
|
51
51
|
include Enumerable
|
52
52
|
include Gherkin::Rubify
|
53
53
|
|
54
|
-
NULL_CONVERSIONS = Hash.new(lambda{ |cell_value| cell_value }).freeze
|
54
|
+
NULL_CONVERSIONS = Hash.new({ :strict => false, :proc => lambda{ |cell_value| cell_value } }).freeze
|
55
55
|
|
56
56
|
attr_accessor :file
|
57
57
|
|
@@ -71,7 +71,7 @@ module Cucumber
|
|
71
71
|
# You don't typically create your own Table objects - Cucumber will do
|
72
72
|
# it internally and pass them to your Step Definitions.
|
73
73
|
#
|
74
|
-
def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
|
74
|
+
def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup, header_mappings = {}, header_conversion_proc = nil)
|
75
75
|
@cells_class = Cells
|
76
76
|
@cell_class = Cell
|
77
77
|
raw = ensure_array_of_array(rubify(raw))
|
@@ -79,17 +79,19 @@ module Cucumber
|
|
79
79
|
transposed = raw.transpose
|
80
80
|
create_cell_matrix(raw)
|
81
81
|
@conversion_procs = conversion_procs
|
82
|
+
@header_mappings = header_mappings
|
83
|
+
@header_conversion_proc = header_conversion_proc
|
82
84
|
end
|
83
85
|
|
84
86
|
def to_step_definition_arg
|
85
87
|
dup
|
86
88
|
end
|
87
89
|
|
88
|
-
# Creates a copy of this table, inheriting any column mappings
|
89
|
-
# registered with #map_headers
|
90
|
+
# Creates a copy of this table, inheriting any column and header mappings
|
91
|
+
# registered with #map_column! and #map_headers!.
|
90
92
|
#
|
91
93
|
def dup
|
92
|
-
self.class.new(raw.dup, @conversion_procs.dup)
|
94
|
+
self.class.new(raw.dup, @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
93
95
|
end
|
94
96
|
|
95
97
|
# Returns a new, transposed table. Example:
|
@@ -104,9 +106,9 @@ module Cucumber
|
|
104
106
|
# | 4 | 2 |
|
105
107
|
#
|
106
108
|
def transpose
|
107
|
-
self.class.new(raw.transpose, @conversion_procs.dup)
|
109
|
+
self.class.new(raw.transpose, @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
108
110
|
end
|
109
|
-
|
111
|
+
|
110
112
|
# Converts this table into an Array of Hash where the keys of each
|
111
113
|
# Hash are the headers in the table. For example, a Table built from
|
112
114
|
# the following plain text:
|
@@ -122,9 +124,7 @@ module Cucumber
|
|
122
124
|
# Use #map_column! to specify how values in a column are converted.
|
123
125
|
#
|
124
126
|
def hashes
|
125
|
-
@hashes ||=
|
126
|
-
row.to_hash
|
127
|
-
end
|
127
|
+
@hashes ||= build_hashes
|
128
128
|
end
|
129
129
|
|
130
130
|
# Converts this table into a Hash where the first column is
|
@@ -238,22 +238,8 @@ module Cucumber
|
|
238
238
|
# # => ['phone number', 'ADDRESS']
|
239
239
|
#
|
240
240
|
def map_headers!(mappings={}, &block)
|
241
|
-
|
242
|
-
|
243
|
-
if block_given?
|
244
|
-
header_values = header_cells.map { |cell| cell.value } - mappings.keys
|
245
|
-
mappings = mappings.merge(Hash[*header_values.zip(header_values.map(&block)).flatten])
|
246
|
-
end
|
247
|
-
|
248
|
-
mappings.each_pair do |pre, post|
|
249
|
-
mapped_cells = header_cells.select{|cell| pre === cell.value}
|
250
|
-
raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
|
251
|
-
raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map{|c| c.value}.inspect}" if mapped_cells.length > 1
|
252
|
-
mapped_cells[0].value = post
|
253
|
-
if @conversion_procs.has_key?(pre)
|
254
|
-
@conversion_procs[post] = @conversion_procs.delete(pre)
|
255
|
-
end
|
256
|
-
end
|
241
|
+
@header_mappings = mappings
|
242
|
+
@header_conversion_proc = block
|
257
243
|
end
|
258
244
|
|
259
245
|
# Returns a new Table where the headers are redefined. See #map_headers!
|
@@ -276,8 +262,7 @@ module Cucumber
|
|
276
262
|
# end
|
277
263
|
#
|
278
264
|
def map_column!(column_name, strict=true, &conversion_proc)
|
279
|
-
|
280
|
-
@conversion_procs[column_name.to_s] = conversion_proc
|
265
|
+
@conversion_procs[column_name.to_s] = { :strict => strict, :proc => conversion_proc }
|
281
266
|
self
|
282
267
|
end
|
283
268
|
|
@@ -319,8 +304,12 @@ module Cucumber
|
|
319
304
|
options = {:missing_row => true, :surplus_row => true, :missing_col => true, :surplus_col => false}.merge(options)
|
320
305
|
|
321
306
|
other_table = ensure_table(other_table)
|
307
|
+
other_table.convert_headers!
|
322
308
|
other_table.convert_columns!
|
323
309
|
ensure_green!
|
310
|
+
|
311
|
+
convert_headers!
|
312
|
+
convert_columns!
|
324
313
|
|
325
314
|
original_width = cell_matrix[0].length
|
326
315
|
other_table_cell_matrix = pad!(other_table.cell_matrix)
|
@@ -331,7 +320,6 @@ module Cucumber
|
|
331
320
|
|
332
321
|
require_diff_lcs
|
333
322
|
cell_matrix.extend(Diff::LCS)
|
334
|
-
convert_columns!
|
335
323
|
changes = cell_matrix.diff(other_table_cell_matrix).flatten
|
336
324
|
|
337
325
|
inserted = 0
|
@@ -386,7 +374,8 @@ module Cucumber
|
|
386
374
|
hash[key.to_s] if key.is_a?(Symbol)
|
387
375
|
end
|
388
376
|
column_names.each_with_index do |column_name, column_index|
|
389
|
-
|
377
|
+
verify_column(column_name) if @conversion_procs[column_name][:strict]
|
378
|
+
value = @conversion_procs[column_name][:proc].call(cells.value(column_index))
|
390
379
|
hash[column_name] = value
|
391
380
|
end
|
392
381
|
hash
|
@@ -470,6 +459,14 @@ module Cucumber
|
|
470
459
|
|
471
460
|
protected
|
472
461
|
|
462
|
+
def build_hashes
|
463
|
+
convert_headers!
|
464
|
+
convert_columns!
|
465
|
+
cells_rows[1..-1].map do |row|
|
466
|
+
row.to_hash
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
473
470
|
def inspect_rows(missing_row, inserted_row) #:nodoc:
|
474
471
|
missing_row.each_with_index do |missing_cell, col|
|
475
472
|
inserted_cell = inserted_row[col]
|
@@ -490,14 +487,38 @@ module Cucumber
|
|
490
487
|
end
|
491
488
|
|
492
489
|
def convert_columns! #:nodoc:
|
490
|
+
@conversion_procs.each do |column_name, conversion_proc|
|
491
|
+
verify_column(column_name) if conversion_proc[:strict]
|
492
|
+
end
|
493
|
+
|
493
494
|
cell_matrix.transpose.each do |col|
|
494
|
-
|
495
|
+
column_name = col[0].value
|
496
|
+
conversion_proc = @conversion_procs[column_name][:proc]
|
495
497
|
col[1..-1].each do |cell|
|
496
498
|
cell.value = conversion_proc.call(cell.value)
|
497
499
|
end
|
498
500
|
end
|
499
501
|
end
|
500
502
|
|
503
|
+
def convert_headers! #:nodoc:
|
504
|
+
header_cells = cell_matrix[0]
|
505
|
+
|
506
|
+
if @header_conversion_proc
|
507
|
+
header_values = header_cells.map { |cell| cell.value } - @header_mappings.keys
|
508
|
+
@header_mappings = @header_mappings.merge(Hash[*header_values.zip(header_values.map(&@header_conversion_proc)).flatten])
|
509
|
+
end
|
510
|
+
|
511
|
+
@header_mappings.each_pair do |pre, post|
|
512
|
+
mapped_cells = header_cells.select { |cell| pre === cell.value }
|
513
|
+
raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
|
514
|
+
raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map { |c| c.value }.inspect}" if mapped_cells.length > 1
|
515
|
+
mapped_cells[0].value = post
|
516
|
+
if @conversion_procs.has_key?(pre)
|
517
|
+
@conversion_procs[post] = @conversion_procs.delete(pre)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
501
522
|
def require_diff_lcs #:nodoc:
|
502
523
|
begin
|
503
524
|
require 'diff/lcs'
|
data/lib/cucumber/cli/main.rb
CHANGED
data/lib/cucumber/cli/options.rb
CHANGED
@@ -271,6 +271,9 @@ module Cucumber
|
|
271
271
|
opts.on("--port PORT", "Specify DRb port. Ignored without --drb") do |port|
|
272
272
|
@options[:drb_port] = port
|
273
273
|
end
|
274
|
+
opts.on("--dotcucumber DIR", "Write metadata to DIR") do |dir|
|
275
|
+
@options[:dotcucumber] = dir
|
276
|
+
end
|
274
277
|
opts.on_tail("--version", "Show version.") do
|
275
278
|
@out_stream.puts Cucumber::VERSION
|
276
279
|
Kernel.exit(0)
|
data/lib/cucumber/constantize.rb
CHANGED
@@ -7,7 +7,7 @@ module Cucumber
|
|
7
7
|
names = camel_cased_word.split('::')
|
8
8
|
names.shift if names.empty? || names.first.empty?
|
9
9
|
|
10
|
-
constant = Object
|
10
|
+
constant = ::Object
|
11
11
|
names.each do |name|
|
12
12
|
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
13
13
|
end
|
@@ -47,7 +47,7 @@ module Cucumber
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
50
|
-
arguments = step_match.step_arguments.map{|a| Gherkin::Formatter::Argument.new(a.
|
50
|
+
arguments = step_match.step_arguments.map{|a| Gherkin::Formatter::Argument.new(a.offset, a.val)}
|
51
51
|
location = step_match.file_colon_line
|
52
52
|
match = Gherkin::Formatter::Model::Match.new(arguments, location)
|
53
53
|
if @print_emtpy_match
|
@@ -311,7 +311,7 @@ module Cucumber
|
|
311
311
|
@builder.tr do
|
312
312
|
@builder.td(:colspan => @col_index.to_s, :class => 'failed') do
|
313
313
|
@builder.pre do |pre|
|
314
|
-
pre << format_exception(table_row.exception)
|
314
|
+
pre << h(format_exception(table_row.exception))
|
315
315
|
end
|
316
316
|
end
|
317
317
|
end
|
@@ -378,6 +378,11 @@ module Cucumber
|
|
378
378
|
matches = message.match(/<code>([^(\/)]+)<\//m)
|
379
379
|
message = matches ? matches[1] : ""
|
380
380
|
end
|
381
|
+
|
382
|
+
unless exception.instance_of?(RuntimeError)
|
383
|
+
message << " (#{exception.class})"
|
384
|
+
end
|
385
|
+
|
381
386
|
@builder.pre do
|
382
387
|
@builder.text!(message)
|
383
388
|
end
|
@@ -22,9 +22,9 @@ module Cucumber
|
|
22
22
|
@file_colon_lines = Hash.new{|h,k| h[k] = []}
|
23
23
|
end
|
24
24
|
|
25
|
-
def before_feature(
|
25
|
+
def before_feature(feature_element)
|
26
26
|
@lines = []
|
27
|
-
@file =
|
27
|
+
@file = feature_element.file
|
28
28
|
end
|
29
29
|
|
30
30
|
def after_feature(*)
|
@@ -46,17 +46,40 @@ module Cucumber
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def after_feature_element(feature_element)
|
49
|
-
if @rerun
|
50
|
-
|
51
|
-
@lines << line
|
52
|
-
@file = file
|
49
|
+
if (@rerun || feature_element.failed?) && !(Ast::ScenarioOutline === feature_element)
|
50
|
+
@lines << feature_element.line
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
54
|
+
def after_table_row(table_row)
|
55
|
+
return unless @in_examples and Cucumber::Ast::OutlineTable::ExampleRow === table_row
|
56
|
+
unless @header_row
|
57
|
+
if table_row.failed?
|
58
|
+
@rerun = true
|
59
|
+
@lines << table_row.line
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
@header_row = false if @header_row
|
64
|
+
end
|
65
|
+
|
66
|
+
def before_examples(*args)
|
67
|
+
@header_row = true
|
68
|
+
@in_examples = true
|
69
|
+
end
|
70
|
+
|
71
|
+
def after_examples(*args)
|
72
|
+
@in_examples = false
|
73
|
+
end
|
74
|
+
|
75
|
+
def before_table_row(table_row)
|
76
|
+
return unless @in_examples
|
77
|
+
end
|
78
|
+
|
56
79
|
def step_name(keyword, step_match, status, source_indent, background)
|
57
80
|
@rerun = true if [:failed, :pending, :undefined].index(status)
|
58
81
|
end
|
59
|
-
|
82
|
+
|
60
83
|
private
|
61
84
|
|
62
85
|
def after_first_time
|
@@ -4,10 +4,6 @@ require 'cucumber/step_definition_light'
|
|
4
4
|
module Cucumber
|
5
5
|
module LanguageSupport
|
6
6
|
module LanguageMethods
|
7
|
-
def create_step_match(step_definition, step_name, name_to_report, step_arguments)
|
8
|
-
StepMatch.new(step_definition, step_name, name_to_report, step_arguments)
|
9
|
-
end
|
10
|
-
|
11
7
|
def around(scenario)
|
12
8
|
execute_around(scenario) do
|
13
9
|
yield
|
data/lib/cucumber/platform.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rbconfig'
|
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
unless defined?(Cucumber::VERSION)
|
7
|
-
VERSION = '1.1.
|
7
|
+
VERSION = '1.1.3'
|
8
8
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
9
9
|
LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
10
10
|
JRUBY = defined?(JRUBY_VERSION)
|
@@ -65,20 +65,6 @@ module Cucumber
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
# Gets called for each file under features (or whatever is overridden
|
69
|
-
# with --require).
|
70
|
-
def step_definitions_for(rb_file) # Looks Unused - Delete?
|
71
|
-
begin
|
72
|
-
require rb_file # This will cause self.add_step_definition and self.add_hook to be called from RbDsl
|
73
|
-
step_definitions
|
74
|
-
rescue LoadError => e
|
75
|
-
e.message << "\nFailed to load #{code_file}"
|
76
|
-
raise e
|
77
|
-
ensure
|
78
|
-
@step_definitions = nil
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
68
|
def step_matches(name_to_match, name_to_format)
|
83
69
|
@step_definitions.map do |step_definition|
|
84
70
|
if(arguments = step_definition.arguments_from(name_to_match))
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'gherkin/formatter/argument'
|
2
2
|
|
3
3
|
module Cucumber
|
4
4
|
module RbSupport
|
@@ -9,8 +9,8 @@ module Cucumber
|
|
9
9
|
n = 0
|
10
10
|
match.captures.map do |val|
|
11
11
|
n += 1
|
12
|
-
|
13
|
-
|
12
|
+
offset = match.offset(n)[0]
|
13
|
+
Gherkin::Formatter::Argument.new(offset, val)
|
14
14
|
end
|
15
15
|
else
|
16
16
|
nil
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
require 'gherkin/rubify'
|
2
3
|
require 'gherkin/i18n'
|
3
4
|
require 'cucumber/configuration'
|
@@ -118,6 +119,42 @@ module Cucumber
|
|
118
119
|
@support_code.unknown_programming_language?
|
119
120
|
end
|
120
121
|
|
122
|
+
def write_stepdefs_json
|
123
|
+
if(@configuration.dotcucumber)
|
124
|
+
stepdefs = []
|
125
|
+
@support_code.step_definitions.sort{|a,b| a.to_hash['source'] <=> a.to_hash['source']}.each do |stepdef|
|
126
|
+
stepdef_hash = stepdef.to_hash
|
127
|
+
steps = []
|
128
|
+
features.each do |feature|
|
129
|
+
feature.feature_elements.each do |feature_element|
|
130
|
+
feature_element.raw_steps.each do |step|
|
131
|
+
args = stepdef.arguments_from(step.name)
|
132
|
+
if(args)
|
133
|
+
steps << {
|
134
|
+
'name' => step.name,
|
135
|
+
'args' => args.map do |arg|
|
136
|
+
{
|
137
|
+
'offset' => arg.offset,
|
138
|
+
'val' => arg.val
|
139
|
+
}
|
140
|
+
end
|
141
|
+
}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
stepdef_hash['steps'] = steps.uniq.sort {|a,b| a['name'] <=> b['name']}
|
147
|
+
stepdefs << stepdef_hash
|
148
|
+
end
|
149
|
+
if !File.directory?(@configuration.dotcucumber)
|
150
|
+
FileUtils.mkdir_p(@configuration.dotcucumber)
|
151
|
+
end
|
152
|
+
File.open(File.join(@configuration.dotcucumber, 'stepdefs.json'), 'w') do |io|
|
153
|
+
io.write(JSON.pretty_generate(stepdefs))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
121
158
|
private
|
122
159
|
|
123
160
|
def fire_after_configuration_hook #:nodoc
|
@@ -125,11 +162,11 @@ module Cucumber
|
|
125
162
|
end
|
126
163
|
|
127
164
|
def features
|
128
|
-
loader
|
165
|
+
@loader ||= Runtime::FeaturesLoader.new(
|
129
166
|
@configuration.feature_files,
|
130
167
|
@configuration.filters,
|
131
168
|
@configuration.tag_expression)
|
132
|
-
loader.features
|
169
|
+
@loader.features
|
133
170
|
end
|
134
171
|
|
135
172
|
def load_step_definitions
|