honkster-erector 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/README.txt +116 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/erector +14 -0
  4. data/lib/erector.rb +34 -0
  5. data/lib/erector/abstract_widget.rb +172 -0
  6. data/lib/erector/after_initialize.rb +34 -0
  7. data/lib/erector/caching.rb +93 -0
  8. data/lib/erector/convenience.rb +58 -0
  9. data/lib/erector/dependencies.rb +24 -0
  10. data/lib/erector/dependency.rb +30 -0
  11. data/lib/erector/erect/erect.rb +160 -0
  12. data/lib/erector/erect/erected.rb +75 -0
  13. data/lib/erector/erect/indenting.rb +36 -0
  14. data/lib/erector/erect/rhtml.treetop +233 -0
  15. data/lib/erector/errors.rb +12 -0
  16. data/lib/erector/extensions/hash.rb +21 -0
  17. data/lib/erector/extensions/object.rb +18 -0
  18. data/lib/erector/externals.rb +97 -0
  19. data/lib/erector/html.rb +352 -0
  20. data/lib/erector/inline.rb +37 -0
  21. data/lib/erector/jquery.rb +36 -0
  22. data/lib/erector/mixin.rb +12 -0
  23. data/lib/erector/needs.rb +94 -0
  24. data/lib/erector/output.rb +117 -0
  25. data/lib/erector/rails.rb +27 -0
  26. data/lib/erector/rails/extensions/action_controller.rb +16 -0
  27. data/lib/erector/rails/extensions/rails_helpers.rb +159 -0
  28. data/lib/erector/rails/extensions/rails_widget.rb +126 -0
  29. data/lib/erector/rails/rails_form_builder.rb +24 -0
  30. data/lib/erector/rails/rails_version.rb +6 -0
  31. data/lib/erector/rails/template_handlers/ert_handler.rb +32 -0
  32. data/lib/erector/rails/template_handlers/rb_handler.rb +52 -0
  33. data/lib/erector/raw_string.rb +8 -0
  34. data/lib/erector/sass.rb +22 -0
  35. data/lib/erector/unicode.rb +18185 -0
  36. data/lib/erector/unicode_builder.rb +67 -0
  37. data/lib/erector/version.rb +12 -0
  38. data/lib/erector/widget.rb +54 -0
  39. data/lib/erector/widgets.rb +6 -0
  40. data/lib/erector/widgets/environment_badge.rb +29 -0
  41. data/lib/erector/widgets/external_renderer.rb +51 -0
  42. data/lib/erector/widgets/field_table.rb +110 -0
  43. data/lib/erector/widgets/form.rb +30 -0
  44. data/lib/erector/widgets/page.rb +165 -0
  45. data/lib/erector/widgets/table.rb +104 -0
  46. data/rails/init.rb +4 -0
  47. data/spec/erect/erect_rails_spec.rb +114 -0
  48. data/spec/erect/erect_spec.rb +175 -0
  49. data/spec/erect/erected_spec.rb +164 -0
  50. data/spec/erect/rhtml_parser_spec.rb +361 -0
  51. data/spec/erector/caching_spec.rb +269 -0
  52. data/spec/erector/convenience_spec.rb +259 -0
  53. data/spec/erector/dependency_spec.rb +67 -0
  54. data/spec/erector/externals_spec.rb +236 -0
  55. data/spec/erector/html_spec.rb +509 -0
  56. data/spec/erector/indentation_spec.rb +211 -0
  57. data/spec/erector/inline_spec.rb +94 -0
  58. data/spec/erector/jquery_spec.rb +35 -0
  59. data/spec/erector/mixin_spec.rb +65 -0
  60. data/spec/erector/needs_spec.rb +120 -0
  61. data/spec/erector/output_spec.rb +199 -0
  62. data/spec/erector/sample-file.txt +1 -0
  63. data/spec/erector/sass_spec.rb +33 -0
  64. data/spec/erector/unicode_builder_spec.rb +75 -0
  65. data/spec/erector/widget_spec.rb +250 -0
  66. data/spec/erector/widgets/field_table_spec.rb +133 -0
  67. data/spec/erector/widgets/form_spec.rb +31 -0
  68. data/spec/erector/widgets/page_spec.rb +85 -0
  69. data/spec/erector/widgets/table_spec.rb +99 -0
  70. data/spec/spec_helper.rb +95 -0
  71. metadata +191 -0
