cucumber 3.2.0 → 5.2.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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +280 -19
  3. data/CONTRIBUTING.md +11 -25
  4. data/README.md +4 -5
  5. data/bin/cucumber +1 -1
  6. data/lib/autotest/cucumber_mixin.rb +46 -53
  7. data/lib/cucumber/cli/configuration.rb +5 -5
  8. data/lib/cucumber/cli/main.rb +12 -12
  9. data/lib/cucumber/cli/options.rb +90 -73
  10. data/lib/cucumber/cli/profile_loader.rb +49 -26
  11. data/lib/cucumber/configuration.rb +44 -29
  12. data/lib/cucumber/constantize.rb +2 -5
  13. data/lib/cucumber/deprecate.rb +31 -7
  14. data/lib/cucumber/errors.rb +5 -7
  15. data/lib/cucumber/events/envelope.rb +9 -0
  16. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  17. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  18. data/lib/cucumber/events/step_activated.rb +2 -1
  19. data/lib/cucumber/events/test_case_created.rb +13 -0
  20. data/lib/cucumber/events/test_case_ready.rb +12 -0
  21. data/lib/cucumber/events/test_step_created.rb +13 -0
  22. data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
  23. data/lib/cucumber/events.rb +13 -6
  24. data/lib/cucumber/file_specs.rb +6 -6
  25. data/lib/cucumber/filters/activate_steps.rb +5 -3
  26. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  27. data/lib/cucumber/filters/prepare_world.rb +5 -9
  28. data/lib/cucumber/filters/quit.rb +1 -3
  29. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
  30. data/lib/cucumber/filters.rb +1 -0
  31. data/lib/cucumber/formatter/ansicolor.rb +40 -45
  32. data/lib/cucumber/formatter/ast_lookup.rb +163 -0
  33. data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
  34. data/lib/cucumber/formatter/console.rb +58 -66
  35. data/lib/cucumber/formatter/console_counts.rb +4 -9
  36. data/lib/cucumber/formatter/console_issues.rb +6 -3
  37. data/lib/cucumber/formatter/duration.rb +1 -1
  38. data/lib/cucumber/formatter/duration_extractor.rb +3 -1
  39. data/lib/cucumber/formatter/errors.rb +6 -0
  40. data/lib/cucumber/formatter/fanout.rb +2 -0
  41. data/lib/cucumber/formatter/html.rb +11 -598
  42. data/lib/cucumber/formatter/http_io.rb +43 -42
  43. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  44. data/lib/cucumber/formatter/interceptor.rb +11 -30
  45. data/lib/cucumber/formatter/io.rb +46 -10
  46. data/lib/cucumber/formatter/json.rb +102 -116
  47. data/lib/cucumber/formatter/junit.rb +55 -55
  48. data/lib/cucumber/formatter/message.rb +22 -0
  49. data/lib/cucumber/formatter/message_builder.rb +255 -0
  50. data/lib/cucumber/formatter/pretty.rb +359 -153
  51. data/lib/cucumber/formatter/progress.rb +30 -32
  52. data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
  53. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  54. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  55. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  56. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  57. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  58. data/lib/cucumber/formatter/rerun.rb +22 -4
  59. data/lib/cucumber/formatter/stepdefs.rb +1 -2
  60. data/lib/cucumber/formatter/steps.rb +3 -4
  61. data/lib/cucumber/formatter/summary.rb +16 -8
  62. data/lib/cucumber/formatter/unicode.rb +15 -17
  63. data/lib/cucumber/formatter/url_reporter.rb +17 -0
  64. data/lib/cucumber/formatter/usage.rb +11 -10
  65. data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
  66. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
  67. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
  68. data/lib/cucumber/gherkin/steps_parser.rb +17 -8
  69. data/lib/cucumber/glue/hook.rb +34 -11
  70. data/lib/cucumber/glue/invoke_in_world.rb +13 -18
  71. data/lib/cucumber/glue/proto_world.rb +42 -33
  72. data/lib/cucumber/glue/registry_and_more.rb +42 -12
  73. data/lib/cucumber/glue/snippet.rb +23 -22
  74. data/lib/cucumber/glue/step_definition.rb +42 -19
  75. data/lib/cucumber/glue/world_factory.rb +1 -1
  76. data/lib/cucumber/hooks.rb +11 -11
  77. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +2 -2
  78. data/lib/cucumber/multiline_argument/data_table.rb +97 -64
  79. data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
  80. data/lib/cucumber/multiline_argument.rb +4 -6
  81. data/lib/cucumber/platform.rb +3 -3
  82. data/lib/cucumber/rake/task.rb +16 -18
  83. data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
  84. data/lib/cucumber/rspec/doubles.rb +3 -5
  85. data/lib/cucumber/running_test_case.rb +2 -53
  86. data/lib/cucumber/runtime/after_hooks.rb +8 -4
  87. data/lib/cucumber/runtime/before_hooks.rb +8 -4
  88. data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
  89. data/lib/cucumber/runtime/step_hooks.rb +6 -2
  90. data/lib/cucumber/runtime/support_code.rb +13 -15
  91. data/lib/cucumber/runtime/user_interface.rb +6 -16
  92. data/lib/cucumber/runtime.rb +41 -58
  93. data/lib/cucumber/step_definition_light.rb +4 -3
  94. data/lib/cucumber/step_definitions.rb +2 -2
  95. data/lib/cucumber/step_match.rb +12 -11
  96. data/lib/cucumber/step_match_search.rb +2 -1
  97. data/lib/cucumber/term/ansicolor.rb +9 -9
  98. data/lib/cucumber/term/banner.rb +56 -0
  99. data/lib/cucumber/version +1 -1
  100. data/lib/cucumber.rb +1 -1
  101. metadata +253 -80
  102. data/lib/cucumber/formatter/cucumber.css +0 -286
  103. data/lib/cucumber/formatter/cucumber.sass +0 -247
  104. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  105. data/lib/cucumber/formatter/html_builder.rb +0 -121
  106. data/lib/cucumber/formatter/inline-js.js +0 -30
  107. data/lib/cucumber/formatter/jquery-min.js +0 -154
  108. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  109. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  110. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  111. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  112. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  113. data/lib/cucumber/step_argument.rb +0 -25
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'cucumber/step_match'
4
- require 'cucumber/step_argument'
5
4
  require 'cucumber/core_ext/string'
