pivotal-erector 0.5.1
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/README.txt +81 -0
- data/VERSION.yml +4 -0
- data/bin/erect +7 -0
- data/lib/erector/erect.rb +148 -0
- data/lib/erector/erected.rb +63 -0
- data/lib/erector/extensions/object.rb +18 -0
- data/lib/erector/indenting.rb +36 -0
- data/lib/erector/rails/extensions/action_controller/1.2.5/action_controller.rb +17 -0
- data/lib/erector/rails/extensions/action_controller/2.2.0/action_controller.rb +26 -0
- data/lib/erector/rails/extensions/action_controller.rb +8 -0
- data/lib/erector/rails/extensions/action_view.rb +21 -0
- data/lib/erector/rails/extensions/widget/1.2.5/widget.rb +18 -0
- data/lib/erector/rails/extensions/widget/2.2.0/widget.rb +36 -0
- data/lib/erector/rails/extensions/widget.rb +117 -0
- data/lib/erector/rails/supported_rails_versions.rb +14 -0
- data/lib/erector/rails/template_handlers/1.2.5/action_view_template_handler.rb +32 -0
- data/lib/erector/rails/template_handlers/2.0.0/action_view_template_handler.rb +36 -0
- data/lib/erector/rails/template_handlers/2.1.0/action_view_template_handler.rb +31 -0
- data/lib/erector/rails/template_handlers/2.2.0/action_view_template_handler.rb +46 -0
- data/lib/erector/rails/template_handlers/action_view_template_handler.rb +14 -0
- data/lib/erector/rails.rb +6 -0
- data/lib/erector/raw_string.rb +8 -0
- data/lib/erector/rhtml.treetop +156 -0
- data/lib/erector/unicode.rb +18185 -0
- data/lib/erector/unicode_builder.rb +67 -0
- data/lib/erector/version.rb +10 -0
- data/lib/erector/widget.rb +510 -0
- data/lib/erector/widgets/table.rb +96 -0
- data/lib/erector/widgets.rb +2 -0
- data/lib/erector.rb +16 -0
- data/spec/core_spec_suite.rb +3 -0
- data/spec/erect/erect_spec.rb +145 -0
- data/spec/erect/erected_spec.rb +80 -0
- data/spec/erect/rhtml_parser_spec.rb +318 -0
- data/spec/erector/indentation_spec.rb +136 -0
- data/spec/erector/unicode_builder_spec.rb +75 -0
- data/spec/erector/widget_spec.rb +657 -0
- data/spec/erector/widgets/table_spec.rb +99 -0
- data/spec/rails_spec_suite.rb +3 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/spec_suite.rb +45 -0
- metadata +118 -0
@@ -0,0 +1,657 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
+
|
3
|
+
module WidgetSpec
|
4
|
+
describe Erector::Widget do
|
5
|
+
describe ".all_tags" do
|
6
|
+
it "returns set of full and empty tags" do
|
7
|
+
Erector::Widget.all_tags.class.should == Array
|
8
|
+
Erector::Widget.all_tags.should == Erector::Widget.full_tags + Erector::Widget.empty_tags
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#to_s" do
|
13
|
+
class << self
|
14
|
+
define_method("invokes #render and returns the string representation of the rendered widget") do
|
15
|
+
it "invokes #render and returns the string representation of the rendered widget" do
|
16
|
+
widget = Erector::Widget.new do
|
17
|
+
div "Hello"
|
18
|
+
end
|
19
|
+
mock.proxy(widget).render
|
20
|
+
widget.to_s.should == "<div>Hello</div>"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when passed no arguments" do
|
26
|
+
send "invokes #render and returns the string representation of the rendered widget"
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when passed an argument that is #render" do
|
30
|
+
send "invokes #render and returns the string representation of the rendered widget"
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when passed an argument that is not #render" do
|
34
|
+
attr_reader :widget
|
35
|
+
before do
|
36
|
+
@widget = Erector::Widget.new
|
37
|
+
def widget.alternate_render
|
38
|
+
div "Hello from Alternate Render"
|
39
|
+
end
|
40
|
+
mock.proxy(widget).alternate_render
|
41
|
+
end
|
42
|
+
|
43
|
+
it "invokes the passed in method name and returns the string representation of the rendered widget" do
|
44
|
+
widget.to_s(:alternate_render).should == "<div>Hello from Alternate Render</div>"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not invoke #render" do
|
48
|
+
dont_allow(widget).render
|
49
|
+
widget.to_s(:alternate_render)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#instruct" do
|
55
|
+
it "when passed no arguments; returns an XML declaration with version 1 and utf-8" do
|
56
|
+
html = Erector::Widget.new do
|
57
|
+
instruct
|
58
|
+
# version must precede encoding, per XML 1.0 4th edition (section 2.8)
|
59
|
+
end.to_s.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#widget" do
|
64
|
+
context "when nested" do
|
65
|
+
it "renders the tag around the rest of the block" do
|
66
|
+
parent_widget = Class.new(Erector::Widget) do
|
67
|
+
def render
|
68
|
+
div :id => "parent_widget" do
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
child_widget = Class.new(Erector::Widget) do
|
74
|
+
def render
|
75
|
+
div :id => "child_widget" do
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
widget = Class.new(Erector::Widget) do
|
82
|
+
def render
|
83
|
+
widget(parent_widget) do
|
84
|
+
widget(child_widget) do
|
85
|
+
super
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
widget.new(nil, :parent_widget => parent_widget, :child_widget => child_widget) do
|
92
|
+
div :id => "widget"
|
93
|
+
end.to_s.should == '<div id="parent_widget"><div id="child_widget"><div id="widget"></div></div></div>'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#element" do
|
99
|
+
context "when receiving one argument" do
|
100
|
+
it "returns an empty element" do
|
101
|
+
Erector::Widget.new do
|
102
|
+
element('div')
|
103
|
+
end.to_s.should == "<div></div>"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with a attribute hash" do
|
108
|
+
it "returns an empty element with the attributes" do
|
109
|
+
html = Erector::Widget.new do
|
110
|
+
element(
|
111
|
+
'div',
|
112
|
+
:class => "foo bar",
|
113
|
+
:style => "display: none; color: white; float: left;",
|
114
|
+
:nil_attribute => nil
|
115
|
+
)
|
116
|
+
end.to_s
|
117
|
+
doc = Hpricot(html)
|
118
|
+
div = doc.at('div')
|
119
|
+
div[:class].should == "foo bar"
|
120
|
+
div[:style].should == "display: none; color: white; float: left;"
|
121
|
+
div[:nil_attribute].should be_nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "with an array of CSS classes" do
|
126
|
+
it "returns a tag with the classes separated" do
|
127
|
+
Erector::Widget.new do
|
128
|
+
element('div', :class => [:foo, :bar])
|
129
|
+
end.to_s.should == "<div class=\"foo bar\"></div>";
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "with an array of CSS classes as strings" do
|
134
|
+
it "returns a tag with the classes separated" do
|
135
|
+
Erector::Widget.new do
|
136
|
+
element('div', :class => ['foo', 'bar'])
|
137
|
+
end.to_s.should == "<div class=\"foo bar\"></div>";
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
context "with a CSS class which is a string" do
|
143
|
+
it "just use that as the attribute value" do
|
144
|
+
Erector::Widget.new do
|
145
|
+
element('div', :class => "foo bar")
|
146
|
+
end.to_s.should == "<div class=\"foo bar\"></div>";
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "with many attributes" do
|
151
|
+
it "alphabetize them" do
|
152
|
+
Erector::Widget.new do
|
153
|
+
empty_element('foo', :alpha => "", :betty => "5", :aardvark => "tough",
|
154
|
+
:carol => "", :demon => "", :erector => "", :pi => "3.14", :omicron => "", :zebra => "", :brain => "")
|
155
|
+
end.to_s.should == "<foo aardvark=\"tough\" alpha=\"\" betty=\"5\" brain=\"\" carol=\"\" demon=\"\" " \
|
156
|
+
"erector=\"\" omicron=\"\" pi=\"3.14\" zebra=\"\" />";
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "with inner tags" do
|
161
|
+
it "returns nested tags" do
|
162
|
+
widget = Erector::Widget.new do
|
163
|
+
element 'div' do
|
164
|
+
element 'div'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
widget.to_s.should == '<div><div></div></div>'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "with text" do
|
172
|
+
it "returns element with inner text" do
|
173
|
+
Erector::Widget.new do
|
174
|
+
element 'div', 'test text'
|
175
|
+
end.to_s.should == "<div>test text</div>"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with object other than hash" do
|
180
|
+
it "returns element with inner text == object.to_s" do
|
181
|
+
object = ['a', 'b']
|
182
|
+
Erector::Widget.new do
|
183
|
+
element 'div', object
|
184
|
+
end.to_s.should == "<div>#{object.to_s}</div>"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "with parameters and block" do
|
189
|
+
it "returns element with inner html and attributes" do
|
190
|
+
Erector::Widget.new do
|
191
|
+
element 'div', 'class' => "foobar" do
|
192
|
+
element 'span', 'style' => 'display: none;'
|
193
|
+
end
|
194
|
+
end.to_s.should == '<div class="foobar"><span style="display: none;"></span></div>'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "with content and parameters" do
|
199
|
+
it "returns element with content as inner html and attributes" do
|
200
|
+
Erector::Widget.new do
|
201
|
+
element 'div', 'test text', :style => "display: none;"
|
202
|
+
end.to_s.should == '<div style="display: none;">test text</div>'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with more than three arguments" do
|
207
|
+
it "raises ArgumentError" do
|
208
|
+
proc do
|
209
|
+
Erector::Widget.new do
|
210
|
+
element 'div', 'foobar', {}, 'fourth'
|
211
|
+
end.to_s
|
212
|
+
end.should raise_error(ArgumentError)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "renders the proper full tags" do
|
217
|
+
Erector::Widget.full_tags.each do |tag_name|
|
218
|
+
expected = "<#{tag_name}></#{tag_name}>"
|
219
|
+
actual = Erector::Widget.new do
|
220
|
+
send(tag_name)
|
221
|
+
end.to_s
|
222
|
+
begin
|
223
|
+
actual.should == expected
|
224
|
+
rescue Spec::Expectations::ExpectationNotMetError => e
|
225
|
+
puts "Expected #{tag_name} to be a full element. Expected #{expected}, got #{actual}"
|
226
|
+
raise e
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "quoting" do
|
232
|
+
context "when outputting text" do
|
233
|
+
it "quotes it" do
|
234
|
+
Erector::Widget.new do
|
235
|
+
element 'div', 'test &<>text'
|
236
|
+
end.to_s.should == "<div>test &<>text</div>"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when outputting text via text" do
|
241
|
+
it "quotes it" do
|
242
|
+
Erector::Widget.new do
|
243
|
+
element 'div' do
|
244
|
+
text "test &<>text"
|
245
|
+
end
|
246
|
+
end.to_s.should == "<div>test &<>text</div>"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context "when outputting attribute value" do
|
251
|
+
it "quotes it" do
|
252
|
+
Erector::Widget.new do
|
253
|
+
element 'a', :href => "foo.cgi?a&b"
|
254
|
+
end.to_s.should == "<a href=\"foo.cgi?a&b\"></a>"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "with raw text" do
|
259
|
+
it "does not quote it" do
|
260
|
+
Erector::Widget.new do
|
261
|
+
element 'div' do
|
262
|
+
text raw("<b>bold</b>")
|
263
|
+
end
|
264
|
+
end.to_s.should == "<div><b>bold</b></div>"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "with raw text and no block" do
|
269
|
+
it "does not quote it" do
|
270
|
+
Erector::Widget.new do
|
271
|
+
element 'div', raw("<b>bold</b>")
|
272
|
+
end.to_s.should == "<div><b>bold</b></div>"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "with raw attribute" do
|
277
|
+
it "does not quote it" do
|
278
|
+
Erector::Widget.new do
|
279
|
+
element 'a', :href => raw("foo?x= ")
|
280
|
+
end.to_s.should == "<a href=\"foo?x= \"></a>"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
context "with quote in attribute" do
|
285
|
+
it "quotes it" do
|
286
|
+
Erector::Widget.new do
|
287
|
+
element 'a', :onload => "alert(\"foo\")"
|
288
|
+
end.to_s.should == "<a onload=\"alert("foo")\"></a>"
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
context "with a non-string, non-raw" do
|
294
|
+
it "calls to_s and quotes" do
|
295
|
+
Erector::Widget.new do
|
296
|
+
element 'a' do
|
297
|
+
text [7, "foo&bar"]
|
298
|
+
end
|
299
|
+
end.to_s.should == "<a>7foo&bar</a>"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe "#empty_element" do
|
305
|
+
context "when receiving attributes" do
|
306
|
+
it "renders an empty element with the attributes" do
|
307
|
+
Erector::Widget.new do
|
308
|
+
empty_element 'input', :name => 'foo[bar]'
|
309
|
+
end.to_s.should == '<input name="foo[bar]" />'
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context "when not receiving attributes" do
|
314
|
+
it "renders an empty element without attributes" do
|
315
|
+
Erector::Widget.new do
|
316
|
+
empty_element 'br'
|
317
|
+
end.to_s.should == '<br />'
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
it "renders the proper empty-element tags" do
|
322
|
+
Erector::Widget.empty_tags.each do |tag_name|
|
323
|
+
expected = "<#{tag_name} />"
|
324
|
+
actual = Erector::Widget.new do
|
325
|
+
send(tag_name)
|
326
|
+
end.to_s
|
327
|
+
begin
|
328
|
+
actual.should == expected
|
329
|
+
rescue Spec::Expectations::ExpectationNotMetError => e
|
330
|
+
puts "Expected #{tag_name} to be an empty-element tag. Expected #{expected}, got #{actual}"
|
331
|
+
raise e
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe "#nbsp" do
|
338
|
+
it "turns consecutive spaces into consecutive non-breaking spaces" do
|
339
|
+
Erector::Widget.new do
|
340
|
+
text nbsp("a b")
|
341
|
+
end.to_s.should == "a  b"
|
342
|
+
end
|
343
|
+
|
344
|
+
it "works in text context" do
|
345
|
+
Erector::Widget.new do
|
346
|
+
element 'a' do
|
347
|
+
text nbsp("&<> foo")
|
348
|
+
end
|
349
|
+
end.to_s.should == "<a>&<> foo</a>"
|
350
|
+
end
|
351
|
+
|
352
|
+
it "works in attribute value context" do
|
353
|
+
Erector::Widget.new do
|
354
|
+
element 'a', :href => nbsp("&<> foo")
|
355
|
+
end.to_s.should == "<a href=\"&<> foo\"></a>"
|
356
|
+
end
|
357
|
+
|
358
|
+
it "defaults to a single non-breaking space if given no argument" do
|
359
|
+
Erector::Widget.new do
|
360
|
+
text nbsp
|
361
|
+
end.to_s.should == " "
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
366
|
+
describe "#character" do
|
367
|
+
it "renders a character given the codepoint number" do
|
368
|
+
Erector::Widget.new do
|
369
|
+
text character(160)
|
370
|
+
end.to_s.should == " "
|
371
|
+
end
|
372
|
+
|
373
|
+
it "renders a character given the unicode name" do
|
374
|
+
Erector::Widget.new do
|
375
|
+
text character(:right_arrow)
|
376
|
+
end.to_s.should == "→"
|
377
|
+
end
|
378
|
+
|
379
|
+
it "renders a character above 0xffff" do
|
380
|
+
Erector::Widget.new do
|
381
|
+
text character(:old_persian_sign_ka)
|
382
|
+
end.to_s.should == "𐎣"
|
383
|
+
end
|
384
|
+
|
385
|
+
it "throws an exception if a name is not recognized" do
|
386
|
+
lambda {
|
387
|
+
Erector::Widget.new do
|
388
|
+
text character(:no_such_character_name)
|
389
|
+
end.to_s
|
390
|
+
}.should raise_error("Unrecognized character no_such_character_name")
|
391
|
+
end
|
392
|
+
|
393
|
+
it "throws an exception if passed something besides a symbol or integer" do
|
394
|
+
# Perhaps calling to_s would be more ruby-esque, but that seems like it might
|
395
|
+
# be pretty confusing when this method can already take either a name or number
|
396
|
+
lambda {
|
397
|
+
Erector::Widget.new do
|
398
|
+
text character([])
|
399
|
+
end.to_s
|
400
|
+
}.should raise_error("Unrecognized argument to character: ")
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
describe "#join" do
|
405
|
+
|
406
|
+
it "empty array means nothing to join" do
|
407
|
+
Erector::Widget.new do
|
408
|
+
join [], Erector::Widget.new { text "x" }
|
409
|
+
end.to_s.should == ""
|
410
|
+
end
|
411
|
+
|
412
|
+
it "larger example with two tabs" do
|
413
|
+
Erector::Widget.new do
|
414
|
+
tab1 =
|
415
|
+
Erector::Widget.new do
|
416
|
+
a "Upload document", :href => "/upload"
|
417
|
+
end
|
418
|
+
tab2 =
|
419
|
+
Erector::Widget.new do
|
420
|
+
a "Logout", :href => "/logout"
|
421
|
+
end
|
422
|
+
join [tab1, tab2],
|
423
|
+
Erector::Widget.new { text nbsp(" |"); text " " }
|
424
|
+
end.to_s.should ==
|
425
|
+
'<a href="/upload">Upload document</a> | <a href="/logout">Logout</a>'
|
426
|
+
end
|
427
|
+
|
428
|
+
it "plain string as join separator means pass it to text" do
|
429
|
+
Erector::Widget.new do
|
430
|
+
join [
|
431
|
+
Erector::Widget.new { text "x" },
|
432
|
+
Erector::Widget.new { text "y" }
|
433
|
+
], "<>"
|
434
|
+
end.to_s.should == "x<>y"
|
435
|
+
end
|
436
|
+
|
437
|
+
it "plain string as item to join means pass it to text" do
|
438
|
+
Erector::Widget.new do
|
439
|
+
join [
|
440
|
+
"<",
|
441
|
+
"&"
|
442
|
+
], Erector::Widget.new { text " + " }
|
443
|
+
end.to_s.should == "< + &"
|
444
|
+
end
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
describe '#h' do
|
449
|
+
before do
|
450
|
+
@widget = Erector::Widget.new
|
451
|
+
end
|
452
|
+
|
453
|
+
it "escapes regular strings" do
|
454
|
+
@widget.h("&").should == "&"
|
455
|
+
end
|
456
|
+
|
457
|
+
it "does not escape raw strings" do
|
458
|
+
@widget.h(@widget.raw("&")).should == "&"
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
describe "#javascript" do
|
463
|
+
context "when receiving a block" do
|
464
|
+
it "renders the content inside of script text/javascript tags" do
|
465
|
+
expected = <<-EXPECTED
|
466
|
+
<script type="text/javascript">
|
467
|
+
// <![CDATA[
|
468
|
+
if (x < y && x > z) alert("don't stop");
|
469
|
+
// ]]>
|
470
|
+
</script>
|
471
|
+
EXPECTED
|
472
|
+
expected.gsub!(/^ /, '')
|
473
|
+
Erector::Widget.new do
|
474
|
+
javascript do
|
475
|
+
rawtext 'if (x < y && x > z) alert("don\'t stop");'
|
476
|
+
end
|
477
|
+
end.to_s.should == expected
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
it "renders the raw content inside script tags when given text" do
|
482
|
+
expected = <<-EXPECTED
|
483
|
+
<script type="text/javascript">
|
484
|
+
// <![CDATA[
|
485
|
+
alert("&<>'hello");
|
486
|
+
// ]]>
|
487
|
+
</script>
|
488
|
+
EXPECTED
|
489
|
+
expected.gsub!(/^ /, '')
|
490
|
+
Erector::Widget.new do
|
491
|
+
javascript('alert("&<>\'hello");')
|
492
|
+
end.to_s.should == expected
|
493
|
+
end
|
494
|
+
|
495
|
+
context "when receiving a params hash" do
|
496
|
+
it "renders a source file" do
|
497
|
+
html = Erector::Widget.new do
|
498
|
+
javascript(:src => "/my/js/file.js")
|
499
|
+
end.to_s
|
500
|
+
doc = Hpricot(html)
|
501
|
+
doc.at('/')[:src].should == "/my/js/file.js"
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
context "when receiving text and a params hash" do
|
506
|
+
it "renders a source file" do
|
507
|
+
html = Erector::Widget.new do
|
508
|
+
javascript('alert("&<>\'hello");', :src => "/my/js/file.js")
|
509
|
+
end.to_s
|
510
|
+
doc = Hpricot(html)
|
511
|
+
script_tag = doc.at('script')
|
512
|
+
script_tag[:src].should == "/my/js/file.js"
|
513
|
+
script_tag.inner_html.should include('alert("&<>\'hello");')
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
context "with too many arguments" do
|
518
|
+
it "raises ArgumentError" do
|
519
|
+
proc do
|
520
|
+
Erector::Widget.new do
|
521
|
+
javascript 'foobar', {}, 'fourth'
|
522
|
+
end.to_s
|
523
|
+
end.should raise_error(ArgumentError)
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
describe "#css" do
|
529
|
+
it "makes a link when passed a string" do
|
530
|
+
Erector::Widget.new do
|
531
|
+
css "erector.css"
|
532
|
+
end.to_s.should == "<link href=\"erector.css\" rel=\"stylesheet\" type=\"text/css\" />"
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
describe "#url" do
|
537
|
+
it "renders an anchor tag with the same href and text" do
|
538
|
+
Erector::Widget.new do
|
539
|
+
url "http://example.com"
|
540
|
+
end.to_s.should == "<a href=\"http://example.com\">http://example.com</a>"
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
describe '#capture' do
|
545
|
+
it "should return content rather than write it to the buffer" do
|
546
|
+
widget = Erector::Widget.new do
|
547
|
+
captured = capture do
|
548
|
+
p 'Captured Content'
|
549
|
+
end
|
550
|
+
div do
|
551
|
+
text captured
|
552
|
+
end
|
553
|
+
end
|
554
|
+
widget.to_s.should == '<div><p>Captured Content</p></div>'
|
555
|
+
end
|
556
|
+
|
557
|
+
it "works with nested captures" do
|
558
|
+
widget = Erector::Widget.new do
|
559
|
+
captured = capture do
|
560
|
+
captured = capture do
|
561
|
+
p 'Nested Capture'
|
562
|
+
end
|
563
|
+
p 'Captured Content'
|
564
|
+
text captured
|
565
|
+
end
|
566
|
+
div do
|
567
|
+
text captured
|
568
|
+
end
|
569
|
+
end
|
570
|
+
widget.to_s.should == '<div><p>Captured Content</p><p>Nested Capture</p></div>'
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
describe 'nested' do
|
575
|
+
it "can insert another widget without raw" do
|
576
|
+
inner = Erector::Widget.new do
|
577
|
+
p "foo"
|
578
|
+
end
|
579
|
+
|
580
|
+
outer = Erector::Widget.new do
|
581
|
+
div inner
|
582
|
+
end.to_s.should == '<div><p>foo</p></div>'
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
describe '#widget' do
|
587
|
+
before do
|
588
|
+
class Parent < Erector::Widget
|
589
|
+
def render
|
590
|
+
text 1
|
591
|
+
widget Child do
|
592
|
+
text 2
|
593
|
+
third
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
def third
|
598
|
+
text 3
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
class Child < Erector::Widget
|
603
|
+
def render
|
604
|
+
super
|
605
|
+
end
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
it "renders nested widgets in the correct order" do
|
610
|
+
Parent.new.to_s.should == '123'
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
describe '#render_to' do
|
615
|
+
class A < Erector::Widget
|
616
|
+
def render
|
617
|
+
p "A"
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
it "renders to a doc" do
|
622
|
+
class B < Erector::Widget
|
623
|
+
def render
|
624
|
+
text "B"
|
625
|
+
A.new.render_to(@output)
|
626
|
+
text "B"
|
627
|
+
end
|
628
|
+
end
|
629
|
+
b = B.new
|
630
|
+
b.to_s.should == "B<p>A</p>B"
|
631
|
+
b.output.size.should == 10 # B, <p>, A, </p>, B
|
632
|
+
end
|
633
|
+
|
634
|
+
it "renders to a widget's doc" do
|
635
|
+
class B < Erector::Widget
|
636
|
+
def render
|
637
|
+
text "B"
|
638
|
+
A.new.render_to(self)
|
639
|
+
text "B"
|
640
|
+
end
|
641
|
+
end
|
642
|
+
b = B.new
|
643
|
+
b.to_s.should == "B<p>A</p>B"
|
644
|
+
b.output.size.should == 10 # B, <p>, A, </p>, B
|
645
|
+
end
|
646
|
+
|
647
|
+
it "passing a widget to text method renders it" do
|
648
|
+
Erector::Widget.new() do
|
649
|
+
text "B"
|
650
|
+
text A.new()
|
651
|
+
text "B"
|
652
|
+
end.to_s.should == "B<p>A</p>B"
|
653
|
+
end
|
654
|
+
|
655
|
+
end
|
656
|
+
end
|
657
|
+
end
|