pivotal-erector 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/README.txt +5 -5
  2. data/VERSION.yml +2 -2
  3. data/bin/{erect → erector} +0 -0
  4. data/lib/erector/erect.rb +1 -1
  5. data/lib/erector/erected.rb +1 -1
  6. data/lib/erector/rails/extensions/action_controller.rb +25 -7
  7. data/lib/erector/rails/extensions/{widget.rb → rails_widget/helpers.rb} +2 -9
  8. data/lib/erector/rails/extensions/{widget/2.2.0/widget.rb → rails_widget.rb} +4 -2
  9. data/lib/erector/rails/rails_version.rb +6 -0
  10. data/lib/erector/rails/template_handlers/action_view_template_handler.rb +43 -11
  11. data/lib/erector/rails.rb +2 -1
  12. data/lib/erector/version.rb +1 -1
  13. data/lib/erector/widget.rb +213 -73
  14. data/lib/erector/widgets/table.rb +3 -3
  15. data/spec/erector/indentation_spec.rb +39 -24
  16. data/spec/erector/widget_spec.rb +197 -64
  17. data/spec/erector/widgets/table_spec.rb +3 -3
  18. data/spec/spec.opts +1 -0
  19. data/spec/spec_helper.rb +1 -4
  20. data/spec/spec_suite.rb +6 -12
  21. metadata +18 -30
  22. data/lib/erector/rails/extensions/action_controller/1.2.5/action_controller.rb +0 -17
  23. data/lib/erector/rails/extensions/action_controller/2.2.0/action_controller.rb +0 -26
  24. data/lib/erector/rails/extensions/widget/1.2.5/widget.rb +0 -18
  25. data/lib/erector/rails/supported_rails_versions.rb +0 -14
  26. data/lib/erector/rails/template_handlers/1.2.5/action_view_template_handler.rb +0 -32
  27. data/lib/erector/rails/template_handlers/2.0.0/action_view_template_handler.rb +0 -36
  28. data/lib/erector/rails/template_handlers/2.1.0/action_view_template_handler.rb +0 -31
  29. data/lib/erector/rails/template_handlers/2.2.0/action_view_template_handler.rb +0 -46
  30. data/spec/erect/erect_spec.rb +0 -145
  31. data/spec/erect/erected_spec.rb +0 -80
  32. data/spec/erect/rhtml_parser_spec.rb +0 -318
@@ -13,7 +13,7 @@ module Erector
13
13
  # row_classes :even, :odd
14
14
  # end
15
15
  #
16
- # render_widget UsersTable, :row_objects => [user_1, user_2, user_3]
16
+ # widget UsersTable, :row_objects => [user_1, user_2, user_3]
17
17
  class Table < Erector::Widget
18
18
  ColumnDefinition = Struct.new(:id, :name, :cell_proc)
19
19
  class << self
@@ -42,8 +42,8 @@ module Erector
42
42
  attr_reader :row_class_list
43
43
  end
44
44
 
45
- # The standard erector render method.
46
- def render
45
+ # The standard erector content method.
46
+ def content
47
47
  table do
48
48
  thead do
49
49
  tr do
@@ -4,8 +4,9 @@ describe "indentation" do
4
4
 
5
5
  it "can detect newliney tags" do
6
6
  widget = ::Erector::Widget.new
7
- string = widget.output
8
- widget.enable_prettyprint = true
7
+ widget.instance_eval do
8
+ @prettyprint = true
9
+ end
9
10
  widget.newliney("i").should == false
10
11
  widget.newliney("table").should == true
11
12
  end
@@ -14,21 +15,21 @@ describe "indentation" do
14
15
  Erector::Widget.new() do
15
16
  text "Hello, "
16
17
  b "World"
17
- end.enable_prettyprint(true).to_s.should == "Hello, <b>World</b>"
18
+ end.to_pretty.should == "Hello, <b>World</b>"
18
19
  end
19
20
 
20
21
  it "should add newlines before open newliney tags" do
21
22
  Erector::Widget.new() do
22
23
  p "foo"
