cucumber 3.1.2 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1880 -1146
- data/CONTRIBUTING.md +220 -61
- data/README.md +143 -22
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +49 -53
- data/lib/autotest/discover.rb +3 -2
- data/lib/cucumber/cli/configuration.rb +32 -7
- data/lib/cucumber/cli/main.rb +16 -15
- data/lib/cucumber/cli/options.rb +111 -79
- data/lib/cucumber/cli/profile_loader.rb +45 -26
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/configuration.rb +47 -31
- data/lib/cucumber/constantize.rb +3 -6
- data/lib/cucumber/deprecate.rb +32 -7
- data/lib/cucumber/errors.rb +5 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
- data/lib/cucumber/events/hook_test_step_created.rb +12 -0
- data/lib/cucumber/events/step_activated.rb +0 -5
- data/lib/cucumber/events/step_definition_registered.rb +0 -5
- data/lib/cucumber/events/test_case_created.rb +12 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_run_finished.rb +2 -1
- data/lib/cucumber/events/test_step_created.rb +12 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +9 -0
- data/lib/cucumber/events.rb +15 -8
- data/lib/cucumber/file_specs.rb +8 -7
- data/lib/cucumber/filters/activate_steps.rb +6 -3
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/filters/prepare_world.rb +5 -9
- data/lib/cucumber/filters/quit.rb +1 -3
- data/lib/cucumber/filters/tag_limits/verifier.rb +3 -7
- data/lib/cucumber/filters/tag_limits.rb +1 -3
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +74 -86
- data/lib/cucumber/formatter/ast_lookup.rb +163 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -7
- data/lib/cucumber/formatter/console.rb +76 -68
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +12 -4
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +4 -1
- data/lib/cucumber/formatter/errors.rb +7 -0
- data/lib/cucumber/formatter/fanout.rb +3 -1
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +152 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -2
- data/lib/cucumber/formatter/interceptor.rb +11 -30
- data/lib/cucumber/formatter/io.rb +57 -13
- data/lib/cucumber/formatter/json.rb +119 -124
- data/lib/cucumber/formatter/junit.rb +75 -55
- data/lib/cucumber/formatter/message.rb +23 -0
- data/lib/cucumber/formatter/message_builder.rb +256 -0
- data/lib/cucumber/formatter/pretty.rb +370 -153
- data/lib/cucumber/formatter/progress.rb +31 -32
- data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +32 -0
- data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
- data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +42 -0
- data/lib/cucumber/formatter/rerun.rb +24 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +8 -6
- data/lib/cucumber/formatter/summary.rb +17 -8
- data/lib/cucumber/formatter/unicode.rb +18 -20
- data/lib/cucumber/formatter/url_reporter.rb +17 -0
- data/lib/cucumber/formatter/usage.rb +18 -15
- data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +14 -18
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +29 -15
- data/lib/cucumber/glue/hook.rb +37 -11
- data/lib/cucumber/glue/invoke_in_world.rb +17 -22
- data/lib/cucumber/glue/proto_world.rb +47 -53
- data/lib/cucumber/glue/registry_and_more.rb +62 -17
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +48 -23
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +12 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +4 -3
- data/lib/cucumber/multiline_argument/data_table.rb +143 -123
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +5 -5
- data/lib/cucumber/rake/task.rb +34 -25
- data/lib/cucumber/rspec/disable_option_parser.rb +15 -11
- data/lib/cucumber/rspec/doubles.rb +3 -5
- data/lib/cucumber/running_test_case.rb +3 -53
- data/lib/cucumber/runtime/after_hooks.rb +8 -4
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
- data/lib/cucumber/runtime/meta_message_builder.rb +106 -0
- data/lib/cucumber/runtime/step_hooks.rb +6 -2
- data/lib/cucumber/runtime/support_code.rb +16 -15
- data/lib/cucumber/runtime/user_interface.rb +10 -19
- data/lib/cucumber/runtime.rb +78 -76
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +17 -20
- data/lib/cucumber/step_match_search.rb +5 -3
- data/lib/cucumber/term/ansicolor.rb +72 -48
- data/lib/cucumber/term/banner.rb +57 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +3 -2
- data/lib/simplecov_setup.rb +1 -1
- metadata +279 -81
- data/lib/cucumber/core_ext/string.rb +0 -11
- data/lib/cucumber/events/gherkin_source_parsed.rb~ +0 -14
- data/lib/cucumber/formatter/ast_lookup.rb~ +0 -9
- data/lib/cucumber/formatter/cucumber.css +0 -286
- data/lib/cucumber/formatter/cucumber.sass +0 -247
- data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
- data/lib/cucumber/formatter/html_builder.rb +0 -121
- data/lib/cucumber/formatter/inline-js.js +0 -30
- data/lib/cucumber/formatter/jquery-min.js +0 -154
- data/lib/cucumber/formatter/json_pretty.rb +0 -11
- data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
- data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
- data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
- data/lib/cucumber/step_argument.rb +0 -25
@@ -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
|
-
|
32
|
-
|
33
|
-
def self.default_arg_name #:nodoc:
|
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,18 @@ 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::
|
81
|
-
# @param conversion_procs [Hash] see
|
82
|
-
# @param header_mappings [Hash] see map_headers
|
83
|
-
# @param header_conversion_proc [Proc] see map_headers
|
80
|
+
# @param data [Core::Test::DataTable] the data for the table
|
81
|
+
# @param conversion_procs [Hash] see map_column
|
82
|
+
# @param header_mappings [Hash] see map_headers
|
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
87
|
ast_table = data
|
87
88
|
# Verify that it's square
|
88
89
|
ast_table.transpose
|
@@ -107,13 +108,6 @@ module Cucumber
|
|
107
108
|
@ast_table.location
|
108
109
|
end
|
109
110
|
|
110
|
-
# Creates a copy of this table, inheriting any column and header mappings
|
111
|
-
# registered with #map_column! and #map_headers!.
|
112
|
-
#
|
113
|
-
def dup
|
114
|
-
self.class.new(Core::Ast::DataTable.new(raw, location), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
115
|
-
end
|
116
|
-
|
117
111
|
# Returns a new, transposed table. Example:
|
118
112
|
#
|
119
113
|
# | a | 7 | 4 |
|
@@ -126,7 +120,7 @@ module Cucumber
|
|
126
120
|
# | 4 | 2 |
|
127
121
|
#
|
128
122
|
def transpose
|
129
|
-
self.class.new(Core::
|
123
|
+
self.class.new(Core::Test::DataTable.new(raw.transpose), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
|
130
124
|
end
|
131
125
|
|
132
126
|
# Converts this table into an Array of Hash where the keys of each
|
@@ -141,7 +135,7 @@ module Cucumber
|
|
141
135
|
#
|
142
136
|
# [{'a' => '2', 'b' => '3', 'sum' => '5'}, {'a' => '7', 'b' => '9', 'sum' => '16'}]
|
143
137
|
#
|
144
|
-
# Use #map_column
|
138
|
+
# Use #map_column to specify how values in a column are converted.
|
145
139
|
#
|
146
140
|
def hashes
|
147
141
|
@hashes ||= build_hashes
|
@@ -160,8 +154,8 @@ module Cucumber
|
|
160
154
|
#
|
161
155
|
def symbolic_hashes
|
162
156
|
@symbolic_hashes ||=
|
163
|
-
|
164
|
-
|
157
|
+
hashes.map do |string_hash|
|
158
|
+
string_hash.transform_keys { |a| symbolize_key(a) }
|
165
159
|
end
|
166
160
|
end
|
167
161
|
|
@@ -179,8 +173,9 @@ module Cucumber
|
|
179
173
|
#
|
180
174
|
def rows_hash
|
181
175
|
return @rows_hash if @rows_hash
|
176
|
+
|
182
177
|
verify_table_width(2)
|
183
|
-
@rows_hash =
|
178
|
+
@rows_hash = transpose.hashes[0]
|
184
179
|
end
|
185
180
|
|
186
181
|
# Gets the raw data of this table. For example, a Table built from
|
@@ -199,8 +194,8 @@ module Cucumber
|
|
199
194
|
end
|
200
195
|
end
|
201
196
|
|
202
|
-
def column_names
|
203
|
-
@
|
197
|
+
def column_names # :nodoc:
|
198
|
+
@column_names ||= cell_matrix[0].map(&:value)
|
204
199
|
end
|
205
200
|
|
206
201
|
def rows
|
@@ -209,7 +204,7 @@ module Cucumber
|
|
209
204
|
end
|
210
205
|
end
|
211
206
|
|
212
|
-
def each_cells_row(&proc)
|
207
|
+
def each_cells_row(&proc) # :nodoc:
|
213
208
|
cells_rows.each(&proc)
|
214
209
|
end
|
215
210
|
|
@@ -228,7 +223,8 @@ module Cucumber
|
|
228
223
|
pattern.match(header_to_match)
|
229
224
|
end
|
230
225
|
|
231
|
-
#
|
226
|
+
# Returns a new Table where the headers are redefined.
|
227
|
+
# This makes it possible to use
|
232
228
|
# prettier and more flexible header names in the features. The
|
233
229
|
# keys of +mappings+ are Strings or regular expressions
|
234
230
|
# (anything that responds to #=== will work) that may match
|
@@ -244,57 +240,44 @@ module Cucumber
|
|
244
240
|
# A StepDefinition receiving this table can then map the columns
|
245
241
|
# with both Regexp and String:
|
246
242
|
#
|
247
|
-
# table.map_headers
|
243
|
+
# table.map_headers(/phone( number)?/i => :phone, 'Address' => :address)
|
248
244
|
# table.hashes
|
249
245
|
# # => [{:phone => '123456', :address => 'xyz'}, {:phone => '345678', :address => 'abc'}]
|
250
246
|
#
|
251
247
|
# You may also pass in a block if you wish to convert all of the headers:
|
252
248
|
#
|
253
|
-
# table.map_headers
|
249
|
+
# table.map_headers { |header| header.downcase }
|
254
250
|
# table.hashes.keys
|
255
251
|
# # => ['phone number', 'address']
|
256
252
|
#
|
257
253
|
# When a block is passed in along with a hash then the mappings in the hash take precendence:
|
258
254
|
#
|
259
|
-
# table.map_headers
|
255
|
+
# table.map_headers('Address' => 'ADDRESS') { |header| header.downcase }
|
260
256
|
# table.hashes.keys
|
261
257
|
# # => ['phone number', 'ADDRESS']
|
262
258
|
#
|
263
|
-
def map_headers!(mappings = {}, &block)
|
264
|
-
# TODO: Remove this method for 2.0
|
265
|
-
clear_cache!
|
266
|
-
@header_mappings = mappings
|
267
|
-
@header_conversion_proc = block
|
268
|
-
end
|
269
|
-
|
270
|
-
# Returns a new Table where the headers are redefined. See #map_headers!
|
271
259
|
def map_headers(mappings = {}, &block)
|
272
|
-
self.class.new(Core::
|
260
|
+
self.class.new(Core::Test::DataTable.new(raw), @conversion_procs.dup, mappings, block)
|
273
261
|
end
|
274
262
|
|
263
|
+
# Returns a new Table with an additional column mapping.
|
264
|
+
#
|
275
265
|
# Change how #hashes converts column values. The +column_name+ argument identifies the column
|
276
266
|
# and +conversion_proc+ performs the conversion for each cell in that column. If +strict+ is
|
277
267
|
# true, an error will be raised if the column named +column_name+ is not found. If +strict+
|
278
268
|
# is false, no error will be raised. Example:
|
279
269
|
#
|
280
270
|
# Given /^an expense report for (.*) with the following posts:$/ do |table|
|
281
|
-
# posts_table.map_column
|
271
|
+
# posts_table = posts_table.map_column('amount') { |a| a.to_i }
|
282
272
|
# posts_table.hashes.each do |post|
|
283
273
|
# # post['amount'] is a Fixnum, rather than a String
|
284
274
|
# end
|
285
275
|
# end
|
286
276
|
#
|
287
|
-
def map_column
|
288
|
-
# TODO: Remove this method for 2.0
|
289
|
-
@conversion_procs[column_name.to_s] = { :strict => strict, :proc => conversion_proc }
|
290
|
-
self
|
291
|
-
end
|
292
|
-
|
293
|
-
# Returns a new Table with an additional column mapping. See #map_column!
|
294
|
-
def map_column(column_name, strict = true, &conversion_proc)
|
277
|
+
def map_column(column_name, strict: true, &conversion_proc)
|
295
278
|
conversion_procs = @conversion_procs.dup
|
296
|
-
conversion_procs[column_name.to_s] = { :
|
297
|
-
self.class.new(Core::
|
279
|
+
conversion_procs[column_name.to_s] = { strict: strict, proc: conversion_proc }
|
280
|
+
self.class.new(Core::Test::DataTable.new(raw), conversion_procs, @header_mappings.dup, @header_conversion_proc)
|
298
281
|
end
|
299
282
|
|
300
283
|
# Compares +other_table+ to self. If +other_table+ contains columns
|
@@ -312,8 +295,8 @@ module Cucumber
|
|
312
295
|
# where the difference actually is.
|
313
296
|
#
|
314
297
|
# Since all tables that are passed to StepDefinitions always have String
|
315
|
-
# objects in their cells, you may want to use #map_column
|
316
|
-
# #diff!. You can use #map_column
|
298
|
+
# objects in their cells, you may want to use #map_column before calling
|
299
|
+
# #diff!. You can use #map_column on either of the tables.
|
317
300
|
#
|
318
301
|
# A Different error is raised if there are missing rows or columns, or
|
319
302
|
# surplus rows. An error is <em>not</em> raised for surplus columns. An
|
@@ -346,15 +329,20 @@ module Cucumber
|
|
346
329
|
|
347
330
|
class Different < StandardError
|
348
331
|
attr_reader :table
|
332
|
+
|
349
333
|
def initialize(table)
|
350
334
|
@table = table
|
351
335
|
super("Tables were not identical:\n#{table}")
|
352
336
|
end
|
353
337
|
end
|
354
338
|
|
355
|
-
def to_hash
|
356
|
-
|
357
|
-
|
339
|
+
def to_hash
|
340
|
+
cells_rows.map { |cells| cells.map(&:value) }
|
341
|
+
end
|
342
|
+
|
343
|
+
def cells_to_hash(cells) # :nodoc:
|
344
|
+
hash = Hash.new do |hash_inner, key|
|
345
|
+
hash_inner[key.to_s] if key.is_a?(Symbol)
|
358
346
|
end
|
359
347
|
column_names.each_with_index do |column_name, column_index|
|
360
348
|
hash[column_name] = cells.value(column_index)
|
@@ -362,66 +350,90 @@ module Cucumber
|
|
362
350
|
hash
|
363
351
|
end
|
364
352
|
|
365
|
-
def index(cells)
|
353
|
+
def index(cells) # :nodoc:
|
366
354
|
cells_rows.index(cells)
|
367
355
|
end
|
368
356
|
|
369
|
-
def verify_column(column_name)
|
370
|
-
raise %
|
357
|
+
def verify_column(column_name) # :nodoc:
|
358
|
+
raise %(The column named "#{column_name}" does not exist) unless raw[0].include?(column_name)
|
371
359
|
end
|
372
360
|
|
373
|
-
def verify_table_width(width)
|
374
|
-
raise %
|
361
|
+
def verify_table_width(width) # :nodoc:
|
362
|
+
raise %(The table must have exactly #{width} columns) unless raw[0].size == width
|
375
363
|
end
|
376
364
|
|
377
|
-
|
365
|
+
# TODO: remove the below function if it's not actually being used.
|
366
|
+
# Nothing else in this repo calls it.
|
367
|
+
def text?(text) # :nodoc:
|
378
368
|
raw.flatten.compact.detect { |cell_value| cell_value.index(text) }
|
379
369
|
end
|
380
370
|
|
381
|
-
def cells_rows
|
382
|
-
@rows ||= cell_matrix.map do |cell_row|
|
371
|
+
def cells_rows # :nodoc:
|
372
|
+
@rows ||= cell_matrix.map do |cell_row| # rubocop:disable Naming/MemoizedInstanceVariableName
|
383
373
|
Cells.new(self, cell_row)
|
384
374
|
end
|
385
375
|
end
|
386
376
|
|
387
|
-
def headers
|
377
|
+
def headers # :nodoc:
|
388
378
|
raw.first
|
389
379
|
end
|
390
380
|
|
391
|
-
def header_cell(col)
|
381
|
+
def header_cell(col) # :nodoc:
|
392
382
|
cells_rows[0][col]
|
393
383
|
end
|
394
384
|
|
395
385
|
attr_reader :cell_matrix
|
396
386
|
|
397
|
-
def col_width(col)
|
387
|
+
def col_width(col) # :nodoc:
|
398
388
|
columns[col].__send__(:width)
|
399
389
|
end
|
400
390
|
|
401
|
-
def to_s(options = {})
|
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
|
391
|
+
def to_s(options = {}) # :nodoc:
|
392
|
+
indentation = options.key?(:indent) ? options[:indent] : 2
|
393
|
+
prefixes = options.key?(:prefixes) ? options[:prefixes] : TO_S_PREFIXES
|
394
|
+
DataTablePrinter.new(self, indentation, prefixes).to_s
|
418
395
|
end
|
419
396
|
|
420
|
-
|
421
|
-
|
397
|
+
class DataTablePrinter # :nodoc:
|
398
|
+
include Cucumber::Gherkin::Formatter::Escaping
|
399
|
+
attr_reader :data_table, :indentation, :prefixes
|
400
|
+
private :data_table, :indentation, :prefixes
|
401
|
+
|
402
|
+
def initialize(data_table, indentation, prefixes)
|
403
|
+
@data_table = data_table
|
404
|
+
@indentation = indentation
|
405
|
+
@prefixes = prefixes
|
406
|
+
end
|
407
|
+
|
408
|
+
def to_s
|
409
|
+
leading_row = "\n"
|
410
|
+
end_indentation = indentation - 2
|
411
|
+
trailing_row = "\n#{' ' * end_indentation}"
|
412
|
+
table_rows = data_table.cell_matrix.map { |row| format_row(row) }
|
413
|
+
leading_row + table_rows.join("\n") + trailing_row
|
414
|
+
end
|
415
|
+
|
416
|
+
private
|
417
|
+
|
418
|
+
def format_row(row)
|
419
|
+
row_start = "#{' ' * indentation}| "
|
420
|
+
row_end = '|'
|
421
|
+
cells = row.map.with_index do |cell, i|
|
422
|
+
format_cell(cell, data_table.col_width(i))
|
423
|
+
end
|
424
|
+
row_start + cells.join('| ') + row_end
|
425
|
+
end
|
426
|
+
|
427
|
+
def format_cell(cell, col_width)
|
428
|
+
cell_text = escape_cell(cell.value.to_s)
|
429
|
+
cell_text_width = cell_text.unpack('U*').length
|
430
|
+
padded_text = cell_text + (' ' * (col_width - cell_text_width))
|
431
|
+
prefix = prefixes[cell.status]
|
432
|
+
"#{prefix}#{padded_text} "
|
433
|
+
end
|
422
434
|
end
|
423
435
|
|
424
|
-
def columns
|
436
|
+
def columns # :nodoc:
|
425
437
|
@columns ||= cell_matrix.transpose.map do |cell_row|
|
426
438
|
Cells.new(self, cell_row)
|
427
439
|
end
|
@@ -441,19 +453,23 @@ module Cucumber
|
|
441
453
|
def build_hashes
|
442
454
|
convert_headers!
|
443
455
|
convert_columns!
|
444
|
-
cells_rows[1
|
456
|
+
cells_rows[1..].map(&:to_hash)
|
445
457
|
end
|
446
458
|
|
447
|
-
def create_cell_matrix(ast_table)
|
459
|
+
def create_cell_matrix(ast_table) # :nodoc:
|
448
460
|
ast_table.raw.map do |raw_row|
|
449
|
-
line =
|
461
|
+
line = begin
|
462
|
+
raw_row.line
|
463
|
+
rescue StandardError
|
464
|
+
-1
|
465
|
+
end
|
450
466
|
raw_row.map do |raw_cell|
|
451
467
|
Cell.new(raw_cell, self, line)
|
452
468
|
end
|
453
469
|
end
|
454
470
|
end
|
455
471
|
|
456
|
-
def convert_columns!
|
472
|
+
def convert_columns! # :nodoc:
|
457
473
|
@conversion_procs.each do |column_name, conversion_proc|
|
458
474
|
verify_column(column_name) if conversion_proc[:strict]
|
459
475
|
end
|
@@ -461,13 +477,13 @@ module Cucumber
|
|
461
477
|
cell_matrix.transpose.each do |col|
|
462
478
|
column_name = col[0].value
|
463
479
|
conversion_proc = @conversion_procs[column_name][:proc]
|
464
|
-
col[1
|
480
|
+
col[1..].each do |cell|
|
465
481
|
cell.value = conversion_proc.call(cell.value)
|
466
482
|
end
|
467
483
|
end
|
468
484
|
end
|
469
485
|
|
470
|
-
def convert_headers!
|
486
|
+
def convert_headers! # :nodoc:
|
471
487
|
header_cells = cell_matrix[0]
|
472
488
|
|
473
489
|
if @header_conversion_proc
|
@@ -476,22 +492,22 @@ module Cucumber
|
|
476
492
|
end
|
477
493
|
|
478
494
|
@header_mappings.each_pair do |pre, post|
|
479
|
-
mapped_cells = header_cells.select { |cell| pre
|
495
|
+
mapped_cells = header_cells.select { |cell| pre.is_a?(Regexp) ? cell.value.match?(pre) : cell.value == pre }
|
480
496
|
raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
|
481
497
|
raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map(&:value).inspect}" if mapped_cells.length > 1
|
498
|
+
|
482
499
|
mapped_cells[0].value = post
|
483
|
-
if @conversion_procs.key?(pre)
|
484
|
-
@conversion_procs[post] = @conversion_procs.delete(pre)
|
485
|
-
end
|
500
|
+
@conversion_procs[post] = @conversion_procs.delete(pre) if @conversion_procs.key?(pre)
|
486
501
|
end
|
487
502
|
end
|
488
503
|
|
489
|
-
def clear_cache!
|
490
|
-
@hashes = @rows_hash = @
|
504
|
+
def clear_cache! # :nodoc:
|
505
|
+
@hashes = @rows_hash = @column_names = @rows = @columns = nil
|
491
506
|
end
|
492
507
|
|
493
|
-
def ensure_table(table_or_array)
|
494
|
-
return table_or_array if DataTable
|
508
|
+
def ensure_table(table_or_array) # :nodoc:
|
509
|
+
return table_or_array if DataTable == table_or_array.class
|
510
|
+
|
495
511
|
DataTable.from(table_or_array)
|
496
512
|
end
|
497
513
|
|
@@ -500,18 +516,20 @@ module Cucumber
|
|
500
516
|
end
|
501
517
|
|
502
518
|
# Represents a row of cells or columns of cells
|
503
|
-
class Cells
|
519
|
+
class Cells # :nodoc:
|
504
520
|
include Enumerable
|
505
521
|
include Cucumber::Gherkin::Formatter::Escaping
|
506
522
|
|
507
523
|
attr_reader :exception
|
508
524
|
|
509
525
|
def initialize(table, cells)
|
510
|
-
@table
|
526
|
+
@table = table
|
527
|
+
@cells = cells
|
511
528
|
end
|
512
529
|
|
513
530
|
def accept(visitor)
|
514
531
|
return if Cucumber.wants_to_quit
|
532
|
+
|
515
533
|
each do |cell|
|
516
534
|
visitor.visit_table_cell(cell)
|
517
535
|
end
|
@@ -519,15 +537,15 @@ module Cucumber
|
|
519
537
|
end
|
520
538
|
|
521
539
|
# For testing only
|
522
|
-
def to_sexp
|
540
|
+
def to_sexp # :nodoc:
|
523
541
|
[:row, line, *@cells.map(&:to_sexp)]
|
524
542
|
end
|
525
543
|
|
526
|
-
def to_hash
|
527
|
-
@to_hash ||= @table.
|
544
|
+
def to_hash # :nodoc:
|
545
|
+
@to_hash ||= @table.cells_to_hash(self)
|
528
546
|
end
|
529
547
|
|
530
|
-
def value(n)
|
548
|
+
def value(n) # :nodoc:
|
531
549
|
self[n].value
|
532
550
|
end
|
533
551
|
|
@@ -558,24 +576,26 @@ module Cucumber
|
|
558
576
|
end
|
559
577
|
end
|
560
578
|
|
561
|
-
class Cell
|
579
|
+
class Cell # :nodoc:
|
562
580
|
attr_reader :line, :table
|
563
581
|
attr_accessor :status, :value
|
564
582
|
|
565
583
|
def initialize(value, table, line)
|
566
|
-
@value
|
584
|
+
@value = value
|
585
|
+
@table = table
|
586
|
+
@line = line
|
567
587
|
end
|
568
588
|
|
569
589
|
def inspect!
|
570
590
|
@value = "(i) #{value.inspect}"
|
571
591
|
end
|
572
592
|
|
573
|
-
def ==(
|
574
|
-
SurplusCell
|
593
|
+
def ==(other)
|
594
|
+
SurplusCell == other.class || value == other.value
|
575
595
|
end
|
576
596
|
|
577
|
-
def eql?(
|
578
|
-
self ==
|
597
|
+
def eql?(other)
|
598
|
+
self == other
|
579
599
|
end
|
580
600
|
|
581
601
|
def hash
|
@@ -583,17 +603,17 @@ module Cucumber
|
|
583
603
|
end
|
584
604
|
|
585
605
|
# For testing only
|
586
|
-
def to_sexp
|
606
|
+
def to_sexp # :nodoc:
|
587
607
|
[:cell, @value]
|
588
608
|
end
|
589
609
|
end
|
590
610
|
|
591
|
-
class SurplusCell < Cell
|
611
|
+
class SurplusCell < Cell # :nodoc:
|
592
612
|
def status
|
593
613
|
:comment
|
594
614
|
end
|
595
615
|
|
596
|
-
def ==(
|
616
|
+
def ==(_other)
|
597
617
|
true
|
598
618
|
end
|
599
619
|
|
@@ -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,9 +7,9 @@ require 'cucumber/core/platform'
|
|
7
7
|
|
8
8
|
module Cucumber
|
9
9
|
unless defined?(Cucumber::VERSION)
|
10
|
-
VERSION = File.read(File.expand_path('
|
11
|
-
BINARY = File.expand_path(File.dirname(__FILE__)
|
12
|
-
LIBDIR = File.expand_path(File.dirname(__FILE__)
|
10
|
+
VERSION = File.read(File.expand_path('version', __dir__)).strip
|
11
|
+
BINARY = File.expand_path("#{File.dirname(__FILE__)}/../../bin/cucumber")
|
12
|
+
LIBDIR = File.expand_path("#{File.dirname(__FILE__)}/../../lib")
|
13
13
|
RAILS = defined?(Rails)
|
14
14
|
RUBY_BINARY = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
15
15
|
RUBY = defined? RUBY_VERSION
|
@@ -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
|