Class: Cucumber::Core::Ast::DataTable

Inherits:
Object
  • Object
show all
Includes:
DescribesItself, HasLocation, Gherkin::Rubify
Defined in:
lib/cucumber/core/ast/data_table.rb

Overview

Step Definitions that match a plain text Step with a multiline argument table will receive it as an instance of DataTable. A DataTable object holds the data of a table parsed from a feature file and lets you access and manipulate the data in different ways.

For example:

Given I have:
  | a | b |
  | c | d |

And a matching StepDefinition:

Given /I have:/ do |table|
  data = table.raw
end

This will store [['a', 'b'], ['c', 'd']] in the data variable.

Defined Under Namespace

Classes: Builder, Cell, Cells

Constant Summary collapse

NULL_CONVERSIONS =
Hash.new({ :strict => false, :proc => lambda{ |cell_value| cell_value } }).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasLocation

#attributes, #comments, #file_colon_line, #line, #location, #match_locations?, #multiline_arg, #tags

Methods included from DescribesItself

#describe_to

Constructor Details

#initialize(raw, location) ⇒ DataTable

Creates a new instance. raw should be an Array of Array of String or an Array of Hash You don’t typically create your own DataTable objects - Cucumber will do it internally and pass them to your Step Definitions.



66
67
68
69
70
71
72
73
74
# File 'lib/cucumber/core/ast/data_table.rb', line 66

def initialize(raw, location)
  @cells_class = Cells
  @cell_class = Cell
  raw = ensure_array_of_array(rubify(raw))
  # Verify that it's square
  raw.transpose
  create_cell_matrix(raw)
  @location = location
end

Instance Attribute Details

#fileObject

Returns the value of attribute file.



52
53
54
# File 'lib/cucumber/core/ast/data_table.rb', line 52

def file
  @file
end

Class Method Details

.parse(text, uri, location) ⇒ Object



54
55
56
57
58
59
# File 'lib/cucumber/core/ast/data_table.rb', line 54

def self.parse(text, uri, location)
  builder = Builder.new
  lexer = ::Gherkin::Lexer::I18nLexer.new(builder)
  lexer.scan(text)
  new(builder.rows, location)
end

Instance Method Details

#==(other) ⇒ Object



207
208
209
# File 'lib/cucumber/core/ast/data_table.rb', line 207

def ==(other)
  other.class == self.class && raw == other.raw
end

#cell_matrixObject

:nodoc:



199
200
201
# File 'lib/cucumber/core/ast/data_table.rb', line 199

def cell_matrix #:nodoc:
  @cell_matrix
end

#cells_rowsObject

:nodoc:



189
190
191
192
193
# File 'lib/cucumber/core/ast/data_table.rb', line 189

def cells_rows #:nodoc:
  cell_matrix.map do |cell_row|
    @cells_class.new(self, cell_row)
  end
end

#col_width(col) ⇒ Object

:nodoc:



203
204
205
# File 'lib/cucumber/core/ast/data_table.rb', line 203

def col_width(col) #:nodoc:
  columns[col].__send__(:width)
end

#column_namesObject

:nodoc:



160
161
162
# File 'lib/cucumber/core/ast/data_table.rb', line 160

def column_names #:nodoc:
  cell_matrix[0].map { |cell| cell.value }
end

#dupObject

Creates a copy of this table



82
83
84
# File 'lib/cucumber/core/ast/data_table.rb', line 82

def dup
  self.class.new(raw.dup, location)
end

#hashesObject

Converts this table into an Array of Hash where the keys of each Hash are the headers in the table. For example, a DataTable built from the following plain text:

| a | b | sum |
| 2 | 3 | 5   |
| 7 | 9 | 16  |

Gets converted into the following:

[{'a' => '2', 'b' => '3', 'sum' => '5'}, {'a' => '7', 'b' => '9', 'sum' => '16'}]


121
122
123
# File 'lib/cucumber/core/ast/data_table.rb', line 121

def hashes
  build_hashes
end

#headersObject

:nodoc:



195
196
197
# File 'lib/cucumber/core/ast/data_table.rb', line 195

def headers #:nodoc:
  raw.first
end

#inspectObject



211
212
213
# File 'lib/cucumber/core/ast/data_table.rb', line 211

def inspect
  raw.inspect
end

#map(&block) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/cucumber/core/ast/data_table.rb', line 101

def map(&block)
  new_raw = raw.map do |row|
    row.map(&block)
  end

  self.class.new(new_raw, location)
end

#rawObject

Gets the raw data of this table. For example, a DataTable built from the following plain text:

| a | b |
| c | d |

gets converted into the following:

[['a', 'b'], ['c', 'd']]


152
153
154
155
156
157
158
# File 'lib/cucumber/core/ast/data_table.rb', line 152

def raw
  cell_matrix.map do |row|
    row.map do |cell|
      cell.value
    end
  end
end

#rowsObject



164
165
166
167
168
# File 'lib/cucumber/core/ast/data_table.rb', line 164

def rows
  hashes.map do |hash|
    hash.values_at(*headers)
  end
end

#rows_hashObject

Converts this table into a Hash where the first column is used as keys and the second column is used as values

| a | 2 |
| b | 3 |

Gets converted into the following:

{'a' => '2', 'b' => '3'}

The table must be exactly two columns wide



137
138
139
140
# File 'lib/cucumber/core/ast/data_table.rb', line 137

def rows_hash
  verify_table_width(2)
  self.transpose.hashes[0]
end

#to_hash(cells) ⇒ Object

:nodoc:



175
176
177
178
179
180
181
182
183
# File 'lib/cucumber/core/ast/data_table.rb', line 175

def to_hash(cells) #:nodoc:
  hash = Hash.new do |the_hash, key|
    the_hash[key.to_s] if key.is_a?(Symbol)
  end
  column_names.each_with_index do |column_name, column_index|
    hash[column_name] = cells.value(column_index)
  end
  hash
end

#to_sexpObject

For testing only



171
172
173
# File 'lib/cucumber/core/ast/data_table.rb', line 171

def to_sexp #:nodoc:
  [:table, *cells_rows.map{|row| row.to_sexp}]
end

#to_step_definition_argObject



76
77
78
# File 'lib/cucumber/core/ast/data_table.rb', line 76

def to_step_definition_arg
  dup
end

#transposeObject

Returns a new, transposed table. Example:

| a | 7 | 4 |
| b | 9 | 2 |

Gets converted into the following:

| a | b |
| 7 | 9 |
| 4 | 2 |


97
98
99
# File 'lib/cucumber/core/ast/data_table.rb', line 97

def transpose
  self.class.new(raw.transpose, location)
end

#verify_table_width(width) ⇒ Object

:nodoc:



185
186
187
# File 'lib/cucumber/core/ast/data_table.rb', line 185

def verify_table_width(width) #:nodoc:
  raise %{The table must have exactly #{width} columns} unless raw[0].size == width
end