23
24
  p "bar"
24
- end.enable_prettyprint(true).to_s.should == "<p>foo</p>\n<p>bar</p>\n"
25
+ end.to_pretty.should == "<p>foo</p>\n<p>bar</p>\n"
25
26
  end
26
27
 
27
28
  it "should add newlines between text and open newliney tag" do
28
29
  Erector::Widget.new() do
29
30
  text "One"
30
31
  p "Two"
31
- end.enable_prettyprint(true).to_s.should == "One\n<p>Two</p>\n"
32
+ end.to_pretty.should == "One\n<p>Two</p>\n"
32
33
  end
33
34
 
34
35
  it "should add newlines after end newliney tags" do
@@ -36,7 +37,7 @@ describe "indentation" do
36
37
  tr do
37
38
  td "cell"
38
39
  end
39
- end.enable_prettyprint(true).to_s.should == "<tr>\n <td>cell</td>\n</tr>\n"
40
+ end.to_pretty.should == "<tr>\n <td>cell</td>\n</tr>\n"
40
41
  end
41
42
 
42
43
  it "should treat empty elements as start and end" do
@@ -44,7 +45,7 @@ describe "indentation" do
44
45
  p "before"
45
46
  br
46
47
  p "after"
47
- end.enable_prettyprint(true).to_s.should == "<p>before</p>\n<br />\n<p>after</p>\n"
48
+ end.to_pretty.should == "<p>before</p>\n<br />\n<p>after</p>\n"
48
49
  end
49
50
 
50
51
  it "empty elements sets at_start_of_line" do
@@ -52,7 +53,7 @@ describe "indentation" do
52
53
  text "before"
53
54
  br
54
55
  p "after"
55
- end.enable_prettyprint(true).to_s.should == "before\n<br />\n<p>after</p>\n"
56
+ end.to_pretty.should == "before\n<br />\n<p>after</p>\n"
56
57
  end
57
58
 
58
59
  it "will not insert extra space before/after input element" do
@@ -62,7 +63,7 @@ describe "indentation" do
62
63
  text 'Name'
63
64
  input :type => 'text'
64
65
  text 'after'
65
- end.enable_prettyprint(true).to_s.should == 'Name<input type="text" />after'
66
+ end.to_pretty.should == 'Name<input type="text" />after'
66
67
  end
67
68
 
68
69
  it "will indent" do
@@ -77,7 +78,7 @@ describe "indentation" do
77
78
  end
78
79
  end
79
80
  end
80
- end.enable_prettyprint(true).to_s.should == <<END
81
+ end.to_pretty.should == <<END
81
82
  <html>
82
83
  <head>
83
84
  <title>hi</title>
@@ -91,22 +92,43 @@ describe "indentation" do
91
92
  END
92
93
  end
93
94
 
95
+ it "preserves indentation for sub-rendered widgets" do
96
+ tea = Erector::Widget.new do
97
+ div do
98
+ p "oolong"
99
+ end
100
+ end
101
+ cup = Erector::Widget.new do
102
+ div do
103
+ p "fine china"
104
+ tea.write_via(self)
105
+ end
106
+ end
107
+
108
+ cup.to_pretty.should == <<END
109
+ <div>
110
+ <p>fine china</p>
111
+ <div>
112
+ <p>oolong</p>
113
+ </div>
114
+ </div>
115
+ END
116
+ end
117
+
94
118
  it "can turn off newlines" do
95
119
  Erector::Widget.new() do
96
120
  text "One"
97
121
  p "Two"
98
- end.enable_prettyprint(false).to_s.should == "One<p>Two</p>"
122
+ end.to_s.should == "One<p>Two</p>"
99
123
  end
100
124
 
101
- it "cannot turn newlines on and off, because the output is cached" do
125
+ it "can turn newlines on and off" do
102
126
  widget = Erector::Widget.new() do
103
127
  text "One"
104
128
  p "Two"
105
- end.enable_prettyprint(false)
106
- widget.to_s.should == "One<p>Two</p>"
107
- widget.enable_prettyprint(true)
129
+ end
108
130
  widget.to_s.should == "One<p>Two</p>"
