erector 0.8.3 → 0.9.0.pre1

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.
Files changed (115) hide show
  1. data/Gemfile +21 -0
  2. data/Rakefile +171 -0
  3. data/VERSION.yml +3 -2
  4. data/lib/erector.rb +3 -5
  5. data/lib/erector/abstract_widget.rb +76 -31
  6. data/lib/erector/attributes.rb +34 -0
  7. data/lib/erector/caching.rb +1 -0
  8. data/lib/erector/convenience.rb +12 -4
  9. data/lib/erector/dependency.rb +2 -1
  10. data/lib/erector/element.rb +113 -0
  11. data/lib/erector/erect/erect.rb +10 -7
  12. data/lib/erector/externals.rb +2 -1
  13. data/lib/erector/html.rb +6 -340
  14. data/lib/erector/html_widget.rb +300 -0
  15. data/lib/erector/inline.rb +1 -1
  16. data/lib/erector/output.rb +39 -12
  17. data/lib/erector/promise.rb +137 -0
  18. data/lib/erector/rails2/extensions/rails_widget.rb +1 -1
  19. data/lib/erector/rails3.rb +1 -1
  20. data/lib/erector/sass.rb +14 -19
  21. data/lib/erector/tag.rb +65 -0
  22. data/lib/erector/text.rb +123 -0
  23. data/lib/erector/version.rb +1 -1
  24. data/lib/erector/widget.rb +52 -12
  25. data/lib/erector/widgets/page.rb +12 -10
  26. data/lib/erector/xml_widget.rb +131 -0
  27. data/spec/erector/caching_spec.rb +1 -0
  28. data/spec/erector/externals_spec.rb +0 -1
  29. data/spec/erector/html_spec.rb +9 -25
  30. data/spec/erector/output_spec.rb +102 -9
  31. data/spec/erector/promise_spec.rb +173 -0
  32. data/spec/erector/sass_spec.rb +1 -1
  33. data/spec/erector/tag_spec.rb +67 -0
  34. data/spec/erector/widget_spec.rb +53 -2
  35. data/spec/erector/xml_widget_spec.rb +74 -0
  36. data/spec/rails2/rails_app/Gemfile +1 -0
  37. data/spec/rails2/rails_app/spec/rails_spec_helper.rb +2 -0
  38. data/spec/rails_root/Gemfile +11 -0
  39. data/spec/rails_root/README +256 -0
  40. data/spec/rails_root/Rakefile +7 -0
  41. data/spec/rails_root/app/controllers/application.rb +6 -0
  42. data/spec/rails_root/app/controllers/application_controller.rb +3 -0
  43. data/spec/rails_root/app/helpers/application_helper.rb +2 -0
  44. data/spec/rails_root/app/views/layouts/application.html.erb +14 -0
  45. data/spec/rails_root/app/views/test/_erb.erb +1 -0
  46. data/spec/rails_root/app/views/test/_erector.rb +5 -0
  47. data/spec/rails_root/app/views/test/_partial_with_locals.rb +7 -0
  48. data/spec/rails_root/app/views/test/bare.rb +5 -0
  49. data/spec/rails_root/app/views/test/erb_from_erector.html.rb +5 -0
  50. data/spec/rails_root/app/views/test/erector_from_erb.html.erb +1 -0
  51. data/spec/rails_root/app/views/test/erector_with_locals_from_erb.html.erb +6 -0
  52. data/spec/rails_root/app/views/test/implicit_assigns.html.rb +5 -0
  53. data/spec/rails_root/app/views/test/needs.html.rb +7 -0
  54. data/spec/rails_root/app/views/test/needs_subclass.html.rb +5 -0
  55. data/spec/rails_root/app/views/test/protected_instance_variable.html.rb +5 -0
  56. data/spec/rails_root/app/views/test/render_default.html.rb +5 -0
  57. data/spec/rails_root/app/views/test/render_partial.html.rb +5 -0
  58. data/spec/rails_root/config.ru +4 -0
  59. data/spec/rails_root/config/application.rb +42 -0
  60. data/spec/rails_root/config/boot.rb +13 -0
  61. data/spec/rails_root/config/database.yml +22 -0
  62. data/spec/rails_root/config/environment.rb +5 -0
  63. data/spec/rails_root/config/environments/development.rb +22 -0
  64. data/spec/rails_root/config/environments/production.rb +49 -0
  65. data/spec/rails_root/config/environments/test.rb +35 -0
  66. data/spec/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  67. data/spec/rails_root/config/initializers/inflections.rb +10 -0
  68. data/spec/rails_root/config/initializers/mime_types.rb +5 -0
  69. data/spec/rails_root/config/initializers/secret_token.rb +7 -0
  70. data/spec/rails_root/config/initializers/session_store.rb +8 -0
  71. data/spec/rails_root/config/locales/en.yml +5 -0
  72. data/spec/rails_root/config/routes.rb +58 -0
  73. data/spec/rails_root/db/seeds.rb +7 -0
  74. data/spec/rails_root/doc/README_FOR_APP +2 -0
  75. data/spec/rails_root/log/development.log +17 -0
  76. data/spec/rails_root/log/test.log +3750 -0
  77. data/spec/rails_root/public/404.html +26 -0
  78. data/spec/rails_root/public/422.html +26 -0
  79. data/spec/rails_root/public/500.html +26 -0
  80. data/spec/rails_root/public/dispatch.cgi +10 -0
  81. data/spec/rails_root/public/dispatch.fcgi +24 -0
  82. data/spec/rails_root/public/dispatch.rb +10 -0
  83. data/spec/rails_root/public/favicon.ico +0 -0
  84. data/spec/rails_root/public/images/rails.png +0 -0
  85. data/spec/rails_root/public/index.html +262 -0
  86. data/spec/rails_root/public/javascripts/application.js +2 -0
  87. data/spec/rails_root/public/javascripts/controls.js +965 -0
  88. data/spec/rails_root/public/javascripts/dragdrop.js +974 -0
  89. data/spec/rails_root/public/javascripts/effects.js +1123 -0
  90. data/spec/rails_root/public/javascripts/prototype.js +6001 -0
  91. data/spec/rails_root/public/javascripts/rails.js +175 -0
  92. data/spec/rails_root/public/robots.txt +5 -0
  93. data/spec/rails_root/script/about +3 -0
  94. data/spec/rails_root/script/console +3 -0
  95. data/spec/rails_root/script/destroy +3 -0
  96. data/spec/rails_root/script/generate +3 -0
  97. data/spec/rails_root/script/performance/benchmarker +3 -0
  98. data/spec/rails_root/script/performance/profiler +3 -0
  99. data/spec/rails_root/script/performance/request +3 -0
  100. data/spec/rails_root/script/plugin +3 -0
  101. data/spec/rails_root/script/process/inspector +3 -0
  102. data/spec/rails_root/script/process/reaper +3 -0
  103. data/spec/rails_root/script/process/spawner +3 -0
  104. data/spec/rails_root/script/rails +6 -0
  105. data/spec/rails_root/script/runner +3 -0
  106. data/spec/rails_root/script/server +3 -0
  107. data/spec/rails_root/spec/form_builder_spec.rb +21 -0
  108. data/spec/rails_root/spec/rails_helpers_spec.rb +220 -0
  109. data/spec/rails_root/spec/rails_spec_helper.rb +10 -0
  110. data/spec/rails_root/spec/rails_widget_spec.rb +83 -0
  111. data/spec/rails_root/spec/render_spec.rb +298 -0
  112. data/spec/rails_root/test/performance/browsing_test.rb +9 -0
  113. data/spec/rails_root/test/test_helper.rb +13 -0
  114. data/spec/spec_helper.rb +3 -1
  115. metadata +202 -66
