markaby 0.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG.rdoc +79 -0
  3. data/Markaby.gemspec +103 -0
  4. data/{README → README.rdoc} +14 -6
  5. data/Rakefile +71 -14
  6. data/VERSION +1 -0
  7. data/garlic.rb +29 -0
  8. data/init.rb +6 -0
  9. data/lib/markaby.rb +4 -9
  10. data/lib/markaby/builder.rb +156 -143
  11. data/lib/markaby/builder_tags.rb +64 -0
  12. data/lib/markaby/cssproxy.rb +36 -34
  13. data/lib/markaby/kernel_method.rb +7 -0
  14. data/lib/markaby/rails.rb +64 -39
  15. data/lib/markaby/rails/current.rb +46 -0
  16. data/lib/markaby/rails/deprecated.rb +124 -0
  17. data/lib/markaby/rails/rails_builder.rb +50 -0
  18. data/lib/markaby/tags.rb +158 -130
  19. data/lib/markaby/tilt.rb +21 -0
  20. data/spec/markaby/builder_spec.rb +118 -0
  21. data/spec/markaby/css_proxy_spec.rb +47 -0
  22. data/spec/markaby/fragment_spec.rb +10 -0
  23. data/spec/markaby/markaby_other_static.mab +1 -0
  24. data/spec/markaby/markaby_spec.rb +232 -0
  25. data/spec/markaby/rails/spec_helper.rb +21 -0
  26. data/spec/markaby/rails/views/markaby/_a_partial.mab +3 -0
  27. data/spec/markaby/rails/views/markaby/_partial_child_with_locals.mab +1 -0
  28. data/spec/markaby/rails/views/markaby/access_to_helpers.mab +1 -0
  29. data/spec/markaby/rails/views/markaby/broken.mab +7 -0
  30. data/spec/markaby/rails/views/markaby/correct_template_values.mab +5 -0
  31. data/spec/markaby/rails/views/markaby/form_for.mab +2 -0
  32. data/spec/markaby/rails/views/markaby/form_for_with_fields.mab +3 -0
  33. data/spec/markaby/rails/views/markaby/form_for_with_multiple_fields.mab +4 -0
  34. data/spec/markaby/rails/views/markaby/no_values_passed.mab +3 -0
  35. data/spec/markaby/rails/views/markaby/partial_parent.mab +1 -0
  36. data/spec/markaby/rails/views/markaby/partial_parent_with_locals.mab +7 -0
  37. data/spec/markaby/rails/views/markaby/render_erb_without_explicit_render_call.erb +1 -0
  38. data/spec/markaby/rails/views/markaby/render_explicit_but_empty_markaby_layout.mab +0 -0
  39. data/spec/markaby/rails/views/markaby/render_mab_without_explicit_render_call.mab +3 -0
  40. data/spec/markaby/rails/views/markaby/render_with_ivar.mab +3 -0
  41. data/spec/markaby/rails/views/markaby/renders_erb.rhtml +1 -0
  42. data/spec/markaby/rails_spec.rb +249 -0
  43. data/spec/markaby/rails_version_spec.rb +37 -0
  44. data/spec/markaby/tilt/erb.erb +1 -0
  45. data/spec/markaby/tilt/locals.mab +1 -0
  46. data/spec/markaby/tilt/markaby.mab +1 -0
  47. data/spec/markaby/tilt/markaby_other_static.mab +1 -0
  48. data/spec/markaby/tilt/render_twice.mab +1 -0
  49. data/spec/markaby/tilt/scope.mab +1 -0
  50. data/spec/markaby/tilt/yielding.mab +2 -0
  51. data/spec/markaby/tilt_spec.rb +86 -0
  52. data/spec/spec.opts +2 -0
  53. data/spec/spec_helper.rb +39 -0
  54. metadata +132 -52
  55. data/lib/markaby/metaid.rb +0 -16
  56. data/lib/markaby/template.rb +0 -12
  57. data/setup.rb +0 -1551
  58. data/test/test_markaby.rb +0 -109
  59. data/tools/rakehelp.rb +0 -106
