table_cloth 0.2.3 → 0.3.0.beta1
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.
- data/.gitignore +1 -0
- data/lib/generators/templates/table.rb +7 -0
- data/lib/table_cloth.rb +14 -15
- data/lib/table_cloth/base.rb +3 -26
- data/lib/table_cloth/column.rb +0 -12
- data/lib/table_cloth/{action.rb → column_jury.rb} +10 -6
- data/lib/table_cloth/configurable_elements.rb +6 -13
- data/lib/table_cloth/extensions/actions.rb +25 -0
- data/lib/table_cloth/extensions/actions/action.rb +21 -0
- data/lib/table_cloth/extensions/actions/action_collection.rb +11 -0
- data/lib/table_cloth/extensions/actions/column.rb +21 -0
- data/lib/table_cloth/extensions/actions/jury.rb +37 -0
- data/lib/table_cloth/presenter.rb +16 -5
- data/lib/table_cloth/presenters/default.rb +1 -1
- data/lib/table_cloth/version.rb +1 -1
- data/spec/factories/actions.rb +6 -0
- data/spec/factories/columns.rb +18 -0
- data/spec/factories/dummy_tables.rb +11 -0
- data/spec/lib/base_spec.rb +6 -22
- data/spec/lib/column_jury_spec.rb +35 -0
- data/spec/lib/column_spec.rb +9 -14
- data/spec/lib/extensions/actions/action_collection_spec.rb +29 -0
- data/spec/lib/extensions/actions/action_spec.rb +57 -0
- data/spec/lib/extensions/actions/column_spec.rb +23 -0
- data/spec/lib/extensions/actions/jury_spec.rb +67 -0
- data/spec/lib/extensions/actions_spec.rb +42 -0
- data/spec/lib/presenter_spec.rb +29 -31
- data/spec/lib/presenters/default_spec.rb +61 -124
- data/spec/spec_helper.rb +7 -0
- data/spec/support/dummy_table.rb +0 -4
- data/spec/support/dummy_table_with_value_options.rb +1 -1
- data/spec/support/matchers/element_matchers.rb +6 -0
- data/table_cloth.gemspec +2 -0
- metadata +63 -14
- data/lib/table_cloth/actions.rb +0 -23
- data/lib/table_cloth/columns/action.rb +0 -24
- data/spec/lib/actions_spec.rb +0 -28
- data/spec/lib/columns/action_spec.rb +0 -73
- data/spec/support/dummy_table_with_actions.rb +0 -7
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::ColumnJury do
|
4
|
+
let(:dummy_table) { stub(:table, admin?: true, moderator?: false) }
|
5
|
+
|
6
|
+
subject { TableCloth::ColumnJury.new(column, dummy_table) }
|
7
|
+
|
8
|
+
context 'conditions' do
|
9
|
+
context 'if' do
|
10
|
+
let(:column) { FactoryGirl.build(:if_column) }
|
11
|
+
|
12
|
+
specify 'the column is available when condition returns true' do
|
13
|
+
expect(subject).to be_available
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'the column is not available when condition returns false' do
|
17
|
+
dummy_table.stub admin?: false
|
18
|
+
expect(subject).not_to be_available
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'unless' do
|
23
|
+
let(:column) { FactoryGirl.build(:unless_column) }
|
24
|
+
|
25
|
+
specify 'the column is available when condition returns false' do
|
26
|
+
expect(subject).to be_available
|
27
|
+
end
|
28
|
+
|
29
|
+
specify 'the column is not available when condition returns true' do
|
30
|
+
dummy_table.stub moderator?: true
|
31
|
+
expect(subject).not_to be_available
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/lib/column_spec.rb
CHANGED
@@ -20,22 +20,17 @@ describe TableCloth::Column do
|
|
20
20
|
it 'returns the email from a proc correctly' do
|
21
21
|
email_column.value(dummy_model, view_context).should == 'robert at example.com'
|
22
22
|
end
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns false on failed constraints' do
|
32
|
-
table = Class.new(DummyTable).new([dummy_model], view_context)
|
33
|
-
table.stub admin?: false
|
34
|
-
|
25
|
+
context "human name" do
|
26
|
+
it "returns the label when set" do
|
27
|
+
column = FactoryGirl.build(:column, options: { label: "Whatever" })
|
28
|
+
expect(column.human_name).to eq("Whatever")
|
29
|
+
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
it "humanizes the symbol if no label is set" do
|
32
|
+
column = FactoryGirl.build(:column, name: :email)
|
33
|
+
expect(column.human_name).to eq("Email")
|
39
34
|
end
|
40
35
|
end
|
41
36
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::Extensions::Actions::ActionCollection do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
context "#action" do
|
7
|
+
it "adds an action" do
|
8
|
+
subject.action { }
|
9
|
+
expect(subject).to have(1).actions
|
10
|
+
end
|
11
|
+
|
12
|
+
it "adds an action with options" do
|
13
|
+
subject.action(option: "something") { }
|
14
|
+
expect(subject.actions.first.options[:option]).to eq("something")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#actions" do
|
19
|
+
before(:each) do
|
20
|
+
subject.action { }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns a list of actions" do
|
24
|
+
subject.actions.each do |action|
|
25
|
+
expect(action).to be_kind_of TableCloth::Extensions::Actions::Action
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::Extensions::Actions::Action do
|
4
|
+
let(:action_hash) { {proc: Proc.new{}} }
|
5
|
+
subject { described_class.new(action_hash) }
|
6
|
+
|
7
|
+
it "initializes with a hash" do
|
8
|
+
expect(subject.options).to eq(action_hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "defines a delegator to a jury" do
|
12
|
+
expect(subject.jury).to be_kind_of TableCloth::Extensions::Actions::Jury
|
13
|
+
end
|
14
|
+
|
15
|
+
context "#value" do
|
16
|
+
let(:model) { FactoryGirl.build(:dummy_model) }
|
17
|
+
let(:view_context) { ActionView::Base.new }
|
18
|
+
|
19
|
+
context "string" do
|
20
|
+
let(:action_hash) { {proc: Proc.new{ "something" }} }
|
21
|
+
|
22
|
+
it "returns a string" do
|
23
|
+
expect(subject.value(model, view_context)).to match /something/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "view helper" do
|
28
|
+
let(:action_hash) do
|
29
|
+
{proc: Proc.new { link_to "blank", "something" }}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns a link" do
|
33
|
+
expect(subject.value(model, view_context)).to match /href="something"/
|
34
|
+
expect(subject.value(model, view_context)).to match />blank</
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "conditional" do
|
39
|
+
let(:action_hash) do
|
40
|
+
{
|
41
|
+
proc: Proc.new { "something" },
|
42
|
+
if: Proc.new {|object| object.admin? }
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns the link when the model condition succeeds" do
|
47
|
+
model.stub admin?: true
|
48
|
+
expect(subject.value(model, view_context)).to include "something"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not return the link when the model condition fails" do
|
52
|
+
model.stub admin?: false
|
53
|
+
expect(subject.value(model, view_context)).not_to include "something"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::Extensions::Actions::Column do
|
4
|
+
let(:view_context) { ActionView::Base.new }
|
5
|
+
let(:dummy_model) { FactoryGirl.build(:dummy_model) }
|
6
|
+
let(:action_collection) { TableCloth::Extensions::Actions::ActionCollection.new }
|
7
|
+
|
8
|
+
subject { described_class.new(:actions, collection: action_collection) }
|
9
|
+
|
10
|
+
context "value" do
|
11
|
+
it "returns action values" do
|
12
|
+
action_collection.action { "something" }
|
13
|
+
expect(subject.value(dummy_model, view_context)).to match /something/
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns multiple action values" do
|
17
|
+
action_collection.action { "something" }
|
18
|
+
action_collection.action { "else" }
|
19
|
+
expect(subject.value(dummy_model, view_context)).to match /something/
|
20
|
+
expect(subject.value(dummy_model, view_context)).to match /else/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::Extensions::Actions::Jury do
|
4
|
+
let(:action) { FactoryGirl.build(:action, options: action_options) }
|
5
|
+
subject { described_class.new(action) }
|
6
|
+
let(:model) { double("model") }
|
7
|
+
|
8
|
+
context "Proc" do
|
9
|
+
context "if .available?" do
|
10
|
+
let(:action_options) { {if: Proc.new{|o| o.state == "valid" }} }
|
11
|
+
|
12
|
+
it "returns true for valid models" do
|
13
|
+
model.stub state: "valid"
|
14
|
+
expect(subject).to be_available(model)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns false for invalid models" do
|
18
|
+
model.stub state: "invalid"
|
19
|
+
expect(subject).not_to be_available(model)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "unless .available?" do
|
24
|
+
let(:action_options) { {unless: Proc.new{|o| o.state == "invalid" }} }
|
25
|
+
|
26
|
+
it "returns true for valid models" do
|
27
|
+
model.stub state: "valid"
|
28
|
+
expect(subject).to be_available(model)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns false for invalid models" do
|
32
|
+
model.stub state: "invalid"
|
33
|
+
expect(subject).not_to be_available(model)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "Symbol" do
|
39
|
+
context "if .available?" do
|
40
|
+
let(:action_options) { {if: :valid?} }
|
41
|
+
|
42
|
+
it "returns true for valid?" do
|
43
|
+
model.stub valid?: true
|
44
|
+
expect(subject).to be_available(model)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns true for valid?" do
|
48
|
+
model.stub valid?: false
|
49
|
+
expect(subject).not_to be_available(model)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "unless .available?" do
|
54
|
+
let(:action_options) { {unless: :valid?} }
|
55
|
+
|
56
|
+
it "returns true for valid models" do
|
57
|
+
model.stub valid?: false
|
58
|
+
expect(subject).to be_available(model)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns false for invalid models" do
|
62
|
+
model.stub valid?: true
|
63
|
+
expect(subject).not_to be_available(model)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TableCloth::Extensions::Actions do
|
4
|
+
let(:dummy_table) { FactoryGirl.build(:dummy_table) }
|
5
|
+
|
6
|
+
context "inclusion" do
|
7
|
+
it "gives the table class an actions method" do
|
8
|
+
expect { dummy_table.send(:include, described_class) }.to change { dummy_table.respond_to? :actions }.to true
|
9
|
+
end
|
10
|
+
|
11
|
+
context ".actions" do
|
12
|
+
before(:each) { dummy_table.send(:include, described_class) }
|
13
|
+
|
14
|
+
it "yields an ActionCollection block" do
|
15
|
+
block_type = nil
|
16
|
+
dummy_table.actions { block_type = self }
|
17
|
+
expect(block_type).to be_kind_of TableCloth::Extensions::Actions::ActionCollection
|
18
|
+
end
|
19
|
+
|
20
|
+
it "creates an actions column on the table" do
|
21
|
+
dummy_table.actions { }
|
22
|
+
expect(dummy_table.columns).to have_key :actions
|
23
|
+
end
|
24
|
+
|
25
|
+
it "accepts options" do
|
26
|
+
dummy_table.actions(if: :admin?) { }
|
27
|
+
expect(dummy_table.columns[:actions][:options]).to have_key :if
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sets a collection key for the column pointing to the collection object" do
|
31
|
+
dummy_table.actions { }
|
32
|
+
expect(dummy_table.columns[:actions][:options][:collection]).to be_kind_of TableCloth::Extensions::Actions::ActionCollection
|
33
|
+
end
|
34
|
+
|
35
|
+
it "sets the column class to an action column" do
|
36
|
+
dummy_table.actions { }
|
37
|
+
column = dummy_table.columns[:actions]
|
38
|
+
expect(column[:class]).to eq(TableCloth::Extensions::Actions::Column)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/lib/presenter_spec.rb
CHANGED
@@ -10,50 +10,48 @@ describe TableCloth::Presenter do
|
|
10
10
|
let(:view_context) { ActionView::Base.new }
|
11
11
|
subject { TableCloth::Presenter.new(objects, dummy_table, view_context) }
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
before(:each) { table_instance.stub admin?: false, awesome?: true }
|
17
|
-
|
18
|
-
it 'returns all names' do
|
19
|
-
dummy_table.column :name, :email
|
20
|
-
subject.column_names.should =~ ["Id", "Name", "Email"]
|
13
|
+
context ".columns" do
|
14
|
+
it "returns all columns from the table" do
|
15
|
+
expect(subject).to have(3).columns
|
21
16
|
end
|
22
17
|
|
23
|
-
it
|
24
|
-
|
25
|
-
|
18
|
+
it "returns them as columns" do
|
19
|
+
subject.columns.each do |column|
|
20
|
+
expect(column).to be_kind_of TableCloth::Column
|
21
|
+
end
|
26
22
|
end
|
27
23
|
|
28
|
-
|
29
|
-
dummy_table.
|
30
|
-
|
31
|
-
|
24
|
+
context "that are unavaialble" do
|
25
|
+
let(:dummy_table) { FactoryGirl.build(:dummy_table, email: {if: :admin?}) }
|
26
|
+
let(:table_instance) { dummy_table.new(objects, view_context) }
|
27
|
+
before(:each) do
|
28
|
+
table_instance.stub admin?: false
|
29
|
+
subject.stub table: table_instance
|
32
30
|
end
|
33
|
-
subject.column_names.should include 'Actions'
|
34
|
-
end
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
specify "are not returned" do
|
33
|
+
expect(subject).to have(0).columns
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "name is not returned" do
|
37
|
+
expect(subject.column_names).not_to include "email"
|
38
|
+
end
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
context ".column_names" do
|
43
|
+
let(:table_instance) { dummy_table.new(objects, view_context) }
|
44
|
+
before(:each) { table_instance.stub admin?: false, awesome?: true }
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
action {|object, view| link_to 'Edit', '/model/1/edit' }
|
46
|
+
it 'returns all names' do
|
47
|
+
subject.column_names.should == ["Id", "Name", "Email"]
|
49
48
|
end
|
50
|
-
|
51
|
-
actions_value = subject.row_values(dummy_model).last
|
52
|
-
column = Nokogiri::HTML(actions_value)
|
53
|
-
column.at_xpath('//a')[:href].should == '/model/1/edit'
|
54
|
-
column.at_xpath('//a').text.should == 'Edit'
|
55
49
|
end
|
56
50
|
|
51
|
+
it 'returns all values for a row' do
|
52
|
+
subject.row_values(dummy_model).should == [dummy_model.id, dummy_model.name, dummy_model.email]
|
53
|
+
end
|
54
|
+
|
57
55
|
it 'generates the values for all of the rows' do
|
58
56
|
expected = objects.map {|o| [o.id, o.name, o.email] }
|
59
57
|
expect(subject.rows).to eq(expected)
|
@@ -2,197 +2,134 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe TableCloth::Presenters::Default do
|
4
4
|
let(:dummy_table) { Class.new(DummyTable) }
|
5
|
-
let(:dummy_model)
|
6
|
-
DummyModel.new.tap do |d|
|
7
|
-
d.id = 1
|
8
|
-
d.email = 'robert@example.com'
|
9
|
-
d.name = 'robert'
|
10
|
-
end
|
11
|
-
end
|
5
|
+
let(:dummy_model) { FactoryGirl.build(:dummy_model) }
|
12
6
|
|
13
7
|
let(:objects) do
|
14
|
-
|
8
|
+
FactoryGirl.build_list(:dummy_model, 3)
|
15
9
|
end
|
16
10
|
|
17
11
|
let(:view_context) { ActionView::Base.new }
|
18
12
|
subject { TableCloth::Presenters::Default.new(objects, dummy_table, view_context) }
|
19
13
|
|
20
|
-
|
21
|
-
|
22
|
-
doc = Nokogiri::HTML(header)
|
14
|
+
context "header" do
|
15
|
+
let(:column_names) { ["Col1", "Col2"] }
|
23
16
|
|
24
|
-
|
25
|
-
|
17
|
+
before(:each) do
|
18
|
+
subject.stub column_names: column_names
|
19
|
+
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
it "creates a thead" do
|
22
|
+
expect(subject.render_header).to have_tag "thead"
|
23
|
+
end
|
29
24
|
|
30
|
-
|
31
|
-
|
25
|
+
it "creates th's" do
|
26
|
+
header = Nokogiri::HTML(subject.render_header)
|
27
|
+
expect(header.css("th").size).to be 2
|
28
|
+
end
|
32
29
|
|
33
|
-
th
|
30
|
+
it "creates th's with the correct text" do
|
31
|
+
header = Nokogiri::HTML(subject.render_header)
|
32
|
+
header.css("th").each_with_index {|th, i| expect(th.text).to eq(column_names[i]) }
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
tbody
|
42
|
-
|
43
|
-
|
44
|
-
row.xpath('.//td').each_with_index do |td, td_index|
|
45
|
-
object = objects[row_index]
|
46
|
-
case td_index
|
47
|
-
when 0
|
48
|
-
object.id.to_s == td.text
|
49
|
-
when 1
|
50
|
-
object.name.should == td.text
|
51
|
-
when 2
|
52
|
-
object.email.should == td.text
|
53
|
-
end
|
54
|
-
end
|
36
|
+
context "rows" do
|
37
|
+
it 'creates a tbody' do
|
38
|
+
expect(subject.render_rows).to have_tag "tbody"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates a row in the tbody" do
|
42
|
+
tbody = Nokogiri::HTML(subject.render_rows)
|
43
|
+
expect(tbody.css('tr').size).to be 3
|
55
44
|
end
|
56
45
|
end
|
57
46
|
|
58
47
|
context 'escaped values' do
|
59
48
|
let(:objects) do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
d.name = '<script>alert("Im in your columns, snatching your main thread.")</script>'
|
64
|
-
end
|
65
|
-
|
66
|
-
[model]
|
49
|
+
FactoryGirl.build_list(:dummy_model, 1,
|
50
|
+
name: "<script>alert(\"Im in your columns, snatching your main thread.\")</script>"
|
51
|
+
)
|
67
52
|
end
|
68
53
|
|
69
54
|
it 'does not allow unescaped values in columns' do
|
70
|
-
|
71
|
-
doc = Nokogiri::HTML(rows)
|
55
|
+
tbody = Nokogiri::HTML(subject.render_rows).at_xpath('//tbody')
|
72
56
|
|
73
|
-
tbody = doc.xpath('//tbody')
|
74
57
|
tbody.xpath('//td').each do |td|
|
75
58
|
td.at_xpath('.//script').should_not be_present
|
76
59
|
end
|
77
60
|
end
|
78
61
|
end
|
79
62
|
|
80
|
-
it 'creates an entire table' do
|
81
|
-
doc = Nokogiri::HTML(subject.render_table)
|
82
|
-
table = doc.xpath('//table')
|
83
|
-
table.should be_present
|
84
|
-
|
85
|
-
thead = table.xpath('.//thead')
|
86
|
-
thead.should be_present
|
87
|
-
|
88
|
-
tbody = table.at_xpath('.//tbody')
|
89
|
-
tbody.should be_present
|
90
|
-
|
91
|
-
tbody.xpath('.//tr').length.should == 3
|
92
|
-
end
|
93
|
-
|
94
63
|
context 'configuration' do
|
95
|
-
before(:all) do
|
96
|
-
TableCloth::Configuration.configure do |config|
|
97
|
-
config.table.class = 'table'
|
98
|
-
config.thead.class = 'thead'
|
99
|
-
config.th.class = 'th'
|
100
|
-
config.tbody.class = 'tbody'
|
101
|
-
config.tr.class = 'tr'
|
102
|
-
config.td.class = 'td'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
64
|
let(:doc) { Nokogiri::HTML(subject.render_table) }
|
107
65
|
|
108
66
|
it 'tables have a class attached' do
|
67
|
+
TableCloth.stub config_for: {class: "table"}
|
109
68
|
doc.at_xpath('//table')[:class].should include 'table'
|
110
69
|
end
|
111
70
|
|
112
71
|
it 'thead has a class attached' do
|
72
|
+
TableCloth.stub config_for: {class: "thead"}
|
113
73
|
doc.at_xpath('//thead')[:class].should include 'thead'
|
114
74
|
end
|
115
75
|
|
116
76
|
it 'th has a class attached' do
|
77
|
+
TableCloth.stub config_for: {class: "th"}
|
117
78
|
doc.at_xpath('//th')[:class].should include 'th'
|
118
79
|
end
|
119
80
|
|
120
81
|
it 'tbody has a class attached' do
|
82
|
+
TableCloth.stub config_for: {class: "tbody"}
|
121
83
|
doc.at_xpath('//tbody')[:class].should include 'tbody'
|
122
84
|
end
|
123
85
|
|
124
86
|
it 'tr has a class attached' do
|
87
|
+
TableCloth.stub config_for: {class: "tr"}
|
125
88
|
doc.at_xpath('//tr')[:class].should include 'tr'
|
126
89
|
end
|
127
90
|
|
128
91
|
it 'td has a class attached' do
|
92
|
+
TableCloth.stub config_for: {class: "td"}
|
129
93
|
doc.at_xpath('//td')[:class].should include 'td'
|
130
94
|
end
|
131
95
|
|
132
96
|
end
|
133
97
|
|
134
|
-
context
|
135
|
-
let(:
|
136
|
-
|
137
|
-
column :email, td_options: { class: 'email_column' }
|
138
|
-
end
|
139
|
-
end
|
98
|
+
context "column configuration" do
|
99
|
+
let(:column) { FactoryGirl.build(:column, options: {td_options: {class: "email_column"}}) }
|
100
|
+
let(:model) { FactoryGirl.build(:dummy_model) }
|
140
101
|
|
141
|
-
it
|
142
|
-
|
143
|
-
|
102
|
+
it "td has a class set" do
|
103
|
+
td = Nokogiri::HTML(subject.render_td(column, model)).at_css("td")
|
104
|
+
expect(td[:class]).to eq "email_column"
|
144
105
|
end
|
145
106
|
|
146
|
-
context
|
147
|
-
|
148
|
-
|
149
|
-
specify 'actions column has a class set' do
|
150
|
-
doc = Nokogiri::HTML(subject.render_table)
|
151
|
-
td = doc.at_css('td:last')
|
152
|
-
td[:class].should include "actions"
|
107
|
+
context "by value of row column" do
|
108
|
+
before(:each) do
|
109
|
+
column.stub value: ["robert@example.com", {class: "special-class"}]
|
153
110
|
end
|
154
111
|
|
155
|
-
|
156
|
-
|
157
|
-
Class.new(TableCloth::Base) do
|
158
|
-
actions do
|
159
|
-
action { nil }
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
it "changes nil to empty string" do
|
165
|
-
doc = Nokogiri::HTML(subject.render_table)
|
166
|
-
td = doc.at_css('td:last')
|
167
|
-
expect(td.text).to eq "\n"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
context 'by value of row column' do
|
173
|
-
let(:dummy_table) { Class.new(DummyTableWithValueOptions) }
|
112
|
+
specify "column has options because of value" do
|
113
|
+
td = Nokogiri::HTML(subject.render_td(column, model)).at_css("td")
|
174
114
|
|
175
|
-
|
176
|
-
doc = Nokogiri::HTML(subject.render_table)
|
177
|
-
td = doc.at_xpath('//td')
|
178
|
-
expect(td.text).to include "robert@creativequeries.com"
|
115
|
+
expect(td.text).to include "robert@example.com"
|
179
116
|
expect(td[:class]).to eq("special-class")
|
180
117
|
end
|
181
118
|
end
|
182
119
|
end
|
183
120
|
|
184
|
-
context
|
121
|
+
context "table configuration" do
|
185
122
|
let(:doc) { Nokogiri::HTML(subject.render_table) }
|
186
123
|
let(:dummy_table) do
|
187
124
|
Class.new(TableCloth::Base) do
|
188
125
|
column :email
|
189
126
|
|
190
|
-
config.table.class =
|
191
|
-
config.thead.class =
|
192
|
-
config.th.class =
|
193
|
-
config.tbody.class =
|
194
|
-
config.tr.class =
|
195
|
-
config.td.class =
|
127
|
+
config.table.class = "table2"
|
128
|
+
config.thead.class = "thead2"
|
129
|
+
config.th.class = "th2"
|
130
|
+
config.tbody.class = "tbody2"
|
131
|
+
config.tr.class = "tr2"
|
132
|
+
config.td.class = "td2"
|
196
133
|
end
|
197
134
|
end
|
198
135
|
|
@@ -203,12 +140,12 @@ describe TableCloth::Presenters::Default do
|
|
203
140
|
Class.new(TableCloth::Base) do
|
204
141
|
column :email
|
205
142
|
|
206
|
-
config.table.class =
|
207
|
-
config.thead.class =
|
208
|
-
config.th.class =
|
209
|
-
config.tbody.class =
|
210
|
-
config.tr.class =
|
211
|
-
config.td.class =
|
143
|
+
config.table.class = "table2"
|
144
|
+
config.thead.class = "thead2"
|
145
|
+
config.th.class = "th2"
|
146
|
+
config.tbody.class = "tbody2"
|
147
|
+
config.tr.class = "tr2"
|
148
|
+
config.td.class = "td2"
|
212
149
|
end
|
213
150
|
end
|
214
151
|
|