erector 0.3.110 → 0.4.191

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.txt +1 -1
  2. data/bin/erect +0 -0
  3. data/lib/erector.rb +13 -10
  4. data/lib/erector/doc.rb +138 -0
  5. data/lib/erector/erected.rb +1 -1
  6. data/lib/erector/rails.rb +6 -0
  7. data/lib/erector/rails/extensions/action_controller.rb +17 -0
  8. data/lib/erector/rails/extensions/action_view.rb +21 -0
  9. data/lib/erector/{helpers.rb → rails/extensions/widget.rb} +21 -14
  10. data/lib/erector/rails/supported_rails_versions.rb +11 -0
  11. data/lib/erector/rails/template_handlers/action_view_template_handler.rb +92 -0
  12. data/lib/erector/rhtml.treetop +6 -1
  13. data/lib/erector/unicode.rb +18185 -0
  14. data/lib/erector/unicode_builder.rb +67 -0
  15. data/lib/erector/widget.rb +86 -82
  16. data/spec/core_spec_suite.rb +3 -0
  17. data/spec/erect/erect_spec.rb +1 -4
  18. data/spec/erect/erected_spec.rb +1 -4
  19. data/spec/erect/rhtml_parser_spec.rb +9 -7
  20. data/spec/erector/doc_spec.rb +55 -0
  21. data/spec/erector/indentation_spec.rb +127 -0
  22. data/spec/erector/unicode_builder_spec.rb +75 -0
  23. data/spec/erector/widget_spec.rb +339 -175
  24. data/spec/erector/widgets/table_spec.rb +26 -37
  25. data/spec/rails_spec_suite.rb +3 -0
  26. data/spec/spec_helper.rb +11 -6
  27. data/spec/spec_suite.rb +44 -3
  28. metadata +54 -28
  29. data/lib/erector/extensions/action_controller.rb +0 -24
  30. data/lib/erector/extensions/action_view_template_handler.rb +0 -66
  31. data/lib/erector/html_parts.rb +0 -63
  32. data/spec/erector/extensions/render_widget_spec.rb +0 -68
  33. data/spec/erector/extensions/template_handler_spec.rb +0 -29
  34. data/spec/erector/rails_helpers_spec.rb +0 -149
  35. data/spec/rails/standard_helpers_spec.rb +0 -102
  36. data/spec/rails/view_spec.rb +0 -33
  37. data/spec/view_caching.rb +0 -30
  38. data/test/rails_root/app/views/template_handler_spec/test_page.rb +0 -8