@@ -1,107 +1,114 @@
1
1
  module Markaby
2
-
3
- FORM_TAGS = [ :form, :input, :select, :textarea ]
4
- SELF_CLOSING_TAGS = [ :base, :meta, :link, :hr, :br, :param, :img, :area, :input, :col ]
5
- NO_PROXY = [ :hr, :br ]
2
+ FORM_TAGS = [ :form, :input, :select, :textarea ]
3
+ SELF_CLOSING_TAGS = [ :base, :meta, :link, :hr, :br, :param, :img, :area, :input, :col, :frame ]
6
4
 
7
5
  # Common sets of attributes.
8
- AttrCore = [:id, :class, :style, :title]
9
- AttrI18n = [:lang, 'xml:lang'.intern, :dir]
10
- AttrEvents = [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, :onmousemove,
11
- :onmouseout, :onkeypress, :onkeydown, :onkeyup]
12
- AttrFocus = [:accesskey, :tabindex, :onfocus, :onblur]
6
+ AttrCore = [:id, :class, :style, :title]
7
+ AttrI18n = [:lang, 'xml:lang'.intern, :dir]
8
+ AttrEvents = [:onclick,
9
+ :ondblclick,
10
+ :onmousedown,
11
+ :onmouseup,
12
+ :onmouseover,
13
+ :onmousemove,
14
+ :onmouseout,
15
+ :onkeypress,
16
+ :onkeydown,
17
+ :onkeyup]
18
+ AttrFocus = [:accesskey, :tabindex, :onfocus, :onblur]
13
19
  AttrHAlign = [:align, :char, :charoff]
14
20
  AttrVAlign = [:valign]
15
- Attrs = AttrCore + AttrI18n + AttrEvents
21
+ Attrs = AttrCore + AttrI18n + AttrEvents
16
22
 
17
23
  # All the tags and attributes from XHTML 1.0 Strict
18
24
  class XHTMLStrict
19
25
  class << self
20
26
  attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
21
27
  end