109
- widget.enable_prettyprint(false)
131
+ widget.to_pretty.should == "One\n<p>Two</p>\n"
110
132
  widget.to_s.should == "One<p>Two</p>"
111
133
  end
112
134
 
@@ -114,14 +136,7 @@ END
114
136
  widget = Erector::Widget.new() do
115
137
  text "One"
116
138
  p "Two"
117
- end.enable_prettyprint(false).to_pretty.should == "One\n<p>Two</p>\n"
118
- end
119
-
120
- it "to_pretty will leave newlines on if they already were" do
121
- widget = Erector::Widget.new() do
122
- text "One"
123
- p "Two"
124
- end.enable_prettyprint(true).to_pretty.should == "One\n<p>Two</p>\n"
139
+ end.to_pretty.should == "One\n<p>Two</p>\n"
125
140
  end
126
141
 
127
142
  it "can turn newlines on/off via global variable" do
@@ -11,42 +11,42 @@ module WidgetSpec
11
11
 
12
12
  describe "#to_s" do
13
13
  class << self
14
- define_method("invokes #render and returns the string representation of the rendered widget") do
15
- it "invokes #render and returns the string representation of the rendered widget" do
14
+ define_method("invokes #content and returns the string representation of the rendered widget") do
15
+ it "invokes #content and returns the string representation of the rendered widget" do
16
16
  widget = Erector::Widget.new do
17
17
  div "Hello"
18
18
  end
19
- mock.proxy(widget).render
19
+ mock.proxy(widget).content
20
20
  widget.to_s.should == "<div>Hello</div>"
21
21
  end
22
22
  end
23
23
  end
24
24
 
25
25
  context "when passed no arguments" do
26
- send "invokes #render and returns the string representation of the rendered widget"
26
+ send "invokes #content and returns the string representation of the rendered widget"
27
27
  end
28
28
 
29
- context "when passed an argument that is #render" do
30
- send "invokes #render and returns the string representation of the rendered widget"
29
+ context "when passed an argument that is #content" do
30
+ send "invokes #content and returns the string representation of the rendered widget"
31
31
  end
32
32
 
33
- context "when passed an argument that is not #render" do
33
+ context "when passed an argument that is not #content" do
34
34
  attr_reader :widget
35
35
  before do
36
36
  @widget = Erector::Widget.new
37
- def widget.alternate_render
38
- div "Hello from Alternate Render"
37
+ def widget.alternate_content
38
+ div "Hello from Alternate Write"
39
39
  end
40
- mock.proxy(widget).alternate_render
40
+ mock.proxy(widget).alternate_content
41
41
  end
42
42
 
43
43
  it "invokes the passed in method name and returns the string representation of the rendered widget" do
44
- widget.to_s(:alternate_render).should == "<div>Hello from Alternate Render</div>"
44
+ widget.to_s(:content_method_name => :alternate_content).should == "<div>Hello from Alternate Write</div>"
45
45
  end
46
46
 
47
- it "does not invoke #render" do
48
- dont_allow(widget).render
49
- widget.to_s(:alternate_render)
47
+ it "does not invoke #content" do
48
+ dont_allow(widget).content
49
+ widget.to_s(:content_method_name => :alternate_content)
50
50
  end
51
51
  end
52
52
  end
@@ -60,18 +60,76 @@ module WidgetSpec
60
60
  end
61
61
  end
62
62
 
63
+ describe '#widget' do
64
+ context "basic nesting" do
65
+ before do
66
+ class Parent < Erector::Widget
67
+ def content
68
+ text 1
69
+ widget Child do
70
+ text 2
71
+ third
72
+ end
73
+ end
74
+
75
+ def third
76
+ text 3
77
+ end
78
+ end
79
+
80
+ class Child < Erector::Widget
81
+ def content
82
+ super
83
+ end
84
+ end
85
+ end
86
+
87
+ it "renders nested widgets in the correct order" do
88
+ Parent.new.to_s.should == '123'
89
+ end
90
+ end
91
+
92
+ end
93
+
63
94
  describe "#widget" do
