Class: Cucumber::Ast::Table

Inherits:
Object show all
Defined in:
lib/cucumber/ast/table.rb

Overview

Holds the data of a table parsed from a feature file:

| a | b |
| c | d |

This gets parsed into a Table holding the values [['a', 'b'], ['c', 'd']]

Direct Known Subclasses

OutlineTable

Defined Under Namespace

Classes: Cell, Cells

Constant Summary collapse

NULL_CONVERSIONS =
Hash.new(lambda{ |cell_value| cell_value }).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw, conversions = NULL_CONVERSIONS.dup) ⇒ Table

Returns a new instance of Table.



19
20
21
22
23
24
25
26
# File 'lib/cucumber/ast/table.rb', line 19

def initialize(raw, conversions = NULL_CONVERSIONS.dup)
  # Verify that it's square
  raw.transpose
  @raw = raw
  @cells_class = Cells
  @cell_class = Cell
  @conversion_procs = conversions
end

Instance Attribute Details

#fileObject

Returns the value of attribute file.



13
14
15
# File 'lib/cucumber/ast/table.rb', line 13

def file
  @file
end

Class Method Details

.default_arg_nameObject



15
16
17
# File 'lib/cucumber/ast/table.rb', line 15

def self.default_arg_name
  "table"
end

Instance Method Details

#accept(visitor) ⇒ Object



108
109
110
111
112
113
# File 'lib/cucumber/ast/table.rb', line 108

def accept(visitor)
  cells_rows.each do |row|
    visitor.visit_table_row(row)
  end
  nil
end

#arguments_replaced(arguments) ⇒ Object

:nodoc:



179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/cucumber/ast/table.rb', line 179

def arguments_replaced(arguments) #:nodoc:
  raw_with_replaced_args = raw.map do |row|
    row.map do |cell|
      cell_with_replaced_args = cell
      arguments.each do |name, value|
        if cell_with_replaced_args && cell_with_replaced_args.include?(name)
          cell_with_replaced_args = value ? cell_with_replaced_args.gsub(name, value) : nil
        end
      end
      cell_with_replaced_args
    end
  end
  Table.new(raw_with_replaced_args)
end

#cells_rowsObject



194
195
196
197
198
# File 'lib/cucumber/ast/table.rb', line 194

def cells_rows
  @rows ||= cell_matrix.map do |cell_row|
    @cells_class.new(self, cell_row)
  end
end

#dupObject

Creates a copy of this table, inheriting the column mappings.



29
30
31
# File 'lib/cucumber/ast/table.rb', line 29

def dup
  self.class.new(@raw.dup, @conversion_procs.dup)
end

#each_cells_row(&proc) ⇒ Object



104
105
106
# File 'lib/cucumber/ast/table.rb', line 104

def each_cells_row(&proc)
  cells_rows.each(&proc)
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 Table 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'}]

Use #map_column! to specify how values in a column are converted.



62
63
64
65
66
# File 'lib/cucumber/ast/table.rb', line 62

def hashes
  @hashes ||= cells_rows[1..-1].map do |row|
    row.to_hash
  end
end

#header_cell(col) ⇒ Object



200
201
202
# File 'lib/cucumber/ast/table.rb', line 200

def header_cell(col)
  cells_rows[0][col]
end

#index(cells) ⇒ Object

:nodoc:



167
168
169
# File 'lib/cucumber/ast/table.rb', line 167

def index(cells) #:nodoc:
  cells_rows.index(cells)
end

#map_column!(column_name, strict = true, &conversion_proc) ⇒ Object

Change how #hashes converts column values. The column_name argument identifies the column and conversion_proc performs the conversion for each cell in that column. If strict is true, an error will be raised if the column named column_name is not found. If strict is false, no error will be raised. Example:

Given /^an expense report for (.*) with the following posts:$/ do |table|
  posts_table.map_column!('amount') { |a| a.to_i }
  posts_table.hashes.each do |post|
    # post['amount'] is a Fixnum, rather than a String
  end
end


151
152
153
154
# File 'lib/cucumber/ast/table.rb', line 151

def map_column!(column_name, strict=true, &conversion_proc)
  verify_column(column_name) if strict
  @conversion_procs[column_name] = conversion_proc
end

#map_headers(mappings) ⇒ Object

Returns a new Table where the headers are redefined. This makes it possible to use prettier header names in the features. Example:

| Phone Number | Address |
| 123456       | xyz     |
| 345678       | abc     |

A StepDefinition receiving this table can then map the columns:

mapped_table = table.map_columns('Phone Number' => :phone, 'Address' => :address)
hashes = mapped_table.hashes
# => [{:phone => '123456', :address => 'xyz'}, {:phone => '345678', :address => 'abc'}]


133
134
135
136
137
# File 'lib/cucumber/ast/table.rb', line 133

def map_headers(mappings)
  table = self.dup
  table.map_headers!(mappings)
  table
end

#rawObject

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

| a | b |
| c | d |

Get converted into the following:

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


95
96
97
# File 'lib/cucumber/ast/table.rb', line 95

def raw
  @raw
end

#rowsObject

Same as #raw, but skips the first (header) row



100
101
102
# File 'lib/cucumber/ast/table.rb', line 100

def rows
  @raw[1..-1]
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



80
81
82
83
# File 'lib/cucumber/ast/table.rb', line 80

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

#to_hash(cells) ⇒ Object

:nodoc:



156
157
158
159
160
161
162
163
164
165
# File 'lib/cucumber/ast/table.rb', line 156

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

#to_sexpObject

For testing only



116
117
118
# File 'lib/cucumber/ast/table.rb', line 116

def to_sexp #:nodoc:
  [:table, *cells_rows.map{|row| row.to_sexp}]
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 |



44
45
46
# File 'lib/cucumber/ast/table.rb', line 44

def transpose
  self.class.new(@raw.transpose, @conversion_procs.dup)
end

#verify_column(column_name) ⇒ Object



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

def verify_column(column_name)
  raise %{The column named "#{column_name}" does not exist} unless @raw[0].include?(column_name)
end

#verify_table_width(width) ⇒ Object



175
176
177
# File 'lib/cucumber/ast/table.rb', line 175

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