22
- @doctype = ["-//W3C//DTD XHTML 1.0 Strict//EN", "DTD/xhtml1-strict.dtd"]
23
- @tagset = {
24
- :html => AttrI18n + [:id, :xmlns],
25
- :head => AttrI18n + [:id, :profile],
26
- :title => AttrI18n + [:id],
27
- :base => [:href, :id],
28
- :meta => AttrI18n + [:id, :http, :name, :content, :scheme, 'http-equiv'.intern],
29
- :link => Attrs + [:charset, :href, :hreflang, :type, :rel, :rev, :media],
30
- :style => AttrI18n + [:id, :type, :media, :title, 'xml:space'.intern],
31
- :script => [:id, :charset, :type, :src, :defer, 'xml:space'.intern],
32
- :noscript => Attrs,
33
- :body => Attrs + [:onload, :onunload],
34
- :div => Attrs,
35
- :p => Attrs,
36
- :ul => Attrs,
37
- :ol => Attrs,
38
- :li => Attrs,
39
- :dl => Attrs,
40
- :dt => Attrs,
41
- :dd => Attrs,
42
- :address => Attrs,
43
- :hr => Attrs,
44
- :pre => Attrs + ['xml:space'.intern],
28
+
29
+ @doctype = ['-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd']
30
+ @tagset = {
31
+ :html => AttrI18n + [:id, :xmlns],
32
+ :head => AttrI18n + [:id, :profile],
33
+ :title => AttrI18n + [:id],
34
+ :base => [:href, :id],
35
+ :meta => AttrI18n + [:id, :http, :name, :content, :scheme, 'http-equiv'.intern],
36
+ :link => Attrs + [:charset, :href, :hreflang, :type, :rel, :rev, :media],
37
+ :style => AttrI18n + [:id, :type, :media, :title, 'xml:space'.intern],
38
+ :script => [:id, :charset, :type, :src, :defer, 'xml:space'.intern],
39
+ :noscript => Attrs,
40
+ :body => Attrs + [:onload, :onunload],
41
+ :div => Attrs,
42
+ :p => Attrs,
43
+ :ul => Attrs,
44
+ :ol => Attrs,
45
+ :li => Attrs,
46
+ :dl => Attrs,
47
+ :dt => Attrs,
48
+ :dd => Attrs,
49
+ :address => Attrs,
50
+ :hr => Attrs,
51
+ :pre => Attrs + ['xml:space'.intern],
45
52
  :blockquote => Attrs + [:cite],
46
- :ins => Attrs + [:cite, :datetime],
47
- :del => Attrs + [:cite, :datetime],
48
- :a => Attrs + AttrFocus + [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords],
49
- :span => Attrs,
50
- :bdo => AttrCore + AttrEvents + [:lang, 'xml:lang'.intern, :dir],
51
- :br => AttrCore,
52
- :em => Attrs,
53
- :strong => Attrs,
54
- :dfn => Attrs,
55
- :code => Attrs,
56
- :samp => Attrs,
57
- :kbd => Attrs,
58
- :var => Attrs,
59
- :cite => Attrs,
60
- :abbr => Attrs,
61
- :acronym => Attrs,
62
- :q => Attrs + [:cite],
63
- :sub => Attrs,
64
- :sup => Attrs,
65
- :tt => Attrs,
66
- :i => Attrs,
67
- :b => Attrs,
68
- :big => Attrs,
69
- :small => Attrs,
70
- :object => Attrs + [:declare, :classid, :codebase, :data, :type, :codetype, :archive, :standby, :height, :width, :usemap, :name, :tabindex],
71
- :param => [:id, :name, :value, :valuetype, :type],
72
- :img => Attrs + [:src, :alt, :longdesc, :height, :width, :usemap, :ismap],
73
- :map => AttrI18n + AttrEvents + [:id, :class, :style, :title, :name],
74
- :area => Attrs + AttrFocus + [:shape, :coords, :href, :nohref, :alt],
75
- :form => Attrs + [:action, :method, :enctype, :onsubmit, :onreset, :accept, :accept],
76
- :label => Attrs + [:for, :accesskey, :onfocus, :onblur],
77
- :input => Attrs + AttrFocus + [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength, :src, :alt, :usemap, :onselect, :onchange, :accept],
78
- :select => Attrs + [:name, :size, :multiple, :disabled, :tabindex, :onfocus, :onblur, :onchange],
79
- :optgroup => Attrs + [:disabled, :label],
80
- :option => Attrs + [:selected, :disabled, :label, :value],
81
- :textarea => Attrs + AttrFocus + [:name, :rows, :cols, :disabled, :readonly, :onselect, :onchange],
82
- :fieldset => Attrs,
83
- :legend => Attrs + [:accesskey],
84
- :button => Attrs + AttrFocus + [:name, :value, :type, :disabled],
85
- :table => Attrs + [:summary, :width, :border, :frame, :rules, :cellspacing, :cellpadding],
86
- :caption => Attrs,
87
- :colgroup => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
88
- :col => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
89
- :thead => Attrs + AttrHAlign + AttrVAlign,
90
- :tfoot => Attrs + AttrHAlign + AttrVAlign,
91
- :tbody => Attrs + AttrHAlign + AttrVAlign,
92
- :tr => Attrs + AttrHAlign + AttrVAlign,
93
- :th => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
94
- :td => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
95
- :h1 => Attrs,
96
- :h2 => Attrs,
97
- :h3 => Attrs,
98
- :h4 => Attrs,
99
- :h5 => Attrs,
100
- :h6 => Attrs
53
+ :ins => Attrs + [:cite, :datetime],
54
+ :del => Attrs + [:cite, :datetime],
55
+ :a => Attrs + AttrFocus + [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords],
56
+ :span => Attrs,
57
+ :bdo => AttrCore + AttrEvents + [:lang, 'xml:lang'.intern, :dir],
58
+ :br => AttrCore,
59
+ :em => Attrs,
60
+ :strong => Attrs,
61
+ :dfn => Attrs,
62
+ :code => Attrs,
63
+ :samp => Attrs,
64
+ :kbd => Attrs,
65
+ :var => Attrs,
66
+ :cite => Attrs,
67
+ :abbr => Attrs,
68
+ :acronym => Attrs,
69
+ :q => Attrs + [:cite],
70
+ :sub => Attrs,
71
+ :sup => Attrs,
72
+ :tt => Attrs,
73
+ :i => Attrs,
74
+ :b => Attrs,
75
+ :big => Attrs,
76
+ :small => Attrs,
77
+ :object => Attrs + [:declare, :classid, :codebase, :data, :type, :codetype, :archive, :standby, :height, :width, :usemap, :name, :tabindex],
78
+ :param => [:id, :name, :value, :valuetype, :type],
79
+ :img => Attrs + [:src, :alt, :longdesc, :height, :width, :usemap, :ismap],
80
+ :map => AttrI18n + AttrEvents + [:id, :class, :style, :title, :name],
81
+ :area => Attrs + AttrFocus + [:shape, :coords, :href, :nohref, :alt],
82
+ :form => Attrs + [:action, :method, :enctype, :onsubmit, :onreset, :accept, :accept],
83
+ :label => Attrs + [:for, :accesskey, :onfocus, :onblur],
84
+ :input => Attrs + AttrFocus + [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength, :src, :alt, :usemap, :onselect, :onchange, :accept],
85
+ :select => Attrs + [:name, :size, :multiple, :disabled, :tabindex, :onfocus, :onblur, :onchange],
86
+ :optgroup => Attrs + [:disabled, :label],
87
+ :option => Attrs + [:selected, :disabled, :label, :value],
88
+ :textarea => Attrs + AttrFocus + [:name, :rows, :cols, :disabled, :readonly, :onselect, :onchange],
89
+ :fieldset => Attrs,
90
+ :legend => Attrs + [:accesskey],
91
+ :button => Attrs + AttrFocus + [:name, :value, :type, :disabled],
92
+ :table => Attrs + [:summary, :width, :border, :frame, :rules, :cellspacing, :cellpadding],
93
+ :caption => Attrs,
94
+ :colgroup => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
95
+ :col => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
96
+ :thead => Attrs + AttrHAlign + AttrVAlign,
97
+ :tfoot => Attrs + AttrHAlign + AttrVAlign,
98
+ :tbody => Attrs + AttrHAlign + AttrVAlign,
99
+ :tr => Attrs + AttrHAlign + AttrVAlign,
100
+ :th => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
101
+ :td => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
102
+ :h1 => Attrs,
103
+ :h2 => Attrs,
104
+ :h3 => Attrs,
105
+ :h4 => Attrs,
106
+ :h5 => Attrs,
107
+ :h6 => Attrs
101
108
  }
102
109
 
103
- @tags = @tagset.keys
104
- @forms = @tags & FORM_TAGS
110
+ @tags = @tagset.keys
111
+ @forms = @tags & FORM_TAGS
105
112
  @self_closing = @tags & SELF_CLOSING_TAGS
106
113
  end
107
114
 
@@ -110,51 +117,56 @@ module Markaby
110
117
  class << self
111
118
  attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
112
119
  end
113
- @doctype = ["-//W3C//DTD XHTML 1.0 Transitional//EN", "DTD/xhtml1-transitional.dtd"]
114
- @tagset = XHTMLStrict.tagset.merge \
115
- :strike => Attrs,
116
- :center => Attrs,
117
- :dir => Attrs + [:compact],
120
+
121
+ @doctype = ['-//W3C//DTD XHTML 1.0 Transitional//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd']
122
+ @tagset = XHTMLStrict.tagset.merge({
123
+ :strike => Attrs,
124
+ :center => Attrs,
125
+ :dir => Attrs + [:compact],
118
126
  :noframes => Attrs,
119
- :basefont => [:id, :size, :color, :face],
120
- :u => Attrs,
121
- :menu => Attrs + [:compact],
122
- :iframe => AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :scrolling, :align, :height, :width],
123
- :font => AttrCore + AttrI18n + [:size, :color, :face],
124
- :s => Attrs,
125
- :applet => AttrCore + [:codebase, :archive, :code, :object, :alt, :name, :width, :height, :align, :hspace, :vspace],
126
- :isindex => AttrCore + AttrI18n + [:prompt]
127
+ :basefont => [:id, :size, :color, :face],
128
+ :u => Attrs,
129
+ :menu => Attrs + [:compact],
130
+ :iframe => AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :scrolling, :align, :height, :width],
131
+ :font => AttrCore + AttrI18n + [:size, :color, :face],
132
+ :s => Attrs,
133
+ :applet => AttrCore + [:codebase, :archive, :code, :object, :alt, :name, :width, :height, :align, :hspace, :vspace],
134
+ :isindex => AttrCore + AttrI18n + [:prompt]
135
+ })
127
136
 
