pivotal-erector 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,165 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ require "erector/erect"
4
+
5
+ module Erector
6
+ describe Erect do
7
+ it "parses an empty command line" do
8
+ erect = Erect.new([])
9
+ erect.files.should == []
10
+ end
11
+
12
+ it "parses a command line with one filename on it" do
13
+ erect = Erect.new(["foo.html"])
14
+ erect.files.should == ["foo.html"]
15
+ end
16
+
17
+ it "parses a command line with several filenames on it" do
18
+ erect = Erect.new(["foo.html", "bar/baz.html"])
19
+ erect.files.should == ["foo.html", "bar/baz.html"]
20
+ end
21
+
22
+ it "is verbose by default, but quiet when told" do
23
+ Erect.new([]).verbose.should be_true
24
+ Erect.new(["-q"]).verbose.should be_false
25
+ end
26
+
27
+ it "parses a command line with several filenames and an option on it" do
28
+ erect = Erect.new(["-q", "foo.html", "bar/baz.html"])
29
+ erect.files.should == ["foo.html", "bar/baz.html"]
30
+ end
31
+
32
+ def capturing_output
33
+ output = StringIO.new
34
+ $stdout = output
35
+ yield
36
+ output.string
37
+ ensure
38
+ $stdout = STDOUT
39
+ end
40
+
41
+ it "exits immediately from help" do
42
+ output = capturing_output do
43
+ lambda {
44
+ erect = Erect.new(["-h"])
45
+ }.should raise_error(SystemExit)
46
+ end
47
+ output.should =~ /^Usage/
48
+ end
49
+
50
+ it "exits immediately from --version" do
51
+ output = capturing_output do
52
+ lambda {
53
+ erect = Erect.new(["--version"])
54
+ }.should raise_error(SystemExit)
55
+ end
56
+ output.should == Erector::VERSION + "\n"
57
+ end
58
+
59
+ it "changes to html output" do
60
+ erect = Erect.new(["--to-html"])
61
+ erect.mode.should == :to_html
62
+ end
63
+
64
+ it "changes to html output when passed a .rb file" do
65
+ pending do
66
+ erect = Erect.new(["foo.rb"])
67
+ erect.mode.should == :to_html
68
+ end
69
+ end
70
+
71
+ it "fails when given both .rb and .html files" do
72
+ pending do
73
+ lambda {
74
+ erect = Erect.new(["foo.rb", "bar.html"])
75
+ }.should raise_error
76
+ end
77
+ end
78
+
79
+ it "returns false when there's an error during run" do
80
+ capturing_output do
81
+ Erect.new(["MISSINGFILE"]).run.should == false
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ describe "Erect functionally" do
89
+
90
+ attr_reader :dir, :fred_html, :wilma_rhtml, :barney_html_erb, :fred_rb
91
+
92
+ def create(file, body="hi")
93
+ File.open(file, "w") do |f|
94
+ f.puts(body)
95
+ end
96
+ end
97
+
98
+ before :all do
99
+ @dir = Dir.tmpdir + "/#{Time.now.to_i}" + "/explode"
100
+ @fred_html = "#{dir}/fred.html"
101
+ @wilma_rhtml = "#{dir}/wilma.rhtml"
102
+ @barney_html_erb = "#{dir}/barney.html.erb"
103
+ @fred_rb = "#{dir}/fred.rb"
104
+
105
+ FileUtils.mkdir_p(dir)
106
+ create(fred_html)
107
+ create(wilma_rhtml)
108
+ create(barney_html_erb)
109
+ create(fred_rb, "class Fred < Erector::Widget\ndef content\ndiv 'dino'\nend\nend")
110
+ end
111
+
112
+ it "explodes dirs into .html etc. files when in to-rb mode" do
113
+ erect = Erect.new(["--to-erector", dir])
114
+ erect.files.sort.should == [barney_html_erb, fred_html, wilma_rhtml]
115
+ end
116
+
117
+ it "explodes dirs into .rb files when in to-html mode" do
118
+ erect = Erect.new(["--to-html", dir])
119
+ erect.files.should == [fred_rb]
120
+ end
121
+
122
+ it "outputs .rb files in the same directory as the input .html files" do
123
+ erect = Erect.new(["--to-erector", "-q", fred_html])
124
+ erect.run
125
+ File.exist?(fred_rb).should be_true
126
+ File.read(fred_rb).should include("text 'hi'")
127
+ end
128
+
129
+ it "outputs .html files in the same directory as the input .rb files" do
130
+ betty_rb = "#{dir}/betty.rb"
131
+ betty_html = "#{dir}/betty.html"
132
+ create(betty_rb, "class Betty < Erector::Widget\ndef content\ndiv 'bam bam'\nend\nend")
133
+
134
+ erect = Erect.new(["--to-html", "-q", betty_rb])
135
+ erect.run
136
+ File.exist?(betty_html).should be_true
137
+ File.read(betty_html).should == "<div>bam bam</div>\n"
138
+ end
139
+
140
+ it "outputs .html files in the given directory" do
141
+ create(fred_rb, "class Fred < Erector::Widget\ndef content\ndiv 'dino'\nend\nend")
142
+ out_dir = "#{dir}/out"
143
+ out_file = "#{out_dir}/fred.html"
144
+
145
+ Erect.new([]).output_dir.should be_nil
146
+ erect = Erect.new(["--to-html", "-o", "#{out_dir}", "-q", fred_rb])
147
+ erect.output_dir.should == out_dir
148
+ erect.run
149
+ File.exist?(out_file).should be_true
150
+ File.read(out_file).should == "<div>dino</div>\n"
151
+ end
152
+
153
+ it "skips rendering classes that aren't widgets" do
154
+ mr_slate_rb = "#{dir}/mr_slate.rb"
155
+ mr_slate_html = "#{dir}/mr_slate.html"
156
+ create(mr_slate_rb, "class MrSlate\nend")
157
+ erect = Erect.new(["-q", "--to-html", mr_slate_rb])
158
+ erect.run
159
+ File.exist?(mr_slate_html).should be_false
160
+ end
161
+
162
+ # it "properly indents lines beginning with for, unless, etc."
163
+ end
164
+
165
+ end
@@ -0,0 +1,93 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ require "erector/erect"
4
+
5
+ module Erector
6
+ describe Erected do
7
+
8
+ it "picks the right file name" do
9
+ Erected.new("foo.html.erb").filename.should == "foo.rb"
10
+ Erected.new("foo.html").filename.should == "foo.rb"
11
+ Erected.new("foo.bar.html").filename.should == "foo.rb"
12
+ Erected.new("foo_bar.html.erb").filename.should == "foo_bar.rb"
13
+ Erected.new("stuff/foo_bar.html.erb").filename.should == "stuff/foo_bar.rb"
14
+ end
15
+
16
+ it "picks a nice class name" do
17
+ Erected.new("foo.html.erb").classname.should == "Foo"
18
+ Erected.new("foo.html").classname.should == "Foo"
19
+ Erected.new("foo.bar.html").classname.should == "Foo"
20
+ Erected.new("foo_bar.html.erb").classname.should == "FooBar"
21
+ Erected.new("stuff/foo_bar.html.erb").classname.should == "FooBar"
22
+ end
23
+
24
+ it "picks an even nicer class name if it's in a views dir" do
25
+ Erected.new("app/views/stuff/foo_bar.html.erb").classname.should == "Views::Stuff::FooBar"
26
+ Erected.new("views/stuff/foo_bar.html.erb").classname.should == "Views::Stuff::FooBar"
27
+ end
28
+
29
+ it "uses Widget as the parent class" do
30
+ Erected.new("foo_bar.html").parent_class.should == "Erector::Widget"
31
+ Erected.new("foo_bar.html.erb").parent_class.should == "Erector::Widget"
32
+ Erected.new("stuff/foo_bar.html.erb").parent_class.should == "Erector::Widget"
33
+ end
34
+
35
+ it "uses RailsWidget as the parent class if it's in a views dir" do
36
+ Erected.new("app/views/stuff/foo_bar.html.erb").parent_class.should == "Erector::RailsWidget"
37
+ Erected.new("views/stuff/foo_bar.html.erb").parent_class.should == "Erector::RailsWidget"
38
+ end
39
+
40
+ def convert(dir, input, output)
41
+ dir = Dir.tmpdir + "/#{Time.now.to_i}" + "/#{dir}"
42
+
43
+ FileUtils.mkdir_p(dir)
44
+ html = "#{dir}/dummy.html"
45
+ rb = "#{dir}/dummy.rb"
46
+
47
+ File.open(html, "w") do |f|
48
+ f.puts(input)
49
+ end
50
+
51
+ @e = Erected.new(html)
52
+ @e.convert
53
+
54
+ File.read(rb).should == output
55
+ end
56
+
57
+ it "converts a normal file" do
58
+ convert(".",
59
+ "<div>hello</div>",
60
+ "class Dummy < Erector::Widget\n" +
61
+ " def content\n" +
62
+ " div do\n" +
63
+ " text 'hello'\n" +
64
+ " end\n" +
65
+ " end\n" +
66
+ "end\n"
67
+ )
68
+ end
69
+
70
+ it "converts a views file" do
71
+ convert("app/views/foos",
72
+ "<div>hello</div>",
73
+ "class Views::Foos::Dummy < Erector::RailsWidget\n" +
74
+ " def content\n" +
75
+ " div do\n" +
76
+ " text 'hello'\n" +
77
+ " end\n" +
78
+ " end\n" +
79
+ "end\n"
80
+ )
81
+ end
82
+
83
+ # todo: figure out if there is any such thing as unparsable HTML anymore
84
+ # it "raises an exception if given unparsable HTML" do
85
+ # begin
86
+ # convert(".", "<", "")
87
+ # rescue => e
88
+ # e.to_s.should include("Could not parse")
89
+ # end
90
+ # end
91
+
92
+ end
93
+ end
@@ -0,0 +1,351 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ require "erector/erect"
4
+
5
+ module ParserTestHelper
6
+ def assert_evals_to_self(input)
7
+ assert_evals_to(input, input)
8
+ end
9
+
10
+ def parse(input)
11
+ result = @parser.parse(input)
12
+ if result
13
+ result.set_indent(0) if result.respond_to? :set_indent
14
+ else
15
+ puts @parser.failure_reason
16
+ puts @parser.terminal_failures.join("\n")
17
+ result.should_not be_nil
18
+ end
19
+ result
20
+ end
21
+ end
22
+
23
+ describe RhtmlParser do
24
+ include ParserTestHelper
25
+
26
+ before :each do
27
+ @parser = RhtmlParser.new
28
+ end
29
+
30
+ it "converts text" do
31
+ parse("hello").convert.should == "text 'hello'\n"
32
+ parse("hello maude!").convert.should == "text 'hello maude!'\n"
33
+ parse(" hello ").convert.should == "text 'hello'\n"
34
+ end
35
+
36
+ it "unescapes HTML entities in text" do
37
+ parse("&lt;").convert.should == "text '<'\n"
38
+ parse("5 &gt; 2").convert.should == "text '5 > 2'\n"
39
+ end
40
+
41
+ it "converts self-closing tags" do
42
+ parse("<br/>").convert.should == "br\n"
43
+ parse("<br />").convert.should == "br\n"
44
+ end
45
+
46
+ it "converts open tag" do
47
+ parse("<div>").convert.should == "div do\n"
48
+ parse("<h1>").convert.should == "h1 do\n"
49
+ end
50
+
51
+ it "converts close tag" do
52
+ parse("</div>").convert.should == "end\n"
53
+ parse("</h1>").convert.should == "end\n"
54
+ end
55
+
56
+ it "converts two nested divs" do
57
+ parse("<div><div></div></div>").convert.should ==
58
+ "div do\n" +
59
+ " div do\n" +
60
+ " end\n" +
61
+ "end\n"
62
+ end
63
+
64
+ it "converts two nested divs with whitespace" do
65
+ parse("<div> <div> </div> </div>").convert.should ==
66
+ "div do\n" +
67
+ " div do\n" +
68
+ " end\n" +
69
+ "end\n"
70
+ end
71
+
72
+ it "converts no open, text, and no close tag" do
73
+ parse("hello</div>").convert.should == "text 'hello'\nend\n"
74
+ end
75
+
76
+ it "converts open, text, and no close tag" do
77
+ parse("<div>hello").convert.should == "div do\n text 'hello'\n"
78
+ end
79
+
80
+ it "converts open, text, close" do
81
+ parse("<div>hello</div>").convert.should == "div do\n text 'hello'\nend\n"
82
+ end
83
+
84
+ it "autocloses an img tag" do
85
+ parse("<img src='foo'>").convert.should == "img :src => 'foo'\n"
86
+ end
87
+
88
+ it "converts a scriptlet" do
89
+ parse("<% foo %>").convert.should == "foo\n"
90
+ end
91
+
92
+ it "converts open, text, scriptlet, text, close" do
93
+ parse("<div>hello <% 5.times do %> very <% end %> much</div>").convert.should ==
94
+ "div do\n" +
95
+ " text 'hello'\n" +
96
+ " 5.times do\n" +
97
+ " text 'very'\n" +
98
+ " end\n" +
99
+ " text 'much'\n" +
100
+ "end\n"
101
+ end
102
+
103
+ it "converts open, scriptlet, text, close" do
104
+ parse("<div><% 5.times do %> very <% end %> much</div>").convert.should ==
105
+ "div do\n" +
106
+ " 5.times do\n" +
107
+ " text 'very'\n" +
108
+ " end\n" +
109
+ " text 'much'\n" +
110
+ "end\n"
111
+ end
112
+
113
+ it "converts open, text, scriptlet, close" do
114
+ parse("<div>hello <% 5.times do %> very <% end %></div>").convert.should ==
115
+ "div do\n" +
116
+ " text 'hello'\n" +
117
+ " 5.times do\n" +
118
+ " text 'very'\n" +
119
+ " end\n" +
120
+ "end\n"
121
+ end
122
+
123
+ it "converts printlets into rawtext statements" do
124
+ parse("<%= 1+1 %>").convert.should == "rawtext 1+1\n"
125
+ parse("<%= link_to \"mom\" %>").convert.should == "rawtext link_to(\"mom\")\n"
126
+ end
127
+
128
+ it "converts h-printlets into text statements" do
129
+ parse("<%=h foo %>").convert.should == "text foo\n"
130
+ parse("<%= h \"mom\" %>").convert.should == "text \"mom\"\n"
131
+ end
132
+
133
+ it "allows naked percent signs inside scriptlets" do
134
+ parse("<% x = 10 % 5 %>").convert.should == "x = 10 % 5\n"
135
+ end
136
+
137
+ it "indents" do
138
+ i = Erector::Indenting.new(nil, nil)
139
+ i.line("foo").should == "foo\n"
140
+ i.line_in("bar").should == "bar\n"
141
+ i.line_in("baz").should == " baz\n"
142
+ i.line("baf").should == " baf\n"
143
+ i.line_out("end").should == " end\n"
144
+ i.line_out("end").should == "end\n"
145
+ end
146
+
147
+ it "indents extra when told to" do
148
+ parse("<div>hello</div>").set_indent(2).convert.should ==
149
+ " div do\n" +
150
+ " text 'hello'\n" +
151
+ " end\n"
152
+ end
153
+
154
+ it "indents scriptlets ending with do and end" do
155
+ parse("<% form_for :foo do |x,y| %><% 5.times do %>hello<% end %><% end %>bye").convert.should ==
156
+ "form_for :foo do |x,y|\n" +
157
+ " 5.times do\n" +
158
+ " text 'hello'\n" +
159
+ " end\n" +
160
+ "end\n" +
161
+ "text 'bye'\n"
162
+ end
163
+
164
+ it "converts HTML attributes" do
165
+ parse("<div id='foo'/>").convert.should == "div :id => 'foo'\n"
166
+ parse("<div id='foo' class='bar'/>").convert.should == "div :id => 'foo', :class => 'bar'\n"
167
+ parse("<div id='foo'>bar</div>").convert.should == "div :id => 'foo' do\n text 'bar'\nend\n"
168
+ end
169
+
170
+ it "escapes single quotes inside attribute values" do
171
+ @parser.root = :attribute
172
+ parse("a=\"don't worry\"").convert.should == ":a => 'don\\'t worry'"
173
+ end
174
+
175
+ it "escapes single quotes inside text strings" do
176
+ parse("isn't she lovely").convert.should == "text 'isn" + "\\" + "'t she lovely'\n"
177
+ end
178
+
179
+ it "allows newlines where whitespace is allowed" do
180
+ parse("<img src='foo' \nalt='bar' />").convert.should == "img :src => 'foo', :alt => 'bar'\n"
181
+ end
182
+
183
+ it "treats tab characters the same as spaces" do
184
+ parse("<div \t />").convert.should == "div\n"
185
+ end
186
+
187
+ it "deals with HTML entities in text" do
188
+ parse("&lt;").convert.should == "text '<'\n"
189
+ end
190
+
191
+ it "deals with a naked less-than or greater-than sign inside text" do
192
+ parse("if x > 2 or x< 5 then").convert.should == "text 'if x > 2 or x< 5 then'\n"
193
+ end
194
+
195
+ it "wraps printlets in parens if necessary, to avoid warning: parenthesize argument(s) for future version" do
196
+ parse("<%= h \"mom\" %>").convert.should == "text \"mom\"\n"
197
+ parse("<%= h hi \"mom\" %>").convert.should == "text hi(\"mom\")\n"
198
+
199
+ parse("<%= \"mom\" %>").convert.should == "rawtext \"mom\"\n"
200
+ parse("<%= \"hi mom\" %>").convert.should == "rawtext \"hi mom\"\n"
201
+ parse("<%= hi \"mom\" %>").convert.should == "rawtext hi(\"mom\")\n"
202
+
203
+ parse("<%= link_to blah %>").convert.should == "rawtext link_to(blah)\n"
204
+ parse("<%= link_to blah blah %>").convert.should == "rawtext link_to(blah blah)\n"
205
+ parse("<%= link_to blah(blah) %>").convert.should == "rawtext link_to(blah(blah))\n"
206
+
207
+ parse("<%= link_to(blah) %>").convert.should == "rawtext link_to(blah)\n"
208
+ end
209
+
210
+ it "won't parenthesize expressions" do
211
+ parse("<%= h foo / bar %>").convert.should == "text foo / bar\n"
212
+ end
213
+
214
+ it "understands a varname" do
215
+ @parser.root = :varname
216
+ parse("head").text_value.should == "head"
217
+ end
218
+
219
+ it "converts yield printlet into a use of @content_for_layout, commented for your edification" do
220
+ parse("<%= yield %>").convert.should == "rawtext @content_for_layout # Note: you must define @content_for_layout elsewhere\n"
221
+ parse("<%= yield :head %>").convert.should == "rawtext @content_for_head # Note: you must define @content_for_head elsewhere\n"
222
+ parse("<%= \"yield\" %>").convert.should == "rawtext \"yield\"\n"
223
+ parse("<%= \"the yield is good\" %>").convert.should == "rawtext \"the yield is good\"\n"
224
+ end
225
+
226
+ it "parses quoted strings" do
227
+ @parser.root = :quoted
228
+ parse("'foo'").value.should == "foo"
229
+ parse("\"foo\"").value.should == "foo"
230
+ end
231
+
232
+ it "converts attributes in isolation" do
233
+ @parser.root = :attribute
234
+ parse("a='foo'").convert.should == ":a => 'foo'"
235
+ parse("a=\"foo\"").convert.should == ":a => 'foo'"
236
+ end
237
+
238
+ it "parses a set of attributes" do
239
+ @parser.root = :attributes
240
+ parse("a='foo' b='bar'").convert.should == " :a => 'foo', :b => 'bar'"
241
+ end
242
+
243
+ it "works with namespaced attributes" do
244
+ @parser.root = :attribute
245
+ parse('xml:lang="en"').convert.should == "'xml:lang' => 'en'"
246
+ end
247
+
248
+ it "deals with HTML entities in attribute values" do
249
+ @parser.root = :attribute
250
+ parse("foo='b<r'").convert.should == ":foo => 'b<r'"
251
+ parse("foo='b&lt;r'").convert.should == ":foo => 'b<r'"
252
+ end
253
+
254
+ it "converts DOCTYPEs" do
255
+ html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
256
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
257
+ parse(html).convert.should == "rawtext '#{html}'\n"
258
+ end
259
+
260
+ ["<!--[if IE]>", "<![endif]-->", "<![if !IE]>", "<![endif]>", "<!--[if IE 5.5000]>", "<!--[if IE 6]>"].each do |html|
261
+ it "converts IE directive '#{html}'" do
262
+ parse(html).convert.should == "rawtext '#{html}'\n"
263
+ end
264
+ end
265
+
266
+ ## More functional-type specs below here
267
+
268
+ it "ignores spaces, tabs and newlines" do
269
+ parse(" <div>\t\n" + "\thello !" + "\n\t</div>").convert.should ==
270
+ "div do\n" +
271
+ " text 'hello !'\n" +
272
+ "end\n"
273
+ end
274
+
275
+ it "parses some scaffolding" do
276
+ parse("<p>
277
+ <b>Name:</b>
278
+ <%=h @foo.name %>
279
+ </p>").convert.should ==
280
+ "p do\n" +
281
+ " b do\n" +
282
+ " text 'Name:'\n" +
283
+ " end\n" +
284
+ " text @foo.name\n" +
285
+ "end\n"
286
+ end
287
+
288
+ it "parses edit.erb.html" do
289
+ parse("<h1>Editing foo</h1>
290
+
291
+ <%= error_messages_for :foo %>
292
+
293
+ <% form_for(@foo) do |f| %>
294
+ <p>
295
+ <b>Name</b><br />
296
+ <%= f.text_field :name %>
297
+ </p>
298
+
299
+ <p>
300
+ <b>Age</b><br />
301
+ <%= f.text_field :age %>
302
+ </p>
303
+
304
+ <p>
305
+ <%= f.submit \"Update\" %>
306
+ </p>
307
+ <% end %>
308
+
309
+ <%= link_to 'Show', @foo %> |
310
+ <%= link_to 'Back', foos_path %>
311
+ ")
312
+ end
313
+
314
+ it "parses show.html.erb" do
315
+ parse("<p>
316
+ <b>Name:</b>
317
+ <%=h @foo.name %>
318
+ </p>
319
+
320
+ <p>
321
+ <b>Age:</b>
322
+ <%=h @foo.age %>
323
+ </p>
324
+
325
+
326
+ <%= link_to 'Edit', edit_foo_path(@foo) %> |
327
+ <%= link_to 'Back', foos_path %>
328
+ ")
329
+ end
330
+
331
+ it "does meta" do
332
+ parse('<meta http-equiv="content-type" content="text/html;charset=UTF-8" />').convert.should ==
333
+ "meta 'http-equiv' => 'content-type', :content => 'text/html;charset=UTF-8'\n"
334
+ end
335
+
336
+ it "parses JayTee's IE and DOCTYPE test file" do
337
+ parse <<-HTML
338
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
339
+ <html xmlns="http://www.w3.org/1999/xhtml">
340
+ <head>
341
+ <!--[if IE]><link href="custom.css" rel="stylesheet" type="text/css" /><![endif]-->
342
+ <!--[if IE]><link href="custom.css" rel="stylesheet" type="text/css" /><![endif]-->
343
+ <script language="javascript" type="text/javascript"> /* <![CDATA[ */
344
+ var myJavascriptCode = 1; /*]]>*/ </script>
345
+ </head>
346
+ <body>
347
+ </body>
348
+ </html>
349
+ HTML
350
+ end
351
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+ require 'benchmark'
3
+
4
+ module MixinSpec
5
+ class Thing
6
+ include Erector::Mixin
7
+ end
8
+
9
+ describe Erector::Mixin do
10
+ describe "#erector" do
11
+ it "renders its block to a string" do
12
+
13
+ class MixinSpec::Thing
14
+ def name
15
+ erector do
16
+ span :class => "name" do
17
+ text "Gabriel "
18
+ i "Garcia"
19
+ text " Marquez"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ Thing.new.name.should == "<span class=\"name\">Gabriel <i>Garcia</i> Marquez</span>"
26
+ end
27
+
28
+ it "passes its parameters to to_s" do
29
+ class MixinSpec::Thing
30
+ def pretty_name
31
+ erector(:prettyprint => true) do
32
+ div :class => "name" do
33
+ ul do
34
+ li "Gabriel"
35
+ li "Garcia"
36
+ li "Marquez"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ Thing.new.pretty_name.should ==
44
+ "<div class=\"name\">\n" +
45
+ " <ul>\n" +
46
+ " <li>Gabriel</li>\n" +
47
+ " <li>Garcia</li>\n" +
48
+ " <li>Marquez</li>\n" +
49
+ " </ul>\n" +
50
+ "</div>\n"
51
+ end
52
+ end
53
+ end
54
+ end