erector 0.7.2 → 0.8.0
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 +17 -3
- data/VERSION.yml +2 -2
- data/bin/erector +1 -1
- data/lib/erector.rb +22 -2
- data/lib/erector/after_initialize.rb +34 -0
- data/lib/erector/caching.rb +93 -0
- data/lib/erector/convenience.rb +58 -0
- data/lib/erector/dependencies.rb +24 -0
- data/lib/erector/dependency.rb +21 -0
- data/lib/erector/{erect.rb → erect/erect.rb} +14 -4
- data/lib/erector/{erected.rb → erect/erected.rb} +6 -4
- data/lib/erector/{indenting.rb → erect/indenting.rb} +0 -0
- data/lib/erector/{rhtml.treetop → erect/rhtml.treetop} +51 -11
- data/lib/erector/errors.rb +12 -0
- data/lib/erector/extensions/hash.rb +21 -0
- data/lib/erector/externals.rb +88 -24
- data/lib/erector/html.rb +352 -0
- data/lib/erector/inline.rb +5 -5
- data/lib/erector/jquery.rb +36 -0
- data/lib/erector/mixin.rb +3 -5
- data/lib/erector/needs.rb +94 -0
- data/lib/erector/output.rb +117 -0
- data/lib/erector/rails.rb +2 -2
- data/lib/erector/rails/extensions/action_controller.rb +5 -3
- data/lib/erector/rails/extensions/rails_helpers.rb +159 -0
- data/lib/erector/rails/extensions/rails_widget.rb +98 -56
- data/lib/erector/rails/rails_form_builder.rb +8 -4
- data/lib/erector/rails/rails_version.rb +2 -2
- data/lib/erector/rails/template_handlers/ert_handler.rb +1 -1
- data/lib/erector/rails/template_handlers/rb_handler.rb +42 -1
- data/lib/erector/raw_string.rb +2 -2
- data/lib/erector/sass.rb +22 -0
- data/lib/erector/widget.rb +100 -653
- data/lib/erector/widgets.rb +1 -0
- data/lib/erector/widgets/external_renderer.rb +51 -0
- data/lib/erector/widgets/page.rb +45 -63
- data/lib/erector/widgets/table.rb +9 -1
- data/spec/erect/erect_rails_spec.rb +19 -17
- data/spec/erect/erect_spec.rb +11 -1
- data/spec/erect/erected_spec.rb +76 -5
- data/spec/erect/rhtml_parser_spec.rb +11 -1
- data/spec/erector/caching_spec.rb +267 -0
- data/spec/erector/convenience_spec.rb +258 -0
- data/spec/erector/dependency_spec.rb +46 -0
- data/spec/erector/externals_spec.rb +233 -0
- data/spec/erector/html_spec.rb +508 -0
- data/spec/erector/indentation_spec.rb +84 -24
- data/spec/erector/inline_spec.rb +19 -8
- data/spec/erector/jquery_spec.rb +35 -0
- data/spec/erector/mixin_spec.rb +1 -1
- data/spec/erector/needs_spec.rb +120 -0
- data/spec/erector/output_spec.rb +199 -0
- data/spec/erector/sample-file.txt +1 -0
- data/spec/erector/sass_spec.rb +33 -0
- data/spec/erector/widget_spec.rb +113 -932
- data/spec/erector/widgets/field_table_spec.rb +6 -6
- data/spec/erector/widgets/form_spec.rb +3 -3
- data/spec/erector/widgets/page_spec.rb +52 -6
- data/spec/erector/widgets/table_spec.rb +4 -4
- data/spec/spec_helper.rb +70 -29
- metadata +56 -19
- data/lib/erector/rails/extensions/rails_widget/rails_helpers.rb +0 -137
- data/spec/core_spec_suite.rb +0 -3
- data/spec/erector/external_spec.rb +0 -110
- data/spec/rails_spec_suite.rb +0 -3
- data/spec/spec.opts +0 -1
- data/spec/spec_suite.rb +0 -40
@@ -1,10 +1,11 @@
|
|
1
1
|
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
2
|
|
3
3
|
describe "indentation" do
|
4
|
+
include Erector::Mixin
|
4
5
|
|
5
6
|
it "can detect newliney tags" do
|
6
7
|
widget = ::Erector.inline
|
7
|
-
widget.instance_eval do
|
8
|
+
widget.instance_eval do
|
8
9
|
@prettyprint = true
|
9
10
|
end
|
10
11
|
widget.send(:newliney?, "i").should == false
|
@@ -17,21 +18,21 @@ describe "indentation" do
|
|
17
18
|
b "World"
|
18
19
|
end.to_pretty.should == "Hello, <b>World</b>"
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
it "should add newlines before open newliney tags" do
|
22
23
|
Erector.inline do
|
23
24
|
p "foo"
|
24
25
|
p "bar"
|
25
26
|
end.to_pretty.should == "<p>foo</p>\n<p>bar</p>\n"
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
it "should add newlines between text and open newliney tag" do
|
29
30
|
Erector.inline do
|
30
31
|
text "One"
|
31
32
|
p "Two"
|
32
33
|
end.to_pretty.should == "One\n<p>Two</p>\n"
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
it "should add newlines after end newliney tags" do
|
36
37
|
Erector.inline do
|
37
38
|
tr do
|
@@ -39,7 +40,7 @@ describe "indentation" do
|
|
39
40
|
end
|
40
41
|
end.to_pretty.should == "<tr>\n <td>cell</td>\n</tr>\n"
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
it "should treat empty elements as start and end" do
|
44
45
|
Erector.inline do
|
45
46
|
p "before"
|
@@ -47,13 +48,13 @@ describe "indentation" do
|
|
47
48
|
p "after"
|
48
49
|
end.to_pretty.should == "<p>before</p>\n<br />\n<p>after</p>\n"
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
it "empty elements sets at_start_of_line" do
|
52
53
|
Erector.inline do
|
53
54
|
text "before"
|
54
55
|
br
|
55
56
|
p "after"
|
56
|
-
end.to_pretty.should == "before
|
57
|
+
end.to_pretty.should == "before<br />\n<p>after</p>\n"
|
57
58
|
end
|
58
59
|
|
59
60
|
it "will not insert extra space before/after input element" do
|
@@ -65,7 +66,7 @@ describe "indentation" do
|
|
65
66
|
text 'after'
|
66
67
|
end.to_pretty.should == 'Name<input type="text" />after'
|
67
68
|
end
|
68
|
-
|
69
|
+
|
69
70
|
it "will indent" do
|
70
71
|
Erector.inline do
|
71
72
|
html do
|
@@ -91,7 +92,7 @@ describe "indentation" do
|
|
91
92
|
</html>
|
92
93
|
END
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
it "preserves indentation for sub-rendered widgets" do
|
96
97
|
tea = Erector.inline do
|
97
98
|
div do
|
@@ -101,10 +102,10 @@ END
|
|
101
102
|
cup = Erector.inline do
|
102
103
|
div do
|
103
104
|
p "fine china"
|
104
|
-
tea
|
105
|
+
widget tea
|
105
106
|
end
|
106
107
|
end
|
107
|
-
|
108
|
+
|
108
109
|
cup.to_pretty.should == <<END
|
109
110
|
<div>
|
110
111
|
<p>fine china</p>
|
@@ -114,38 +115,97 @@ END
|
|
114
115
|
</div>
|
115
116
|
END
|
116
117
|
end
|
117
|
-
|
118
|
-
|
118
|
+
|
119
|
+
# see http://github.com/pivotal/erector/issues/#issue/5
|
120
|
+
it "indents scripts properly" do
|
121
|
+
pending
|
119
122
|
Erector.inline do
|
123
|
+
html :xmlns => 'http://www.w3.org/1999/xhtml' do
|
124
|
+
head do
|
125
|
+
javascript "Cufon.replace('#content');"
|
126
|
+
javascript '$(document).ready(function(){ $(document).pngFix(); });'
|
127
|
+
end
|
128
|
+
body do
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end.to_pretty.should == <<-HTML
|
132
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
133
|
+
<head>
|
134
|
+
<script type="text/javascript">
|
135
|
+
// <![CDATA[
|
136
|
+
Cufon.replace('#content');
|
137
|
+
// ]]>
|
138
|
+
</script>
|
139
|
+
<script type="text/javascript">
|
140
|
+
// <![CDATA[
|
141
|
+
$(document).ready(function(){ $(document).pngFix(); });
|
142
|
+
// ]]>
|
143
|
+
</script>
|
144
|
+
</head>
|
145
|
+
<body></body>
|
146
|
+
</html>
|
147
|
+
HTML
|
148
|
+
end
|
149
|
+
|
150
|
+
it "can turn off newlines" do
|
151
|
+
erector do
|
120
152
|
text "One"
|
121
153
|
p "Two"
|
122
|
-
end.
|
154
|
+
end.should == "One<p>Two</p>"
|
123
155
|
end
|
124
|
-
|
156
|
+
|
125
157
|
it "can turn newlines on and off" do
|
126
158
|
widget = Erector.inline do
|
127
159
|
text "One"
|
128
160
|
p "Two"
|
129
161
|
end
|
130
|
-
widget.
|
162
|
+
widget.to_html.should == "One<p>Two</p>"
|
131
163
|
widget.to_pretty.should == "One\n<p>Two</p>\n"
|
132
|
-
widget.
|
164
|
+
widget.to_html.should == "One<p>Two</p>"
|
133
165
|
end
|
134
|
-
|
166
|
+
|
135
167
|
it "can turn on newlines via to_pretty" do
|
136
168
|
widget = Erector.inline do
|
137
169
|
text "One"
|
138
170
|
p "Two"
|
139
171
|
end.to_pretty.should == "One\n<p>Two</p>\n"
|
140
172
|
end
|
141
|
-
|
173
|
+
|
142
174
|
it "can turn newlines on/off via global variable" do
|
143
|
-
|
175
|
+
erector { br }.should == "<br />"
|
144
176
|
Erector::Widget.prettyprint_default = true
|
145
|
-
|
177
|
+
erector { br }.should == "<br />\n"
|
146
178
|
Erector::Widget.prettyprint_default = false
|
147
|
-
|
179
|
+
erector { br }.should == "<br />"
|
148
180
|
end
|
149
|
-
|
150
|
-
end
|
151
181
|
|
182
|
+
describe ":max_length" do
|
183
|
+
it "wraps after N characters" do
|
184
|
+
Erector.inline do
|
185
|
+
div "the quick brown fox jumps over the lazy dog"
|
186
|
+
end.to_html(:max_length => 20).should ==
|
187
|
+
"<div>the quick brown\n" +
|
188
|
+
"fox jumps over the\n" +
|
189
|
+
"lazy dog</div>"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "preserves pretty indent" do
|
193
|
+
Erector.inline do
|
194
|
+
div "the quick brown fox jumps over the lazy dog"
|
195
|
+
end.to_pretty(:max_length => 20).should ==
|
196
|
+
"<div>the quick brown\n" +
|
197
|
+
" fox jumps over the\n" +
|
198
|
+
" lazy dog</div>\n"
|
199
|
+
end
|
200
|
+
|
201
|
+
it "preserves raw strings" do
|
202
|
+
Erector.inline do
|
203
|
+
div raw("the quick <brown> fox <jumps> over the lazy dog")
|
204
|
+
end.to_html(:max_length => 20).should ==
|
205
|
+
"<div>the quick\n" +
|
206
|
+
"<brown> fox <jumps>\n" +
|
207
|
+
"over the lazy dog\n" +
|
208
|
+
"</div>"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/spec/erector/inline_spec.rb
CHANGED
@@ -3,18 +3,29 @@ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
|
3
3
|
describe Erector::Widget do
|
4
4
|
it "provides access to instance variables from the calling context" do
|
5
5
|
@var = "yay"
|
6
|
-
Erector::Widget.new { @var.should == "yay"; @var = "yum" }.
|
6
|
+
Erector::Widget.new { @var.should == "yay"; @var = "yum" }.to_html
|
7
7
|
@var.should == "yum"
|
8
8
|
end
|
9
9
|
|
10
10
|
it "provides access to bound variables from the calling context" do
|
11
11
|
var = "yay"
|
12
|
-
Erector::Widget.new { var.should == "yay"; var = "yum" }.
|
12
|
+
Erector::Widget.new { var.should == "yay"; var = "yum" }.to_html
|
13
13
|
var.should == "yum"
|
14
14
|
end
|
15
15
|
|
16
16
|
it "doesn't provide access to Erector methods" do
|
17
|
-
Erector::Widget.new { lambda { text "yay" }.should raise_error(NoMethodError) }.
|
17
|
+
Erector::Widget.new { lambda { text "yay" }.should raise_error(NoMethodError) }.to_html
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".inline" do
|
21
|
+
it "returns an instance with Erector::Inline mixed in" do
|
22
|
+
widget_subclass = Class.new(Erector::Widget)
|
23
|
+
widget_subclass.ancestors.should_not include(Erector::Inline)
|
24
|
+
|
25
|
+
inlined_instance = widget_subclass.inline
|
26
|
+
inlined_instance.class.ancestors.should include(widget_subclass)
|
27
|
+
inlined_instance.class.ancestors.should include(Erector::Inline)
|
28
|
+
end
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
@@ -25,16 +36,16 @@ describe Erector::Inline do
|
|
25
36
|
|
26
37
|
it "doesn't provide access to instance variables from the calling context" do
|
27
38
|
@var = "yay"
|
28
|
-
Erector.inline { text @var }.
|
39
|
+
Erector.inline { text @var }.to_html.should == ""
|
29
40
|
end
|
30
41
|
|
31
42
|
it "provides access to bound variables from the calling context" do
|
32
43
|
var = "yay"
|
33
|
-
Erector.inline { text var }.
|
44
|
+
Erector.inline { text var }.to_html.should == "yay"
|
34
45
|
end
|
35
46
|
|
36
47
|
it "provides access to explicit assigns" do
|
37
|
-
Erector.inline(:var => "yay") { text @var }.
|
48
|
+
Erector.inline(:var => "yay") { text @var }.to_html.should == "yay"
|
38
49
|
end
|
39
50
|
|
40
51
|
it "provides access to methods from the calling context" do
|
@@ -42,7 +53,7 @@ describe Erector::Inline do
|
|
42
53
|
"yay"
|
43
54
|
end
|
44
55
|
|
45
|
-
Erector.inline { text helper }.
|
56
|
+
Erector.inline { text helper }.to_html.should == "yay"
|
46
57
|
end
|
47
58
|
|
48
59
|
describe "#call_block" do
|
@@ -53,7 +64,7 @@ describe Erector::Inline do
|
|
53
64
|
end
|
54
65
|
|
55
66
|
# inside the block...
|
56
|
-
x.
|
67
|
+
x.to_html.should ==
|
57
68
|
"<arg>#{x.object_id}</arg>" + # the argument is the child
|
58
69
|
"<self>#{x.object_id}</self>" # and self is also the child
|
59
70
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
+
|
3
|
+
describe Erector::JQuery do
|
4
|
+
include Erector::Mixin
|
5
|
+
|
6
|
+
describe "#jquery" do
|
7
|
+
def expected(event, *args)
|
8
|
+
|
9
|
+
"<script #{'id="foo" ' if args.include? :id}type=\"text/javascript\">\n" +
|
10
|
+
"// <![CDATA[\n\n" +
|
11
|
+
"jQuery(document).#{event}(function($){\n" +
|
12
|
+
"alert('hello');\n});\n// ]]>\n</script>\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "outputs a 'jquery ready' script block by default" do
|
16
|
+
erector { jquery "alert('hello');" }.should == expected("ready")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "outputs attributes" do
|
20
|
+
erector { jquery "alert('hello');", :id => 'foo' }.should == expected("ready", :id)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "outputs a 'jquery ready' script block when passed a symbol for the first arg" do
|
24
|
+
erector { jquery :ready, "alert('hello');" }.should == expected("ready")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "outputs a 'jquery load' script block" do
|
28
|
+
erector { jquery :load, "alert('hello');" }.should == expected("load")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "combines event, text, and attributes" do
|
32
|
+
erector { jquery :load, "alert('hello');", :id => "foo" }.should == expected("load", :id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/erector/mixin_spec.rb
CHANGED
@@ -0,0 +1,120 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
+
|
3
|
+
describe Erector::Needs do
|
4
|
+
it "doesn't complain if there aren't any needs declared" do
|
5
|
+
class Thing1 < Erector::Widget
|
6
|
+
end
|
7
|
+
Thing1.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "allows you to say that you don't want any parameters" do
|
11
|
+
class Thing2 < Erector::Widget
|
12
|
+
needs nil
|
13
|
+
end
|
14
|
+
lambda { Thing2.new }.should_not raise_error
|
15
|
+
lambda { Thing2.new(:foo => 1) }.should raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "doesn't complain if you pass it a declared parameter" do
|
19
|
+
class Thing2b < Erector::Widget
|
20
|
+
needs :foo
|
21
|
+
end
|
22
|
+
lambda { Thing2b.new(:foo => 1) }.should_not raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "complains if you pass it an undeclared parameter" do
|
26
|
+
class Thing3 < Erector::Widget
|
27
|
+
needs :foo
|
28
|
+
end
|
29
|
+
lambda { Thing3.new(:bar => 1) }.should raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it "allows multiple declared parameters" do
|
33
|
+
class Thing4 < Erector::Widget
|
34
|
+
needs :foo, :bar
|
35
|
+
end
|
36
|
+
lambda { Thing4.new(:foo => 1, :bar => 2) }.should_not raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "complains when passing in an extra parameter after declaring many parameters" do
|
40
|
+
class Thing5 < Erector::Widget
|
41
|
+
needs :foo, :bar
|
42
|
+
end
|
43
|
+
lambda { Thing5.new(:foo => 1, :bar => 2, :baz => 3) }.should raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "complains when you forget to pass in a needed parameter" do
|
47
|
+
class Thing6 < Erector::Widget
|
48
|
+
needs :foo, :bar
|
49
|
+
end
|
50
|
+
lambda { Thing6.new(:foo => 1) }.should raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it "doesn't complain if you omit a parameter with a default value" do
|
54
|
+
class Thing7 < Erector::Widget
|
55
|
+
needs :foo
|
56
|
+
needs :bar => 7
|
57
|
+
needs :baz => 8
|
58
|
+
end
|
59
|
+
lambda {
|
60
|
+
thing = Thing7.new(:foo => 1, :baz => 3)
|
61
|
+
thing.instance_variable_get(:@bar).should equal(7)
|
62
|
+
thing.instance_variable_get(:@baz).should equal(3)
|
63
|
+
}.should_not raise_error
|
64
|
+
end
|
65
|
+
|
66
|
+
it "allows multiple values on a line, including default values at the end of the line" do
|
67
|
+
class Thing8 < Erector::Widget
|
68
|
+
needs :foo, :bar => 7, :baz => 8
|
69
|
+
end
|
70
|
+
lambda {
|
71
|
+
thing = Thing8.new(:foo => 1, :baz => 2)
|
72
|
+
thing.instance_variable_get(:@foo).should equal(1)
|
73
|
+
thing.instance_variable_get(:@bar).should equal(7)
|
74
|
+
thing.instance_variable_get(:@baz).should equal(2)
|
75
|
+
}.should_not raise_error
|
76
|
+
end
|
77
|
+
|
78
|
+
it "allows nil to be a default value" do
|
79
|
+
class Thing9 < Erector::Widget
|
80
|
+
needs :foo => nil
|
81
|
+
end
|
82
|
+
lambda {
|
83
|
+
thing = Thing9.new
|
84
|
+
thing.instance_variable_get(:@foo).should be_nil
|
85
|
+
}.should_not raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
it "accumulates needs across the inheritance chain even with modules mixed in" do
|
89
|
+
module Something
|
90
|
+
end
|
91
|
+
|
92
|
+
class Vehicle < Erector::Widget
|
93
|
+
needs :wheels
|
94
|
+
end
|
95
|
+
|
96
|
+
class Car < Vehicle
|
97
|
+
include Something
|
98
|
+
needs :engine
|
99
|
+
end
|
100
|
+
|
101
|
+
lambda { Car.new(:engine => 'V-8', :wheels => 4) }.should_not raise_error
|
102
|
+
lambda { Car.new(:engine => 'V-8') }.should raise_error
|
103
|
+
lambda { Car.new(:wheels => 4) }.should raise_error
|
104
|
+
end
|
105
|
+
|
106
|
+
it "no longer defines accessors for each of the needed variables" do
|
107
|
+
class NeedfulThing < Erector::Widget
|
108
|
+
needs :love
|
109
|
+
end
|
110
|
+
thing = NeedfulThing.new(:love => "all we need")
|
111
|
+
lambda {thing.love}.should raise_error(NoMethodError)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "no longer complains if you attempt to 'need' a variable whose name overlaps with an existing method" do
|
115
|
+
class ThingWithOverlap < Erector::Widget
|
116
|
+
needs :text
|
117
|
+
end
|
118
|
+
lambda { ThingWithOverlap.new(:text => "alas") }.should_not raise_error(ArgumentError)
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
+
|
3
|
+
module Erector
|
4
|
+
describe Erector::Output do
|
5
|
+
before do
|
6
|
+
@output = Output.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "accepts a string via the << operator" do
|
10
|
+
@output.to_s.should == ""
|
11
|
+
@output << "foo"
|
12
|
+
@output.to_s.should == "foo"
|
13
|
+
@output << "bar"
|
14
|
+
@output.to_s.should == "foobar"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "#<< accepts a number" do
|
18
|
+
@output << 1
|
19
|
+
@output.to_s.should == "1"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts chained <<s" do
|
23
|
+
@output << "foo" << "bar"
|
24
|
+
@output.to_s.should == "foobar"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "provides a placeholder string to be filled in later" do
|
28
|
+
@output << "foo"
|
29
|
+
placeholder = @output.placeholder
|
30
|
+
@output << "bar"
|
31
|
+
@output.to_s.should == "foobar"
|
32
|
+
placeholder << "baz"
|
33
|
+
@output.to_s.should == "foobazbar"
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#to_a' do
|
37
|
+
it "emits an array" do
|
38
|
+
@output << "foo" << "bar"
|
39
|
+
@output.to_a.join.should == "foobar"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can be initialized with an existing string buffer" do
|
44
|
+
s = "foo"
|
45
|
+
@output = Output.new { s }
|
46
|
+
@output << "bar"
|
47
|
+
s.should == "foobar"
|
48
|
+
@output.to_s.should == "foobar"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "accepts a prettyprint option" do
|
52
|
+
Erector::Output.new(:prettyprint => true).prettyprint.should be_true
|
53
|
+
Erector::Output.new(:prettyprint => false).prettyprint.should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "accepts the global prettyprint_default setting" do
|
57
|
+
old_default = Erector::Widget.new.prettyprint_default
|
58
|
+
begin
|
59
|
+
Erector::Widget.prettyprint_default = true
|
60
|
+
Erector::Output.new.prettyprint.should be_true
|
61
|
+
Erector::Widget.prettyprint_default = false
|
62
|
+
Erector::Output.new.prettyprint.should be_false
|
63
|
+
ensure
|
64
|
+
Erector::Widget.prettyprint_default = old_default
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#newline' do
|
69
|
+
it "inserts a newline if we're in prettyprint mode" do
|
70
|
+
@output = Output.new(:prettyprint => true)
|
71
|
+
@output << "foo"
|
72
|
+
@output.newline
|
73
|
+
@output.should be_at_line_start
|
74
|
+
@output.to_s.should == "foo\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "tracks whether we're at the beginning of a line or not" do
|
78
|
+
@output = Output.new(:prettyprint => true)
|
79
|
+
@output.should be_at_line_start
|
80
|
+
@output << "foo"
|
81
|
+
@output.should_not be_at_line_start
|
82
|
+
@output.newline
|
83
|
+
@output.should be_at_line_start
|
84
|
+
@output << "bar"
|
85
|
+
@output.should_not be_at_line_start
|
86
|
+
@output.newline
|
87
|
+
@output.should be_at_line_start
|
88
|
+
end
|
89
|
+
|
90
|
+
it "doesn't insert a newline (or track line starts) if we're not in prettyprint mode" do
|
91
|
+
@output = Output.new(:prettyprint => false)
|
92
|
+
@output << "foo"
|
93
|
+
@output.newline
|
94
|
+
@output.should_not be_at_line_start
|
95
|
+
@output.to_s.should == "foo"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "pretty printing" do
|
100
|
+
before do
|
101
|
+
@output = Output.new(:prettyprint => true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "indents the next line when we're at line start and indented" do
|
105
|
+
@output << "foo"
|
106
|
+
@output.newline
|
107
|
+
@output.indent
|
108
|
+
@output << "bar"
|
109
|
+
@output.newline
|
110
|
+
@output.undent
|
111
|
+
@output << "baz"
|
112
|
+
@output.newline
|
113
|
+
|
114
|
+
@output.to_s.should == "foo\n bar\nbaz\n"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "doesn't indent if there's a linebreak in the middle of a string" do
|
118
|
+
@output.indent
|
119
|
+
@output << "foo\nbar\nbaz\n"
|
120
|
+
@output.to_s.should == " foo\nbar\nbaz\n"
|
121
|
+
end
|
122
|
+
|
123
|
+
it "turns off if prettyprint is false" do
|
124
|
+
@output = Output.new(:prettyprint => false)
|
125
|
+
@output.indent
|
126
|
+
@output << "bar"
|
127
|
+
@output.to_s.should == "bar"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "doesn't crash if indentation level is less than 0" do
|
131
|
+
@output.undent
|
132
|
+
@output << "bar"
|
133
|
+
@output.to_s.should == "bar"
|
134
|
+
# [@indentation, 0].max
|
135
|
+
end
|
136
|
+
|
137
|
+
it "accepts an initial indentation level" do
|
138
|
+
@output = Output.new(:prettyprint => true, :indentation => 2)
|
139
|
+
@output << "foo"
|
140
|
+
@output.to_s.should == " foo"
|
141
|
+
end
|
142
|
+
|
143
|
+
it "accepts a max line length" do
|
144
|
+
@output = Output.new(:prettyprint => true, :max_length => 10)
|
145
|
+
@output << "Now is the winter of our discontent made "
|
146
|
+
@output << "glorious summer by this sun of York."
|
147
|
+
@output.to_s.should ==
|
148
|
+
"Now is the\n" +
|
149
|
+
"winter of\n" +
|
150
|
+
"our\n" +
|
151
|
+
"discontent\n" +
|
152
|
+
"made \n" +
|
153
|
+
"glorious\n" +
|
154
|
+
"summer by\n" +
|
155
|
+
"this sun\n" +
|
156
|
+
"of York."
|
157
|
+
end
|
158
|
+
|
159
|
+
it "preserves leading and trailing spaces" do
|
160
|
+
@output = Output.new(:max_length => 10)
|
161
|
+
@output << "123456789"
|
162
|
+
@output << " foo "
|
163
|
+
@output << "bar"
|
164
|
+
@output.to_s.should == "123456789 \nfoo bar"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "accepts a max line length wth indentation" do
|
168
|
+
# note that 1 indent = 2 spaces
|
169
|
+
@output = Output.new(:prettyprint => true, :indentation => 1, :max_length => 10)
|
170
|
+
@output << "Now is the winter of our discontent made glorious summer by this sun of York."
|
171
|
+
@output.to_s.should ==
|
172
|
+
" Now is\n" +
|
173
|
+
" the\n" +
|
174
|
+
" winter\n" +
|
175
|
+
" of our\n" +
|
176
|
+
" discontent\n" +
|
177
|
+
" made\n" +
|
178
|
+
" glorious\n" +
|
179
|
+
" summer\n" +
|
180
|
+
" by this\n" +
|
181
|
+
" sun of\n" +
|
182
|
+
" York."
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
class Puppy < Erector::Widget
|
188
|
+
end
|
189
|
+
class Kitten < Erector::Widget
|
190
|
+
end
|
191
|
+
|
192
|
+
it "can keep track of widget classes emitted to it" do
|
193
|
+
@output.widgets << Puppy
|
194
|
+
@output.widgets << Kitten
|
195
|
+
@output.widgets << Puppy
|
196
|
+
@output.widgets.to_a.should include_only [Puppy, Kitten]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|