@@ -1,5 +1,6 @@
1
1
  require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
2
 
3
+ # todo: figure out why "include Caching" only works when it's on Widget
3
4
  describe Erector::Cache do
4
5
  before do
5
6
  @cache = Erector::Cache.new
@@ -27,7 +27,6 @@ module ExternalsSpec
27
27
  Quesadilla.my_dependencies.should == []
28
28
  end
29
29
 
30
-
31
30
  describe '#interpret_args' do
32
31
 
33
32
  class Test
@@ -3,13 +3,6 @@ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
3
3
  describe Erector::HTML do
4
4
  include Erector::Mixin
5
5
 
6
- describe ".all_tags" do
7
- it "returns set of full and empty tags" do
8
- Erector::Widget.all_tags.class.should == Array
9
- Erector::Widget.all_tags.should == Erector::Widget.full_tags + Erector::Widget.empty_tags
10
- end
11
- end
12
-
13
6
  describe "#instruct" do
14
7
  it "when passed no arguments; returns an XML declaration with version 1 and utf-8" do
15
8
  # version must precede encoding, per XML 1.0 4th edition (section 2.8)
@@ -148,7 +141,7 @@ describe Erector::HTML do
148
141
  end
149
142
 
150
143
  it "renders the proper full tags" do
151
- Erector::Widget.full_tags.each do |tag_name|
144
+ Erector::HTMLWidget.full_tags.each do |tag_name|
152
145
  expected = "<#{tag_name}></#{tag_name}>"