@@ -0,0 +1,127 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ describe "indentation" do
4
+
5
+ it "can detect newliney tags" do
6
+ doc = Erector::Doc.new(StringIO.new(""))
7
+ doc.enable_prettyprint = true
8
+ doc.newliney("i").should == false
9
+ doc.newliney("table").should == true
10
+ end
11
+
12
+ it "should not add newline for non-newliney tags" do
13
+ Erector::Widget.new() do
14
+ text "Hello, "
15
+ b "World"
16
+ end.enable_prettyprint(true).to_s.should == "Hello, <b>World</b>"
17
+ end
18
+
19
+ it "should add newlines before open newliney tags" do
20
+ Erector::Widget.new() do
21
+ p "foo"
22
+ p "bar"
23
+ end.enable_prettyprint(true).to_s.should == "<p>foo</p>\n<p>bar</p>\n"
24
+ end
25
+
26
+ it "should add newlines between text and open newliney tag" do
27
+ Erector::Widget.new() do
28
+ text "One"
29
+ p "Two"
30
+ end.enable_prettyprint(true).to_s.should == "One\n<p>Two</p>\n"
31
+ end
32
+
33
+ it "should add newlines after end newliney tags" do
34
+ Erector::Widget.new() do
35
+ tr do
36
+ td "cell"
37
+ end
38
+ end.enable_prettyprint(true).to_s.should == "<tr>\n <td>cell</td>\n</tr>\n"
39
+ end
40
+
41
+ it "should treat empty elements as start and end" do
42
+ Erector::Widget.new() do
43
+ p "before"
44
+ br
45
+ p "after"
46
+ end.enable_prettyprint(true).to_s.should == "<p>before</p>\n<br />\n<p>after</p>\n"
47
+ end
48
+
49
+ it "empty elements sets at_start_of_line" do
50
+ Erector::Widget.new() do
51
+ text "before"
52
+ br
53
+ p "after"
54
+ end.enable_prettyprint(true).to_s.should == "before\n<br />\n<p>after</p>\n"
55
+ end
56
+
57
+ it "will not insert extra space before/after input element" do
58
+ # If dim memory serves, the reason for not adding spaces here is
59
+ # because it affects/affected the rendering in browsers.
60
+ Erector::Widget.new() do
61
+ text 'Name'
62
+ input :type => 'text'
63
+ text 'after'
64
+ end.enable_prettyprint(true).to_s.should == 'Name<input type="text" />after'
65
+ end
66
+
67
+ it "will indent" do
68
+ Erector::Widget.new() do
69
+ html do
70
+ head do
71
+ title "hi"
72
+ end
73
+ body do
74
+ div do
75
+ p "paragraph"
76
+ end
77
+ end
78
+ end
79
+ end.enable_prettyprint(true).to_s.should == <<END
80
+ <html>
81
+ <head>
82
+ <title>hi</title>
83
+ </head>
84
+ <body>
85
+ <div>
86
+ <p>paragraph</p>
87
+ </div>
88
+ </body>
89
+ </html>
90
+ END
91
+ end
92
+
93
+ it "can turn off newlines" do
94
+ Erector::Widget.new() do
95
+ text "One"
96
+ p "Two"
97
+ end.enable_prettyprint(false).to_s.should == "One<p>Two</p>"
98
+ end
99
+
100
+ it "cannot turn newlines on and off, because the output is cached" do
101
+ widget = Erector::Widget.new() do
102
+ text "One"
103
+ p "Two"
104
+ end.enable_prettyprint(false)
105
+ widget.to_s.should == "One<p>Two</p>"
106
+ widget.enable_prettyprint(true)
107
+ widget.to_s.should == "One<p>Two</p>"
108
+ widget.enable_prettyprint(false)
109
+ widget.to_s.should == "One<p>Two</p>"
110
+ end
111
+
112
+ it "can turn on newlines via to_pretty" do
113
+ widget = Erector::Widget.new() do
114
+ text "One"
115
+ p "Two"
116
+ end.enable_prettyprint(false).to_pretty.should == "One\n<p>Two</p>\n"
117
+ end
118
+
119
+ it "to_pretty will leave newlines on if they already were" do
120
+ widget = Erector::Widget.new() do
121
+ text "One"
122
+ p "Two"
123
+ end.enable_prettyprint(true).to_pretty.should == "One\n<p>Two</p>\n"
124
+ end
125
+
126
+ end
127
+
@@ -0,0 +1,75 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+ require File.expand_path("#{File.dirname(__FILE__)}/../../lib/erector/unicode_builder")
3
+
4
+ describe "build unicode" do
5
+
6
+ def make_builder(input_string)
7
+ @output = ""
8
+ Erector::UnicodeBuilder.new(
9
+ StringIO.new(input_string),
10
+ StringIO.new(@output))
11
+ end
12
+
13
+ it "#generate generates header and footer" do
14
+ make_builder("").generate()
15
+ @output.should == "Erector::CHARACTERS = {\n}\n"
16
+ end
17
+
18
+ it "generates nothing from empty file" do
19
+ make_builder("").process_file()
20
+ @output.should == ""
21
+ end
22
+
23
+ it "generates nothing from blank line" do
24
+ make_builder("\n").process_file()
25
+ @output.should == ""
26
+ end
27
+
28
+ it "generates entry from a simple line" do
29
+ make_builder(%q{
30
+ 0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
31
+ }).process_file()
32
+ @output.should == " :percent_sign => 0x0025\n"
33
+ end
34
+
35
+ it "can process two lines" do
36
+ make_builder(%q{
37
+ 0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
38
+ 237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;
39
+ }).process_file()
40
+ @output.should == " :devanagari_letter_aa => 0x0906,\n" +
41
+ " :bell_symbol => 0x237e\n"
42
+ end
43
+
44
+ it "also adds an entry for an alias" do
45
+ make_builder(%q{
46
+ 2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
47
+ }).process_file()
48
+ @output.should == " :rightwards_arrow => 0x2192,\n" +
49
+ " :right_arrow => 0x2192\n"
50
+ end
51
+
52
+ it "can handle hyphen in name" do
53
+ make_builder(%q{
54
+ 2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;;
55
+ }).process_file()
56
+ @output.should == " :recycling_symbol_for_type_1_plastics => 0x2673\n"
57
+ end
58
+
59
+ it "can handle characters above 0xffff" do
60
+ make_builder(%q{
61
+ 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
62
+ }).process_file()
63
+ @output.should == " :deseret_capital_letter_long_i => 0x10400\n"
64
+ end
65
+
66
+ it "ignores entries whose names start with less than" do
67
+ make_builder(%q{
68
+ F0000;<Plane 15 Private Use, First>;Co;0;L;;;;;N;;;;;
69
+ FFFFD;<Plane 15 Private Use, Last>;Co;0;L;;;;;N;;;;;
70
+ }).process_file()
71
+ @output.should == ""
72
+ end
73
+
74
+ end
75
+
@@ -9,6 +9,48 @@ module WidgetSpec
9
9
  end