@@ -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
@@ -0,0 +1 @@
1
+ sample file contents, 2 + 2 = #{2 + 2}
@@ -0,0 +1,33 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ if !Object.const_defined?(:Sass)
4
+ puts "Skipping Sass spec... run 'gem install haml' to enable these tests."
5
+ else
6
+ module CacheSpec
7
+ describe Erector::Sass do
8
+ include Erector::Mixin
9
+ it "works" do
10
+ erector {sass SAMPLE_SASS}.should == SAMPLE_CSS
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ SAMPLE_SASS =<<-SASS
17
+ h1
18
+ height: 118px
19
+ margin-top: 1em
20
+
21
+ .tagline
22
+ font-size: 26px
23
+ text-align: right
24
+ SASS
25
+
26
+ SAMPLE_CSS ="""<style>h1 {
27
+ height: 118px;
28
+ margin-top: 1em; }
29
+
30
+ .tagline {
31
+ font-size: 26px;
32
+ text-align: right; }
33
+ </style>"""
@@ -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
+
@@ -0,0 +1,250 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+ require 'benchmark'
3
+
4
+ module WidgetSpec
5
+ describe Erector::Widget do
6
+ include Erector::Mixin
7
+
8
+ describe "#to_html" do
9
+ it "invokes #content and returns the string representation of the rendered widget" do
10
+ Class.new(Erector::Widget) do
11
+ def content
12
+ text "Hello"
13
+ end
14
+ end.new.to_html.should == "Hello"
15
+ end
16
+
17
+ it "supports other content methods via :content_method_name" do
18
+ Class.new(Erector::Widget) do
19
+ def alternate
20
+ text "Alternate"
21
+ end
22
+ end.new.to_html(:content_method_name => :alternate).should == "Alternate"
23
+ end
24
+
25
+ it "returns an HTML-safe string" do
26
+ Erector::Widget.new.to_html.should be_html_safe
27
+ end
28
+
29
+ it "accepts an existing string as an output buffer" do
30
+ s = "foo"
31
+ Erector.inline { text "bar" }.to_html(:output => s)
32
+ s.should == "foobar"
33
+ end
34
+
35
+ it "accepts an existing Output as an output buffer" do
36
+ output = Erector::Output.new
37
+ output << "foo"
38
+ Erector.inline { text "bar" }.to_html(:output => output)
39
+ output.to_s.should == "foobar"
40
+ end
41
+ end
42
+
43
+ describe "#to_a" do
44
+ it "returns an array" do
45
+ a = Erector.inline { div "Hello" }.to_a
46
+ a.should be_an(Array)
47
+ a.join.should == "<div>Hello</div>"
48
+ end
49
+ end
50
+
51
+ describe '#widget' do
52
+ class Orphan < Erector::Widget
53
+ def content
54
+ p @name
55
+ end
56
+ end
57
+
58
+ it "renders a widget class" do
59
+ erector do
60
+ div do
61
+ widget Orphan, :name => "Annie"
62
+ end
63
+ end.should == "<div><p>Annie</p></div>"
64
+ end
65
+
66
+ it "renders a widget instance" do
67
+ erector do
68
+ div do
69
+ widget Orphan.new(:name => "Oliver")
70
+ end
71
+ end.should == "<div><p>Oliver</p></div>"
72
+ end
73
+
74
+ it "adds the widget to the parent's output widgets" do
75
+ inner = Class.new(Erector::Widget)
76
+ outer = Erector.inline { widget inner }
77
+ outer.to_html
78
+ outer.output.widgets.should include(inner)
79
+ end
80
+
81
+ it "supports specifying content_method_name" do
82
+ inner = Class.new(Erector::Widget) do
83
+ def foo; text "foo"; end
84
+ end
85
+ erector do
86
+ widget inner, {}, :content_method_name => :foo
87
+ end.should == "foo"
88
+ end
89
+
90
+ it "renders nested widgets in the correct order" do
91
+ class Parent < Erector::Widget
92
+ def content
93
+ text 1
94
+ widget Erector::Widget do
95
+ text 2
96
+ third
97
+ end
98
+ end
99
+
100
+ def third
101
+ text 3
102
+ end
103
+ end
104
+
105
+ Parent.new.to_html.should == '123'
106
+ end
107
+
108
+ context "when nested" do
109
+ module WhenNested
110
+ class Parent < Erector::Widget
111
+ def content
112
+ div :id => "parent_widget" do
113
+ super
114
+ end
115
+ end
116
+ end
117
+
118
+ class Child < Erector::Widget
119
+ def content
120
+ div :id => "child_widget" do
121
+ super
122
+ end
123
+ end
124
+ end
125
+
126
+ class Grandchild < Erector::Widget
127
+ needs :parent_widget, :child_widget
128
+ def content
129
+ widget(@parent_widget) do
130
+ widget(@child_widget) do
131
+ div :id => "grandchild"
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ it "renders the tag around the rest of the block" do
139
+ WhenNested::Grandchild.new(
140
+ :parent_widget => WhenNested::Parent,
141
+ :child_widget => WhenNested::Child
142
+ ).to_html.should == '<div id="parent_widget"><div id="child_widget"><div id="grandchild"></div></div></div>'
143
+ end
144
+
145
+ it "renders the tag around the rest of the block with proper indentation" do
146
+ WhenNested::Grandchild.new(
147
+ :parent_widget => WhenNested::Parent,
148
+ :child_widget => WhenNested::Child
149
+ ).to_pretty.should ==
150
+ "<div id=\"parent_widget\">\n" +
151
+ " <div id=\"child_widget\">\n" +
152
+ " <div id=\"grandchild\"></div>\n" +
153
+ " </div>\n" +
154
+ "</div>\n"
155
+ end
156
+
157
+ it "passes a pointer to the child object back into the parent object's block" do
158
+ child_widget = Erector::Widget.new
159
+
160
+ class Parent2 < Erector::Widget
161
+ needs :child_widget
162
+ def content
163
+ div do
164
+ widget @child_widget do |child|
165
+ b child.dom_id
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ Parent2.new(:child_widget => child_widget).to_html.should == "<div><b>#{child_widget.dom_id}</b></div>"
172
+ end
173
+ end
174
+ end
175
+
176
+ describe "#call_block" do
177
+ it "calls the block with a pointer to self" do
178
+ inside_arg = nil
179
+ inside_self = nil
180
+ x = Erector::Widget.new do |y|
181
+ inside_arg = y.object_id
182
+ inside_self = self.object_id
183
+ end
184
+ x.call_block
185
+ # inside the block...
186
+ inside_arg.should == x.object_id # the argument is the child
187
+ inside_self.should == self.object_id # and self is the parent
188
+ end
189
+ end
190
+
191
+ describe '#capture' do
192
+ it "should return content rather than write it to the buffer" do
193
+ erector do
194
+ captured = capture do
195
+ p 'Captured Content'
196
+ end
197
+ div do
198
+ text captured
199
+ end
200
+ end.should == '<div><p>Captured Content</p></div>'
201
+ end
202
+
203
+ it "returns a RawString" do
204
+ captured = nil
205
+ erector do
206
+ captured = capture {}
207
+ end.should == ""
208
+ captured.should be_a_kind_of(Erector::RawString)
209
+ end
210
+
211
+ it "works with nested captures" do
212
+ erector do
213
+ captured = capture do
214
+ captured = capture do
215
+ p 'Nested Capture'
216
+ end
217
+ p 'Captured Content'
218
+ text captured
219
+ end
220
+ div do
221
+ text captured
222
+ end
223
+ end.should == '<div><p>Captured Content</p><p>Nested Capture</p></div>'
224
+ end
225
+ end
226
+
227
+ describe '#text' do
228
+ it "renders a widget" do
229
+ erector do
230
+ text "B"
231
+ text Erector.inline { p "A" }
232
+ text "B"
233
+ end.should == "B<p>A</p>B"
234
+ end
235
+ end
236
+
237
+ describe "assigning instance variables" do
238
+ it "handles instance variable names with and without '@' in the beginning" do
239
+ html = Erector.inline(:foo => "bar", '@baz' => 'quux') do
240
+ div do
241
+ p @foo
242
+ p @baz
243
+ end
244
+ end.to_html
245
+ doc = Nokogiri::HTML(html)
246
+ doc.css("p").map {|p| p.inner_html}.should == ["bar", "quux"]
247
+ end
248
+ end
249
+ end
250
+ end