inversion 0.12.3 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +305 -9
  5. data/Examples.rdoc +134 -0
  6. data/GettingStarted.rdoc +44 -0
  7. data/Guide.rdoc +47 -0
  8. data/History.rdoc +15 -0
  9. data/Manifest.txt +7 -2
  10. data/README.rdoc +9 -10
  11. data/Rakefile +23 -10
  12. data/Tags.rdoc +561 -0
  13. data/lib/inversion.rb +2 -2
  14. data/lib/inversion/renderstate.rb +46 -11
  15. data/lib/inversion/template.rb +85 -7
  16. data/lib/inversion/template/attrtag.rb +1 -1
  17. data/lib/inversion/template/begintag.rb +8 -8
  18. data/lib/inversion/template/fragmenttag.rb +60 -0
  19. data/lib/inversion/template/rescuetag.rb +1 -1
  20. data/spec/{lib/helpers.rb → helpers.rb} +7 -30
  21. data/spec/inversion/mixins_spec.rb +55 -65
  22. data/spec/inversion/monkeypatches_spec.rb +2 -12
  23. data/spec/inversion/parser_spec.rb +34 -44
  24. data/spec/inversion/renderstate_spec.rb +123 -69
  25. data/spec/inversion/sinatra_spec.rb +6 -19
  26. data/spec/inversion/template/attrtag_spec.rb +56 -76
  27. data/spec/inversion/template/begintag_spec.rb +24 -41
  28. data/spec/inversion/template/calltag_spec.rb +1 -18
  29. data/spec/inversion/template/codetag_spec.rb +6 -24
  30. data/spec/inversion/template/commenttag_spec.rb +9 -27
  31. data/spec/inversion/template/configtag_spec.rb +5 -16
  32. data/spec/inversion/template/containertag_spec.rb +4 -21
  33. data/spec/inversion/template/defaulttag_spec.rb +6 -23
  34. data/spec/inversion/template/elsetag_spec.rb +9 -26
  35. data/spec/inversion/template/elsiftag_spec.rb +7 -24
  36. data/spec/inversion/template/endtag_spec.rb +6 -23
  37. data/spec/inversion/template/escapetag_spec.rb +10 -25
  38. data/spec/inversion/template/fortag_spec.rb +20 -37
  39. data/spec/inversion/template/fragmenttag_spec.rb +40 -0
  40. data/spec/inversion/template/iftag_spec.rb +23 -40
  41. data/spec/inversion/template/importtag_spec.rb +8 -25
  42. data/spec/inversion/template/includetag_spec.rb +27 -42
  43. data/spec/inversion/template/node_spec.rb +6 -15
  44. data/spec/inversion/template/pptag_spec.rb +10 -23
  45. data/spec/inversion/template/publishtag_spec.rb +4 -21
  46. data/spec/inversion/template/rescuetag_spec.rb +12 -29
  47. data/spec/inversion/template/subscribetag_spec.rb +8 -25
  48. data/spec/inversion/template/tag_spec.rb +24 -37
  49. data/spec/inversion/template/textnode_spec.rb +8 -24
  50. data/spec/inversion/template/timedeltatag_spec.rb +31 -43
  51. data/spec/inversion/template/unlesstag_spec.rb +7 -24
  52. data/spec/inversion/template/uriencodetag_spec.rb +6 -23
  53. data/spec/inversion/template/yieldtag_spec.rb +3 -20
  54. data/spec/inversion/template_spec.rb +155 -108
  55. data/spec/inversion/tilt_spec.rb +7 -16
  56. data/spec/inversion_spec.rb +7 -22
  57. metadata +63 -40
  58. metadata.gz.sig +0 -0
  59. data/spec/lib/constants.rb +0 -9
@@ -1,31 +1,14 @@
1
1
  #!/usr/bin/env rspec -cfd -b
2
2
  # vim: set noet nosta sw=4 ts=4 :
3
3
 
4
- BEGIN {
5
- require 'pathname'
6
- basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
- libdir = basedir + 'lib'
4
+ require_relative '../../helpers'
8
5
 
9
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
- }
12
-
13
- require 'rspec'
14
- require 'spec/lib/helpers'
15
6
  require 'inversion/template/unlesstag'
16
7
  require 'inversion/template/textnode'
17
8
  require 'inversion/renderstate'
18
9
 
19
10
  describe Inversion::Template::UnlessTag do
20
11
 
21
- before( :all ) do
22
- setup_logging( :fatal )
23
- end
24
-
25
- after( :all ) do
26
- reset_logging()
27
- end
28
-
29
12
 