95
+ class Orphan < Erector::Widget
96
+ def content
97
+ p @name
98
+ end
99
+ end
100
+
101
+ context "when passed a class" do
102
+ it "renders it" do
103
+ Erector::Widget.new do
104
+ div do
105
+ widget Orphan, :name => "Annie"
106
+ end
107
+ end.to_s.should == "<div><p>Annie</p></div>"
108
+ end
109
+ end
110
+
111
+ context "when passed an instance" do
112
+ it "renders it" do
113
+ Erector::Widget.new do
114
+ div do
115
+ widget Orphan.new(:name => "Oliver")
116
+ end
117
+ end.to_s.should == "<div><p>Oliver</p></div>"
118
+ end
119
+ end
120
+
64
121
  context "when nested" do
65
122
  it "renders the tag around the rest of the block" do
66
123
  parent_widget = Class.new(Erector::Widget) do
67
- def render
124
+ def content
68
125
  div :id => "parent_widget" do
69
126
  super
70
127
  end
71
128
  end
72
129
  end
130
+
73
131
  child_widget = Class.new(Erector::Widget) do
74
- def render
132
+ def content
75
133
  div :id => "child_widget" do
76
134
  super
77
135
  end
@@ -79,7 +137,8 @@ module WidgetSpec
79
137
  end
80
138
 
81
139
  widget = Class.new(Erector::Widget) do
82
- def render
140
+ needs :parent_widget, :child_widget
141
+ def content
83
142
  widget(parent_widget) do
84
143
  widget(child_widget) do
85
144
  super
@@ -88,7 +147,7 @@ module WidgetSpec
88
147
  end
89
148
  end
90
149
 
91
- widget.new(nil, :parent_widget => parent_widget, :child_widget => child_widget) do
150
+ widget.new(:parent_widget => parent_widget, :child_widget => child_widget) do
92
151
  div :id => "widget"
93
152
  end.to_s.should == '<div id="parent_widget"><div id="child_widget"><div id="widget"></div></div></div>'
94
153
  end
@@ -583,65 +642,23 @@ module WidgetSpec
583
642
  end
584
643
  end
585
644
 
586
- describe '#widget' do
587
- before do
588
- class Parent < Erector::Widget
589
- def render
590
- text 1
591
- widget Child do
592
- text 2
593
- third
594
- end
595
- end
596
-
597
- def third
598
- text 3
599
- end
600
- end
601
-
602
- class Child < Erector::Widget
603
- def render
604
- super
605
- end
606
- end
607
- end
608
-
609
- it "renders nested widgets in the correct order" do
610
- Parent.new.to_s.should == '123'
611
- end
612
- end
613
-
614
- describe '#render_to' do
645
+ describe '#write_via' do
615
646
  class A < Erector::Widget
616
- def render
647
+ def content
617
648
  p "A"
618
649
  end
619
650
  end
620
651
 
621
- it "renders to a doc" do
622
- class B < Erector::Widget
623
- def render
624
- text "B"
625
- A.new.render_to(@output)
626
- text "B"
627
- end
628
- end
629
- b = B.new
630
- b.to_s.should == "B<p>A</p>B"
631
- b.output.size.should == 10 # B, <p>, A, </p>, B
632
- end
633
-
634
652
  it "renders to a widget's doc" do
635
653
  class B < Erector::Widget
636
- def render
654
+ def content
637
655
  text "B"
638
- A.new.render_to(self)
656
+ A.new.write_via(self)
639
657
  text "B"
640
658
  end
641
659
  end
642
660
  b = B.new
643
661
  b.to_s.should == "B<p>A</p>B"
644
- b.output.size.should == 10 # B, <p>, A, </p>, B
645
662
  end
646
663
 
647
664
  it "passing a widget to text method renders it" do
@@ -653,5 +670,121 @@ module WidgetSpec
653
670
  end
654
671
 
655
672
  end
