Skip to content

Commit d657888

Browse files
committed
fix and improve table DSL
1 parent f126b7d commit d657888

File tree

7 files changed

+136
-30
lines changed

7 files changed

+136
-30
lines changed

CHANGELOG.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Fixed
9+
- `table_selector`, `within_table_for` incorrect resource name
810

9-
## [0.2.0] - 2020-04-14
10-
### Breaking change
11-
- rename #have_table_col to #have_table_cell
12-
- change options of #have_table_cell
13-
- change options of #have_table_row
11+
### Changed
12+
- `table_selector` receives 2 arguments
13+
- `within_table_for` receives 2 arguments
14+
- `current_table_name` renamed to `current_table_model_name`
15+
- `table_row_selector` can receive modal class as model name
16+
17+
# Added
18+
- `have_table` matcher
19+
- add tests for table with namespaced resource class and multi-word resource name
1420

15-
### Change
21+
## [0.2.0] - 2020-04-14
22+
### Changed
23+
- rename `have_table_col` to `have_table_cell`
24+
- change options of `have_table_cell`
25+
- change options of `have_table_row`
1626
- refactor modules hierarchy: split DSL into selectors, finders, matchers and actions
1727

1828
### Added

lib/capybara/active_admin/finders/table.rb

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ module Capybara
44
module ActiveAdmin
55
module Finders
66
module Table
7-
def current_table_name
8-
@__current_table_name
7+
def current_table_model_name
8+
@__current_table_model_name
99
end
1010

11-
def within_table_for(name)
12-
name = name.model_name.plural if name.is_a?(Class)
13-
selector = table_selector(name)
11+
# @param model_name [Class<#model_name>, String] records class or model name to match rows.
12+
# @param resource_name [String, nil] resource name of index page.
13+
# @yield within table.
14+
def within_table_for(model_name, resource_name = nil)
15+
selector = table_selector(resource_name)
1416

1517
within(selector) do
16-
old = @__current_table_name
17-
@__current_table_name = name
18+
old = @__current_table_model_name
19+
@__current_table_model_name = model_name
1820
begin
1921
yield
2022
ensure
21-
@__current_table_name = old
23+
@__current_table_model_name = old
2224
end
2325
end
2426
end
@@ -33,12 +35,12 @@ def find_table_row(id: nil, index: nil)
3335
raise ArgumentError, 'must provide :id or :index' if id.nil? && index.nil?
3436

3537
if id
36-
model = @__current_table_name
37-
selector = table_row_selector(model, id)
38+
selector = table_row_selector(current_table_model_name, id)
3839
return find(selector)
3940
end
4041

41-
find_all(table_row_selector(nil, nil), minimum: index + 1)[index]
42+
selector = table_row_selector(nil, nil)
43+
find_all(selector, minimum: index + 1)[index]
4244
end
4345

4446
def within_table_cell(name)

lib/capybara/active_admin/matchers/table.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ module Capybara
44
module ActiveAdmin
55
module Matchers
66
module Table
7+
# @param options [Hash]
8+
# :resource_name [String, nil] active admin page resource name
9+
# for other options @see Capybara::RSpecMatchers#have_selector
10+
# @example
11+
# expect(page).to have_table
12+
# expect(page).to have_table(resource_name: 'users')
13+
#
14+
def have_table(options = {})
15+
resource_name = options.delete(:resource_name)
16+
selector = table_selector(resource_name)
17+
have_selector(selector, options)
18+
end
19+
720
# @param options [Hash]
821
# :text [String, nil] cell content
922
# :id [String, Number, nil] record ID
@@ -15,7 +28,7 @@ module Table
1528
#
1629
def have_table_row(options = {})
1730
row_id = options.delete(:id)
18-
selector = table_row_selector(current_table_name, row_id)
31+
selector = table_row_selector(current_table_model_name, row_id)
1932
have_selector(selector, options)
2033
end
2134

lib/capybara/active_admin/selectors/table.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,29 @@ module Capybara
44
module ActiveAdmin
55
module Selectors
66
module Table
7-
def table_selector(model)
8-
return 'table.index_table' if model.nil?
7+
def table_selector(resource_name)
8+
return 'table.index_table' if resource_name.nil?
99

10-
"table.index_table#index_table_#{model.to_s.pluralize}"
10+
resource_name = resource_name.to_s.gsub(' ', '_').pluralize.downcase
11+
"table#index_table_#{resource_name}"
1112
end
1213

13-
def table_row_selector(model, record_id)
14+
def table_row_selector(model_name, record_id)
1415
return 'tbody > tr' if record_id.nil?
1516

16-
"tbody > tr##{model.to_s.singularize}_#{record_id}"
17+
model_name = model_name.model_name.singular if model_name.is_a?(Class)
18+
model_name = model_name.to_s.gsub(' ', '_').singularize.downcase
19+
"tbody > tr##{model_name}_#{record_id}"
1720
end
1821

1922
def table_header_selector
2023
'thead > tr > th.col'
2124
end
2225

2326
def table_cell_selector(column)
24-
column = column.to_s.gsub(' ', '_').downcase unless column.nil?
2527
return 'td.col' if column.nil?
2628