30
13
  it "renders its contents if its attribute is false" do
31
14
  tag = Inversion::Template::UnlessTag.new( 'attribute' )
@@ -33,7 +16,7 @@ describe Inversion::Template::UnlessTag do
33
16
 
34
17
  renderstate = Inversion::RenderState.new( :attribute => false )
35
18
  tag.render( renderstate )
36
- renderstate.to_s.should == 'the body'
19
+ expect( renderstate.to_s ).to eq( 'the body' )
37
20
  end
38
21
 
39
22
  it "renders its contents if its methodchain is false" do
@@ -42,7 +25,7 @@ describe Inversion::Template::UnlessTag do
42
25
 
43
26
  renderstate = Inversion::RenderState.new( :attribute => {:bar => 1} )
44
27
  tag.render( renderstate )
45
- renderstate.to_s.should == 'the body'
28
+ expect( renderstate.to_s ).to eq( 'the body' )
46
29
  end
47
30
 
48
31
  it "doesn't render its contents if its attribute is true" do
@@ -51,7 +34,7 @@ describe Inversion::Template::UnlessTag do
51
34
 
52
35
  renderstate = Inversion::RenderState.new( :attribute => true )
53
36
  tag.render( renderstate )
54
- renderstate.to_s.should == ''
37
+ expect( renderstate.to_s ).to eq( '' )
55
38
  end
56
39
 
57
40
  it "doesn't render its contents if its methodchain is true" do
@@ -60,7 +43,7 @@ describe Inversion::Template::UnlessTag do
60
43
 
61
44
  renderstate = Inversion::RenderState.new( :attribute => {:foo => 1} )
62
45
  tag.render( renderstate )
63
- renderstate.to_s.should == ''
46
+ expect( renderstate.to_s ).to eq( '' )
64
47
  end
65
48
 
66
49
  context "with an 'else' clause" do
@@ -76,13 +59,13 @@ describe Inversion::Template::UnlessTag do
76
59
  it "only renders the second half of the contents if its attribute is true" do
77
60
  renderstate = Inversion::RenderState.new( :attribute => true )
78
61
  @tag.render( renderstate )
79
- renderstate.to_s.should == 'the body after else'
62
+ expect( renderstate.to_s ).to eq( 'the body after else' )
80
63
  end
81
64
 
82
65
  it "only renders the first half of the contents if its attribute is false" do
83
66
  renderstate = Inversion::RenderState.new( :attribute => false )
84
67
  @tag.render( renderstate )
85
- renderstate.to_s.should == 'the body before else'
68
+ expect( renderstate.to_s ).to eq( 'the body before else' )
86
69
  end
87
70
 
88
71
  end
@@ -1,49 +1,32 @@
1
1
  #!/usr/bin/env rspec -cfd -b
2
2
  # vim: set noet nosta sw=4 ts=4 :
3
3
 
4
- BEGIN {
5
- require 'pathname'
6
- basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
- libdir = basedir + 'lib'
4
+ require_relative '../../helpers'
8
5
 
9
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
- }
12
-
13
- require 'rspec'
14
- require 'spec/lib/helpers'
15
6
  require 'inversion/template/uriencodetag'
16
7
 
17
8
  describe Inversion::Template::UriencodeTag do
18
9
 
19
- before( :all ) do
20
- setup_logging( :fatal )
21
- end
22
-
23
- after( :all ) do
24
- reset_logging()
25
- end
26
-
27
10
  before( :each ) do
28
- @attribute_object = mock( "template attribute" )
11
+ @attribute_object = double( "template attribute" )
29
12
  end
30
13
 
31
14
 
32
15
  it "URI encodes the results of rendering" do
33
16
  template = Inversion::Template.new( 'this is<?uriencode foo.bar ?>' )
34
17
  template.foo = @attribute_object
35
- @attribute_object.should_receive( :bar ).with( no_args() ).
18
+ expect( @attribute_object ).to receive( :bar ).with( no_args() ).
36
19
  and_return( " 25% Sparta!" )
37
20
 
38
- template.render.should == "this is%2025%25%20Sparta%21"
21
+ expect( template.render ).to eq( "this is%2025%25%20Sparta%21" )
39
22
  end
40
23
 
41
24
  it "stringifies its content before encoding" do
42
25
  template = Inversion::Template.new( '<?uriencode foo.bar ?> bottles of beer on the wall' )
43
26
  template.foo = @attribute_object
44
- @attribute_object.should_receive( :bar ).with( no_args() ).
27
+ expect( @attribute_object ).to receive( :bar ).with( no_args() ).
45
28
  and_return( 99.999 )
46
29
 