6
5
  require 'cucumber/glue/invoke_in_world'
7
6
 
@@ -25,9 +24,9 @@ module Cucumber
25
24
  end
26
25
 
27
26
  class << self
28
- def new(registry, string_or_regexp, proc_or_sym, options)
27
+ def new(id, registry, string_or_regexp, proc_or_sym, options)
29
28
  raise MissingProc if proc_or_sym.nil?
30
- super registry, registry.create_expression(string_or_regexp), create_proc(proc_or_sym, options)
29
+ super id, registry, registry.create_expression(string_or_regexp), create_proc(proc_or_sym, options)
31
30
  end
32
31
 
33
32
  private
@@ -44,33 +43,59 @@ module Cucumber
44
43
  end
45
44
 
46
45
  def patch_location_onto(block)
47
- location = Core::Ast::Location.of_caller(5)
46
+ location = Core::Test::Location.of_caller(5)
48
47
  block.define_singleton_method(:source_location) { [location.file, location.line] }
49
48
  block
50
49
  end
51
50
 
52
51
  def parse_target_proc_from(options)
53
- return lambda { self } unless options.key?(:on)
52
+ return -> { self } unless options.key?(:on)
54
53
  target = options[:on]
55
54
  case target
56
55
  when Proc
57
56
  target
58
57
  when Symbol
59
- lambda { self.send(target) }
58
+ -> { send(target) }
60
59
  else
61
- lambda { raise ArgumentError, 'Target must be a symbol or a proc' }
60
+ -> { raise ArgumentError, 'Target must be a symbol or a proc' }
62
61
  end
63
62
  end
64
63
  end
65
64
 
66
- attr_reader :expression, :registry
65
+ attr_reader :id, :expression, :registry
67
66
 
68
- def initialize(registry, expression, proc)
67
+ def initialize(id, registry, expression, proc)
69
68
  raise 'No regexp' if expression.is_a?(Regexp)
