inversion 0.12.3 → 0.14.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 (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