hammer_builder 0.1.2 → 0.2.0
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/CHANGELOG.md +4 -0
- data/README.md +24 -41
- data/lib/hammer_builder.rb +3 -699
- data/lib/hammer_builder/abstract.rb +205 -0
- data/lib/hammer_builder/abstract/abstract_double_tag.rb +148 -0
- data/lib/hammer_builder/abstract/abstract_single_tag.rb +18 -0
- data/lib/hammer_builder/abstract/abstract_tag.rb +233 -0
- data/lib/hammer_builder/data.rb +11 -0
- data/lib/hammer_builder/data/html5.rb +179 -0
- data/lib/hammer_builder/doc.rb +385 -0
- data/lib/hammer_builder/dynamic_classes.rb +136 -130
- data/lib/hammer_builder/formatted.rb +43 -0
- data/lib/hammer_builder/helper.rb +24 -0
- data/lib/hammer_builder/pool.rb +72 -0
- data/lib/hammer_builder/rails.rb +40 -0
- data/lib/hammer_builder/standard.rb +48 -0
- data/lib/hammer_builder/strings.rb +29 -0
- data/spec/hammer_builder_spec.rb +239 -146
- data/spec/spec_helper.rb +3 -1
- metadata +264 -96
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'hammer_builder/formatted'
|
2
|
+
|
3
|
+
warn '"hammer_builder/rails" is very early experiment'
|
4
|
+
|
5
|
+
module HammerBuilder::Rails
|
6
|
+
class AbstractBuilder
|
7
|
+
extend HammerBuilder::Helper
|
8
|
+
|
9
|
+
attr_reader :controller
|
10
|
+
|
11
|
+
def initialize(controller)
|
12
|
+
@controller = controller
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
ActionController::Renderers.add :hb do |klass_or_obj, options|
|
18
|
+
obj = case
|
19
|
+
when klass_or_obj.kind_of?(Class)
|
20
|
+
klass_or_obj.new(self)
|
21
|
+
when klass_or_obj.nil? || klass_or_obj == self
|
22
|
+
self.class.to_s.gsub(/Controller/, 'Builder').constantize.new(self)
|
23
|
+
else
|
24
|
+
klass_or_obj
|
25
|
+
end
|
26
|
+
|
27
|
+
$hammer_builder_pool ||= HammerBuilder::SynchronizedPool.new(HammerBuilder::Formatted) # FIXME
|
28
|
+
|
29
|
+
render(
|
30
|
+
:text => $hammer_builder_pool.get.
|
31
|
+
go_in { render obj, "#{options[:method] || options[:template]}" }.to_html!,
|
32
|
+
:layout => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'hammer_builder/abstract'
|
2
|
+
|
3
|
+
module HammerBuilder
|
4
|
+
|
5
|
+
# Builder implementation without formating (one line output)
|
6
|
+
class Standard < Abstract
|
7
|
+
|
8
|
+
dynamic_classes do
|
9
|
+
extend_class :AbstractTag do
|
10
|
+
# add global HTML5 attributes
|
11
|
+
self.add_attributes Data::HTML5.abstract_attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
Data::HTML5.double_tags.each do |tag|
|
15
|
+
next if tag.name == :html
|
16
|
+
|
17
|
+
def_class tag.name.to_s.camelize.to_sym, :AbstractDoubleTag do
|
18
|
+
set_tag tag.name
|
19
|
+
self.add_attributes tag.attributes
|
20
|
+
end
|
21
|
+
|
22
|
+
base.define_tag(tag.name)
|
23
|
+
end
|
24
|
+
|
25
|
+
html_tag = Data::HTML5.double_tags.find { |t| t.name == :html }
|
26
|
+
def_class :Html, :AbstractDoubleTag do
|
27
|
+
set_tag html_tag.name
|
28
|
+
self.add_attributes html_tag.attributes
|
29
|
+
|
30
|
+
def default
|
31
|
+
attribute :xmlns ,'http://www.w3.org/1999/xhtml'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
base.define_tag(html_tag.name)
|
35
|
+
|
36
|
+
Data::HTML5.single_tags.each do |tag|
|
37
|
+
def_class tag.name.to_s.camelize.to_sym, :AbstractSingleTag do
|
38
|
+
set_tag tag.name
|
39
|
+
self.add_attributes tag.attributes
|
40
|
+
end
|
41
|
+
|
42
|
+
base.define_tag(tag.name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HammerBuilder
|
2
|
+
module Strings
|
3
|
+
def self.add(name, value)
|
4
|
+
name = name.to_s.upcase
|
5
|
+
if const_defined?(name)
|
6
|
+
raise "values are different for const #{name}: #{[const_get(name), value].inspect}" if const_get(name) != value
|
7
|
+
else
|
8
|
+
const_set(name, value.freeze)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
add :lt, '<'
|
13
|
+
add :gt, '>'
|
14
|
+
add :slash_lt, '</'
|
15
|
+
add :slash_gt, ' />'
|
16
|
+
add :underscore, '_'
|
17
|
+
add :space, ' '
|
18
|
+
add :max_levels, 300
|
19
|
+
add :spaces, Array.new(MAX_LEVELS) { |i| (' ' * i).freeze }
|
20
|
+
add :newline, "\n"
|
21
|
+
add :quote, '"'
|
22
|
+
add :eql, '='
|
23
|
+
add :eql_quote, EQL + QUOTE
|
24
|
+
add :comment_start, '<!--'
|
25
|
+
add :comment_end, '-->'
|
26
|
+
add :cdata_start, '<![CDATA['
|
27
|
+
add :cdata_end, ']]>'
|
28
|
+
end
|
29
|
+
end
|
data/spec/hammer_builder_spec.rb
CHANGED
@@ -1,185 +1,278 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
describe HammerBuilder do
|
5
|
-
|
6
|
-
|
4
|
+
shared_examples "pool" do
|
5
|
+
it('should return correct instance') { pool.get.should be_kind_of(HammerBuilder::Formatted) }
|
6
|
+
it "should return instance into pool" do
|
7
|
+
pool.get.release
|
8
|
+
pool.size.should == 1
|
9
|
+
pool.get.to_html!
|
10
|
+
pool.size.should == 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe HammerBuilder::Pool do
|
15
|
+
let(:pool) { HammerBuilder::Pool.new HammerBuilder::Formatted }
|
16
|
+
include_examples 'pool'
|
17
|
+
end
|
18
|
+
|
19
|
+
describe HammerBuilder::SynchronizedPool do
|
20
|
+
let(:pool) { HammerBuilder::SynchronizedPool.new HammerBuilder::Formatted }
|
21
|
+
include_examples 'pool'
|
7
22
|
end
|
8
23
|
|
9
24
|
describe 'object with HammerBuilder::Helper' do
|
10
|
-
|
11
|
-
include HammerBuilder::Helper
|
25
|
+
let(:pool) { HammerBuilder::Pool.new HammerBuilder::Standard }
|
12
26
|
|
13
|
-
|
14
|
-
|
15
|
-
div 'a'
|
16
|
-
end
|
17
|
-
end
|
27
|
+
class User
|
28
|
+
extend HammerBuilder::Helper
|
18
29
|
|
19
|
-
|
30
|
+
builder :detail do |_, arg|
|
31
|
+
div arg
|
32
|
+
end
|
20
33
|
|
21
|
-
|
22
|
-
|
23
|
-
|
34
|
+
def detail2(b, arg)
|
35
|
+
b.div { b.text arg }
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
|
-
describe '
|
27
|
-
|
28
|
-
it
|
39
|
+
describe 'User.new' do
|
40
|
+
it { User.new.should be_respond_to(:detail) }
|
41
|
+
it "should render correctly" do
|
42
|
+
pool.get.dive(User.new) do |user|
|
43
|
+
render user, :detail, 'content'
|
44
|
+
render user, :detail2, 'content'
|
45
|
+
end.to_html!.should == "<div>content</div><div>content</div>"
|
46
|
+
end
|
29
47
|
end
|
48
|
+
|
30
49
|
end
|
31
50
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# describe '.define_class' do
|
42
|
-
# before do
|
43
|
-
# klass.define_class(:AClass) do
|
44
|
-
# def a_method
|
45
|
-
# end
|
46
|
-
# end
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# it { }
|
50
|
-
# end
|
51
|
-
# end
|
51
|
+
describe HammerBuilder::DynamicClasses do
|
52
|
+
class Parent
|
53
|
+
extend HammerBuilder::DynamicClasses
|
54
|
+
dc do
|
55
|
+
def_class :LeftEye do
|
56
|
+
def to_s;
|
57
|
+
'left eye';
|
58
|
+
end
|
59
|
+
end
|
52
60
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
61
|
+
def_class :RightEye, :LeftEye do
|
62
|
+
class_eval <<-RUBYCODE, __FILE__, __LINE__+1
|
63
|
+
def to_s; 'next to ' + super; end
|
64
|
+
RUBYCODE
|
65
|
+
end
|
58
66
|
end
|
67
|
+
end
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
(@builder = HammerBuilder::Standard.get).release!
|
63
|
-
end
|
69
|
+
class AChild < Parent
|
70
|
+
end
|
64
71
|
|
65
|
-
|
66
|
-
|
72
|
+
class AMutant < Parent
|
73
|
+
dc do
|
74
|
+
extend_class :LeftEye do
|
75
|
+
def to_s;
|
76
|
+
'laser ' + super;
|
77
|
+
end
|
67
78
|
end
|
68
79
|
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it '#to_s should print correct values' do
|
83
|
+
Parent.dc[:LeftEye].new.to_s.should == 'left eye'
|
84
|
+
Parent.dc[:RightEye].new.to_s.should == 'next to left eye'
|
85
|
+
AChild.dc[:LeftEye].new.to_s.should == 'left eye'
|
86
|
+
AChild.dc[:RightEye].new.to_s.should == 'next to left eye'
|
87
|
+
AMutant.dc[:LeftEye].new.to_s.should == 'laser left eye'
|
88
|
+
AMutant.dc[:RightEye].new.to_s.should == 'next to laser left eye'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should create different classes for each carrying class' do
|
92
|
+
Parent.dc[:LeftEye].should_not == AChild.dc[:LeftEye]
|
93
|
+
Parent.dc[:LeftEye].should_not == AMutant.dc[:LeftEye]
|
94
|
+
end
|
69
95
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
96
|
+
describe 'Parent.dc.class_names' do
|
97
|
+
it do
|
98
|
+
Parent.dc.class_names.should include(:LeftEye, :RightEye)
|
99
|
+
Parent.dc.class_names.should have(2).items
|
74
100
|
end
|
75
101
|
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe HammerBuilder::Standard do
|
105
|
+
let(:pool) { HammerBuilder::Pool.new HammerBuilder::Standard }
|
106
|
+
let(:builder) { pool.get }
|
107
|
+
|
108
|
+
def quick_render &block
|
109
|
+
builder.dive(&block).to_html!
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should render #content' do
|
113
|
+
quick_render { div 'content' }.should == '<div>content</div>'
|
114
|
+
quick_render { div.content 'content' }.should == '<div>content</div>'
|
115
|
+
quick_render { div :content => 'content' }.should == '<div>content</div>'
|
116
|
+
quick_render { div { text 'content' } }.should == '<div>content</div>'
|
117
|
+
quick_render { div.with { text 'content' } }.should == '<div>content</div>'
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should render #id' do
|
121
|
+
quick_render { div.id :an_id }.should == '<div id="an_id"></div>'
|
122
|
+
quick_render { div.an_id! }.should == '<div id="an_id"></div>'
|
123
|
+
quick_render { div.an_id! { text 'content' } }.should == '<div id="an_id">content</div>'
|
124
|
+
quick_render { div.an_id! 'content' }.should == '<div id="an_id">content</div>'
|
125
|
+
quick_render { div.an_id! }.should == '<div id="an_id"></div>'
|
126
|
+
quick_render { div :id => 12 }.should == '<div id="12"></div>'
|
127
|
+
quick_render { div 'asd', :id => 12 }.should == '<div id="12">asd</div>'
|
128
|
+
quick_render { hr.id 'an_id' }.should == '<hr id="an_id" />'
|
129
|
+
quick_render { hr.an_id! }.should == '<hr id="an_id" />'
|
130
|
+
quick_render { hr :id => 'an_id' }.should == '<hr id="an_id" />'
|
131
|
+
|
132
|
+
quick_render { hr.id 'an', 'id', nil, false }.should == '<hr id="an_id" />'
|
133
|
+
quick_render { div.id 'an', 'id', nil, false }.should == '<div id="an_id"></div>'
|
134
|
+
end
|
76
135
|
|
77
|
-
|
78
|
-
|
136
|
+
it 'should render #class' do
|
137
|
+
#noinspection RubyArgCount
|
138
|
+
quick_render { div.class 'an_class' }.should == '<div class="an_class"></div>'
|
139
|
+
quick_render { div.an_class }.should == '<div class="an_class"></div>'
|
140
|
+
quick_render { div :class => 'an_class' }.should == '<div class="an_class"></div>'
|
141
|
+
#noinspection RubyArgCount
|
142
|
+
quick_render { hr.class 'an_class' }.should == '<hr class="an_class" />'
|
143
|
+
quick_render { hr.an_class }.should == '<hr class="an_class" />'
|
144
|
+
quick_render { hr :class => 'an_class' }.should == '<hr class="an_class" />'
|
79
145
|
|
80
|
-
|
81
|
-
|
82
|
-
|
146
|
+
quick_render { div.an_class.another_class }.should == '<div class="an_class another_class"></div>'
|
147
|
+
#noinspection RubyArgCount
|
148
|
+
quick_render { div.class 'an_class', 'another_class' }.should == '<div class="an_class another_class"></div>'
|
149
|
+
quick_render { div :class => ['an_class', 'another_class'] }.should == '<div class="an_class another_class"></div>'
|
150
|
+
#noinspection RubyArgCount
|
151
|
+
quick_render { div.class(false, nil, 'an_class', true && 'another_class') }.should ==
|
152
|
+
'<div class="an_class another_class"></div>'
|
153
|
+
end
|
154
|
+
|
155
|
+
it "#attribute" do
|
156
|
+
quick_render { div.attribute 'xml:ns', 'gibris' }.should == '<div xml:ns="gibris"></div>'
|
157
|
+
quick_render { div.attribute(:class, 'a') { text 'asd' } }.should == '<div class="a">asd</div>'
|
158
|
+
end
|
159
|
+
|
160
|
+
it '#[]' do
|
161
|
+
obj = Object.new
|
162
|
+
quick_render { div[obj] }.should == %Q(<div id="object_#{obj.object_id}" class="object"></div>)
|
163
|
+
|
164
|
+
class AnObject
|
165
|
+
def self.hammer_builder_ref
|
166
|
+
"a"
|
83
167
|
end
|
84
168
|
|
85
|
-
|
86
|
-
|
87
|
-
after { @builder.release! }
|
88
|
-
subject { @builder.send(tag).methods }
|
89
|
-
it "should include its attribute methods" do
|
90
|
-
attrs = (HammerBuilder::GLOBAL_ATTRIBUTES + HammerBuilder::EXTRA_ATTRIBUTES[tag]).
|
91
|
-
map {|attr| attr.to_sym}
|
92
|
-
should include(*attrs)
|
93
|
-
end
|
169
|
+
def hammer_builder_ref
|
170
|
+
'b'
|
94
171
|
end
|
95
172
|
end
|
173
|
+
obj = AnObject.new
|
174
|
+
quick_render { div[obj] }.should == %Q(<div id="b" class="a"></div>)
|
96
175
|
|
176
|
+
obj = Object.new.extend(Module.new do
|
177
|
+
def id;
|
178
|
+
"an_id";
|
179
|
+
end
|
180
|
+
end)
|
181
|
+
quick_render { div[obj] }.should == %Q(<div id="object_an_id" class="object"></div>)
|
182
|
+
quick_render { div.mimic(obj) { text 'a' } }.should == %Q(<div id="object_an_id" class="object">a</div>)
|
97
183
|
end
|
98
184
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
meta.http_equiv CONTENT
|
111
|
-
p.content CONTENT
|
112
|
-
div.id CONTENT
|
113
|
-
div.data_id CONTENT
|
114
|
-
div :id => CONTENT, :content => CONTENT
|
115
|
-
div.attributes :id => CONTENT, :content => CONTENT
|
116
|
-
div.attribute :newone, CONTENT
|
117
|
-
div { text CONTENT }
|
118
|
-
div[CONTENT].with { article CONTENT }
|
119
|
-
js 'var < 1;'
|
120
|
-
div do
|
121
|
-
strong :content
|
122
|
-
text :content
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end.to_xhtml!.strip
|
127
|
-
end
|
185
|
+
it "#data-.*" do
|
186
|
+
quick_render { div('a').data_secret("I won't tell.") }.should == '<div data-secret="I won\'t tell.">a</div>'
|
187
|
+
end
|
188
|
+
|
189
|
+
it '#data' do
|
190
|
+
quick_render { hr.data(:secret => true) }.should == '<hr data-secret="true" />'
|
191
|
+
quick_render { div('a', :data => { :secret => "I won't tell." }) }.should ==
|
192
|
+
'<div data-secret="I won\'t tell.">a</div>'
|
193
|
+
quick_render { div('a').data(:secret => "I won't tell.") { text 'a' } }.should ==
|
194
|
+
'<div data-secret="I won\'t tell.">a</div>'
|
195
|
+
end
|
128
196
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
<body>
|
138
|
-
<div>cc<>&cc</div>
|
139
|
-
<meta http-equiv="cc<>&cc" />
|
140
|
-
<p>cc<>&cc</p>
|
141
|
-
<div id="cc<>&cc"></div>
|
142
|
-
<div data-id="cc<>&cc"></div>
|
143
|
-
<div id="cc<>&cc">cc<>&cc</div>
|
144
|
-
<div id="cc<>&cc">cc<>&cc</div>
|
145
|
-
<div newone="cc<>&cc"></div>
|
146
|
-
<div>cc<>&cc
|
147
|
-
</div>
|
148
|
-
<div id="cc<>&cc">
|
149
|
-
<article>cc<>&cc</article>
|
150
|
-
</div>
|
151
|
-
<script type="text/javascript"><![CDATA[var < 1;]]>
|
152
|
-
</script>
|
153
|
-
<div>
|
154
|
-
<strong>content</strong>content
|
155
|
-
</div>
|
156
|
-
</body>
|
157
|
-
</html>
|
158
|
-
STR
|
197
|
+
it 'tags should have all the attributes' do
|
198
|
+
builder.tags.each do |tag|
|
199
|
+
builder.should be_respond_to(tag)
|
200
|
+
tag_instance = builder.send(tag)
|
201
|
+
(HammerBuilder::Data::HTML5.abstract_attributes.map(&:name) +
|
202
|
+
(HammerBuilder::Data::HTML5.single_tags + HammerBuilder::Data::HTML5.double_tags).
|
203
|
+
find { |t| t.name.to_s == tag }.attributes.map(&:name)).each do |attr|
|
204
|
+
tag_instance.should be_respond_to(attr)
|
159
205
|
end
|
160
206
|
end
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
207
|
+
end
|
208
|
+
|
209
|
+
it "boolean attributes should render correctly" do
|
210
|
+
quick_render { input.readonly }.should == '<input readonly="readonly" />'
|
211
|
+
quick_render { option.selected { text 'asd' } }.should == '<option selected="selected">asd</option>'
|
212
|
+
quick_render { option.selected(true) }.should == '<option selected="selected"></option>'
|
213
|
+
quick_render { option.selected(1) }.should == '<option selected="selected"></option>'
|
214
|
+
quick_render { option.selected(false) }.should == '<option></option>'
|
215
|
+
quick_render { div.hidden('asd') }.should == '<div hidden="hidden"></div>'
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should render correctly" do
|
219
|
+
quick_render do
|
220
|
+
html5
|
221
|
+
html do
|
222
|
+
head do
|
223
|
+
title.an_id! 'a_title'
|
224
|
+
meta.charset "utf-8"
|
225
|
+
end
|
226
|
+
body.id 'content' do
|
227
|
+
text 'asd'
|
228
|
+
div.left.style nil do
|
229
|
+
raw 'asd'
|
230
|
+
hr
|
169
231
|
end
|
170
|
-
|
232
|
+
br
|
233
|
+
div.left do
|
234
|
+
hr
|
235
|
+
js 'asd'
|
236
|
+
js 'asd', :cdata => true
|
237
|
+
end
|
238
|
+
comment 'asd'
|
239
|
+
end
|
240
|
+
comment 'asd'
|
171
241
|
end
|
242
|
+
end.should == '<!DOCTYPE html>' + "\n" +
|
243
|
+
'<html xmlns="http://www.w3.org/1999/xhtml"><head><title id="an_id">a_title</title><meta charset="utf-8" />'+
|
244
|
+
'</head><body id="content">asd<div style="" class="left">asd<hr /></div><br /><div class="left"><hr />'+
|
245
|
+
'<script type="text/javascript">asd</script><script type="text/javascript"><![CDATA[asd]]></script>'+
|
246
|
+
'</div><!--asd--></body><!--asd--></html>'
|
247
|
+
end
|
172
248
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
249
|
+
it "#set variables" do
|
250
|
+
r = builder.set_variables(:a => 'a') do |b|
|
251
|
+
b.dive { p @a }
|
252
|
+
end.to_html!
|
253
|
+
|
254
|
+
r.should == '<p>a</p>'
|
255
|
+
builder.instance_variable_get(:@a).should be_nil
|
256
|
+
end
|
257
|
+
|
258
|
+
it "#join" do
|
259
|
+
quick_render { join([1, 2]) { |n| text n } }.should == '12'
|
260
|
+
quick_render { join([1, 2], 'a') { |n| text n } }.should == '1a2'
|
261
|
+
quick_render { join([lambda { text 1 }, 2], 'a') { |n| text n } }.should == '1a2'
|
262
|
+
quick_render { join([lambda { text 1 }, 2], lambda { text 'a' }) { |n| text n } }.should == '1a2'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe HammerBuilder::Formatted do
|
267
|
+
let(:pool) { HammerBuilder::Pool.new HammerBuilder::Formatted }
|
268
|
+
let(:builder) { pool.get }
|
269
|
+
|
270
|
+
def quick_render &block
|
271
|
+
builder.dive(&block).to_html!
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should be formatted" do
|
275
|
+
quick_render { div { comment 'asd'; br }; p }.should == "\n<div>\n <!--asd-->\n <br />\n</div>\n<p></p>"
|
183
276
|
end
|
184
277
|
end
|
185
|
-
end
|
278
|
+
end
|