10
10
  end
11
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
+
12
54
  describe "#instruct" do
13
55
  it "when passed no arguments; returns an XML declaration with version 1 and utf-8" do
14
56
  html = Erector::Widget.new do
@@ -18,97 +60,157 @@ module WidgetSpec
18
60
  end
19
61
  end
20
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
+
21
98
  describe "#element" do
22
- it "when receiving one argument; returns an empty element" do
23
- Erector::Widget.new do
24
- element('div')
25
- end.to_s.should == "<div></div>"
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
26
105
  end
27
106
 
28
- it "with a attribute hash; returns an empty element with the attributes" do
29
- html = Erector::Widget.new do
30
- element(
31
- 'div',
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',
32
112
  :class => "foo bar",
33
113
  :style => "display: none; color: white; float: left;",
34
114
  :nil_attribute => nil
35
- )
36
- end.to_s
37
- doc = Hpricot(html)
38
- div = doc.at('div')
39
- div[:class].should == "foo bar"
40
- div[:style].should == "display: none; color: white; float: left;"
41
- div[:nil_attribute].should be_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
42
123
  end
43
124
 
44
- it "with an array of CSS classes, returns a tag with the classes separated" do
45
- Erector::Widget.new do
46
- element('div', :class => [:foo, :bar])
47
- end.to_s.should == "<div class=\"foo bar\"></div>";
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
48
131
  end
49
132
 
50
- it "with an array of CSS classes as strings, returns a tag with the classes separated" do
51
- Erector::Widget.new do
52
- element('div', :class => ['foo', 'bar'])
53
- end.to_s.should == "<div class=\"foo bar\"></div>";
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
54
139
  end
55
140
 
56
- it "with a CSS class which is a string, just use that as the attribute value" do
57
- Erector::Widget.new do
58
- element('div', :class => "foo bar")
59
- end.to_s.should == "<div class=\"foo bar\"></div>";
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
60
148
  end
61
149
 
62
- it "with many attributes, alphabetize them" do
63
- Erector::Widget.new do
64
- empty_element('foo', :alpha => "", :betty => "5", :aardvark => "tough",
65
- :carol => "", :demon => "", :erector => "", :pi => "3.14", :omicron => "", :zebra => "", :brain => "")
66
- end.to_s.should == "<foo aardvark=\"tough\" alpha=\"\" betty=\"5\" brain=\"\" carol=\"\" demon=\"\" " \
67
- "erector=\"\" omicron=\"\" pi=\"3.14\" zebra=\"\" />";
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
68
158
  end
69
159
 