47
- template.render.should == "99.999 bottles of beer on the wall"
30
+ expect( template.render ).to eq( "99.999 bottles of beer on the wall" )
48
31
  end
49
32
  end
@@ -1,29 +1,12 @@
1
1
  #!/usr/bin/env rspec -cfd -b
2
2
  # vim: set noet nosta sw=4 ts=4 :
3
3
 
4
- BEGIN {
5
- require 'pathname'
6
- basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
7
- libdir = basedir + 'lib'
4
+ require_relative '../../helpers'
8
5
 
9
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
- }
12
-
13
- require 'rspec'
14
- require 'spec/lib/helpers'
15
6
  require 'inversion/template/yieldtag'
16
7
 
17
8
  describe Inversion::Template::YieldTag do
18
9
 
19
- before( :all ) do
20
- setup_logging( :fatal )
21
- end
22
-
23
- after( :all ) do
24
- reset_logging()
25
- end
26
-
27
10
 
28
11
  it "calls the renderstate's block before rendering, and renders as its return value" do
29
12
  tag = Inversion::Template::YieldTag.new( '' )
@@ -36,7 +19,7 @@ describe Inversion::Template::YieldTag do
36
19
  renderstate << tag
37
20
  end
38
21
 
39
- rendered_output.should == [ :return_value ]
22
+ expect( rendered_output ).to eq([ :return_value ])
40
23
  end
41
24
 
42
25
  it "renders as nothing if there wasn't a render block" do
@@ -48,7 +31,7 @@ describe Inversion::Template::YieldTag do
48
31
  renderstate << tag
49
32
  end
50
33
 
51
- rendered_output.should == [ nil ]
34
+ expect( rendered_output ).to eq([ nil ])
52
35
  end
53
36
 
54
37
  end
@@ -1,48 +1,42 @@
1
1
  #!/usr/bin/env rspec -cfd -b
2
2
  # vim: set noet nosta sw=4 ts=4 :
3
3
 
4
- BEGIN {
5
- require 'pathname'
6
- basedir = Pathname( __FILE__ ).dirname.parent.parent
7
- libdir = basedir + 'lib'
4
+ require_relative '../helpers'
8
5
 
9
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
10
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
- }
12
-
13
- require 'rspec'
14
6
  require 'stringio'
15
7
 
16
- require 'spec/lib/helpers'
17
8
  require 'inversion/template'
18
9
 
19
10
  describe Inversion::Template do
20
11
 
21
- before( :all ) do
22
- setup_logging( :fatal )
23
- end
12
+ context "created from a simple string" do
24
13
 
25
- it "can be loaded from a String" do
26
- Inversion::Template.new( "a template" ).source.should == 'a template'
27
- end
14
+ let( :template ) { described_class.new("a template") }
28
15
 
29
- it "renders the source as-is if there are no instructions" do
30
- Inversion::Template.new( "a template" ).render.should == 'a template'
31
- end
16
+ it "can be loaded from a String" do
17
+ expect( template.source ).to eq( 'a template' )
18
+ end
19
+
20
+ it "renders the source as-is if there are no instructions" do
21
+ expect( template.render ).to eq( 'a template' )
22
+ end
23
+
24
+ it "renders when stringified" do
25
+ expect( template.to_s ).to eq( 'a template' )
26
+ end
32
27
 
33
- it "renders when stringified" do
34
- Inversion::Template.new( "a template" ).to_s.should == 'a template'
35
28
  end
36
29
 
30
+
37
31
  it "calls before and after rendering hooks on all of its nodes when rendered" do
38
32
  node = double( "fake node" )
39
33
  parentstate = Inversion::RenderState.new( :foo => 'the merged stuff' )
40
- tmpl = Inversion::Template.new( '' )
34
+ tmpl = described_class.new( '' )
41
35
  tmpl.node_tree << node
42
36
 
43
- node.should_receive( :before_rendering ).with( an_instance_of(Inversion::RenderState) )
44
- node.should_receive( :render ).with( an_instance_of(Inversion::RenderState) )
45
- node.should_receive( :after_rendering ).with( an_instance_of(Inversion::RenderState) )
37
+ expect( node ).to receive( :before_rendering ).with( an_instance_of(Inversion::RenderState) )
38
+ expect( node ).to receive( :render ).with( an_instance_of(Inversion::RenderState) )
39
+ expect( node ).to receive( :after_rendering ).with( an_instance_of(Inversion::RenderState) )
46
40
 
47
41
  tmpl.render( parentstate )
48
42
  end
@@ -50,12 +44,12 @@ describe Inversion::Template do
50
44
 