70
- @registry, @expression, @proc = registry, expression, proc
69
+ @id = id
70
+ @registry = registry
71
+ @expression = expression
72
+ @proc = proc
71
73
  # @registry.available_step_definition(regexp_source, location)
72
74
  end
73
75
 
76
+ def to_envelope
77
+ Cucumber::Messages::Envelope.new(
78
+ step_definition: Cucumber::Messages::StepDefinition.new(
79
+ id: id,
80
+ pattern: Cucumber::Messages::StepDefinition::StepDefinitionPattern.new(
81
+ source: expression.source.to_s,
82
+ type: expression_type
83
+ ),
84
+ source_reference: Cucumber::Messages::SourceReference.new(
85
+ uri: location.file,
86
+ location: Cucumber::Messages::Location.new(
87
+ line: location.lines.first
88
+ )
89
+ )
90
+ )
91
+ )
92
+ end
93
+
94
+ def expression_type
95
+ return Cucumber::Messages::StepDefinition::StepDefinitionPattern::StepDefinitionPatternType::CUCUMBER_EXPRESSION if expression.is_a?(CucumberExpressions::CucumberExpression)
96
+ Cucumber::Messages::StepDefinition::StepDefinitionPattern::StepDefinitionPatternType::REGULAR_EXPRESSION
97
+ end
98
+
74
99
  # @api private
75
100
  def to_hash
76
101
  type = expression.is_a?(CucumberExpressions::RegularExpression) ? 'regular expression' : 'cucumber expression'
@@ -92,8 +117,8 @@ module Cucumber
92
117
  end
93
118
 
94
119
  # @api private
95
- def ==(step_definition)
96
- expression.source == step_definition.expression.source
120
+ def ==(other)
121
+ expression.source == other.expression.source
97
122
  end
98
123
 
99
124
  # @api private
@@ -106,12 +131,10 @@ module Cucumber
106
131
  # @api private
107
132
  # TODO: inline this and step definition just be a value object
108
133
  def invoke(args)
109
- begin
110
- InvokeInWorld.cucumber_instance_exec_in(@registry.current_world, true, @expression.to_s, *args, &@proc)
111
- rescue ArityMismatchError => e
112
- e.backtrace.unshift(self.backtrace_line)
113
- raise e
114
- end
134
+ InvokeInWorld.cucumber_instance_exec_in(@registry.current_world, true, @expression.to_s, *args, &@proc)
135
+ rescue ArityMismatchError => e
136
+ e.backtrace.unshift(backtrace_line)
137
+ raise e
115
138
  end
116
139
 
117
140
  # @api private
@@ -131,7 +154,7 @@ module Cucumber
131
154
 
132
155
  # The source location where the step definition can be found
133
156
  def location
134
- @location ||= Cucumber::Core::Ast::Location.from_source_location(*@proc.source_location)
157
+ @location ||= Cucumber::Core::Test::Location.from_source_location(*@proc.source_location)
135
158
  end
136
159
 
137
160
  # @api private
@@ -10,7 +10,7 @@ module Cucumber
10
10
  end
11
11
 
12
12
  def raise_nil_world
13
- raise NilWorld.new
13
+ raise NilWorld
14
14
  rescue NilWorld => e
15
15
  e.backtrace.clear
16
16
  e.backtrace.push(Glue.backtrace_line(@proc, 'World'))
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
- require 'cucumber/core/ast/location'
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(source, location, &block)
13
- build_hook_step(source, location, block, BeforeHook, Core::Test::UnskippableAction)
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(source, location, &block)
17
- build_hook_step(source, location, block, AfterHook, Core::Test::UnskippableAction)
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(source, location, &block)
21
- raise ArgumentError unless source.last.is_a?(Core::Ast::Step)
22
- build_hook_step(source, location, block, AfterStepHook, Core::Test::Action)
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(_source, &block)
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(source, location, block, hook_type, action_type)
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::Step.new(source + [hook], action)
34
+ Core::Test::HookStep.new(id, hook.text, location, action)
35
35
  end
36
36
  end
37
37
 
@@ -95,7 +95,7 @@ module Cucumber
95
95
  def changes
96
96
  require 'diff/lcs'
