erector 0.7.1 → 0.7.2
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 +14 -0
- data/VERSION.yml +1 -1
- data/bin/erector +9 -4
- data/lib/erector.rb +11 -17
- data/lib/erector/erected.rb +1 -1
- data/lib/erector/externals.rb +19 -16
- data/lib/erector/inline.rb +12 -11
- data/lib/erector/mixin.rb +5 -2
- data/lib/erector/rails.rb +26 -9
- data/lib/erector/rails/extensions/action_controller.rb +2 -14
- data/lib/erector/rails/extensions/rails_widget.rb +65 -25
- data/lib/erector/rails/extensions/rails_widget/rails_helpers.rb +4 -3
- data/lib/erector/rails/template_handlers/ert_handler.rb +1 -1
- data/lib/erector/rails/template_handlers/rb_handler.rb +8 -43
- data/lib/erector/widget.rb +147 -70
- data/lib/erector/widgets.rb +5 -4
- data/lib/erector/widgets/form.rb +30 -0
- data/lib/erector/widgets/page.rb +74 -49
- data/rails/init.rb +4 -0
- data/spec/erect/erect_rails_spec.rb +63 -26
- data/spec/erect/erected_spec.rb +4 -4
- data/spec/erector/external_spec.rb +64 -6
- data/spec/erector/indentation_spec.rb +2 -2
- data/spec/erector/inline_spec.rb +74 -42
- data/spec/erector/mixin_spec.rb +16 -5
- data/spec/erector/widget_spec.rb +184 -7
- data/spec/erector/widgets/form_spec.rb +31 -0
- data/spec/erector/widgets/page_spec.rb +30 -20
- data/spec/spec_suite.rb +4 -3
- metadata +5 -3
- data/lib/erector/rails/extensions/action_view.rb +0 -21
@@ -7,8 +7,8 @@ describe "indentation" do
|
|
7
7
|
widget.instance_eval do
|
8
8
|
@prettyprint = true
|
9
9
|
end
|
10
|
-
widget.newliney
|
11
|
-
widget.newliney
|
10
|
+
widget.send(:newliney?, "i").should == false
|
11
|
+
widget.send(:newliney?, "table").should == true
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should not add newline for non-newliney tags" do
|
data/spec/erector/inline_spec.rb
CHANGED
@@ -1,51 +1,83 @@
|
|
1
1
|
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
2
|
+
|
3
|
+
describe Erector::Widget do
|
4
|
+
it "provides access to instance variables from the calling context" do
|
5
|
+
@var = "yay"
|
6
|
+
Erector::Widget.new { @var.should == "yay"; @var = "yum" }.to_s
|
7
|
+
@var.should == "yum"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "provides access to bound variables from the calling context" do
|
11
|
+
var = "yay"
|
12
|
+
Erector::Widget.new { var.should == "yay"; var = "yum" }.to_s
|
13
|
+
var.should == "yum"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "doesn't provide access to Erector methods" do
|
17
|
+
Erector::Widget.new { lambda { text "yay" }.should raise_error(NoMethodError) }.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Erector::Inline do
|
22
|
+
it "returns an InlineWidget" do
|
23
|
+
Erector.inline.should be_a_kind_of(Erector::InlineWidget)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "doesn't provide access to instance variables from the calling context" do
|
27
|
+
@var = "yay"
|
28
|
+
Erector.inline { text @var }.to_s.should == ""
|
29
|
+
end
|
30
|
+
|
31
|
+
it "provides access to bound variables from the calling context" do
|
32
|
+
var = "yay"
|
33
|
+
Erector.inline { text var }.to_s.should == "yay"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "provides access to explicit assigns" do
|
37
|
+
Erector.inline(:var => "yay") { text @var }.to_s.should == "yay"
|
18
38
|
end
|
19
39
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@sample_instance_variable = "yum"
|
24
|
-
sample_bound_variable = "yay"
|
25
|
-
Erector.inline do
|
26
|
-
@sample_instance_variable.should be_nil
|
27
|
-
sample_bound_variable.should == "yay"
|
28
|
-
text "you can call Erector methods from in here"
|
29
|
-
# puts "uncomment this to prove this is being executed"
|
30
|
-
end.to_s
|
31
|
-
|
40
|
+
it "provides access to methods from the calling context" do
|
41
|
+
def helper
|
42
|
+
"yay"
|
32
43
|
end
|
44
|
+
|
45
|
+
Erector.inline { text helper }.to_s.should == "yay"
|
33
46
|
end
|
34
|
-
|
35
|
-
describe
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
sample_bound_variable = "yay"
|
41
|
-
erector do
|
42
|
-
@sample_instance_variable.should be_nil
|
43
|
-
sample_bound_variable.should == "yay"
|
44
|
-
text "you can call Erector methods from in here"
|
45
|
-
# puts "uncomment this to prove this is being executed"
|
47
|
+
|
48
|
+
describe "#call_block" do
|
49
|
+
it "calls the block with a pointer to self" do
|
50
|
+
x = Erector::InlineWidget.new do |y|
|
51
|
+
element "arg", y.object_id
|
52
|
+
element "self", self.object_id
|
46
53
|
end
|
47
|
-
|
54
|
+
|
55
|
+
# inside the block...
|
56
|
+
x.to_s.should ==
|
57
|
+
"<arg>#{x.object_id}</arg>" + # the argument is the child
|
58
|
+
"<self>#{x.object_id}</self>" # and self is also the child
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Erector::Mixin do
|
64
|
+
include Erector::Mixin
|
65
|
+
|
66
|
+
it "doesn't provide access to instance variables from the calling context" do
|
67
|
+
@var = "yay"
|
68
|
+
erector { text @var }.should == ""
|
69
|
+
end
|
70
|
+
|
71
|
+
it "provides access to bound variables from the calling context" do
|
72
|
+
var = "yay"
|
73
|
+
erector { text var }.should == "yay"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "provides access to methods from the calling context" do
|
77
|
+
def helper
|
78
|
+
"yay"
|
48
79
|
end
|
80
|
+
|
81
|
+
erector { text helper }.should == "yay"
|
49
82
|
end
|
50
|
-
|
51
83
|
end
|
data/spec/erector/mixin_spec.rb
CHANGED
@@ -2,15 +2,13 @@ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
|
2
2
|
require 'benchmark'
|
3
3
|
|
4
4
|
module MixinSpec
|
5
|
-
class Thing
|
6
|
-
include Erector::Mixin
|
7
|
-
end
|
8
5
|
|
9
6
|
describe Erector::Mixin do
|
10
7
|
describe "#erector" do
|
11
8
|
it "renders its block to a string" do
|
12
9
|
|
13
|
-
class
|
10
|
+
class Thing
|
11
|
+
include Erector::Mixin
|
14
12
|
def name
|
15
13
|
erector do
|
16
14
|
span :class => "name" do
|
@@ -26,7 +24,8 @@ module MixinSpec
|
|
26
24
|
end
|
27
25
|
|
28
26
|
it "passes its parameters to to_s" do
|
29
|
-
class
|
27
|
+
class Thing
|
28
|
+
include Erector::Mixin
|
30
29
|
def pretty_name
|
31
30
|
erector(:prettyprint => true) do
|
32
31
|
div :class => "name" do
|
@@ -49,6 +48,18 @@ module MixinSpec
|
|
49
48
|
" </ul>\n" +
|
50
49
|
"</div>\n"
|
51
50
|
end
|
51
|
+
|
52
|
+
it "passes its parameters to the widget too" do
|
53
|
+
class Thing
|
54
|
+
include Erector::Mixin
|
55
|
+
def foo
|
56
|
+
erector(:foo => "bar") do
|
57
|
+
div @foo
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
Thing.new.foo.should == "<div>bar</div>"
|
62
|
+
end
|
52
63
|
end
|
53
64
|
end
|
54
65
|
end
|
data/spec/erector/widget_spec.rb
CHANGED
@@ -190,6 +190,40 @@ module WidgetSpec
|
|
190
190
|
end
|
191
191
|
|
192
192
|
end
|
193
|
+
|
194
|
+
it "passes a pointer to the child object back into the parent object's block" do
|
195
|
+
child_widget = Erector::Widget.new
|
196
|
+
|
197
|
+
class Parent < Erector::Widget
|
198
|
+
needs :child_widget
|
199
|
+
def content
|
200
|
+
div do
|
201
|
+
widget @child_widget do |child|
|
202
|
+
b child.dom_id
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
Parent.new(:child_widget => child_widget).to_s.should == "<div><b>#{child_widget.dom_id}</b></div>"
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "#call_block" do
|
216
|
+
it "calls the block with a pointer to self" do
|
217
|
+
inside_arg = nil
|
218
|
+
inside_self = nil
|
219
|
+
x = Erector::Widget.new do |y|
|
220
|
+
inside_arg = y.object_id
|
221
|
+
inside_self = self.object_id
|
222
|
+
end
|
223
|
+
x.call_block
|
224
|
+
# inside the block...
|
225
|
+
inside_arg.should == x.object_id # the argument is the child
|
226
|
+
inside_self.should == self.object_id # and self is the parent
|
193
227
|
end
|
194
228
|
end
|
195
229
|
|
@@ -244,6 +278,14 @@ module WidgetSpec
|
|
244
278
|
end
|
245
279
|
end
|
246
280
|
|
281
|
+
context "with an empty array of CSS classes" do
|
282
|
+
it "does not emit a class attribute" do
|
283
|
+
Erector.inline do
|
284
|
+
element('div', :class => [])
|
285
|
+
end.to_s.should == "<div></div>"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
247
289
|
context "with many attributes" do
|
248
290
|
it "alphabetize them" do
|
249
291
|
Erector.inline do
|
@@ -441,17 +483,34 @@ module WidgetSpec
|
|
441
483
|
end
|
442
484
|
|
443
485
|
describe "#comment" do
|
444
|
-
it "emits
|
486
|
+
it "emits a single line comment when receiving a string" do
|
445
487
|
Erector.inline do
|
446
488
|
comment "foo"
|
447
|
-
end.to_s.should == "<!--foo
|
489
|
+
end.to_s.should == "<!--foo-->\n"
|
448
490
|
end
|
449
|
-
|
491
|
+
|
492
|
+
it "emits a multiline comment when receiving a block" do
|
493
|
+
Erector.inline do
|
494
|
+
comment do
|
495
|
+
text "Hello"
|
496
|
+
text " world!"
|
497
|
+
end
|
498
|
+
end.to_s.should == "<!--\nHello world!\n-->\n"
|
499
|
+
end
|
500
|
+
|
501
|
+
it "emits a multiline comment when receiving a string and a block" do
|
502
|
+
Erector.inline do
|
503
|
+
comment "Hello" do
|
504
|
+
text " world!"
|
505
|
+
end
|
506
|
+
end.to_s.should == "<!--Hello\n world!\n-->\n"
|
507
|
+
end
|
508
|
+
|
450
509
|
# see http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.4
|
451
510
|
it "does not HTML-escape character references" do
|
452
511
|
Erector.inline do
|
453
512
|
comment " "
|
454
|
-
end.to_s.should == "<!-- 
|
513
|
+
end.to_s.should == "<!-- -->\n"
|
455
514
|
end
|
456
515
|
|
457
516
|
# see http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.4
|
@@ -460,10 +519,25 @@ module WidgetSpec
|
|
460
519
|
capturing_output do
|
461
520
|
Erector.inline do
|
462
521
|
comment "he was -- awesome!"
|
463
|
-
end.to_s.should == "<!--he was -- awesome
|
522
|
+
end.to_s.should == "<!--he was -- awesome!-->\n"
|
464
523
|
end.should == "Warning: Authors should avoid putting two or more adjacent hyphens inside comments.\n"
|
465
|
-
end
|
466
|
-
|
524
|
+
end
|
525
|
+
|
526
|
+
it "renders an IE conditional comment with endif when receiving an if IE" do
|
527
|
+
Erector.inline do
|
528
|
+
comment "[if IE]" do
|
529
|
+
text "Hello IE!"
|
530
|
+
end
|
531
|
+
end.to_s.should == "<!--[if IE]>\nHello IE!\n<![endif]-->\n"
|
532
|
+
end
|
533
|
+
|
534
|
+
it "doesn't render an IE conditional comment if there's just some text in brackets" do
|
535
|
+
Erector.inline do
|
536
|
+
comment "[puppies are cute]"
|
537
|
+
end.to_s.should == "<!--[puppies are cute]-->\n"
|
538
|
+
end
|
539
|
+
|
540
|
+
end
|
467
541
|
|
468
542
|
describe "#nbsp" do
|
469
543
|
it "turns consecutive spaces into consecutive non-breaking spaces" do
|
@@ -590,6 +664,37 @@ module WidgetSpec
|
|
590
664
|
end
|
591
665
|
end
|
592
666
|
|
667
|
+
describe 'escaping' do
|
668
|
+
plain = 'if (x < y && x > z) alert("don\'t stop");'
|
669
|
+
escaped = "if (x < y && x > z) alert("don't stop");"
|
670
|
+
|
671
|
+
describe "#text" do
|
672
|
+
it "does HTML escape its param" do
|
673
|
+
Erector.inline { text plain }.to_s.should == escaped
|
674
|
+
end
|
675
|
+
end
|
676
|
+
describe "#rawtext" do
|
677
|
+
it "doesn't HTML escape its param" do
|
678
|
+
Erector.inline { rawtext plain }.to_s.should == plain
|
679
|
+
end
|
680
|
+
end
|
681
|
+
describe "#text!" do
|
682
|
+
it "doesn't HTML escape its param" do
|
683
|
+
Erector.inline { text! plain }.to_s.should == plain
|
684
|
+
end
|
685
|
+
end
|
686
|
+
describe "#element" do
|
687
|
+
it "does HTML escape its param" do
|
688
|
+
Erector.inline { element "foo", plain }.to_s.should == "<foo>#{escaped}</foo>"
|
689
|
+
end
|
690
|
+
end
|
691
|
+
describe "#element!" do
|
692
|
+
it "doesn't HTML escape its param" do
|
693
|
+
Erector.inline { element! "foo", plain }.to_s.should == "<foo>#{plain}</foo>"
|
694
|
+
end
|
695
|
+
end
|
696
|
+
end
|
697
|
+
|
593
698
|
describe "#javascript" do
|
594
699
|
context "when receiving a block" do
|
595
700
|
it "renders the content inside of script text/javascript tags" do
|
@@ -662,6 +767,45 @@ module WidgetSpec
|
|
662
767
|
css "erector.css"
|
663
768
|
end.to_s.should == "<link href=\"erector.css\" rel=\"stylesheet\" type=\"text/css\" />"
|
664
769
|
end
|
770
|
+
|
771
|
+
it "accepts a media attribute" do
|
772
|
+
Erector.inline do
|
773
|
+
css "print.css", :media => "print"
|
774
|
+
end.to_s.should == "<link href=\"print.css\" media=\"print\" rel=\"stylesheet\" type=\"text/css\" />"
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
describe "#to_text" do
|
779
|
+
it "strips tags" do
|
780
|
+
Erector.inline do
|
781
|
+
div "foo"
|
782
|
+
end.to_text.should == "foo"
|
783
|
+
end
|
784
|
+
|
785
|
+
it "unescapes named entities" do
|
786
|
+
s = "my \"dog\" has fleas & <ticks>"
|
787
|
+
Erector.inline do
|
788
|
+
text s
|
789
|
+
end.to_text.should == s
|
790
|
+
end
|
791
|
+
|
792
|
+
it "ignores >s inside attribute strings" do
|
793
|
+
Erector.inline do
|
794
|
+
a "foo", :href => "http://example.com/x>y"
|
795
|
+
end.to_text.should == "foo"
|
796
|
+
end
|
797
|
+
|
798
|
+
it "doesn't inherit unwanted pretty-printed whitespace (i.e. it turns off prettyprinting)" do
|
799
|
+
old_default = Erector::Widget.new.prettyprint_default
|
800
|
+
begin
|
801
|
+
Erector::Widget.prettyprint_default = true
|
802
|
+
Erector.inline do
|
803
|
+
div { div { div "foo" } }
|
804
|
+
end.to_text.should == "foo"
|
805
|
+
ensure
|
806
|
+
Erector::Widget.prettyprint_default = old_default
|
807
|
+
end
|
808
|
+
end
|
665
809
|
end
|
666
810
|
|
667
811
|
describe "#url" do
|
@@ -670,6 +814,12 @@ module WidgetSpec
|
|
670
814
|
url "http://example.com"
|
671
815
|
end.to_s.should == "<a href=\"http://example.com\">http://example.com</a>"
|
672
816
|
end
|
817
|
+
|
818
|
+
it "accepts extra attributes" do
|
819
|
+
Erector.inline do
|
820
|
+
url "http://example.com", :onclick=>"alert('foo')"
|
821
|
+
end.to_s.should == "<a href=\"http://example.com\" onclick=\"alert('foo')\">http://example.com</a>"
|
822
|
+
end
|
673
823
|
end
|
674
824
|
|
675
825
|
describe '#capture' do
|
@@ -685,6 +835,14 @@ module WidgetSpec
|
|
685
835
|
widget.to_s.should == '<div><p>Captured Content</p></div>'
|
686
836
|
end
|
687
837
|
|
838
|
+
it "returns a RawString" do
|
839
|
+
captured = nil
|
840
|
+
Erector.inline do
|
841
|
+
captured = capture {}
|
842
|
+
end.to_s.should == ""
|
843
|
+
captured.should be_a_kind_of Erector::RawString
|
844
|
+
end
|
845
|
+
|
688
846
|
it "works with nested captures" do
|
689
847
|
widget = Erector.inline do
|
690
848
|
captured = capture do
|
@@ -888,5 +1046,24 @@ module WidgetSpec
|
|
888
1046
|
Erector.inline { close_tag :foo; close_tag :bar }.to_s.should == "</foo></bar>"
|
889
1047
|
end
|
890
1048
|
end
|
1049
|
+
|
1050
|
+
describe "#dom_id" do
|
1051
|
+
class NiceWidget < Erector::Widget
|
1052
|
+
def content
|
1053
|
+
div :id => dom_id
|
1054
|
+
end
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
it "makes a unique id based on the widget's class name and object id" do
|
1058
|
+
widget = NiceWidget.new
|
1059
|
+
widget.dom_id.should include("#{widget.object_id}")
|
1060
|
+
widget.dom_id.should include("NiceWidget")
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
it "can be used as an HTML id" do
|
1064
|
+
widget = NiceWidget.new
|
1065
|
+
widget.to_s.should == "<div id=\"#{widget.dom_id}\"></div>"
|
1066
|
+
end
|
1067
|
+
end
|
891
1068
|
end
|
892
1069
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
|
2
|
+
|
3
|
+
describe Form do
|
4
|
+
|
5
|
+
include Erector::Mixin
|
6
|
+
|
7
|
+
it "defaults to POST, with no magic hidden method param" do
|
8
|
+
Form.new(:action => "/foo").to_s.should == "<form action=\"/foo\" method=\"post\"></form>"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "works plainly with GET too" do
|
12
|
+
Form.new(:action => "/foo", :method => "get").to_s.should == "<form action=\"/foo\" method=\"get\"></form>"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "uses POST and adds a magic hidden field with a _method param for DELETE" do
|
16
|
+
Form.new(:action => "/foo", :method => "delete").to_s.should ==
|
17
|
+
"<form action=\"/foo\" method=\"post\">"+
|
18
|
+
"<input name=\"_method\" type=\"hidden\" value=\"delete\" />"+
|
19
|
+
"</form>"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "executes its block in the caller's 'self' context" do
|
23
|
+
erector {
|
24
|
+
@pet = "dog"
|
25
|
+
widget(Form.new(:action => "/foo") do
|
26
|
+
p @pet
|
27
|
+
end)
|
28
|
+
}.should == "<form action=\"/foo\" method=\"post\"><p>dog</p></form>"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|