51
45
  it "passes the block it was rendered with to its RenderState" do
52
46
  node = double( "fake node", :before_rendering => nil, :after_rendering => nil )
53
- tmpl = Inversion::Template.new( '' )
47
+ tmpl = described_class.new( '' )
54
48
  tmpl.node_tree << node
55
49
 
56
50
  renderblock = Proc.new {}
57
- node.should_receive( :render ).and_return do |renderstate|
58
- renderstate.block.should equal( renderblock )
51
+ expect( node ).to receive( :render ) do |renderstate|
52
+ expect( renderstate.block ).to equal( renderblock )
59
53
  end
60
54
 
61
55
  tmpl.render( &renderblock )
@@ -63,24 +57,40 @@ describe Inversion::Template do
63
57
 
64
58
  it "carries its global configuration to the parser" do
65
59
  begin
66
- orig_config = Inversion::Template.config
67
- Inversion::Template.configure( :ignore_unknown_tags => false )
60
+ orig_config = described_class.config
61
+ described_class.configure( :ignore_unknown_tags => false )
68
62
 
69
63
  expect {
70
- Inversion::Template.new( '<?rumple an unknown tag ?>' )
64
+ described_class.new( '<?rumple an unknown tag ?>' )
71
65
  }.to raise_error( Inversion::ParseError, /unknown tag/i )
72
66
  ensure
73
- Inversion::Template.config = orig_config
67
+ described_class.config = orig_config
68
+ end
69
+ end
70
+
71
+ it "carries its global configuration to per-template options" do
72
+ begin
73
+ orig_config = described_class.config
74
+ described_class.configure( :stat_delay => 300 )
75
+
76
+ template = described_class.new( 'hi!' )
77
+ expect( template.options[ :stat_delay ] ).to eq( 300 )
78
+
79
+ template = described_class.new( 'hi!', :stat_delay => 600 )
80
+ expect( template.options[ :stat_delay ] ).to eq( 600 )
81
+ ensure
82
+ described_class.config = orig_config
74
83
  end
75
84
  end
76
85
 
86
+
77
87
  it "can make an human-readable string version of itself suitable for debugging" do