128
137
  # Additional attributes found in XHTML 1.0 Transitional
129
- { :script => [:language],
130
- :a => [:target],
131
- :td => [:bgcolor, :nowrap, :width, :height],
132
- :p => [:align],
133
- :h5 => [:align],
134
- :h3 => [:align],
135
- :li => [:type, :value],
136
- :div => [:align],
137
- :pre => [:width],
138
- :body => [:background, :bgcolor, :text, :link, :vlink, :alink],
139
- :ol => [:type, :compact, :start],
140
- :h4 => [:align],
141
- :h2 => [:align],
138
+ additional_tags = {
139
+ :script => [:language],
140
+ :a => [:target],
141
+ :td => [:bgcolor, :nowrap, :width, :height],
142
+ :p => [:align],
143
+ :h5 => [:align],
144
+ :h3 => [:align],
145
+ :li => [:type, :value],
146
+ :div => [:align],
147
+ :pre => [:width],
148
+ :body => [:background, :bgcolor, :text, :link, :vlink, :alink],
149
+ :ol => [:type, :compact, :start],
150
+ :h4 => [:align],
151
+ :h2 => [:align],
142
152
  :object => [:align, :border, :hspace, :vspace],
143
- :img => [:name, :align, :border, :hspace, :vspace],
144
- :link => [:target],
153
+ :img => [:name, :align, :border, :hspace, :vspace],
154
+ :link => [:target],
145
155
  :legend => [:align],
146
- :dl => [:compact],
147
- :input => [:align],
148
- :h6 => [:align],
149
- :hr => [:align, :noshade, :size, :width],
150
- :base => [:target],
151
- :ul => [:type, :compact],
152
- :br => [:clear],
153
- :form => [:name, :target],
154
- :area => [:target],
155
- :h1 => [:align]
156
- }.each do |k, v|
157
- @tagset[k] += v
156
+ :dl => [:compact],
157
+ :input => [:align],
158
+ :h6 => [:align],
159
+ :hr => [:align, :noshade, :size, :width],
160
+ :base => [:target],
161
+ :ul => [:type, :compact],
162
+ :br => [:clear],
163
+ :form => [:name, :target],
164
+ :area => [:target],
165
+ :h1 => [:align]
166
+ }
167
+
168
+ additional_tags.each do |k, v|
169
+ @tagset[k] += v
158
170
  end