70
- it "with inner tags; returns nested tags" do
71
- widget = Erector::Widget.new do
72
- element 'div' do
73
- element 'div'
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
74
166
  end
167
+ widget.to_s.should == '<div><div></div></div>'
75
168
  end
76
- widget.to_s.should == '<div><div></div></div>'
77
169
  end
78
170
 
79
- it "with text; returns element with inner text" do
80
- Erector::Widget.new do
81
- element 'div', 'test text'
82
- end.to_s.should == "<div>test text</div>"
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
83
177
  end
84
178
 
85
- it "with object other than hash; returns element with inner text == object.to_s" do
86
- object = ['a', 'b']
87
- Erector::Widget.new do
88
- element 'div', object
89
- end.to_s.should == "<div>#{object.to_s}</div>"
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
90
186
  end
91
187
 
92
- it "with parameters and block; returns element with inner html and attributes" do
93
- Erector::Widget.new do
94
- element 'div', 'class' => "foobar" do
95
- element 'span', 'style' => 'display: none;'
96
- end
97
- end.to_s.should == '<div class="foobar"><span style="display: none;"></span></div>'
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
98
196
  end
99
197
 
100
- it "with content and parameters; returns element with content as inner html and attributes" do
101
- Erector::Widget.new do
102
- element 'div', 'test text', :style => "display: none;"
103
- end.to_s.should == '<div style="display: none;">test text</div>'
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
104
204
  end
105
205
 
106
- it "with more than three arguments; raises ArgumentError" do
107
- proc do
108
- Erector::Widget.new do
109
- element 'div', 'foobar', {}, 'fourth'
110
- end.to_s
111
- end.should raise_error(ArgumentError)
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
112
214
  end
113
215
 
114
216
  it "renders the proper full tags" do
@@ -126,79 +228,94 @@ module WidgetSpec
126
228
  end
127
229
  end
128
230
 
129
- it "when outputting text; quotes it" do
130
- Erector::Widget.new do
131
- element 'div', 'test &<>text'
132
- end.to_s.should == "<div>test &amp;&lt;&gt;text</div>"
133
- end
134
-
135
- it "when outputting text via text; quotes it" do
136
- Erector::Widget.new do
137
- element 'div' do
138
- text "test &<>text"
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 &amp;&lt;&gt;text</div>"
139
237
  end
140
- end.to_s.should == "<div>test &amp;&lt;&gt;text</div>"
141
- end
238
+ end
142
239
 
143
- it "when outputting attribute value; quotes it" do
144
- Erector::Widget.new do
145
- element 'a', :href => "foo.cgi?a&b"
146
- end.to_s.should == "<a href=\"foo.cgi?a&amp;b\"></a>"
147
- end
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 &amp;&lt;&gt;text</div>"
247
+ end
248
+ end
148
249
 
149
- it "with raw text, does not quote it" do
150
- Erector::Widget.new do
151
- element 'div' do
152
- text raw("<b>bold</b>")
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&amp;b\"></a>"
153
255
  end
154
- end.to_s.should == "<div><b>bold</b></div>"
155
- end
256
+ end
156
257
 
157
- it "with raw text and no block, does not quote it" do
158
- Erector::Widget.new do
159
- element 'div', raw("<b>bold</b>")
160
- end.to_s.should == "<div><b>bold</b></div>"
161
- end
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
162
267
 
163
- it "with raw attribute, does not quote it" do
164
- Erector::Widget.new do
165
- element 'a', :href => raw("foo?x=&nbsp;")
166
- end.to_s.should == "<a href=\"foo?x=&nbsp;\"></a>"
167
- end
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
168
275
 
169
- it "with quote in attribute, quotes it" do
170
- Erector::Widget.new do
171
- element 'a', :onload => "alert(\"foo\")"
172
- end.to_s.should == "<a onload=\"alert(&quot;foo&quot;)\"></a>"
173
- end
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=&nbsp;")
280
+ end.to_s.should == "<a href=\"foo?x=&nbsp;\"></a>"
281
+ end
282
+ end
174
283
 
