erector-rails4 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +143 -0
  10. data/README.md +4 -0
  11. data/Rakefile +24 -0
  12. data/erector-rails4.gemspec +36 -0
  13. data/erector-rails4.sublimeproject +20 -0
  14. data/lib/erector/abstract_widget.rb +231 -0
  15. data/lib/erector/after_initialize.rb +29 -0
  16. data/lib/erector/attributes.rb +29 -0
  17. data/lib/erector/cache.rb +37 -0
  18. data/lib/erector/caching.rb +65 -0
  19. data/lib/erector/convenience.rb +98 -0
  20. data/lib/erector/dependencies.rb +24 -0
  21. data/lib/erector/dependency.rb +31 -0
  22. data/lib/erector/element.rb +113 -0
  23. data/lib/erector/externals.rb +104 -0
  24. data/lib/erector/html.rb +12 -0
  25. data/lib/erector/html_widget.rb +220 -0
  26. data/lib/erector/inline.rb +37 -0
  27. data/lib/erector/jquery.rb +28 -0
  28. data/lib/erector/mixin.rb +12 -0
  29. data/lib/erector/needs.rb +95 -0
  30. data/lib/erector/output.rb +144 -0
  31. data/lib/erector/promise.rb +141 -0
  32. data/lib/erector/rails/form_builder.rb +44 -0
  33. data/lib/erector/rails/railtie.rb +13 -0
  34. data/lib/erector/rails/template_handler.rb +16 -0
  35. data/lib/erector/rails/widget_renderer.rb +6 -0
  36. data/lib/erector/rails.rb +221 -0
  37. data/lib/erector/raw_string.rb +12 -0
  38. data/lib/erector/sass.rb +32 -0
  39. data/lib/erector/tag.rb +66 -0
  40. data/lib/erector/text.rb +123 -0
  41. data/lib/erector/unicode.rb +18185 -0
  42. data/lib/erector/unicode_builder.rb +67 -0
  43. data/lib/erector/version.rb +5 -0
  44. data/lib/erector/widget.rb +94 -0
  45. data/lib/erector/widgets.rb +5 -0
  46. data/lib/erector/xml_widget.rb +131 -0
  47. data/lib/erector.rb +28 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/controllers/application.rb +6 -0
  50. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  51. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  52. data/spec/dummy/app/views/layouts/erb_as_layout.html.erb +2 -0
  53. data/spec/dummy/app/views/layouts/widget_as_layout.rb +8 -0
  54. data/spec/dummy/app/views/test/_erb.erb +1 -0
  55. data/spec/dummy/app/views/test/_erector.rb +5 -0
  56. data/spec/dummy/app/views/test/_partial_with_locals.rb +7 -0
  57. data/spec/dummy/app/views/test/bare.rb +5 -0
  58. data/spec/dummy/app/views/test/erb_from_erector.html.rb +5 -0
  59. data/spec/dummy/app/views/test/erector_from_erb.html.erb +1 -0
  60. data/spec/dummy/app/views/test/erector_with_locals_from_erb.html.erb +6 -0
  61. data/spec/dummy/app/views/test/implicit_assigns.html.rb +5 -0
  62. data/spec/dummy/app/views/test/needs.html.rb +7 -0
  63. data/spec/dummy/app/views/test/needs_subclass.html.rb +5 -0
  64. data/spec/dummy/app/views/test/protected_instance_variable.html.rb +5 -0
  65. data/spec/dummy/app/views/test/render_default.html.rb +5 -0
  66. data/spec/dummy/app/views/test/render_default_erb_with_layout.html.erb +1 -0
  67. data/spec/dummy/app/views/test/render_default_widget_with_layout.html.rb +5 -0
  68. data/spec/dummy/app/views/test/render_partial.html.rb +5 -0
  69. data/spec/dummy/app/views/test/render_with_widget_as_layout.rb +5 -0
  70. data/spec/dummy/app/views/test/render_with_widget_as_layout_using_content_for.rb +8 -0
  71. data/spec/dummy/config/application.rb +44 -0
  72. data/spec/dummy/config/boot.rb +10 -0
  73. data/spec/dummy/config/database.yml +22 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +22 -0
  76. data/spec/dummy/config/environments/production.rb +49 -0
  77. data/spec/dummy/config/environments/test.rb +36 -0
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/spec/dummy/config/initializers/inflections.rb +10 -0
  80. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  81. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  82. data/spec/dummy/config/initializers/session_store.rb +8 -0
  83. data/spec/dummy/config/locales/en.yml +5 -0
  84. data/spec/dummy/config/routes.rb +3 -0
  85. data/spec/dummy/config.ru +4 -0
  86. data/spec/dummy/db/seeds.rb +7 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/dummy/spec/form_builder_spec.rb +21 -0
  89. data/spec/dummy/spec/rails_helpers_spec.rb +236 -0
  90. data/spec/dummy/spec/rails_spec_helper.rb +10 -0
  91. data/spec/dummy/spec/rails_widget_spec.rb +83 -0
  92. data/spec/dummy/spec/render_spec.rb +369 -0
  93. data/spec/erector/after_initialize_spec.rb +45 -0
  94. data/spec/erector/cache_spec.rb +133 -0
  95. data/spec/erector/caching_spec.rb +184 -0
  96. data/spec/erector/convenience_spec.rb +250 -0
  97. data/spec/erector/dependency_spec.rb +67 -0
  98. data/spec/erector/hello_from_readme.rb +18 -0
  99. data/spec/erector/hello_from_readme_spec.rb +11 -0
  100. data/spec/erector/html_spec.rb +585 -0
  101. data/spec/erector/indentation_spec.rb +211 -0
  102. data/spec/erector/inline_spec.rb +94 -0
  103. data/spec/erector/jquery_spec.rb +35 -0
  104. data/spec/erector/mixin_spec.rb +65 -0
  105. data/spec/erector/needs_spec.rb +141 -0
  106. data/spec/erector/output_spec.rb +293 -0
  107. data/spec/erector/promise_spec.rb +173 -0
  108. data/spec/erector/sample-file.txt +1 -0
  109. data/spec/erector/sass_spec.rb +57 -0
  110. data/spec/erector/tag_spec.rb +67 -0
  111. data/spec/erector/unicode_builder_spec.rb +75 -0
  112. data/spec/erector/widget_spec.rb +310 -0
  113. data/spec/erector/xml_widget_spec.rb +73 -0
  114. data/spec/spec_helper.rb +31 -0
  115. metadata +368 -0