153
146
  actual = erector { send(tag_name) }
154
147
  begin
@@ -252,7 +245,7 @@ describe Erector::HTML do
252
245
  end
253
246
 
254
247
  it "renders the proper empty-element tags" do
255
- Erector::Widget.empty_tags.each do |tag_name|
248
+ Erector::HTMLWidget.self_closing_tags.each do |tag_name|
256
249
  expected = "<#{tag_name} />"
257
250
  actual = erector { send(tag_name) }
258
251
  begin
@@ -412,6 +405,7 @@ describe Erector::HTML do
412
405
  erector { text h(plain) }.should == escaped
413
406
  end
414
407
  end
408
+
415
409
  describe "#rawtext" do
416
410
  it "doesn't HTML escape its param" do
417
411
  erector { rawtext plain }.should == plain
@@ -427,11 +421,6 @@ describe Erector::HTML do
427
421
  erector { element "foo", plain }.should == "<foo>#{escaped}</foo>"
428
422
  end
429
423
  end
430
- describe "#element!" do
431
- it "doesn't HTML escape its param" do
432
- erector { element! "foo", plain }.should == "<foo>#{plain}</foo>"
433
- end
434
- end
435
424
  end
436
425
 
437
426
  describe "#javascript" do
@@ -500,13 +489,6 @@ describe Erector::HTML do
500
489
  end
501
490
  end
502
491
 
503
- describe "#close_tag" do
504
- it "works when it's all alone, even though it messes with the indent level" do
505
- erector { close_tag :foo }.should == "</foo>"
506
- erector { close_tag :foo; close_tag :bar }.should == "</foo></bar>"
507
- end
508
- end
509
-
510
492
  describe "exception handling" do
511
493
  class RenderWithReturn < Erector::Widget
512
494
  def content
@@ -536,14 +518,16 @@ describe Erector::HTML do
536
518
  it "closes tags when throwing block versus text exception" do
537
519
  erector do
538
520
  begin
539
- span "a value" do
540
- text "a block"
521
+ div do
522
+ span "a value" do
523
+ text "a block"
524
+ end
541
525
  end
542
526
  rescue ArgumentError => e
543
527
  e.to_s.should include(
544
- "You can't pass both a block and a value")
528
+ "You can't pass both a block and a value to span")
545
529
  end
546
- end.should == "<span></span>"
530
+ end.should == "<div></div>"
547
531
  end
548
532
  end
549
533
 
@@ -1,5 +1,7 @@
1
1
  require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
2
 
3
+ require 'active_support'
4
+
3
5
  module Erector
4
6
  describe Erector::Output do
5
7
  before do
@@ -38,11 +40,17 @@ module Erector
38
40
  @output << "foo" << "bar"
39
41
  @output.to_a.join.should == "foobar"
40
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
41
49
  end
42
50
 
43
51
  it "can be initialized with an existing string buffer" do
44
52
  s = "foo"
45
- @output = Output.new { s }
53
+ @output = Output.new(:buffer => s)
46
54
  @output << "bar"
47
55
  s.should == "foobar"
48
56
  @output.to_s.should == "foobar"
@@ -184,16 +192,101 @@ module Erector
184
192
 
185
193
  end
186
194
 
187
- class Puppy < Erector::Widget
188
- end
189
- class Kitten < Erector::Widget
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_only([Puppy, Kitten])
207
+ end
208
+
190
209
  end
