Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #21 from senny/table_row_refactoring

table row refactoring
  • Loading branch information...
commit f90db669cbe38274277984ac1ad65497858a7d24 2 parents 4e00f31 + 54cb05d
@senny authored
View
13 README.md
@@ -49,17 +49,22 @@ flash.assert_flash_is_present(:notice, 'Article saved') # verify that a given fl
```ruby
table = CornerStones::Table.new('.articles')
-table.rows # returns an array of rows. Each row is represented as a Hash {header} => {value}
-table.row('Title' => 'Management') # returns the row-hash for the row with 'Management' in the 'Title' column
+table.rows # returns an array of rows. Each row is represented as a row object.
+table.row('Title' => 'Management') # returns the row object for the row with 'Management' in the 'Title' column
```
+A row object has two primary methods: `#node` is a reference to the capybara node of the row and `#attributes` is a hash
+with the following structure: ({Table Header} => {Cell Value})
+
+The following extensions are available for the `Table`:
+
```ruby
table = CornerStones::Table.new('.articles').tap do |t|
t.extend(CornerStones::Table::SelectableRows)
t.extend(CornerStones::Table::DeletableRows)
end
-table.select_row('Created at' => '01.12.2001') # select the row, which has '01.12.2001' in the 'Created at' column
-table.delete_row('ID' => '9') # delete the row, which contains '9' in the 'ID' column
+table.row('Created at' => '01.12.2001').select # select the row, which has '01.12.2001' in the 'Created at' column
+table.row('ID' => '9').delete # delete the row, which contains '9' in the 'ID' column
```
### Forms
View
16 lib/corner_stones/table.rb
@@ -18,7 +18,7 @@ def initialize(scope, options = {})
def row(options)
rows.detect { |row|
- identity = row.select { |key, value| options.has_key?(key) }
+ identity = row.attributes.select { |key, value| options.has_key?(key) }
identity == options
} or raise MissingRowError, "no row with '#{options.inspect}'\n\ngot:#{rows}"
end
@@ -26,11 +26,16 @@ def row(options)
def rows
within @scope do
all('tbody tr').map do |row|
- attributes_for_row(row)
+ build_row(row)
end
end
end
+ def build_row(node)
+ Row.new(node, attributes_for_row(node))
+ end
+ protected :build_row
+
def headers
@options[:headers] || detect_table_headers
end
@@ -44,7 +49,6 @@ def attributes_for_row(row)
headers.each.with_index.with_object(row_data) do |(header, index), row_data|
augment_row_with_cell(row_data, row, index, header)
end
- row_data['Row-Element'] = row
row_data
end
@@ -57,6 +61,12 @@ def augment_row_with_cell(row_data, row, index, header)
def value_for_cell(cell)
cell.text unless cell.nil?
end
+
+ Row = Struct.new(:node, :attributes) do
+ def [](key)
+ attributes[key]
+ end
+ end
end
end
View
25 lib/corner_stones/table/deletable_rows.rb
@@ -3,16 +3,25 @@ class Table
module DeletableRows
def delete_row(options)
- row = row(options)
- if row['Delete-Link']
- row['Delete-Link'].click
- else
- raise "The row matching '#{options}' does not have a delete-link"
- end
+ warn "[DEPRECATION] `delete_row` is deprecated. Please use `row(row_spec).delete` instead."
+ row(options).delete
+ end
+
+ def build_row(node)
+ row = super
+ row.extend RowMethods
+ row
end
- def attributes_for_row(row)
- super.merge('Delete-Link' => row.first('td .delete-action'))
+ module RowMethods
+ def delete
+ delete_link = node.first('td .delete-action')
+ if delete_link
+ delete_link.click
+ else
+ raise "The row '#{attributes}' does not have a delete-link"
+ end
+ end
end
end
View
15 lib/corner_stones/table/selectable_rows.rb
@@ -3,11 +3,20 @@ class Table
module SelectableRows
def select_row(options)
- visit row(options)['Selected-Link']
+ warn "[DEPRECATION] `select_row` is deprecated. Please use `row(row_spec).select` instead."
+ row(options).select
end
- def attributes_for_row(row)
- super.merge('Selected-Link' => row['data-selected-url'])
+ def build_row(node)
+ row = super
+ row.extend RowMethods
+ row
+ end
+
+ module RowMethods
+ def select
+ visit node['data-selected-url']
+ end
end
end
View
2  spec/integration/corner_stones/table_form_spec.rb
@@ -139,7 +139,7 @@
it 'ignores empty cells' do
expected_data = [{'Title' => 'Indiana Jones', 'Duration' => '210 minutes', 'Time' => nil}]
subject.rows.map {|r|
- r.reject {|key, value| ['Row-Element', 'Inputs'].include? key}
+ r.attributes.reject {|key, _value| !expected_data.first.has_key?(key)}
}.must_equal(expected_data)
end
end
View
73 spec/integration/corner_stones/table_spec.rb
@@ -51,26 +51,20 @@
{ 'ID' => '2', 'Title' => 'Domain Driven Design', 'Author' => 'Eric Evans'}]
subject.rows.map {|r|
- r.each do |k, v|
- r.delete(k) unless expected_data.first.has_key?(k)
+ r.attributes.reject do |key, _value|
+ !expected_data.first.has_key?(key)
end
}.must_equal(expected_data)
end
it 'a row can be accessed with a single key' do
- expected_data = { 'ID' => '2', 'Title' => 'Domain Driven Design', 'Author' => 'Eric Evans' }
actual = subject.row('Title' => 'Domain Driven Design')
-
- actual.each {|k, v| actual.delete(k) unless expected_data.has_key?(k)}
- actual.must_equal(expected_data)
+ actual['Author'].must_equal('Eric Evans')
end
it 'a row can be accessed with multiple keys' do
- expected_data = {'ID' => '1', 'Title' => 'Clean Code', 'Author' => 'Robert C. Martin'}
-
actual = subject.row('ID' => '1', 'Author' => 'Robert C. Martin')
- actual.each {|k, v| actual.delete(k) unless expected_data.has_key?(k)}
- actual.must_equal(expected_data)
+ actual['Title'].must_equal('Clean Code')
end
it 'It raises an Exception when no Row was found' do
@@ -80,7 +74,7 @@
end
it 'extracts the Capybara-Element for the table row' do
- subject.row('ID' => '1')['Row-Element'].path.must_equal('/html/body/table/tbody/tr[1]')
+ subject.row('ID' => '1').node.path.must_equal('/html/body/table/tbody/tr[1]')
end
end
@@ -110,8 +104,8 @@
{ 'Book' => 'Domain Driven Design',
'Author' => 'Eric Evans'}]
subject.rows.map {|r|
- r.each do |k, v|
- r.delete(k) unless expected_data.first.has_key?(k)
+ r.attributes.reject do |key, _value|
+ !expected_data.first.has_key?(key)
end
}.must_equal(expected_data)
end
@@ -141,9 +135,10 @@
it 'ignores empty cells' do
expected_data = [{'ID' => '1', 'Title' => 'Clean Code', 'Author' => nil}]
- subject.rows.map {|r|
- r.reject {|key, value| key == 'Row-Element'}
- }.must_equal(expected_data)
+ actual = subject.rows
+
+ actual = actual.map {|row| row.attributes.reject {|key, _value| !expected_data.first.has_key?(key)}}
+ actual.must_equal(expected_data)
end
end
@@ -184,24 +179,31 @@
subject.extend(CornerStones::Table::DeletableRows)
end
- it 'it includes the "Delete-Link" object in the data' do
- subject.rows.each do |row|
- unless row['Delete-Link'].nil?
- row['Delete-Link'].must_be_kind_of(Capybara::Node::Element)
- end
+ it 'allows you to trigger a deletion with a row selector' do
+ subject.row('Title' => 'Domain Driven Design').delete
+ current_path.must_equal '/delete/domain_driven_design'
+ end
+
+ it 'raises an error when a the target row can not be found' do
+ begin
+ subject.row('ID' => '3').delete
+ rescue => e
+ e.message.must_match /^The row '.*' does not have a delete-link$/
end
end
- it 'allows you to trigger a deletion with a row selector' do
+ it 'the deprecated method #delete_row still works' do
+ errors = StringIO.new
+ original_stderr = $stderr
+ $stderr = errors
+
subject.delete_row('Title' => 'Domain Driven Design')
+
+ $stderr = original_stderr
current_path.must_equal '/delete/domain_driven_design'
+ errors.string.must_equal "[DEPRECATION] `delete_row` is deprecated. Please use `row(row_spec).delete` instead.\n"
end
- it 'raises an error when a the target row can not be found' do
- lambda do
- subject.delete_row('ID' => '3')
- end.must_raise(RuntimeError)
- end
end
describe 'selectable rows' do
@@ -234,15 +236,21 @@
subject.extend(CornerStones::Table::SelectableRows)
end
- it 'it includes the "Selected-Link" object in the data' do
- subject.rows.map do |row|
- row['Selected-Link']
- end.must_equal ['/articles/clean_code', '/articles/domain_driven_design']
+ it 'allows you to select a row' do
+ subject.row('ID' => '1').select
+ current_path.must_equal '/articles/clean_code'
end
- it 'allows you to select a row' do
+ it 'the deprecated method #select_row still works' do
+ errors = StringIO.new
+ original_stderr = $stderr
+ $stderr = errors
+
subject.select_row('ID' => '1')
+
+ $stderr = original_stderr
current_path.must_equal '/articles/clean_code'
+ errors.string.must_equal "[DEPRECATION] `select_row` is deprecated. Please use `row(row_spec).select` instead.\n"
end
end
@@ -276,7 +284,6 @@
it 'strips whitespace from cell content' do
subject.rows.map { |r| r['Author']}.must_equal ["Robert C. Martin", "Eric Evans"]
end
-
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.