@@ -0,0 +1,293 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ require 'active_support'
4
+
5
+ module Erector
6
+ describe Erector::Output do
7
+ before do
8
+ @output = Output.new
9
+ end
10
+
11
+ it "accepts a string via the << operator" do
12
+ @output.to_s.should == ""
13
+ @output << "foo"
14
+ @output.to_s.should == "foo"
15
+ @output << "bar"
16
+ @output.to_s.should == "foobar"
17
+ end
18
+
19
+ it "#<< accepts a number" do
20
+ @output << 1
21
+ @output.to_s.should == "1"
22
+ end
23
+
24
+ it "accepts chained <<s" do
25
+ @output << "foo" << "bar"
26
+ @output.to_s.should == "foobar"
27
+ end
28
+
29
+ it "provides a placeholder string to be filled in later" do
30
+ @output << "foo"
31
+ placeholder = @output.placeholder
32
+ @output << "bar"
33
+ @output.to_s.should == "foobar"
34
+ placeholder << "baz"
35
+ @output.to_s.should == "foobazbar"
36
+ end
37
+
38
+ describe '#to_a' do
39
+ it "emits an array" do
40
+ @output << "foo" << "bar"
41
+ @output.to_a.join.should == "foobar"
42
+ end
43
+
44
+ it "works with a string buffer" do
45
+ o = Output.new(:buffer => "")
46
+ o << "foo" << "bar"
47
+ o.to_a.should == ["foobar"]
48
+ end
49
+ end
50
+
51
+ it "can be initialized with an existing string buffer" do
52
+ s = "foo"
53
+ @output = Output.new(:buffer => s)
54
+ @output << "bar"
55
+ s.should == "foobar"
56
+ @output.to_s.should == "foobar"
57
+ end
58
+
59
+ it "accepts a prettyprint option" do
60
+ Erector::Output.new(:prettyprint => true).prettyprint.should be_true
61
+ Erector::Output.new(:prettyprint => false).prettyprint.should be_false
62
+ end
63
+
64
+ it "accepts the global prettyprint_default setting" do
65
+ old_default = Erector::Widget.new.prettyprint_default
66
+ begin
67
+ Erector::Widget.prettyprint_default = true
68
+ Erector::Output.new.prettyprint.should be_true
69
+ Erector::Widget.prettyprint_default = false
70
+ Erector::Output.new.prettyprint.should be_false
71
+ ensure
72
+ Erector::Widget.prettyprint_default = old_default
73
+ end
74
+ end
75
+
76
+ describe '#newline' do
77
+ it "inserts a newline if we're in prettyprint mode" do
78
+ @output = Output.new(:prettyprint => true)
79
+ @output << "foo"
80
+ @output.newline
81
+ @output.should be_at_line_start
82
+ @output.to_s.should == "foo\n"
83
+ end
84
+
85
+ it "tracks whether we're at the beginning of a line or not" do
86
+ @output = Output.new(:prettyprint => true)
87
+ @output.should be_at_line_start
88
+ @output << "foo"
89
+ @output.should_not be_at_line_start
90
+ @output.newline
91
+ @output.should be_at_line_start
92
+ @output << "bar"
93
+ @output.should_not be_at_line_start
94
+ @output.newline
95
+ @output.should be_at_line_start
96
+ end
97
+
98
+ it "doesn't insert a newline (or track line starts) if we're not in prettyprint mode" do
99
+ @output = Output.new(:prettyprint => false)
100
+ @output << "foo"
101
+ @output.newline
102
+ @output.should_not be_at_line_start
103
+ @output.to_s.should == "foo"
104
+ end
105
+ end
106
+
107
+ describe "pretty printing" do
108
+ before do
109
+ @output = Output.new(:prettyprint => true)
110
+ end
111
+
112
+ it "indents the next line when we're at line start and indented" do
113
+ @output << "foo"
114
+ @output.newline
115
+ @output.indent
116
+ @output << "bar"
117
+ @output.newline
118
+ @output.undent
119
+ @output << "baz"
120
+ @output.newline
121
+
122
+ @output.to_s.should == "foo\n bar\nbaz\n"
123
+ end
124
+
125
+ it "doesn't indent if there's a linebreak in the middle of a string" do
126
+ @output.indent
127
+ @output << "foo\nbar\nbaz\n"
128
+ @output.to_s.should == " foo\nbar\nbaz\n"
129
+ end
130
+
131
+ it "turns off if prettyprint is false" do
132
+ @output = Output.new(:prettyprint => false)
133
+ @output.indent
134
+ @output << "bar"
135
+ @output.to_s.should == "bar"
136
+ end
137
+
138
+ it "doesn't crash if indentation level is less than 0" do
139
+ @output.undent
140
+ @output << "bar"
141
+ @output.to_s.should == "bar"
142
+ # [@indentation, 0].max
143
+ end
144
+
145
+ it "accepts an initial indentation level" do
146
+ @output = Output.new(:prettyprint => true, :indentation => 2)
147
+ @output << "foo"
148
+ @output.to_s.should == " foo"
149
+ end
150
+
151
+ it "accepts a max line length" do
152
+ @output = Output.new(:prettyprint => true, :max_length => 10)
153
+ @output << "Now is the winter of our discontent made "
154
+ @output << "glorious summer by this sun of York."
155
+ @output.to_s.should ==
156
+ "Now is the\n" +
157
+ "winter of\n" +
158
+ "our\n" +
159
+ "discontent\n" +
160
+ "made \n" +
161
+ "glorious\n" +
162
+ "summer by\n" +
163
+ "this sun\n" +
164
+ "of York."
165
+ end
166
+
167
+ it "preserves leading and trailing spaces" do
168
+ @output = Output.new(:max_length => 10)
169
+ @output << "123456789"
170
+ @output << " foo "
171
+ @output << "bar"
172
+ @output.to_s.should == "123456789 \nfoo bar"
173
+ end
174
+
175
+ it "accepts a max line length wth indentation" do
176
+ # note that 1 indent = 2 spaces
177
+ @output = Output.new(:prettyprint => true, :indentation => 1, :max_length => 10)
178
+ @output << "Now is the winter of our discontent made glorious summer by this sun of York."
179
+ @output.to_s.should ==
180
+ " Now is\n" +
181
+ " the\n" +
182
+ " winter\n" +
183
+ " of our\n" +
184
+ " discontent\n" +
185
+ " made\n" +
186
+ " glorious\n" +
187
+ " summer\n" +
188
+ " by this\n" +
189
+ " sun of\n" +
190
+ " York."
191
+ end
192
+
193
+ end
194
+
195
+ describe "widget tracking" do
196
+
197
+ class Puppy < Erector::Widget
198
+ end
199
+ class Kitten < Erector::Widget
200
+ end
201
+
202
+ it "can keep track of widget classes emitted to it" do
203
+ @output.widgets << Puppy
204
+ @output.widgets << Kitten
205
+ @output.widgets << Puppy
206
+ @output.widgets.to_a.should include(Puppy)
207
+ @output.widgets.to_a.should include(Kitten)
208
+ end
209
+
210
+ end
211
+
212
+ describe "mark and rewind" do
213
+ it "with an array buffer" do
214
+ a = []
215
+ @output = Output.new(:buffer => a)
216
+ @output << "foo"
217
+ @output.mark
218
+
219
+ @output << "bar"
220
+ a.should == ["foo", "bar"]
221
+ @output.to_s.should == "foobar"
222
+
223
+ @output.rewind
224
+ @output.to_s.should == "foo"
225
+ a.should == ["foo"]
226
+
227
+ @output << "goo"
228
+ a.should == ["foo", "goo"]
229
+ @output.to_s.should == "foogoo"
230
+
231
+ @output.rewind
232
+ @output << "fa"
233
+ @output << "la"
234
+ a.should == ["foo", "fa", "la"]
235
+ @output.to_s.should == "foofala"
236
+ end
237
+
238
+ it "with a string buffer" do
239
+ s = ""
240
+ @output = Output.new(:buffer => s)
241
+ @output << "foo"
242
+ @output.mark
243
+
244
+ @output << "bar"
245
+ s.should == "foobar"
246
+
247
+ @output.rewind
248
+ s.should == "foo"
249
+
250
+ @output << "goo"
251
+ s.should == "foogoo"
252
+
253
+ @output.rewind
254
+ @output << "fa"
255
+ @output << "la"
256
+ s.should == "foofala"
257
+ end
258
+
259
+ it "with a SafeBuffer buffer" do
260
+ s = ActiveSupport::SafeBuffer.new
261
+ @output = Output.new(:buffer => s)
262
+ @output << "foo"
263
+ @output.mark
264
+
265
+ @output << "bar"
266
+ s.should == "foobar"
267
+
268
+ @output.rewind
269
+ s.should == "foo"
270
+
271
+ @output << "goo"
272
+ s.should == "foogoo"
273
+
274
+ @output.rewind
275
+ @output << "fa"
276
+ @output << "la"
277
+ s.should == "foofala"
278
+ end
279
+
280
+ it "returns and accepts a value" do
281
+ s = ""
282
+ @output = Output.new(:buffer => s)
283
+ @output << "a"
284
+ mark1 = @output.mark
285
+ @output << "b"
286
+ mark2 = @output.mark
287
+
288
+ @output.rewind(mark1)
289
+ s.should == "a"
290
+ end
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,173 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ require "erector/promise"
4
+ # a "promise" is my working name for a pointer back into the output stream, so we can rewrite the current tag (or a different one)
5
+ module Erector
6
+ describe Promise do
7
+ before do
8
+ @buffer = []
9
+ @output = Output.new(:buffer => @buffer)
10
+ end
11
+
12
+ it "has a tag name" do
13
+ promise = Promise.new(@output, "foo")
14
+ promise._tag_name.should == "foo"
15
+ end
16
+
17
+ it "can have attributes" do
18
+ promise = Promise.new(@output, "foo", :att => "val")
19
+ promise._tag_name.should == "foo"
20
+ promise._attributes.should == {"att" => "val"}
21
+ end
22
+
23
+ it "turns a dot call into a 'class' attribute" do
24
+ promise = Promise.new(@output, "foo")
25
+ promise.logo
26
+ promise._tag_name.should == "foo"
27
+ promise._attributes.should == {"class" => "logo"}
28
+ end
29
+
30
+ it "appends dot calls to an existing class attribute" do
31
+ promise = Promise.new(@output, "foo", :class => "logo")
32
+ promise.header
33
+ promise._attributes.should == {"class" => "logo header"}
34
+ end
35
+
36
+ it "chains dot calls" do
37
+ promise = Promise.new(@output, "foo")
38
+ promise.logo
39
+ promise.header
40
+ promise._attributes.should == {"class" => "logo header"}
41
+ end
42
+
43
+ it "turns a dot-bang call into an 'id' attribute" do
44
+ promise = Promise.new(@output, "foo")
45
+ promise.logo!
46
+ promise._tag_name.should == "foo"
47
+ promise._attributes.should == {"id" => "logo"}
48
+ end
49
+
50
+ it "fails if an id is already present" do
51
+ promise = Promise.new(@output, "foo", :id => 'logo')
52
+ lambda {
53
+ promise.logo!
54
+ }.should raise_error(ArgumentError)
55
+ end
56
+
57
+ describe '#_render' do
58
+ it "renders an empty tag" do
59
+ promise = Promise.new(@output, "foo")
60
+ promise._render
61
+ @output.to_s.should == "<foo></foo>"
62
+ end
63
+
64
+ it "renders an empty tag" do
65
+ promise = Promise.new(@output, "foo")
66
+ promise._render
67
+ @output.to_s.should == "<foo></foo>"
68
+ end
69
+
70
+ it "renders a self-closing tag" do
71
+ promise = Promise.new(@output, "foo", {}, true)
72
+ promise._render
73
+ @output.to_s.should == "<foo />"
74
+ end
75
+
76
+ it "renders RawStrings for open and close" do
77
+ promise = Promise.new(@output, "foo")
78
+ promise._render
79
+ @buffer.each{|s| s.should be_a(RawString)}
80
+ end
81
+
82
+ it "fills its target with attributes" do
83
+ promise = Promise.new(@output, "foo", :bar => "baz")
84
+ promise._render
85
+ @output.to_s.should == "<foo bar=\"baz\"></foo>"
86
+ end
87
+
88
+ it "replaces its target after a dot call" do
89
+ promise = Promise.new(@output, "foo")
90
+ promise._render
91
+ promise.logo
92
+ promise._render
93
+ @output.to_s.should == "<foo class=\"logo\"></foo>"
94
+ end
95
+
96
+ it "replaces its target after two dot calls" do
97
+ promise = Promise.new(@output, "foo")
98
+ promise.logo.header
99
+ @output.to_s.should == "<foo class=\"logo header\"></foo>"
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ describe Erector::HTML do
106
+ include Erector::Mixin
107
+
108
+ describe "#element" do
109
+ it "returns a promise" do
110
+ erector {
111
+ div.should be_a(Erector::Promise)
112
+ }.should == "<div></div>"
113
+ end
114
+
115
+ it "re-renders the open tag when the promise changes" do
116
+ erector {
117
+ div.header
118
+ }.should == "<div class=\"header\"></div>"
119
+ end
120
+
121
+ it "re-renders the open tag when passed a hash" do
122
+ erector {
123
+ div.header :style => 'font-size: 10px'
124
+ }.should == "<div class=\"header\" style=\"font-size: 10px\"></div>"
125
+ end
126
+
127
+ it "re-renders the inside tag when passed a string" do
128
+ erector {
129
+ div.header "welcome"
130
+ }.should == "<div class=\"header\">welcome</div>"
131
+ end
132
+
133
+ it "re-renders the open and inside when passed a string and a hash" do
134
+ erector {
135
+ div.header "welcome", :style => 'font-size: 10px'
136
+ }.should == "<div class=\"header\" style=\"font-size: 10px\">welcome</div>"
137
+ end
138
+
139
+ it "re-renders the inside tag when passed a block" do
140
+ erector {
141
+ div.header do
142
+ p "welcome"
143
+ end
144
+ }.should == "<div class=\"header\"><p>welcome</p></div>"
145
+ end
146
+
147
+ it "totally works" do
148
+ erector {
149
+ div.header.zomg!.zoom "hi"
150
+ div.main :style => 'font-size: 12pt' do
151
+ p "hello"
152
+ end
153
+ div.footer! do
154
+ img.logo! :src=>"logo.gif"
155
+ text "OmniCorp"
156
+ end
157
+ }.should == "<div class=\"header zoom\" id=\"zomg\">hi</div>" +
158
+ "<div class=\"main\" style=\"font-size: 12pt\"><p>hello</p></div>" +
159
+ "<div id=\"footer\">" +
160
+ "<img id=\"logo\" src=\"logo.gif\" />" +
161
+ "OmniCorp" +
162
+ "</div>"
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
169
+
170
+
171
+ # newlines and indentation
172
+
173
+ # self-closing tags