active_component 0.1.2
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/.document +4 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +65 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/active_component.gemspec +104 -0
- data/init.rb +1 -0
- data/lib/active_component.rb +196 -0
- data/lib/active_component/base.rb +930 -0
- data/lib/active_component/components/block.rb +20 -0
- data/lib/active_component/components/empty_tag.rb +26 -0
- data/lib/active_component/components/heading.rb +60 -0
- data/lib/active_component/components/inline_tag.rb +24 -0
- data/lib/active_component/components/section.rb +39 -0
- data/lib/active_component/components/table.rb +61 -0
- data/lib/active_component/config.rb +33 -0
- data/lib/active_component/core_extensions.rb +99 -0
- data/lib/active_component/template_handler.rb +20 -0
- data/pkg/active_component-0.1.2.gem +0 -0
- data/spec/active_component_spec.rb +156 -0
- data/spec/active_component_spec_helper.rb +10 -0
- data/spec/base_spec.rb +154 -0
- data/spec/components/block_spec.rb +51 -0
- data/spec/components/heading_spec.rb +95 -0
- data/spec/components/section_spec.rb +35 -0
- data/spec/components/table_spec.rb +88 -0
- data/spec/core_extensions_spec.rb +62 -0
- data/spec/factories.rb +23 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +15 -0
- metadata +166 -0
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe ActiveComponent::Base do
|
4
|
+
|
5
|
+
context "component initialization" do
|
6
|
+
describe "html_class" do
|
7
|
+
it "should include the hyphenized component title" do
|
8
|
+
g = GreetingBox.new
|
9
|
+
g.title = "Happy greeting box"
|
10
|
+
g.instance_eval {[html_class].flatten}.should be_include 'happy-greeting-box'
|
11
|
+
d = Div.new
|
12
|
+
d.title = "Happy div"
|
13
|
+
d.instance_eval {[html_class].flatten}.should be_include 'happy-div'
|
14
|
+
end
|
15
|
+
it "should include the class_name unless it is an html tag wrapper" do
|
16
|
+
g = GreetingBox.new
|
17
|
+
g.instance_eval {[html_class].flatten}.should be_include 'greeting-box'
|
18
|
+
d = Div.new
|
19
|
+
d.instance_eval {[html_class].flatten}.should_not be_include 'div'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class NewsWidget < ActiveComponent::Base
|
24
|
+
attr_accessor :author
|
25
|
+
|
26
|
+
def initialize(*args, &content_block)
|
27
|
+
init_component(args, [:content, :title, :author, :attributes], &content_block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "init_component" do
|
32
|
+
context "custom component" do
|
33
|
+
before :all do
|
34
|
+
@news_content = "The pope claims that condoms are not necessarily evil. Where is this heading to?"
|
35
|
+
# TODO support for special character removal pending
|
36
|
+
#@news_title = "Scandal in the Vatican!"
|
37
|
+
@news_title = "Scandal in the Vatican"
|
38
|
+
@news_author = "Karl Atzinger"
|
39
|
+
@news_attributes = {:class => 'gossip', :title => 'click to read whole article'}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set all parameters correctly when given in order" do
|
43
|
+
n = NewsWidget.new @news_content, @news_title, @news_author, {:class => 'gossip'}
|
44
|
+
n.content.should == @news_content
|
45
|
+
n.title.should == @news_title
|
46
|
+
n.author.should == @news_author
|
47
|
+
n.attributes.should == {:class => ['scandal-in-the-vatican', 'news-widget', 'gossip']}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should set all parameters correctly when given as key value pairs" do
|
51
|
+
n = NewsWidget.new :attributes => @news_attributes, :title => @news_title, :content => @news_content, :author => @news_author
|
52
|
+
n.content.should == @news_content
|
53
|
+
n.title.should == @news_title
|
54
|
+
n.author.should == @news_author
|
55
|
+
n.attributes.should == {:title => @news_attributes[:title], :class => ['scandal-in-the-vatican', 'news-widget', 'gossip']}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set all parameters correctly when given in a mixed way" do
|
59
|
+
n = NewsWidget.new @news_title, @news_author, :content => @news_content, :attributes => @news_attributes
|
60
|
+
n.content.should == @news_content
|
61
|
+
n.title.should == @news_title
|
62
|
+
n.author.should == @news_author
|
63
|
+
n.attributes.should == {:title => @news_attributes[:title], :class => ['scandal-in-the-vatican', 'news-widget', 'gossip']}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should prioritize content blocks over content arguments" do
|
67
|
+
n = NewsWidget.new(:content => "ignorable") { @news_content }
|
68
|
+
n.content.should == @news_content
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should fill @attributes with remaining arguments of the last hash" do
|
72
|
+
n = NewsWidget.new @news_title, :id => 'news', :content => @news_content, :class => @news_attributes[:class]
|
73
|
+
n.content.should == @news_content
|
74
|
+
n.title.should == @news_title
|
75
|
+
n.attributes.should == {:id => 'news', :class => ['scandal-in-the-vatican', 'news-widget', 'gossip']}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "html wrapper component (grand-child of base)" do
|
80
|
+
before :all do
|
81
|
+
@bq_content = "It is better to be quotable than to be honest."
|
82
|
+
@bq_title = "Tom Stoppard on Quotations"
|
83
|
+
@bq_attributes = {:class => 'quotes', :cites => "http://www.quotationspage.com/quote/368.html"}
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set all parameters correctly when given in order" do
|
87
|
+
bq = Blockquote.new @bq_content, @bq_title, @bq_author, @bq_attributes
|
88
|
+
bq.content.should == @bq_content
|
89
|
+
bq.title.should == @bq_title
|
90
|
+
bq.attributes.should == {:cites => @bq_attributes[:cites], :class => [@bq_title.hyphenize, 'quotes']}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should set all parameters correctly when given as key value pairs" do
|
94
|
+
bq = Blockquote.new :attributes => @bq_attributes, :title => @bq_title, :content => @bq_content
|
95
|
+
bq.content.should == @bq_content
|
96
|
+
bq.title.should == @bq_title
|
97
|
+
bq.attributes.should == {:cites => @bq_attributes[:cites], :class => [@bq_title.hyphenize, 'quotes']}
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should set all parameters correctly when given in a mixed way" do
|
101
|
+
bq = Blockquote.new @bq_title, :content => @bq_content, :attributes => @bq_attributes
|
102
|
+
bq.content.should == @bq_content
|
103
|
+
bq.title.should == @bq_title
|
104
|
+
bq.attributes.should == {:cites => @bq_attributes[:cites], :class => [@bq_title.hyphenize, 'quotes']}
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should prioritize content blocks over content arguments" do
|
108
|
+
bq = Blockquote.new(:content => "ignorable") { @bq_content }
|
109
|
+
bq.content.should == @bq_content
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should fill attributes with remaining arguments of the last hash" do
|
113
|
+
bq = Blockquote.new @bq_title, :cites => "http://www.quotationspage.com/quote/368.html", :content => @bq_content, :class => 'quotes'
|
114
|
+
bq.content.should == @bq_content
|
115
|
+
bq.title.should == @bq_title
|
116
|
+
bq.attributes.should == {:cites => @bq_attributes[:cites], :class => [@bq_title.hyphenize, 'quotes']}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "tree node management" do
|
124
|
+
it "should enable to add nodes as children" do
|
125
|
+
a = Block.new
|
126
|
+
b = Block.new("foo")
|
127
|
+
c = Block.new("bar")
|
128
|
+
a << b
|
129
|
+
a << c
|
130
|
+
a[b.object_id].should == b
|
131
|
+
children = []
|
132
|
+
a.children {|child| children << child.node_name}
|
133
|
+
children.should == [b.object_id, c.object_id]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "instantiation helpers" do
|
138
|
+
it "should be available after creating a component" do
|
139
|
+
class NewGreetingBox < ActiveComponent::Base; end
|
140
|
+
ActiveComponent.instance_methods.map(&:to_sym).should be_include(:new_greeting_box)
|
141
|
+
end
|
142
|
+
|
143
|
+
# TODO: How to test this?
|
144
|
+
it "should be available to ActionView and render output"
|
145
|
+
# class GreetingBox < ActiveComponent::Base
|
146
|
+
# def initialize(*args, &content_block); init_component(args, [:content], &content_block); end
|
147
|
+
# def to_html; Span.new("Hello " + print_object(content), :class => 'greeting').to_html; end
|
148
|
+
# end
|
149
|
+
# ActiveComponent::TemplateHandler.new.instance_eval { compile(greeting_box("world")) }.should == "not specified yet"
|
150
|
+
# end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Block do
|
4
|
+
include ActiveComponent
|
5
|
+
include Haml::Helpers
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@content = "It is better to be quotable than to be honest."
|
9
|
+
@title = "Tom Stoppard on Quotations"
|
10
|
+
@tag_type = :blockquote
|
11
|
+
@attributes = {:class => 'quotes', :cites => "http://www.quotationspage.com/quote/368.html"}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "initialize" do
|
15
|
+
it "should assume :div as default block type" do
|
16
|
+
block = Block.new { @content }
|
17
|
+
block.tag_type.should == :div
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not be possible to overwrite tag_type for subclasses of Block" do
|
21
|
+
for elem in ActiveComponent::BLOCK_ELEMENTS
|
22
|
+
elem_class = elem.to_s.camelize.constantize
|
23
|
+
block = elem_class.new(:tag_type => :block) { @content }
|
24
|
+
block.tag_type.should == elem
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "to_html" do
|
30
|
+
it "should render nested blocks" do
|
31
|
+
init_buffer
|
32
|
+
block = Block.new @title, @tag_type, @attributes do
|
33
|
+
[
|
34
|
+
Block.new(@title, :tag_type => :h1),
|
35
|
+
Block.new(@content, :tag_type => :p),
|
36
|
+
Block.new("Details", :tag_type => :aside) do
|
37
|
+
print_buffer do
|
38
|
+
tag_to_buffer :dl do
|
39
|
+
tag_to_buffer :dt, "Author"
|
40
|
+
tag_to_buffer :dd, "Tom Stoppard"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
]
|
45
|
+
end
|
46
|
+
block.to_html.should == "<#{@tag_type} cites='#{@attributes[:cites]}' class='#{@title.hyphenize} block #{@attributes[:class]}'>\n <h1 class='block'>\n #{@title}\n </h1>\n <p class='block'>\n #{@content}\n </p>\n <aside class='details block'>\n <dl>\n <dt>Author</dt>\n <dd>Tom Stoppard</dd>\n </dl>\n \n </aside>\n \n</#{@tag_type}>\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Heading do
|
4
|
+
include ActiveComponent
|
5
|
+
include Haml::Helpers
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@content = "Wall Street Retreats in the Face of a Slowdown"
|
9
|
+
@title = "Business News"
|
10
|
+
@level = 3
|
11
|
+
@attributes = {:class => 'news business'}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "siblings_level" do
|
15
|
+
|
16
|
+
it "should adopt correct siblings level" do
|
17
|
+
h1 = Heading.new('header 1', :level => 3)
|
18
|
+
h2 = Heading.new
|
19
|
+
h3 = Heading.new [h1, h2]
|
20
|
+
h2.siblings_level.should == 3
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return nil if no heading sibling exists" do
|
24
|
+
h1 = Heading.new
|
25
|
+
h2 = Heading.new h1
|
26
|
+
h1.siblings_level.should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return nil if existing heading sibling has no rank" do
|
30
|
+
h1 = Heading.new('header 1')
|
31
|
+
h2 = Heading.new
|
32
|
+
h3 = Heading.new [h1, h2]
|
33
|
+
h2.siblings_level.should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "determine_level" do
|
39
|
+
|
40
|
+
it "should return the rank of a given sibling Heading" do
|
41
|
+
h1 = Heading.new(:level => 3)
|
42
|
+
h2 = Heading.new
|
43
|
+
h3 = Heading.new([h1, h2])
|
44
|
+
|
45
|
+
h2.determine_level.should == 3
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should determine heading rank correctly based on the hierarchy" do
|
49
|
+
h1 = Heading.new('header 1')
|
50
|
+
h2 = Heading.new('header 2')
|
51
|
+
h3 = Heading.new('header 3')
|
52
|
+
div2 = Div.new(:content => [h2, h3])
|
53
|
+
div = Div.new(:content => [
|
54
|
+
h1,
|
55
|
+
div2
|
56
|
+
])
|
57
|
+
h2.determine_level.should == 2
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
describe "to_html" do
|
64
|
+
|
65
|
+
it "should compute heading levels automatically based on the node hierarchy" do
|
66
|
+
section = Section.new(:heading => @title, :content => [
|
67
|
+
Heading.new("It's better to be honest!"),
|
68
|
+
Section.new(:heading => "Tom Stoppard", :content => [
|
69
|
+
Div.new(:title => "Some div inbetween", :content => [
|
70
|
+
Heading.new("Yet Another Heading"),
|
71
|
+
Section.new("Details", :heading => "Leaf Heading")
|
72
|
+
])
|
73
|
+
])
|
74
|
+
])
|
75
|
+
section.to_html.should == "<section>\n <h1 class='heading'>\n Business News\n </h1>\n \n <h1 class='heading'>\n It's better to be honest!\n </h1>\n \n <section>\n <h2 class='heading'>\n Tom Stoppard\n </h2>\n \n <div class='some-div-inbetween'>\n <h3 class='heading'>\n Yet Another Heading\n </h3>\n \n <section>\n <h4 class='heading'>\n Leaf Heading\n </h4>\n \n Details\n </section>\n \n </div>\n \n </section>\n \n</section>\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should compute heading levels automatically also when block syntax used" do
|
79
|
+
section = Section.new(:heading => @title, :content => [
|
80
|
+
Heading.new("It's better to be honest!"),
|
81
|
+
Section.new(:heading => "Tom Stoppard", :content => [
|
82
|
+
Div.new(:title => "Some div inbetween") do
|
83
|
+
[
|
84
|
+
Heading.new("Yet Another Heading"),
|
85
|
+
Section.new("Details", :heading => "Leaf Heading")
|
86
|
+
]
|
87
|
+
end
|
88
|
+
])
|
89
|
+
])
|
90
|
+
section.to_html.should == "<section>\n <h1 class='heading'>\n Business News\n </h1>\n \n <h1 class='heading'>\n It's better to be honest!\n </h1>\n \n <section>\n <h2 class='heading'>\n Tom Stoppard\n </h2>\n \n <div class='some-div-inbetween'>\n <h3 class='heading'>\n Yet Another Heading\n </h3>\n \n <section>\n <h4 class='heading'>\n Leaf Heading\n </h4>\n \n Details\n </section>\n \n </div>\n \n </section>\n \n</section>\n"
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Section do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@content = "It is better to be quotable than to be honest."
|
7
|
+
@title = "Tom Stoppard on Quotations"
|
8
|
+
@tag_type = :blockquote
|
9
|
+
@attributes = {:class => 'quotes', :cites => "http://www.quotationspage.com/quote/368.html"}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "initialize" do
|
13
|
+
it "should assume :section as default section type" do
|
14
|
+
section = Section.new @content
|
15
|
+
section.tag_type.should == :section
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not be possible to overwrite tag_type for subclasses of section" do
|
19
|
+
for elem in ActiveComponent::SECTION_ELEMENTS
|
20
|
+
elem_class = elem.to_s.camelize.constantize
|
21
|
+
section = elem_class.new(:tag_type => :section) { @content }
|
22
|
+
section.tag_type.should == elem
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "to_html" do
|
28
|
+
it "should be able to render nested sections"
|
29
|
+
|
30
|
+
it "should be able to render section subclasses" do
|
31
|
+
b = Blockquote.new(@content, @title, @attributes)
|
32
|
+
b.to_html.should == "<blockquote cites='http://www.quotationspage.com/quote/368.html' class='tom-stoppard-on-quotations quotes'>\n It is better to be quotable than to be honest.\n</blockquote>"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Table do
|
4
|
+
|
5
|
+
def things
|
6
|
+
things = []
|
7
|
+
things << Factory.build(:thing, :name => "thingamabob", :color => :yellow)
|
8
|
+
things << Factory.build(:thing, :name => "whatchamacallit", :color => :red)
|
9
|
+
things << Factory.build(:thing, :name => "gizmo", :color => :blue)
|
10
|
+
things
|
11
|
+
end
|
12
|
+
|
13
|
+
context "rendering a matrix of primitive data" do
|
14
|
+
it "should render without further input" do
|
15
|
+
content = [["a", 1, "first entry"], ["b", 2, "second entry"]]
|
16
|
+
table = Table.new content
|
17
|
+
table.to_html.should == "<table cellspacing='0' class='arrays'>\n <tr>\n <td>a</td>\n <td>1</td>\n <td>first entry</td>\n </tr>\n <tr>\n <td>b</td>\n <td>2</td>\n <td>second entry</td>\n </tr>\n</table>\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should render correctly with all inputs set" do
|
21
|
+
content = [["a", 1, "first entry"], ["b", 2, "second entry"]]
|
22
|
+
table = Table.new content, 'examples', :cols => :to_s, :headers => ["char", "number", "entry"]
|
23
|
+
table.to_html.should == "<table cellspacing='0' class='examples'>\n <tr>\n <th>char</th>\n <th>number</th>\n <th>entry</th>\n </tr>\n <tr>\n <td>a</td>\n <td>1</td>\n <td>first entry</td>\n </tr>\n <tr>\n <td>b</td>\n <td>2</td>\n <td>second entry</td>\n </tr>\n</table>\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "rendering a collection of complex objects (e.g. instances of an Active Record model)" do
|
28
|
+
it "should render without further input" do
|
29
|
+
things = [Factory.build(:thing), Factory.build(:thing, :name => "Whatchamacallit", :color => :red)]
|
30
|
+
table = Table.new things
|
31
|
+
table.to_html.should == "<table cellspacing='0' class='things'>\n <tr>\n <th>Name</th>\n <th>Color</th>\n </tr>\n <tr>\n <td>Thingamabob</td>\n <td>yellow</td>\n </tr>\n <tr>\n <td>Whatchamacallit</td>\n <td>red</td>\n </tr>\n</table>\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should render complex ojects correctly with all inputs set" do
|
35
|
+
color_temperature = proc {|thing| [:yellow, :orange, :red].include?(thing.color) ? "warm" : "cold"}
|
36
|
+
table = Table.new things, 'things-table', :cols => [:name, color_temperature], :headers => ["Name", "Color Temperature"]
|
37
|
+
table.to_html.should == "<table cellspacing='0' class='things-table'>\n <tr>\n <th>Name</th>\n <th>Color Temperature</th>\n </tr>\n <tr>\n <td>thingamabob</td>\n <td>warm</td>\n </tr>\n <tr>\n <td>whatchamacallit</td>\n <td>warm</td>\n </tr>\n <tr>\n <td>gizmo</td>\n <td>cold</td>\n </tr>\n</table>\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
# According Haml template code
|
41
|
+
#-----------------------------
|
42
|
+
# %table
|
43
|
+
# %tr
|
44
|
+
# %th Name
|
45
|
+
# %th Reverse Name
|
46
|
+
# %th Color Temperature
|
47
|
+
# - @things.each |thing| do
|
48
|
+
# %tr
|
49
|
+
# %td= thing.name
|
50
|
+
# %td= thing.name.reverse
|
51
|
+
# %td.color-temp
|
52
|
+
# - temp = [:yellow, :orange, :red].include?(thing.color) ? "warm" : "cold"
|
53
|
+
# %span{:class => temp}
|
54
|
+
# = temp + "!"
|
55
|
+
it "should render complex ojects using other components" do
|
56
|
+
table = Table.new(things, 'things-table', :headers => ["Name", "Color Temperature"], :cols => [
|
57
|
+
:name,
|
58
|
+
proc {|thing| thing.name.reverse},
|
59
|
+
proc do |thing|
|
60
|
+
temp = [:yellow, :orange, :red].include?(thing.color) ? "warm" : "cold"
|
61
|
+
Span.new(temp + "!", :class => temp)
|
62
|
+
end
|
63
|
+
])
|
64
|
+
table.to_html.should == "<table cellspacing='0' class='things-table'>\n <tr>\n <th>Name</th>\n <th>Color Temperature</th>\n </tr>\n <tr>\n <td>thingamabob</td>\n <td>bobamagniht</td>\n <td>\n <span class='warm'>\n warm!\n </span>\n \n </td>\n </tr>\n <tr>\n <td>whatchamacallit</td>\n <td>tillacamahctahw</td>\n <td>\n <span class='warm'>\n warm!\n </span>\n \n </td>\n </tr>\n <tr>\n <td>gizmo</td>\n <td>omzig</td>\n <td>\n <span class='cold'>\n cold!\n </span>\n \n </td>\n </tr>\n</table>\n"
|
65
|
+
end
|
66
|
+
#
|
67
|
+
# it "should render using short hand helper functions"
|
68
|
+
# pending {}
|
69
|
+
# #tab = table(things, 'color-table', :cols => [ col(:name, 'Name'), col(nil, 'Reverse Name') {|thing| thing.name.reverse} ])
|
70
|
+
# #col(:title => 'Color Temperature', :class => 'color-temp') { |thing|
|
71
|
+
# # temp = [:yellow, :orange, :red].include?(thing.color) ? "warm" : "cold"
|
72
|
+
# # span(temp + "!", :class => temp)
|
73
|
+
# #}
|
74
|
+
# #tab.to_html.should == "not specified yet"
|
75
|
+
# end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "passing HTML attributes" do
|
79
|
+
it "should forward attributes for headers" do
|
80
|
+
table = Table.new things, :title => "my-things",
|
81
|
+
:style => "padding: 10px", :class => "custom-class", :cellpadding => 0,
|
82
|
+
:header_attrs => [{:class => 'name-header', :width => '200px'}, {:id => 'temp-col-header', :style => 'color: red'}]
|
83
|
+
table.row_attrs = [{:class => 'head-row'}] + table.content.map {|thing| {:class => thing.name}}
|
84
|
+
table.to_html.should == "<table cellpadding='0' cellspacing='0' class='my-things custom-class' style='padding: 10px'>\n <tr class='head-row'>\n <th class='name-header' width='200px'>Name</th>\n <th id='temp-col-header' style='color: red'>Color</th>\n </tr>\n <tr class='thingamabob'>\n <td>thingamabob</td>\n <td>yellow</td>\n </tr>\n <tr class='whatchamacallit'>\n <td>whatchamacallit</td>\n <td>red</td>\n </tr>\n <tr class='gizmo'>\n <td>gizmo</td>\n <td>blue</td>\n </tr>\n</table>\n"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#TODO transmogrify on more than 2 levels
|
4
|
+
|
5
|
+
describe Object do
|
6
|
+
|
7
|
+
context "transmogrify" do
|
8
|
+
it "should yield self if its not enumerable" do
|
9
|
+
block = Proc.new {|x| x.to_s.to_sym}
|
10
|
+
obj = Object.new
|
11
|
+
obj.transmogrify(&block).should eql(block.call(obj))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context "transmogrify_with_index" do
|
15
|
+
it "should not differ from transmogrify" do
|
16
|
+
block = Proc.new {|x| x.to_s.to_sym}
|
17
|
+
obj = Object.new
|
18
|
+
obj.transmogrify_with_index(&block).should eql(obj.transmogrify(&block))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Enumerable do
|
25
|
+
|
26
|
+
context "transmogrify" do
|
27
|
+
before(:each) do
|
28
|
+
@has_yielded = false
|
29
|
+
@results = []
|
30
|
+
@block = Proc.new do |x|
|
31
|
+
@results << x.to_s.to_sym
|
32
|
+
@has_yielded = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
it "should yield each element" do
|
36
|
+
%w(a b c).transmogrify(&@block)
|
37
|
+
@has_yielded.should be_true
|
38
|
+
@results.should eql([:a, :b, :c])
|
39
|
+
end
|
40
|
+
after(:each) do
|
41
|
+
@has_yielded, @results, @block = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "transmogrify_with_index" do
|
46
|
+
before(:each) do
|
47
|
+
@has_yielded = false
|
48
|
+
@results = {}
|
49
|
+
@block = Proc.new do |elem, index|
|
50
|
+
@results[index] = elem.to_s.to_sym
|
51
|
+
end
|
52
|
+
end
|
53
|
+
it "should yield each element with index" do
|
54
|
+
%w(a b c).transmogrify_with_index(&@block)
|
55
|
+
@results.should == { 0 => :a, 1 => :b, 2 => :c }
|
56
|
+
end
|
57
|
+
after(:each) do
|
58
|
+
@result, @results, @block = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|