175
- it "with a non-string, non-raw, calls to_s and quotes" do
176
- Erector::Widget.new do
177
- element 'a' do
178
- text [7, "foo&bar"]
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(&quot;foo&quot;)\"></a>"
179
289
  end
180
- end.to_s.should == "<a>7foo&amp;bar</a>"
290
+ end
181
291
  end
182
292
 
183
- it "calls to_s" do
184
- Erector::Widget.new do
185
- img :width=>50
186
- end.to_s.should == "<img width=\"50\" />"
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&amp;bar</a>"
300
+ end
187
301
  end
188
-
189
302
  end
190
303
 
191
304
  describe "#empty_element" do
192
- it "when receiving attributes, renders an empty element with the attributes" do
193
- Erector::Widget.new do
194
- empty_element 'input', :name => 'foo[bar]'
195
- end.to_s.should == '<input name="foo[bar]" />'
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
196
311
  end
197
312
 
198
- it "when not receiving attributes, renders an empty element without attributes" do
199
- Erector::Widget.new do
200
- empty_element 'br'
201
- end.to_s.should == '<br />'
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
202
319
  end
203
320
 
204
321
  it "renders the proper empty-element tags" do
@@ -217,7 +334,7 @@ module WidgetSpec
217
334
  end
218
335
  end
219
336
 
220
- describe "nbsp" do
337
+ describe "#nbsp" do
221
338
  it "turns consecutive spaces into consecutive non-breaking spaces" do
222
339
  Erector::Widget.new do
223
340
  text nbsp("a b")
@@ -237,7 +354,51 @@ module WidgetSpec
237
354
  element 'a', :href => nbsp("&<> foo")
238
355
  end.to_s.should == "<a href=\"&amp;&lt;&gt;&#160;foo\"></a>"
239
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 == "&#160;"
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 == "&#xa0;"
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 == "&#x2192;"
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 == "&#x103a3;"
383
+ end
240
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
241
402
  end
242
403
 
243
404
  describe '#h' do
@@ -255,68 +416,71 @@ module WidgetSpec
255
416
  end
256
417
 
257
418
  describe "#javascript" do
258
- it "when receiving a block; renders the content inside of script text/javascript tags" do
259
- Erector::Widget.new do
260
- javascript do
261
- rawtext 'if (x < y && x > z) alert("don\'t stop");'
262
- end
263
- end.to_s.should == <<EXPECTED
264
- <script type="text/javascript">
265
- // <![CDATA[
266
- if (x < y && x > z) alert("don't stop");
267
- // ]]>
268
- </script>
269
- EXPECTED
419
+ context "when receiving a block" do
420
+ it "renders the content inside of script text/javascript tags" do
421
+ expected = <<-EXPECTED
422
+ <script type="text/javascript">
423
+ // <![CDATA[
424
+ if (x < y && x > z) alert("don't stop");
425
+ // ]]>
426
+ </script>
427
+ EXPECTED
428
+ expected.gsub!(/^ /, '')
429
+ Erector::Widget.new do
430
+ javascript do
431
+ rawtext 'if (x < y && x > z) alert("don\'t stop");'
432
+ end
433
+ end.to_s.should == expected
434
+ end
270
435
  end
271
-
436
+
272
437
  it "renders the raw content inside script tags when given text" do
438
+ expected = <<-EXPECTED
439
+ <script type="text/javascript">
440
+ // <![CDATA[
441
+ alert("&<>'hello");
442
+ // ]]>
443
+ </script>
444
+ EXPECTED
445
+ expected.gsub!(/^ /, '')
273
446
  Erector::Widget.new do
274
447
  javascript('alert("&<>\'hello");')
275
- end.to_s.should == <<EXPECTED
276
- <script type="text/javascript">
277
- // <![CDATA[
278
- alert("&<>'hello");
279
- // ]]>
280
- </script>
281
- EXPECTED
448
+ end.to_s.should == expected
282
449
  end
283
450
 
