garterbelt 0.0.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 +5 -0
- data/.rspec +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +21 -0
- data/Rakefile +46 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/garterbelt.gemspec +165 -0
- data/lib/garterbelt.rb +23 -0
- data/lib/page.rb +46 -0
- data/lib/renderers/cache.rb +35 -0
- data/lib/renderers/closed_tag.rb +60 -0
- data/lib/renderers/comment.rb +14 -0
- data/lib/renderers/content_rendering.rb +41 -0
- data/lib/renderers/content_tag.rb +36 -0
- data/lib/renderers/doctype.rb +24 -0
- data/lib/renderers/renderer.rb +33 -0
- data/lib/renderers/text.rb +28 -0
- data/lib/renderers/xml.rb +9 -0
- data/lib/stocking.rb +11 -0
- data/lib/support/string.rb +165 -0
- data/lib/view.rb +341 -0
- data/spec/benchmark/templates/erector.rb +37 -0
- data/spec/benchmark/templates/garterbelt.rb +37 -0
- data/spec/benchmark/vs_erector.rb +53 -0
- data/spec/garterbelt_spec.rb +49 -0
- data/spec/integration/expectations/general_view.html +17 -0
- data/spec/integration/expectations/variables/view_with_user_and_params.html +23 -0
- data/spec/integration/expectations/variables/view_with_user_email.html +23 -0
- data/spec/integration/expectations/view_partial_nest.html +24 -0
- data/spec/integration/expectations/view_with_tags.html +19 -0
- data/spec/integration/templates/view_partial_nest.rb +22 -0
- data/spec/integration/templates/view_with_cache.rb +30 -0
- data/spec/integration/templates/view_with_partial.rb +36 -0
- data/spec/integration/templates/view_with_partial_2.rb +36 -0
- data/spec/integration/templates/view_with_tags.rb +26 -0
- data/spec/integration/templates/view_with_vars.rb +32 -0
- data/spec/integration/view_spec.rb +57 -0
- data/spec/page_spec.rb +99 -0
- data/spec/renderers/cache_spec.rb +85 -0
- data/spec/renderers/closed_tag_spec.rb +172 -0
- data/spec/renderers/comment_spec.rb +68 -0
- data/spec/renderers/content_tag_spec.rb +150 -0
- data/spec/renderers/doctype_spec.rb +46 -0
- data/spec/renderers/text_spec.rb +68 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/mock_view.rb +14 -0
- data/spec/support/puters.rb +10 -0
- data/spec/view/view_basics_spec.rb +106 -0
- data/spec/view/view_caching_spec.rb +132 -0
- data/spec/view/view_partial_spec.rb +63 -0
- data/spec/view/view_rails_type_helpers.rb +148 -0
- data/spec/view/view_render_spec.rb +408 -0
- data/spec/view/view_variables_spec.rb +159 -0
- metadata +367 -0
@@ -0,0 +1,172 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::ClosedTag do
|
4
|
+
ClosedTag = Garterbelt::ClosedTag unless defined?(ClosedTag)
|
5
|
+
|
6
|
+
before do
|
7
|
+
@output = ''
|
8
|
+
@view = mock(:output => @output, :level => 2)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'initialize' do
|
12
|
+
it 'requires a type' do
|
13
|
+
lambda{ ClosedTag.new({:view => @view}) }.should raise_error(ArgumentError, ":type required in initialization options")
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'requires a view' do
|
17
|
+
lambda{ ClosedTag.new({:type => :input}) }.should raise_error(ArgumentError, ":view required in initialization options")
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'store the type as an attribute' do
|
21
|
+
ClosedTag.new({:type => :input, :view => @view}).type.should == :input
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'attributes should be empty by default' do
|
25
|
+
ClosedTag.new(:type => :input, :view => @view).attributes.should == {}
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'sets the attributes' do
|
29
|
+
ClosedTag.new(:type => :input, :attributes => {:foo => :bar}, :view => @view).attributes.should == {:foo => :bar}
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'extracts css_class into its own variable' do
|
33
|
+
ClosedTag.new(:type => :input, :attributes => {:class => :foo}, :view => @view).css_class.should == [:foo]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'pooling' do
|
38
|
+
it 'include RuPol::Swimsuit' do
|
39
|
+
ClosedTag.ancestors.should include(RuPol::Swimsuit)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'has a really large max_pool_size' do
|
43
|
+
ClosedTag._pool.max_size.should == 10000
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'method chaining' do
|
48
|
+
before do
|
49
|
+
@tag = ClosedTag.new(:type => :input, :view => @view)
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#id' do
|
53
|
+
it 'adds an id attribute' do
|
54
|
+
@tag.id(:foo).attributes[:id].should == :foo
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises an argument error if passed an array or something non-stringy' do
|
58
|
+
lambda{ @tag.id([:foo, :bar]) }.should raise_error(ArgumentError, "Id must be a String or Symbol")
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns self' do
|
62
|
+
@tag.id(:foo).should === @tag
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#c' do
|
67
|
+
it 'adds the value to the css_class' do
|
68
|
+
@tag.c(:foo).css_class.should == [:foo]
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'will not overwrite existing css classes' do
|
72
|
+
@tag.c(:foo).css_class.should == [:foo]
|
73
|
+
@tag.c(:bar).css_class.should == [:foo, :bar]
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'takes any number of arguments' do
|
77
|
+
@tag.c(:foo, :bar).css_class.should == [:foo, :bar]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns self' do
|
81
|
+
@tag.c(:foo, :bar).should === @tag
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'view usage' do
|
87
|
+
before do
|
88
|
+
@tag = ClosedTag.new(:type => :input, :view => @view)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'uses its output' do
|
92
|
+
@tag.output.should == @output
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'uses its level' do
|
96
|
+
@tag.level.should == 2
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
describe 'rendering' do
|
102
|
+
before do
|
103
|
+
@tag = ClosedTag.new(
|
104
|
+
:type => :input,
|
105
|
+
:attributes => {:class => :foo_bar, :thing => :thong},
|
106
|
+
:view => @view
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'indent corresponding to the view level' do
|
111
|
+
@tag.indent.should == " "
|
112
|
+
@tag.stub(:level).and_return(1)
|
113
|
+
@tag.indent.should == " "
|
114
|
+
@tag.stub(:level).and_return(0)
|
115
|
+
@tag.indent.should == ""
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#rendered_attributes' do
|
119
|
+
it 'includes the css_class' do
|
120
|
+
@tag.rendered_attributes.should include "class=\"foo_bar\""
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'multiple classes are separated by a space' do
|
124
|
+
@tag.c(:more_classy)
|
125
|
+
@tag.rendered_attributes.should include "class=\"foo_bar more_classy\""
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'include other key/value pairs' do
|
129
|
+
@tag.rendered_attributes.should include "thing=\"thong\""
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'does not include attributes with nil or false values' do
|
133
|
+
@tag.attributes[:checked] = false
|
134
|
+
@tag.attributes[:nily] = nil
|
135
|
+
rendered = @tag.rendered_attributes
|
136
|
+
rendered.should_not include "checked=\"\""
|
137
|
+
rendered.should_not include "nily=\"\""
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should subs out double quotes from attributes' do
|
141
|
+
@tag.attributes[:foo_title] = 'I am not "sure" if this will work'
|
142
|
+
@tag.rendered_attributes.should include "I am not 'sure' if this will work"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'integration' do
|
147
|
+
before do
|
148
|
+
@str = @tag.render
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'starts with the indent' do
|
152
|
+
@str.should match /^\W{4}</
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'includes the full tag' do
|
156
|
+
@str.should match /<input[^>]*>/
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'includes the attributes' do
|
160
|
+
@str.should match /<input#{@tag.rendered_attributes}>/
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'ends with the closing tag and a line break' do
|
164
|
+
@str.should match /\n$/
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'adds the string to the output' do
|
168
|
+
@output.should include @str
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::Comment do
|
4
|
+
before :all do
|
5
|
+
@view = MockView.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'basics' do
|
9
|
+
it 'is decends from Renderer' do
|
10
|
+
Garterbelt::Comment.ancestors.should include Garterbelt::Renderer
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has conent' do
|
14
|
+
comment = Garterbelt::Comment.new(:view => @view, :content => "Initializing ...")
|
15
|
+
comment.content.should == "Initializing ..."
|
16
|
+
comment.content = "foo"
|
17
|
+
comment.content.should == "foo"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises an error when initializing without content' do
|
21
|
+
lambda{ Garterbelt::Comment.new(:view => @view) }.should raise_error(
|
22
|
+
ArgumentError, ":content option required for Garterbelt::Comment initialization"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'has a smaller pool size' do
|
27
|
+
Garterbelt::Comment._pool.max_size.should == 1000
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'render' do
|
32
|
+
before do
|
33
|
+
@view = MockView.new
|
34
|
+
@comment = Garterbelt::Comment.new(:view => @view, :content => 'Render me')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'raises an error with block content' do
|
38
|
+
@comment.content = lambda { puts "foo" }
|
39
|
+
lambda{ @comment.render }.should raise_error(ArgumentError, "Garterbelt::Comment does not take block content")
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'it adds the content to the output' do
|
43
|
+
@comment.render
|
44
|
+
@view.output.should include "Render me"
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'builds the right header tag' do
|
48
|
+
@comment.render
|
49
|
+
@view.output.should match /<!-- Render me/
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'builds the right footer tag' do
|
53
|
+
@comment.render
|
54
|
+
@view.output.should match /Render me -->/
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'indents to the view level' do
|
58
|
+
@comment.render
|
59
|
+
@view.output.should match /^\W{4}<!-- Render me/
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'does not escape the content' do
|
63
|
+
@comment.content = "<div>foo</div>"
|
64
|
+
@comment.render
|
65
|
+
@view.output.should include "<div>foo</div>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::ContentTag do
|
4
|
+
ContentTag = Garterbelt::ContentTag unless defined?(ContentTag)
|
5
|
+
|
6
|
+
before do
|
7
|
+
@view = MockView.new
|
8
|
+
@output = @view.output
|
9
|
+
@params = {:type => :p, :attributes => {:class => 'classy'}, :view => @view}
|
10
|
+
@tag = ContentTag.new(@params)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "basics" do
|
14
|
+
it 'takes a content option' do
|
15
|
+
ContentTag.new(@params.merge(:content => 'My great content')).content.should == "My great content"
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'takes a block as content' do
|
19
|
+
ContentTag.new(@params) do
|
20
|
+
@output << "This is block content"
|
21
|
+
end.content.class.should == Proc
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'will override option content in favor of block content' do
|
25
|
+
ContentTag.new(@params.merge(:content => 'not the block')) do
|
26
|
+
@output << "This is block content"
|
27
|
+
end.content.class.should == Proc
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'inherits a really large max_pool_size' do
|
31
|
+
ContentTag._pool.max_size.should == 10000
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'chaining' do
|
36
|
+
describe 'id' do
|
37
|
+
it 'takes a block and sets it to content' do
|
38
|
+
@tag.id(:foo) do
|
39
|
+
@output << "This is block content"
|
40
|
+
end
|
41
|
+
@tag.content.class.should == Proc
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns self' do
|
45
|
+
@tag.id(:foo).should === @tag
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'c' do
|
50
|
+
it 'takes a block and sets it to content' do
|
51
|
+
@tag.c(:foo) do
|
52
|
+
@output << "This is block content"
|
53
|
+
end
|
54
|
+
@tag.content.class.should == Proc
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns self' do
|
58
|
+
@tag.c(:foo).should === @tag
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'rendering' do
|
64
|
+
describe 'tags' do
|
65
|
+
before do
|
66
|
+
@tag.content = 'My string content'
|
67
|
+
@tag.render
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'indents the beginning tag correctly' do
|
71
|
+
@output.should match /^ <p/
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'renders the beginning tag correctly' do
|
75
|
+
@output.should include "<p class=\"classy\">"
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'indents the ending tag correctly' do
|
79
|
+
@output.should match /^ <\/p/
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'renders the ending tag correctly' do
|
83
|
+
@output.should include "</p>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'content' do
|
88
|
+
describe 'none' do
|
89
|
+
it 'works' do
|
90
|
+
@tag.content.should be_nil
|
91
|
+
@tag.render
|
92
|
+
@output.should match " <p class=\"classy\">\n </p>"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'string' do
|
97
|
+
before do
|
98
|
+
@tag.content = "My string content"
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'makes a Text object' do
|
102
|
+
Garterbelt::Text.should_receive(:new).and_return('text')
|
103
|
+
@tag.render
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'block' do
|
108
|
+
describe 'writing directly to output' do
|
109
|
+
before do
|
110
|
+
@tag.id(:foo) do
|
111
|
+
@output << "Going directly to the source"
|
112
|
+
end
|
113
|
+
@tag.render
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'adds the content' do
|
117
|
+
@output.should include "Going directly to the source"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'does not indent' do
|
121
|
+
@output.should match /^Going/
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should put the content between the tags' do
|
125
|
+
@output.should match /<p.*\nGoing.*<\/p/
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'adding to the tag buffer' do
|
130
|
+
before do
|
131
|
+
@b = Garterbelt::ClosedTag.new(:view => @view, :type => :hr, :attributes => {:class => :linear})
|
132
|
+
@tag.id(:foo) do
|
133
|
+
@view.buffer << @b
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should add the tag to the buffer' do
|
138
|
+
@tag.render
|
139
|
+
@view.buffer.should include @b
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'calls render buffer on the view' do
|
143
|
+
@view.should_receive(:render_buffer)
|
144
|
+
@tag.render
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::Doctype do
|
4
|
+
before :all do
|
5
|
+
@view = MockView.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'basics' do
|
9
|
+
it 'is decends from ClosedTag' do
|
10
|
+
Garterbelt::Doctype.ancestors.should include Garterbelt::ClosedTag
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has a smaller pool size' do
|
14
|
+
Garterbelt::Doctype._pool.max_size.should == 1000
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'render' do
|
19
|
+
before do
|
20
|
+
@view = MockView.new
|
21
|
+
@doctype = Garterbelt::Doctype.new(:view => @view, :type => :transitional)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'builds the right tag for type = :transitional' do
|
25
|
+
tag = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
|
26
|
+
@doctype.render.should include tag
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'builds the right tag for type = :strict' do
|
30
|
+
tag = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
31
|
+
@doctype.type = :strict
|
32
|
+
@doctype.render.should include tag
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'builds the right tag for type = :html5' do
|
36
|
+
tag = '<!DOCTYPE html>'
|
37
|
+
@doctype.type = :html5
|
38
|
+
@doctype.render.should include tag
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'indents to the view level' do
|
42
|
+
@doctype.render
|
43
|
+
@view.output.should match /^\W{4}<!DOCTYPE/
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::Text do
|
4
|
+
before :all do
|
5
|
+
@view = MockView.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'basics' do
|
9
|
+
it 'is decends from Renderer' do
|
10
|
+
Garterbelt::Text.ancestors.should include Garterbelt::Renderer
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has conent' do
|
14
|
+
text = Garterbelt::Text.new(:view => @view, :content => "Initializing ...")
|
15
|
+
text.content.should == "Initializing ..."
|
16
|
+
text.content = "foo"
|
17
|
+
text.content.should == "foo"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises an error when initializing without content' do
|
21
|
+
lambda{ Garterbelt::Text.new(:view => @view) }.should raise_error(
|
22
|
+
ArgumentError, ":content option required for Garterbelt::Text initialization"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'inherits its pool size' do
|
27
|
+
Garterbelt::Text._pool.max_size.should == 10000
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'render' do
|
32
|
+
before do
|
33
|
+
@view = MockView.new
|
34
|
+
@text = Garterbelt::Text.new(:view => @view, :content => 'Render me')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'raises an error with block content' do
|
38
|
+
@text.content = lambda { puts "foo" }
|
39
|
+
lambda{ @text.render }.should raise_error(ArgumentError, "Garterbelt::Text does not take block content")
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'it adds the content to the output' do
|
43
|
+
@text.render
|
44
|
+
@view.output.should include "Render me"
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'indents to the view level' do
|
48
|
+
@text.render
|
49
|
+
@view.output.should match /^\W{4}Render me\n$/
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'escaping' do
|
53
|
+
it 'escapes if view is set to escape' do
|
54
|
+
str = "<a href='/foo.com'>Foo it!</a>"
|
55
|
+
text = Garterbelt::Text.new(:view => @view, :content => str)
|
56
|
+
text.render.should_not include str
|
57
|
+
text.render.should include ERB::Util.html_escape(str)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not escape if the view is set to not escape' do
|
61
|
+
str = "<a href='/foo.com'>Foo it!</a>"
|
62
|
+
@view.escape = false
|
63
|
+
text = Garterbelt::Text.new(:view => @view, :content => str)
|
64
|
+
text.render.should include str
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
require 'hashie'
|
8
|
+
require 'garterbelt'
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
Dir["#{File.dirname(__FILE__)}/integration/templates/**/*.rb"].each {|f| require f}
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
include PutSpec
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class MockView
|
2
|
+
attr_accessor :output, :buffer, :level, :escape, :cache_store
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
self.buffer = []
|
6
|
+
self.output = ""
|
7
|
+
self.level ||= 2
|
8
|
+
self.escape = true
|
9
|
+
self.cache_store = Moneta::Memory.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def render_buffer
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Garterbelt::View do
|
4
|
+
class BasicView < Garterbelt::View
|
5
|
+
def content
|
6
|
+
end
|
7
|
+
|
8
|
+
def alt_content
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
@view = BasicView.new
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'pooling' do
|
17
|
+
it 'includes the swimsuit' do
|
18
|
+
BasicView.ancestors.should include( RuPol::Swimsuit )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'attributes' do
|
23
|
+
it 'has a tag buffer' do
|
24
|
+
@view.buffer.should == []
|
25
|
+
@tag = Garterbelt::ContentTag.new(:view => @view, :type => :hr)
|
26
|
+
@view.buffer << @tag
|
27
|
+
@view.buffer.should == [@tag]
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'output' do
|
31
|
+
it 'has an output' do
|
32
|
+
@view.output.should == ""
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'its output is that of the curator if the curator is not self' do
|
36
|
+
BasicView.new(:curator => @view).output.should === @view.output
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'escape' do
|
41
|
+
it 'has escape set to true by default' do
|
42
|
+
@view.escape.should == true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'can be set' do
|
46
|
+
@view.escape = false
|
47
|
+
@view.escape.should == false
|
48
|
+
BasicView.new(:escape => false).escape.should == false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'level' do
|
53
|
+
it 'is 0 by default' do
|
54
|
+
@view.level.should == 0
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can be set via initialization' do
|
58
|
+
BasicView.new(:level => 42).level.should == 42
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'setting the curator: view responsible for displaying the rendered content' do
|
63
|
+
before do
|
64
|
+
@view.level = 42
|
65
|
+
@view.output = "foo"
|
66
|
+
@view.buffer = ["bar"]
|
67
|
+
@view.escape = false
|
68
|
+
@child = BasicView.new(:curator => @view)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'is self by default' do
|
72
|
+
@view.curator.should == @view
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'can be set' do
|
76
|
+
@view.curator = BasicView.new
|
77
|
+
@view.curator.should_not == @view
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'can be intialized in' do
|
81
|
+
BasicView.new(:curator => @view).curator.should == @view
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'resets other attributes' do
|
85
|
+
it 'sets the output to the curator\'s' do
|
86
|
+
@child.output.should === @view.output
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'sets the level to the curator\'s' do
|
90
|
+
@child.level.should == @view.level
|
91
|
+
@child.level.should == 42
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'sets the buffer to the curator\'s' do
|
95
|
+
@child.buffer.should === @view.buffer
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'sets the escape to the curator\'s' do
|
99
|
+
@child.escape.should == @view.escape
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|