191
210
 
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])
211
+ describe "mark and rewind" do
212
+ it "with an array buffer" do
213
+ a = []
214
+ @output = Output.new(:buffer => a)
215
+ @output << "foo"
216
+ @output.mark
217
+
218
+ @output << "bar"
219
+ a.should == ["foo", "bar"]
220
+ @output.to_s.should == "foobar"
221
+
222
+ @output.rewind
223
+ @output.to_s.should == "foo"
224
+ a.should == ["foo"]
225
+
226
+ @output << "goo"
227
+ a.should == ["foo", "goo"]
228
+ @output.to_s.should == "foogoo"
229
+
230
+ @output.rewind
231
+ @output << "fa"
232
+ @output << "la"
233
+ a.should == ["foo", "fa", "la"]
234
+ @output.to_s.should == "foofala"
235
+ end
236
+
237
+ it "with a string buffer" do
238
+ s = ""
239
+ @output = Output.new(:buffer => s)
240
+ @output << "foo"
241
+ @output.mark
242
+
243
+ @output << "bar"
244
+ s.should == "foobar"
245
+
246
+ @output.rewind
247
+ s.should == "foo"
248
+
249
+ @output << "goo"
250
+ s.should == "foogoo"
251
+
252
+ @output.rewind
253
+ @output << "fa"
254
+ @output << "la"
255
+ s.should == "foofala"
256
+ end
257
+
258
+ it "with a SafeBuffer buffer" do
259
+ s = ActiveSupport::SafeBuffer.new
260
+ @output = Output.new(:buffer => s)
261
+ @output << "foo"
262
+ @output.mark
263
+
264
+ @output << "bar"
265
+ s.should == "foobar"
266
+
267
+ @output.rewind
268
+ s.should == "foo"
269
+
270
+ @output << "goo"
271
+ s.should == "foogoo"
272
+
273
+ @output.rewind
274
+ @output << "fa"
275
+ @output << "la"
276
+ s.should == "foofala"
277
+ end
278
+
279
+ it "returns and accepts a value" do
280
+ s = ""
281
+ @output = Output.new(:buffer => s)
282
+ @output << "a"
283
+ mark1 = @output.mark
284
+ @output << "b"
285
+ mark2 = @output.mark
286
+
287
+ @output.rewind(mark1)
288
+ s.should == "a"
289
+ end
197
290
  end
198
291
  end
199
292
  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
@@ -1,7 +1,7 @@
1
1
  require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
2
 
3
3
  if !Object.const_defined?(:Sass)
4
- puts "Skipping Sass spec... run 'gem install haml' to enable these tests."
4
+ puts "Skipping Sass spec... run 'gem install sass' to enable these tests."
5
5
  else
6
6
  module CacheSpec
7
7
  describe Erector::Sass do
@@ -0,0 +1,67 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+ require "erector/tag"
3
+
4
+ module Erector
5
+ describe Tag do
6
+ it "takes a name" do
7
+ t = Tag.new("foo")
8
+ t.name.should == "foo"
9
+ end
10
+
11
+ it "has default values for its options" do
12
+ t = Tag.new("foo")
13
+ t.self_closing?.should == false
14
+ t.inline?.should == false
15
+ end
16
+
17
+ it "can take any combination of options" do
18
+ t = Tag.new("foo", :self_closing)
19
+ t.self_closing?.should == true
20
+ t.inline?.should == false
21
+
22
+ t = Tag.new("foo", :inline)
23
+ t.self_closing?.should == false
24
+ t.inline?.should == true
25
+
26
+ t = Tag.new("foo", :self_closing, :inline)
27
+ t.self_closing?.should == true
28
+ t.inline?.should == true
29
+
30
+ t = Tag.new("foo", :inline, :self_closing)
31
+ t.self_closing?.should == true
32
+ t.inline?.should == true
33
+ end
34
+
35
+ it "can take a method name" do
36
+ t = Tag.new("foo", "bar")
37
+ t.name.should == "foo"
38
+ t.method_name.should == "bar"
39
+ t.self_closing?.should == false
40
+ t.inline?.should == false
41
+ end
42
+
43
+ it "can take a method name and options" do
44
+ t = Tag.new("foo", "bar", :self_closing, :inline)
45
+ t.name.should == "foo"
46
+ t.method_name.should == "bar"
47
+ t.self_closing?.should == true
48
+ t.inline?.should == true
49
+ end
50
+
51
+ it "can underscorize its method name" do
52
+ t = Tag.new("InclusiveLowerBound", :snake_case)
53
+ t.name.should == "InclusiveLowerBound"
54
+ t.method_name.should == "inclusive_lower_bound"
55
+ end
56
+
57
+ it "is smart about acronyms" do
58
+ t = Tag.new("WatchCNNToday", :snake_case)
59
+ t.name.should == "WatchCNNToday"
60
+ t.method_name.should == "watch_cnn_today"
61
+ end
62
+
63
+
64
+ end
65
+ end
66
+
67
+