29+
column = column.to_s.gsub(' ', '_').downcase
2730
"td.col.col-#{column}"
2831
end
2932
end

spec/dummy/test_application.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
t.string :full_name
2525
t.timestamps
2626
end
27+
28+
create_table :employees, force: true do |t|
29+
t.string :full_name
30+
t.decimal :salary
31+
t.timestamps
32+
end
2733
end
2834

2935
require 'action_controller/railtie'
@@ -85,6 +91,13 @@ class User < ActiveRecord::Base
8591
validates :full_name, presence: true
8692
end
8793

94+
module Billing
95+
class Employee < ActiveRecord::Base
96+
validates :full_name, presence: true
97+
validates :salary, numericality: { greater_than_or_equal_to: 0.01 }
98+
end
99+
end
100+
88101
ActiveAdmin.setup do |config|
89102
# Disabling authentication in specs so that we don't have to worry about
90103
# it allover the place
@@ -105,6 +118,10 @@ class User < ActiveRecord::Base
105118
permit_params :full_name
106119
end
107120

121+
ActiveAdmin.register Billing::Employee, as: 'Business Employee' do
122+
permit_params :full_name, :salary
123+
end
124+
108125
Rails.application.routes.draw do
109126
ActiveAdmin.routes(self)
110127
end
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe 'Business Employees index', js: true do
4+
subject do
5+
visit admin_business_employees_path
6+
end
7+
8+
it 'checks elements on empty users page' do
9+
subject
10+
11+
expect(page).to have_text('There are no Business Employees yet.')
12+
expect(page).to have_action_item('New Business Employee')
13+
expect(page).to_not have_action_item('Edit Business Employee')
14+
end
15+
16+
it 'clicks on New resource_name: ' do
17+
subject
18+
19+
click_action_item('New Business Employee')
20+
expect(page).to have_current_path(new_admin_business_employee_path)
21+
end
22+
23+
it 'finds data in table' do
24+
john = Billing::Employee.create!(full_name: 'John Doe', salary: 100)
25+
jane = Billing::Employee.create!(full_name: 'Jane Air', salary: 101)
26+
subject
27+
28+
expect(page).to have_table
29+
expect(page).to have_table(resource_name: 'Business Employees')
30+
within_table_for(Billing::Employee) do
31+
expect(page).to have_table_row(count: 2)
32+
expect(page).to have_table_cell(count: 12) # 2x id, full_name, salary, created_at, updated_at, actions
33+
34+
expect(page).to have_table_cell(text: 'John Doe')
35+
expect(page).to have_table_cell(text: 'John Doe', column: 'Full Name')
36+
expect(page).to_not have_table_cell(text: 'John Doe', column: 'Id')
37+
38+
within_table_row(id: john.id) do
39+
expect(page).to have_table_cell(count: 6) # id, full_name, salary, created_at, updated_at, actions
40+
expect(page).to have_table_cell(text: 'John Doe')
41+
expect(page).to have_table_cell(text: 'John Doe', column: 'Full Name')
42+
expect(page).to have_table_cell(text: '100', column: 'Salary')
43+
expect(page).to_not have_table_cell(text: 'John Doe', column: 'Id')
44+
end
45+
46+
within_table_row(id: jane.id) do
47+
expect(page).to have_table_cell(count: 6) # id, full_name, salary created_at, updated_at, actions
48+
expect(page).to have_table_cell(text: jane.id, column: 'Id')
49+
expect(page).to have_table_cell(text: 'Jane Air', column: 'Full Name')
50+
expect(page).to have_table_cell(text: '101', column: 'Salary')
51+
expect(page).to_not have_table_cell(text: 'John Doe')
52+
expect(page).to_not have_table_cell(text: 'John Doe', column: 'Full Name')
53+
end
54+
end
55+
# take_screenshot
56+
end
57+
end

spec/system/users_index_spec.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
expect(page).to have_text('There are no Users yet.')
1212
expect(page).to have_action_item('New User')
1313
expect(page).to_not have_action_item('Edit User')
14+
expect(page).to_not have_table
15+
expect(page).to_not have_table(resource_name: 'Users')
1416
end
1517

1618
it 'clicks on New User' do
@@ -25,7 +27,9 @@
2527
jane = User.create!(full_name: 'Jane Air')
2628
subject
2729

28-
within_table_for('users') do
30+
expect(page).to have_table
31+
expect(page).to have_table(resource_name: 'Users')
32+
within_table_for(User) do
2933
expect(page).to have_table_row(count: 2)
3034
expect(page).to have_table_cell(count: 10) # 2x id, full_name, created_at, updated_at, actions
3135

@@ -52,9 +56,9 @@
5256
end
5357

5458
# TODO: filters expect to have
55-
# todo filters fill and click
56-
# todo breadcrumbs expect to have
57-
# todo breadcrumbs click
58-
# todo menu items expect to have
59-
# todo menu items click
59+
# TODO: filters fill and click
60+
# TODO: breadcrumbs expect to have
61+
# TODO: breadcrumbs click
62+
# TODO: menu items expect to have
63+
# TODO: menu items click
6064
end

0 commit comments

Comments
 (0)