erector 0.3.110 → 0.4.191
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 +1 -1
- data/bin/erect +0 -0
- data/lib/erector.rb +13 -10
- data/lib/erector/doc.rb +138 -0
- data/lib/erector/erected.rb +1 -1
- data/lib/erector/rails.rb +6 -0
- data/lib/erector/rails/extensions/action_controller.rb +17 -0
- data/lib/erector/rails/extensions/action_view.rb +21 -0
- data/lib/erector/{helpers.rb → rails/extensions/widget.rb} +21 -14
- data/lib/erector/rails/supported_rails_versions.rb +11 -0
- data/lib/erector/rails/template_handlers/action_view_template_handler.rb +92 -0
- data/lib/erector/rhtml.treetop +6 -1
- data/lib/erector/unicode.rb +18185 -0
- data/lib/erector/unicode_builder.rb +67 -0
- data/lib/erector/widget.rb +86 -82
- data/spec/core_spec_suite.rb +3 -0
- data/spec/erect/erect_spec.rb +1 -4
- data/spec/erect/erected_spec.rb +1 -4
- data/spec/erect/rhtml_parser_spec.rb +9 -7
- data/spec/erector/doc_spec.rb +55 -0
- data/spec/erector/indentation_spec.rb +127 -0
- data/spec/erector/unicode_builder_spec.rb +75 -0
- data/spec/erector/widget_spec.rb +339 -175
- data/spec/erector/widgets/table_spec.rb +26 -37
- data/spec/rails_spec_suite.rb +3 -0
- data/spec/spec_helper.rb +11 -6
- data/spec/spec_suite.rb +44 -3
- metadata +54 -28
- data/lib/erector/extensions/action_controller.rb +0 -24
- data/lib/erector/extensions/action_view_template_handler.rb +0 -66
- data/lib/erector/html_parts.rb +0 -63
- data/spec/erector/extensions/render_widget_spec.rb +0 -68
- data/spec/erector/extensions/template_handler_spec.rb +0 -29
- data/spec/erector/rails_helpers_spec.rb +0 -149
- data/spec/rails/standard_helpers_spec.rb +0 -102
- data/spec/rails/view_spec.rb +0 -33
- data/spec/view_caching.rb +0 -30
- 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
|
+
|
data/spec/erector/widget_spec.rb
CHANGED
|
@@ -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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
element '
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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 &<>text</div>"
|
|
139
237
|
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
238
|
+
end
|
|
142
239
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
148
249
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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>"
|
|
153
255
|
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
256
|
+
end
|
|
156
257
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
|
174
283
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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>"
|
|
179
289
|
end
|
|
180
|
-
end
|
|
290
|
+
end
|
|
181
291
|
end
|
|
182
292
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
|
187
301
|
end
|
|
188
|
-
|
|
189
302
|
end
|
|
190
303
|
|
|
191
304
|
describe "#empty_element" do
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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=\"&<> 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 == " "
|
|
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
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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 ==
|
|
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
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
303
|
-
|
|
304
|
-
Erector::Widget.new do
|
|
305
|
-
javascript
|
|
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
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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 ==
|
|
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 ==
|
|
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"
|