78
- IO.should_receive( :read ).with( '/tmp/inspect.tmpl' ).and_return( '<?attr foo ?>' )
79
- tmpl = Inversion::Template.load( '/tmp/inspect.tmpl' )
80
- tmpl.inspect.should =~ /Inversion::Template/
81
- tmpl.inspect.should =~ %r{/tmp/inspect.tmpl}
82
- tmpl.inspect.should =~ /attributes/
83
- tmpl.inspect.should_not =~ /node_tree/
88
+ expect( IO ).to receive( :read ).with( '/tmp/inspect.tmpl' ).and_return( '<?attr foo ?>' )
89
+ tmpl = described_class.load( '/tmp/inspect.tmpl' )
90
+ expect( tmpl.inspect ).to match( /#{Regexp.escape(described_class.name)}/ )
91
+ expect( tmpl.inspect ).to match( %r{/tmp/inspect.tmpl} )
92
+ expect( tmpl.inspect ).to match( /attributes/ )
93
+ expect( tmpl.inspect ).to_not match( /node_tree/ )
84
94
  end
85
95
 
86
96
  it "includes the node tree in the inspected object if debugging is enabled" do
@@ -88,25 +98,25 @@ describe Inversion::Template do
88
98
  debuglevel = $DEBUG
89
99
  $DEBUG = true
90
100
 
91
- tmpl = Inversion::Template.new( '<?attr something ?>' )
92
- tmpl.inspect.should =~ /node_tree/
101
+ tmpl = described_class.new( '<?attr something ?>' )
102
+ expect( tmpl.inspect ).to match( /node_tree/ )
93
103
  ensure
94
104
  $DEBUG = debuglevel
95
105
  end
96
106
  end
97
107
 
98
108
  it "provides accessors for attributes that aren't identifiers in the template" do
99
- tmpl = Inversion::Template.new( '' )
109
+ tmpl = described_class.new( '' )
100
110
  tmpl.foo = :bar
101
- tmpl.foo.should == :bar
111
+ expect( tmpl.foo ).to eq( :bar )
102
112
  end
103
113
 
104
114
  it "can pass an encoding option to IO.open through the template constructor" do
105
115
  content = 'some stuff'.encode( 'utf-8' )
106
- IO.should_receive( :read ).with( '/a/utf8/template.tmpl', encoding: 'utf-8' ).and_return( content )
107
- template = Inversion::Template.load( '/a/utf8/template.tmpl', encoding: 'utf-8' )
116
+ expect( IO ).to receive( :read ).with( '/a/utf8/template.tmpl', encoding: 'utf-8' ).and_return( content )
117
+ template = described_class.load( '/a/utf8/template.tmpl', encoding: 'utf-8' )
108
118
 
109
- template.render.encoding.should == Encoding::UTF_8
119
+ expect( template.render.encoding ).to eq( Encoding::UTF_8 )
110
120
  end
111
121
 
112
122
 
@@ -115,30 +125,30 @@ describe Inversion::Template do
115
125
  before( :each ) do
116
126
  @timestamp = Time.now
117
127
  content = 'file contents'.taint
118
- IO.stub( :read ).with( '/tmp/hooowat' ).and_return( content )
119
- @template = Inversion::Template.load( '/tmp/hooowat' )
128
+ allow( IO ).to receive( :read ).with( '/tmp/hooowat' ).and_return( content )
129
+ @template = described_class.load( '/tmp/hooowat' )
120
130
  end
121
131
 
122
132
 
123
133
  it "untaints template content loaded from a file" do
124
- @template.source.should_not be_tainted()
134
+ expect( @template.source ).to_not be_tainted()
125
135
  end
126
136
 
127
137
  it "can be reloaded" do
128
138
  newcontent = 'changed file contents'.taint
129
- IO.should_receive( :read ).with( '/tmp/hooowat' ).and_return( newcontent )
139
+ expect( IO ).to receive( :read ).with( '/tmp/hooowat' ).and_return( newcontent )
130
140
  @template.reload
131
- @template.source.should == newcontent
141
+ expect( @template.source ).to eq( newcontent )
132
142
  end
133
143
 
134
144
  context "that hasn't changed since it was loaded" do
135
145
 
136
146
  before( :each ) do
137
- @template.source_file.stub!( :mtime ).and_return( @timestamp )
147
+ allow( @template.source_file ).to receive( :mtime ).and_return( @timestamp )
138
148
  end
139
149
 
140
150
  it "knows that it hasn't changed" do
141
- @template.should_not be_changed()
151
+ expect( @template ).to_not be_changed()
142
152
  end
143
153
 
144
154
  context "with a stat delay" do
@@ -149,13 +159,13 @@ describe Inversion::Template do
149
159
 
150
160
  it "returns unchanged if the delay time hasn't expired" do
151
161
  @template.instance_variable_set( :@last_checked, @timestamp )
152
- @template.should_not be_changed()
162
+ expect( @template ).to_not be_changed()
153
163
  end
154
164
 
155
165
  it "returns unchanged if the delay time has expired" do
156
- @template.source_file.stub!( :mtime ).and_return( @timestamp - 30 )
166
+ expect( @template.source_file ).to receive( :mtime ).and_return( @timestamp - 30 )
157
167
  @template.instance_variable_set( :@last_checked, @timestamp - 30 )
158
- @template.should_not be_changed()
168
+ expect( @template ).to_not be_changed()
159
169
  end
160
170
  end
161
171
  end
@@ -163,11 +173,11 @@ describe Inversion::Template do
163
173
  context "that has changed since it was loaded" do
164
174
 
165
175
  before( :each ) do
166
- @template.source_file.stub!( :mtime ).and_return( @timestamp + 1 )
176
+ allow( @template.source_file ).to receive( :mtime ).and_return( @timestamp + 1 )
167
177
  end
168
178
 
169
179
  it "knows that is has changed" do
170
- @template.should be_changed()
180
+ expect( @template ).to be_changed()
171
181
  end
172
182
 
173
183
  context "with a stat delay" do
@@ -178,12 +188,12 @@ describe Inversion::Template do
178
188
 
179
189
  it "returns unchanged if the delay time hasn't expired" do
180
190
  @template.instance_variable_set( :@last_checked, @timestamp )
181
- @template.should_not be_changed()
191
+ expect( @template ).to_not be_changed()
182
192
  end
183
193
 
184
194
  it "returns changed if the delay time has expired" do
185
195
  @template.instance_variable_set( :@last_checked, @timestamp - 60 )
186
- @template.should be_changed()
196
+ expect( @template ).to be_changed()
187
197
  end
188
198
  end
189
199
  end
@@ -193,11 +203,11 @@ describe Inversion::Template do
193
203
  context "loaded from a String" do
194
204
 
195
205
  before( :each ) do
196
- @template = Inversion::Template.new( 'some stuff' )
206
+ @template = described_class.new( 'some stuff' )
197
207
  end
198
208
 
199
209
  it "never says it has changed" do
200
- @template.should_not be_changed()
210
+ expect( @template ).to_not be_changed()
201
211
  end
202
212
 
203
213
  it "raises an exception if reloaded" do
@@ -213,19 +223,19 @@ describe Inversion::Template do
213
223
  context "without template paths set" do
214
224
 
215
225
  before( :each ) do
216
- Inversion::Template.template_paths.clear
226
+ described_class.template_paths.clear
217
227
  end
218
228
 
219
229
  it "instances can be loaded from an absolute path" do
220
- IO.should_receive( :read ).with( '/tmp/hooowat' ).and_return( 'file contents' )
221
- Inversion::Template.load( '/tmp/hooowat' ).source.should == 'file contents'
230
+ expect( IO ).to receive( :read ).with( '/tmp/hooowat' ).and_return( 'file contents' )
231
+ expect( described_class.load( '/tmp/hooowat' ).source ).to eq( 'file contents' )
222
232
  end
223
233
 
224
234
  it "instances can be loaded from a path relative to the current working directory" do
225
235
  tmplpath = Pathname.pwd + 'hooowat.tmpl'
226
- FileTest.should_receive( :exist? ).with( tmplpath.to_s ).and_return( true )
227
- IO.should_receive( :read ).with( tmplpath.to_s ).and_return( 'file contents' )
228
- Inversion::Template.load( 'hooowat.tmpl' ).source.should == 'file contents'
236
+ expect( FileTest ).to receive( :exist? ).with( tmplpath.to_s ).and_return( true )
237
+ expect( IO ).to receive( :read ).with( tmplpath.to_s ).and_return( 'file contents' )
238
+ expect( described_class.load( 'hooowat.tmpl' ).source ).to eq( 'file contents' )
229
239
  end
230
240
  end
231
241
 
@@ -233,93 +243,93 @@ describe Inversion::Template do
233
243
  context "with template paths set" do
234
244
 
235
245
  before( :each ) do
236
- Inversion::Template.template_paths = [ '/tmp', '/fun' ]
246
+ described_class.template_paths = [ '/tmp', '/fun' ]
237
247
  end
238
248
 
239
249
  after( :each ) do
240
- Inversion::Template.template_paths.clear
250
+ described_class.template_paths.clear
241
251
  end
242
252
 
243
253
  it "instances can be loaded from an absolute path" do
244
- FileTest.should_not_receive( :exist? )
254
+ expect( FileTest ).to_not receive( :exist? )
245
255
 
246
- IO.should_receive( :read ).with( '/tmp/hooowat' ).and_return( 'file contents' )
247
- Inversion::Template.load( '/tmp/hooowat' ).source.should == 'file contents'
256
+ expect( IO ).to receive( :read ).with( '/tmp/hooowat' ).and_return( 'file contents' )
257
+ expect( described_class.load( '/tmp/hooowat' ).source ).to eq( 'file contents' )
248
258
  end
249
259
 
250
260
  it "raises a runtime exception if unable to locate the template" do
251
261
  tmplpath = Pathname.pwd + 'sadmanhose.tmpl'
252
262
 
253
- FileTest.should_receive( :exist? ).with( '/tmp/sadmanhose.tmpl' ).and_return( false )
254
- FileTest.should_receive( :exist? ).with( '/fun/sadmanhose.tmpl' ).and_return( false )
255
- FileTest.should_receive( :exist? ).with( tmplpath.to_s ).and_return( false )
263
+ expect( FileTest ).to receive( :exist? ).with( '/tmp/sadmanhose.tmpl' ).and_return( false )
264
+ expect( FileTest ).to receive( :exist? ).with( '/fun/sadmanhose.tmpl' ).and_return( false )
265
+ expect( FileTest ).to receive( :exist? ).with( tmplpath.to_s ).and_return( false )
256
266
 
257
267
  expect {
258
- Inversion::Template.load( 'sadmanhose.tmpl' )
268
+ described_class.load( 'sadmanhose.tmpl' )
259
269
  }.to raise_error( RuntimeError, /unable to find template ".+" within configured paths/i )
260
270
  end
261
271
 
262
272
  it "loads template relative to directories in the template_paths" do
263
- FileTest.should_receive( :exist? ).with( '/tmp/hooowat.tmpl' ).and_return( false )
264
- FileTest.should_receive( :exist? ).with( '/fun/hooowat.tmpl' ).and_return( true )
265
- IO.should_receive( :read ).with( '/fun/hooowat.tmpl' ).and_return( 'file contents' )
273
+ expect( FileTest ).to receive( :exist? ).with( '/tmp/hooowat.tmpl' ).and_return( false )
274
+ expect( FileTest ).to receive( :exist? ).with( '/fun/hooowat.tmpl' ).and_return( true )
275
+ expect( IO ).to receive( :read ).with( '/fun/hooowat.tmpl' ).and_return( 'file contents' )
266
276
 
267
- Inversion::Template.load( 'hooowat.tmpl' ).source.should == 'file contents'
277
+ expect( described_class.load( 'hooowat.tmpl' ).source ).to eq( 'file contents' )
268
278
  end
269
279
 
270
280
  it "falls back to loading the template relative to the current working directory" do
271
281
  tmplpath = Pathname.pwd + 'hooowat.tmpl'
272
282
 
273
- FileTest.should_receive( :exist? ).with( '/tmp/hooowat.tmpl' ).and_return( false )
274
- FileTest.should_receive( :exist? ).with( '/fun/hooowat.tmpl' ).and_return( false )
275
- FileTest.should_receive( :exist? ).with( tmplpath.to_s ).and_return( true )
276
- IO.should_receive( :read ).with( tmplpath.to_s ).and_return( 'file contents' )
283
+ expect( FileTest ).to receive( :exist? ).with( '/tmp/hooowat.tmpl' ).and_return( false )
284
+ expect( FileTest ).to receive( :exist? ).with( '/fun/hooowat.tmpl' ).and_return( false )
285
+ expect( FileTest ).to receive( :exist? ).with( tmplpath.to_s ).and_return( true )
286
+ expect( IO ).to receive( :read ).with( tmplpath.to_s ).and_return( 'file contents' )
277
287
 
278
- Inversion::Template.load( 'hooowat.tmpl' ).source.should == 'file contents'
288
+ expect( described_class.load( 'hooowat.tmpl' ).source ).to eq( 'file contents' )
279
289
  end
280
290
  end
281
291
 
282
292
 
283
293
  context "with an attribute PI" do
284
294
 
285
- let( :template ) { Inversion::Template.new("<h1><?attr foo ?></h1>") }
295
+ let( :template ) { described_class.new("<h1><?attr foo ?></h1>") }
286
296
 
287
297
 
288
298
  it "has a reader for getting the attribute's value" do
289
- template.should respond_to( :foo )
299
+ expect( template ).to respond_to( :foo )
290
300
  end
291
301
 
292
302
  it "has an accessor for setting the attribute's value" do
293
- template.should respond_to( :foo= )
303
+ expect( template ).to respond_to( :foo= )
294
304
  end
295
305
 
296
306
  it "renders scalar values set for the attribute" do
297
307
  template.foo = "a lion"
298
- template.render.should == "<h1>a lion</h1>"
308
+ expect( template.render ).to eq( "<h1>a lion</h1>" )
299
309
  end
300
310
 
301
311
  it "renders an non-String value set for the attribute using #to_s" do
302
312
  template.foo = [ 'a lion', 'a little guy', 'a bad mousie', 'one birdy' ]
303
- template.render.should == %{<h1>a liona little guya bad mousieone birdy</h1>}
313
+ expect( template.render ).to eq( %{<h1>a liona little guya bad mousieone birdy</h1>} )
304
314
  end
305
315
  end
306
316
 
307
317
 
308
318
  context "with several attribute PIs" do
309
319
 
310
- let( :template ) { Inversion::Template.new("<h1><?attr foo ?> <?attr foo?> RUN!</h1>") }
320
+ let( :template ) { described_class.new("<h1><?attr foo ?> <?attr foo?> RUN!</h1>") }
311
321
 
312
322
  it "has a reader for getting the attribute's value" do
313
- template.should respond_to( :foo )
323
+ expect( template ).to respond_to( :foo )
314
324
  end
315
325
 
316
326
  it "has an accessor for setting the attribute's value" do
317
- template.should respond_to( :foo= )
327
+ expect( template ).to respond_to( :foo= )
318
328
  end
319
329
 
320
330
  it "renders scalar values set for the attribute(s)" do
321
331
  template.foo = "lions!!"
322
- template.render.should == "<h1>lions!! lions!! RUN!</h1>"
332
+ expect( template.render ).to eq( "<h1>lions!! lions!! RUN!</h1>" )
323
333
  end
324
334
  end
325
335
 
@@ -327,11 +337,11 @@ describe Inversion::Template do
327
337
  describe "Configurability support", :if => defined?( Configurability ) do
328
338
 
329
339
  after( :each ) do
330
- Inversion::Template.config = Inversion::Template::DEFAULT_CONFIG
340
+ described_class.config = described_class::DEFAULT_CONFIG
331
341
  end
332
342
 
333
343
  it "is included in the list of configurable objects" do
334
- Configurability.configurable_objects.should include( Inversion::Template )
344
+ expect( Configurability.configurable_objects ).to include( described_class )
335
345
  end
336
346
 
337
347
  it "can be configured using a Configurability::Config object" do
@@ -344,12 +354,12 @@ describe Inversion::Template do
344
354
  comment_end: ""
345
355
  }.gsub(/^\t{3}/, '') )
