erector 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,8 +7,8 @@ describe "indentation" do
7
7
  widget.instance_eval do
8
8
  @prettyprint = true
9
9
  end
10
- widget.newliney("i").should == false
11
- widget.newliney("table").should == true
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
@@ -1,51 +1,83 @@
1
1
  require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
- require 'benchmark'
3
-
4
- describe "passing in a block" do
5
- describe Erector::Widget do
6
- it "'s block is evaluated in the calling object's context" do
7
-
8
- @sample_instance_variable = "yum"
9
- sample_bound_variable = "yay"
10
- Erector::Widget.new do
11
- @sample_instance_variable.should == "yum"
12
- sample_bound_variable.should == "yay"
13
- lambda {text "you can't call Erector methods from in here"}.should raise_error(NoMethodError)
14
- # puts "uncomment this to prove this is being executed"
15
- end.to_s
16
-
17
- end
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
- describe Erector::Inline do
21
- it "'s block is evaluated in the widget's context" do
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 Erector::Mixin do
36
- include Erector::Mixin
37
- it "'s block is evaluated in the parent widget's context" do
38
-
39
- @sample_instance_variable = "yum"
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
@@ -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 MixinSpec::Thing
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 MixinSpec::Thing
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
@@ -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 an HTML comment" do
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 "&nbsp;"
454
- end.to_s.should == "<!--&nbsp;-->"
513
+ end.to_s.should == "<!--&nbsp;-->\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
- end
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 &lt; y &amp;&amp; x &gt; z) alert(&quot;don't stop&quot;);"
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