673
+
674
+ describe "when declaring parameters with the 'needs' macro" do
675
+ it "doesn't complain if there aren't any needs declared" do
676
+ class Thing1 < Erector::Widget
677
+ end
678
+ Thing1.new
679
+ end
680
+
681
+ it "allows you to say that you don't want any parameters" do
682
+ class Thing2 < Erector::Widget
683
+ needs nil
684
+ end
685
+ lambda { Thing2.new }.should_not raise_error
686
+ lambda { Thing2.new(:foo => 1) }.should raise_error
687
+ end
688
+
689
+ it "doesn't complain if you pass it a declared parameter" do
690
+ class Thing2b < Erector::Widget
691
+ needs :foo
692
+ end
693
+ lambda { Thing2b.new(:foo => 1) }.should_not raise_error
694
+ end
695
+
696
+ it "complains if you pass it an undeclared parameter" do
697
+ class Thing3 < Erector::Widget
698
+ needs :foo
699
+ end
700
+ lambda { Thing3.new(:bar => 1) }.should raise_error
701
+ end
702
+
703
+ it "allows multiple declared parameters" do
704
+ class Thing4 < Erector::Widget
705
+ needs :foo, :bar
706
+ end
707
+ lambda { Thing4.new(:foo => 1, :bar => 2) }.should_not raise_error
708
+ end
709
+
710
+ it "complains when passing in an extra parameter after declaring many parameters" do
711
+ class Thing5 < Erector::Widget
712
+ needs :foo, :bar
713
+ end
714
+ lambda { Thing5.new(:foo => 1, :bar => 2, :baz => 3) }.should raise_error
715
+ end
716
+
717
+ it "complains when you forget to pass in a needed parameter" do
718
+ class Thing6 < Erector::Widget
719
+ needs :foo, :bar
720
+ end
721
+ lambda { Thing6.new(:foo => 1) }.should raise_error
722
+ end
723
+
724
+ it "doesn't complain if you omit a parameter with a default value" do
725
+ class Thing7 < Erector::Widget
726
+ needs :foo
727
+ needs :bar => 7
728
+ needs :baz => 8
729
+ end
730
+ lambda {
731
+ thing = Thing7.new(:foo => 1, :baz => 3)
732
+ thing.bar.should equal(7)
733
+ thing.baz.should equal(3)
734
+ }.should_not raise_error
735
+ end
736
+
737
+ it "allows multiple values on a line, including default values at the end of the line" do
738
+ class Thing8 < Erector::Widget
739
+ needs :foo, :bar => 7, :baz => 8
740
+ end
741
+ lambda {
742
+ thing = Thing8.new(:foo => 1, :baz => 2)
743
+ thing.foo.should equal(1)
744
+ thing.bar.should equal(7)
745
+ thing.baz.should equal(2)
746
+ }.should_not raise_error
747
+ end
748
+
749
+ it "allows nil to be a default value" do
750
+ class Thing9 < Erector::Widget
751
+ needs :foo => nil
752
+ end
753
+ lambda {
754
+ thing = Thing9.new
755
+ thing.foo.should be_nil
756
+ }.should_not raise_error
757
+ end
758
+
759
+ it "accumulates needs across the inheritance chain" do
760
+ class Vehicle < Erector::Widget
761
+ needs :wheels
762
+ end
763
+
764
+ class Car < Vehicle
765
+ needs :engine
766
+ end
767
+
768
+ lambda { Car.new(:engine => 'V-8', :wheels => 4) }.should_not raise_error
769
+ lambda { Car.new(:engine => 'V-8') }.should raise_error
770
+ lambda { Car.new(:wheels => 4) }.should raise_error
771
+ end
772
+
773
+ it "defines accessors for each of the needed variables" do
774
+ class NeedfulThing < Erector::Widget
775
+ needs :love
776
+ end
777
+ thing = NeedfulThing.new(:love => "all we need")
778
+ thing.love.should == "all we need"
779
+ end
780
+
781
+ it "doesnt define accessors for non-needed variables" do
782
+ class NeedlessThing < Erector::Widget
783
+ end
784
+ thing = NeedlessThing.new(:love => "all we need")
785
+ lambda {thing.love}.should raise_error
786
+ end
787
+
788
+ end
656
789
  end