346
356
 
347
- Inversion::Template.configure( config.templates )
357
+ described_class.configure( config.templates )
348
358
 
349
- Inversion::Template.config[:ignore_unknown_tags].should be_false()
350
- Inversion::Template.config[:debugging_comments].should be_true()
351
- Inversion::Template.config[:comment_start].should == '#'
352
- Inversion::Template.config[:comment_end].should == ''
359
+ expect( described_class.config[:ignore_unknown_tags] ).to be_false()
360
+ expect( described_class.config[:debugging_comments] ).to be_true()
361
+ expect( described_class.config[:comment_start] ).to eq( '#' )
362
+ expect( described_class.config[:comment_end] ).to eq( '' )
353
363
 
354
364
  end
355
365
 
@@ -359,11 +369,11 @@ describe Inversion::Template do
359
369
  describe "exception-handling:" do
360
370
 
361
371
  before( :each ) do
362
- @source = "Some stuff\n<?call obj.raise_exception ?>\nMore stuff"
363
- @tmpl = Inversion::Template.new( @source )
372
+ @source = "Some stuff\n<?call obj.raise_error ?>\nMore stuff"
373
+ @tmpl = described_class.new( @source )
364
374
 
365
375
  @obj = Object.new
366
- def @obj.raise_exception
376
+ def @obj.raise_error
367
377
  raise "Okay, here's an exception!"