97
97
  diffable_cell_matrix = cell_matrix.dup.extend(::Diff::LCS)
98
- diffable_cell_matrix.diff(other_table_cell_matrix).flatten
98
+ diffable_cell_matrix.diff(other_table_cell_matrix).flatten(1)
99
99
  end
100
100
 
101
101
  def inspect_rows(missing_row, inserted_row)
@@ -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.new(table) if should_raise?
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, location = Core::Ast::Location.of_caller)
39
+ def from(data)
39
40
  case data
40
41
  when Array
41
- from_array(data, location)
42
+ from_array(data)
42
43
  when String
43
- parse(data, location)
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, location = Core::Ast::Location.of_caller)
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, location)
56
+ from_array(builder.rows)
56
57
  end
57
58
 
58
- def from_array(data, location = Core::Ast::Location.of_caller)
59
- new Core::Ast::DataTable.new(data, location)
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({ :strict => false, :proc => lambda { |cell_value| cell_value } }).freeze
78
+ NULL_CONVERSIONS = Hash.new(strict: false, proc: ->(cell_value) { cell_value }).freeze
79
79
 
80
- # @param data [Core::Ast::DataTable] the data for the table
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::Ast::DataTable' unless data.is_a? Core::Ast::DataTable
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::Ast::DataTable.new(raw, location), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
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::Ast::DataTable.new(raw.transpose, location), @conversion_procs.dup, @header_mappings.dup, @header_conversion_proc)
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
- self.hashes.map do |string_hash|
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 = self.transpose.hashes[0]
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
- @col_names ||= cell_matrix[0].map(&:value)
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::Ast::DataTable.new(raw, location), @conversion_procs.dup, mappings, block)
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] = { :strict => strict, :proc => conversion_proc }
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] = { :strict => strict, :proc => conversion_proc }
297
- self.class.new(Core::Ast::DataTable.new(raw, location), conversion_procs, @header_mappings.dup, @header_conversion_proc)
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(cells) #:nodoc:
356
- hash = Hash.new do |hash, key|
357
- hash[key.to_s] if key.is_a?(Symbol)
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 %{The column named "#{column_name}" does not exist} unless raw[0].include?(column_name)
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 %{The table must have exactly #{width} columns} unless raw[0].size == width
378
+ raise %(The table must have exactly #{width} columns) unless raw[0].size == width
375
379
  end
376
380
 
377
- def has_text?(text) #:nodoc:
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
- # TODO: factor out this code so we don't depend on such a big lump of old cruft
403
- require 'cucumber/formatter/pretty'
404
- require 'cucumber/formatter/legacy_api/adapter'
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
- def description_for_visitors
421
- :legacy_table
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 = raw_row.line rescue -1
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.select { |cell| pre === cell.value }
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 = @col_names = @rows = @columns = nil
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 === table_or_array
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, @cells = table, cells
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.to_hash(self)
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, @table, @line = value, table, line
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 ==(o)
574
- SurplusCell === o || value == o.value
606
+ def ==(other)
607
+ SurplusCell == other.class || value == other.value
575
608
  end
576
609
 
577
- def eql?(o)
578
- self == o
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 ==(_o)
629
+ def ==(_other)
597
630
  true
598
631
  end
599
632
 
@@ -4,7 +4,7 @@ module Cucumber
4
4
  module MultilineArgument
5
5
  class DocString < SimpleDelegator
6
6
  def append_to(array)
7
- array << self.to_s
7
+ array << to_s
8
8
  end
9
9
  end
10
10
  end
@@ -12,10 +12,10 @@ module Cucumber
12
12
  end
13
13
 
14
14
  def from(argument, location = nil, content_type = nil)
15
- location ||= Core::Ast::Location.of_caller
15
+ location ||= Core::Test::Location.of_caller
16
16
  case argument
17
17
  when String
18
- builder.doc_string(Core::Ast::DocString.new(argument, content_type, location))
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
@@ -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('../version', __FILE__))
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(m, encoding = 'UTF-8')
22
- "#{m}:#{encoding}"
21
+ def file_mode(mode, encoding = 'UTF-8')
22
+ "#{mode}:#{encoding}"
23
23
  end
24
24
  end
25
25
  self.use_full_backtrace = false