657
790
  end
@@ -23,7 +23,7 @@ module TableSpec
23
23
  describe "with custom heading" do
24
24
  attr_reader :html, :doc
25
25
  before do
26
- widget = CustomHeadingTable.new(nil, :row_objects => [])
26
+ widget = CustomHeadingTable.new(:row_objects => [])
27
27
  @html = widget.to_s
28
28
  @doc = Hpricot(html)
29
29
  end
@@ -45,7 +45,7 @@ module TableSpec
45
45
  attr_reader :html, :doc
46
46
  before do
47
47
  @object1 = Struct.new(:first_name).new("Hello")
48
- widget = CustomCellTable.new(nil, :row_objects => [@object1])
48
+ widget = CustomCellTable.new(:row_objects => [@object1])
49
49
  @html = widget.to_s
50
50
  @doc = Hpricot(html)
51
51
  end
@@ -63,7 +63,7 @@ module TableSpec
63
63
  @object1 = Struct.new(:first_name, :last_name, :email).new(1, 2, 3)
64
64
  @object2 = Struct.new(:first_name, :last_name, :email).new(4, 5, 6)
65
65
  @object3 = Struct.new(:first_name, :last_name, :email).new(7, 8, 9)
66
- widget = DefaultsTestTable.new(nil, :row_objects => [@object1, @object2, @object3])
66
+ widget = DefaultsTestTable.new(:row_objects => [@object1, @object2, @object3])
67
67
  @html = widget.to_s
68
68
  @doc = Hpricot(html)
69
69
  @table = doc.at("table")
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --backtrace
data/spec/spec_helper.rb CHANGED
@@ -2,14 +2,11 @@ dir = File.dirname(__FILE__)
2
2
  require "rubygems"
3
3
  $LOAD_PATH.unshift("#{dir}/../lib")
4
4
  require "erector"
5
- require "erector/rails"
6
5
  require "hpricot"
7
6
  require "rr"
8
7
  require 'tempfile'
9
8
  require 'ostruct'
10
- require 'treetop'
11
- require "erector/erect"
12
- require "erector/erected"
9
+ ARGV.push(*File.read("#{File.dirname(__FILE__)}/spec.opts").split("\n"))
13
10
  require "spec"
14
11
  require "spec/autorun"
15
12
 
data/spec/spec_suite.rb CHANGED
@@ -3,13 +3,12 @@ class SpecSuite
3
3
  def all
4
4
  system("ruby #{dir}/core_spec_suite.rb") || raise("Core Spec Suite failed")
5
5
  dir = File.dirname(__FILE__)
6
- require "#{dir}/../lib/erector/rails/supported_rails_versions"
7
- versions = Erector::Rails::SUPPORTED_RAILS_VERSIONS.keys.sort.reverse
8
- versions.each do |rails_version|
9
- puts "Running rails_spec_suite for Rails version #{rails_version}"
10
- run_with_rails_version("#{dir}/rails_spec_suite.rb", rails_version) ||
11
- "Suite failed for Rails version #{rails_version}"
12
- end
6
+ require "#{dir}/../lib/erector/rails/rails_version"
7
+
8
+ rails_version = Erector::Rails::RAILS_VERSION
9
+ puts "Running rails_spec_suite for Rails version #{rails_version}"
10
+
11
+ system("ruby #{dir}/rails_spec_suite.rb") || raise("Failed for version #{rails_version}")
13
12
  end
14
13
 
15
14
  def core
@@ -29,11 +28,6 @@ class SpecSuite
29
28
  end
30
29
 
31
30
  protected
32
- def run_with_rails_version(suite_path, rails_version)
33
- system("export RAILS_VERSION=#{rails_version} && ruby #{suite_path}") ||
34
- raise("Failed for version #{rails_version}")
35
- end
36
-
37
31
  def dir
38
32
  File.dirname(__FILE__)
39
33
  end