284
- it "when receiving a params hash; renders a source file" do
285
- html = Erector::Widget.new do
286
- javascript(:src => "/my/js/file.js")
287
- end.to_s
288
- doc = Hpricot(html)
289
- doc.at('/')[:src].should == "/my/js/file.js"
290
- end
291
-
292
- it "when receiving text and a params hash; renders a source file" do
293
- html = Erector::Widget.new do
294
- javascript('alert("&<>\'hello");', :src => "/my/js/file.js")
295
- end.to_s
296
- doc = Hpricot(html)
297
- script_tag = doc.at('script')
298
- script_tag[:src].should == "/my/js/file.js"
299
- script_tag.inner_html.should include('alert("&<>\'hello");')
451
+ context "when receiving a params hash" do
452
+ it "renders a source file" do
453
+ html = Erector::Widget.new do
454
+ javascript(:src => "/my/js/file.js")
455
+ end.to_s
456
+ doc = Hpricot(html)
457
+ doc.at('/')[:src].should == "/my/js/file.js"
458
+ end
300
459
  end
301
460
 
302
- it "with too many arguments; raises ArgumentError" do
303
- proc do
304
- Erector::Widget.new do
305
- javascript 'foobar', {}, 'fourth'
461
+ context "when receiving text and a params hash" do
462
+ it "renders a source file" do
463
+ html = Erector::Widget.new do
464
+ javascript('alert("&<>\'hello");', :src => "/my/js/file.js")
306
465
  end.to_s
307
- end.should raise_error(ArgumentError)
466
+ doc = Hpricot(html)
467
+ script_tag = doc.at('script')
468
+ script_tag[:src].should == "/my/js/file.js"
469
+ script_tag.inner_html.should include('alert("&<>\'hello");')
470
+ end
308
471
  end
309
472
 
310
- it "script method doesn't do any magic" do
311
- Erector::Widget.new do
312
- script(:type => "text/javascript") do
313
- rawtext "if (x < y || x > z) onEnterGetTo('/search?a=b&c=d')"
314
- end
315
- end.to_s.should == "<script type=\"text/javascript\">if (x < y || x > z) onEnterGetTo('/search?a=b&c=d')</script>"
473
+ context "with too many arguments" do
474
+ it "raises ArgumentError" do
475
+ proc do
476
+ Erector::Widget.new do
477
+ javascript 'foobar', {}, 'fourth'
478
+ end.to_s
479
+ end.should raise_error(ArgumentError)
480
+ end
316
481
  end
317
-
318
482
  end
319
-
483
+
320
484
  describe "#css" do
321
485
  it "makes a link when passed a string" do
322
486
  Erector::Widget.new do
@@ -324,7 +488,7 @@ EXPECTED
324
488
  end.to_s.should == "<link href=\"erector.css\" rel=\"stylesheet\" type=\"text/css\" />"
325
489
  end
326
490
  end
327
-
491
+
328
492
  describe "#url" do
329
493
  it "renders an anchor tag with the same href and text" do
330
494
  Erector::Widget.new do
@@ -402,7 +566,7 @@ EXPECTED
402
566
  Parent.new.to_s.should == '123'
403
567
  end
404
568
  end
405
-
569
+
406
570
  describe '#render_to' do
407
571
  class A < Erector::Widget
408
572
  def render
@@ -420,9 +584,9 @@ EXPECTED
420
584
  end
421
585
  b = B.new
422
586
  b.to_s.should == "B<p>A</p>B"
423
- b.doc.size.should == 5 # B, <p>, A, </p>, B
587
+ b.doc.size.should == 10 # B, <p>, A, </p>, B
424
588
  end
425
-
589
+
426
590
  it "renders to a widget's doc" do
427
591
  class B < Erector::Widget
428
592
  def render
@@ -433,9 +597,9 @@ EXPECTED
433
597
  end
434
598
  b = B.new
435
599
  b.to_s.should == "B<p>A</p>B"
436
- b.doc.size.should == 5 # B, <p>, A, </p>, B
600
+ b.doc.size.should == 10 # B, <p>, A, </p>, B
437
601
  end
438
-
602
+
439
603
  it "passing a widget to text method renders it" do
440
604
  Erector::Widget.new() do
441
605
  text "B"