pivotal-erector 0.5.1 → 0.6.0

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 (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