159
171
 
160
172
  @tags = @tagset.keys
@@ -162,4 +174,20 @@ module Markaby
162
174
  @self_closing = @tags & SELF_CLOSING_TAGS
163
175
  end
164
176
 
177
+ # Additional tags found in XHTML 1.0 Frameset
178
+ class XHTMLFrameset
179
+ class << self
180
+ attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
181
+ end
182
+
183
+ @doctype = ['-//W3C//DTD XHTML 1.0 Frameset//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd']
184
+ @tagset = XHTMLTransitional.tagset.merge({
185
+ :frameset => AttrCore + [:rows, :cols, :onload, :onunload],
186
+ :frame => AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
187
+ })
188
+
189
+ @tags = @tagset.keys
190
+ @forms = @tags & FORM_TAGS
191
+ @self_closing = @tags & SELF_CLOSING_TAGS
192
+ end
165
193
  end
@@ -0,0 +1,21 @@
1
+ require 'tilt'
2
+
3
+ module Markaby
4
+ module Tilt
5
+ class Template < ::Tilt::Template
6
+ def evaluate(scope, locals, &block)
7
+ builder = Markaby::Builder.new({}, scope)
8
+ builder.locals = locals
9
+ builder.instance_eval(data, __FILE__, __LINE__)
10
+ builder.to_s
11
+ end
12
+
13
+ def prepare; end
14
+ end
15
+ end
16
+ end
17
+
18
+ module Tilt
19
+ MarkabyTemplate = Markaby::Tilt::Template
20
+ register "mab", MarkabyTemplate
21
+ end
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ module Markaby
4
+ describe Builder do
5
+ before do
6
+ Markaby::Builder.restore_defaults!
7
+ end
8
+
9
+ after do
10
+ Markaby::Builder.restore_defaults!
11
+ end
12
+
13
+ it "should have method missing as a private method" do
14
+ private_methods = Markaby::Builder.private_instance_methods.dup
15
+ private_methods.map! { |m| m.to_sym }
16
+ private_methods.should include(:method_missing)
17
+ end
18
+
19
+ describe "setting options" do
20
+ it "should be able to restore defaults after setting" do
21
+ Markaby::Builder.set :indent, 2
22
+ Markaby::Builder.restore_defaults!
23
+
24
+ Markaby::Builder.get(:indent).should == 0
25
+ end
26
+
27
+ it "should be able to set global options" do
28
+ Markaby::Builder.set :indent, 2
29
+ Markaby::Builder.get(:indent).should == 2
30
+ end
31
+ end
32
+
33
+ describe "hidden internal variables" do
34
+ # internal clobbering by passed in assigns
35
+ it "should not overwrite internal helpers ivar when assigning a :helpers key" do
36
+ helper = Class.new do
37
+ def some_method
38
+ "a value"
39
+ end
40
+ end.new
41
+
42
+ builder = Markaby::Builder.new({:helpers => nil}, helper)
43
+ builder.some_method.should == "a value"
44
+ end
45
+ end
46
+
47
+ describe "evaluating blocks" do
48
+ it "should evaluate a pure-string block (without requiring a call to the text method)" do
49
+ b = Builder.new do
50
+ "foo"
51
+ end
52
+
53
+ b.to_s.should == "foo"
54
+ end
55
+
56
+ it "should only evaluate the last argument in a pure-string block" do
57
+ b = Builder.new do
58
+ "foo"
59
+ "bar"
60
+ end
61
+
62
+ b.to_s.should == "bar"
63
+ end
64
+
65
+ it "should evaluate pure-strings inside an tag" do
66
+ b = Builder.new do
67
+ h1 do
68
+ "foo"
69
+ end
70
+ end
71
+
72
+ b.to_s.should == "<h1>foo</h1>"
73
+ end
74
+
75
+ it "should ignore a pure string in the block, even if comes last, if there has been any markup whatsoever" do
76
+ b = Builder.new do
77
+ h1
78
+ "foo"
79
+ end
80
+
81
+ b.to_s.should == "<h1/>"
82
+ end
83
+ end
84
+
85
+ describe "capture" do
86
+ before do
87
+ @builder = Builder.new
88
+ end
89
+
90
+ it "should return the string captured" do
91
+ out = @builder.capture do
92
+ h1 "TEST"
93
+ h2 "CAPTURE ME"
94
+ end
95
+
96
+ out.should == "<h1>TEST</h1><h2>CAPTURE ME</h2>"
97
+ end
98
+
99
+ it "should not change the output buffer" do
100
+ lambda {
101
+ @builder.capture do
102
+ h1 "FOO!"
103
+ end
104
+ }.should_not change { @builder.to_s }
105
+ end
106
+
107
+ it "should be able to capture inside a capture" do
108
+ out = @builder.capture do
109
+ capture do
110
+ h1 "foo"
111
+ end
112
+ end
113
+
114
+ out.should == "<h1>foo</h1>"
115
+ end
116
+ end
117
+ end
118
+ end