368
378
  end
369
379
 
@@ -372,24 +382,61 @@ describe Inversion::Template do
372
382
 
373
383
  it "can be configured to completely ignore exceptions raised while rendering" do
374
384
  @tmpl.options[:on_render_error] = :ignore
375
- @tmpl.render.should == "Some stuff\nMore stuff"
385
+ expect( @tmpl.render ).to eq( "Some stuff\nMore stuff" )
376
386
  end
377
387
 
378
388
  it "can be configured to insert debugging comments for exceptions raised while rendering" do
379
389
  @tmpl.options[:on_render_error] = :comment
380
- @tmpl.render.should ==
381
- "Some stuff\n<!-- RuntimeError: Okay, here's an exception! -->More stuff"
390
+ expect(
391
+ @tmpl.render
392
+ ).to eq( "Some stuff\n<!-- RuntimeError: Okay, here's an exception! -->More stuff" )
382
393
  end
383
394
 
384
395
  it "can be configured to propagate exceptions raised while rendering" do
385
396
  @tmpl.options[:on_render_error] = :propagate
386
397
  expect {
387
398
  @tmpl.render
388
- }.to raise_exception( RuntimeError, /Okay, here's an exception!/ )
399
+ }.to raise_error( RuntimeError, /Okay, here's an exception!/ )
389
400
  end
390
401
 
391
402
  end
392
403
 
393
404
 
405
+ describe "with fragment tags" do
406
+
407
+ before( :each ) do
408
+ @template = Inversion::Template.new <<-TMPL
409
+ <?default bool to 'yes' ?>
410
+ <?fragment pork ?>wooo<?end ?>
411
+ <?fragment beef ?><?attr bool ?> please<?end ?>
412
+ <?attr beef ?>
413
+ TMPL
414
+ end
415
+
416
+ it "doesn't have any fragments before it's been rendered" do
417
+ expect( @template.fragments ).to be_empty
418
+ end
419
+
420
+ it "has a fragment for each tag after it's been rendered" do
421
+ @template.render
422
+
423
+ expect( @template.fragments ).to be_a( Hash )
424
+ expect( @template.fragments ).to include( :pork, :beef )
425
+ expect( @template.fragments.size ).to eq( 2 )
426
+ expect( @template.fragments[:pork] ).to eq( 'wooo' )
427
+ expect( @template.fragments[:beef] ).to eq( 'yes please' )
428
+ end
429
+
430
+ it "clears previous fragments when rendered a second time" do
431
+ @template.render
432
+ expect( @template.fragments[:beef] ).to eq( 'yes please' )
433
+
434
+ @template.bool = 'no'
435
+ @template.render
436
+ expect( @template.fragments[:beef] ).to eq( 'no please' )
437
+ end
438
+
439
+ end
440
+
394
441
  end
395
442