inversion 0.12.3 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -1
- data.tar.gz.sig +0 -0
- data/ChangeLog +305 -9
- data/Examples.rdoc +134 -0
- data/GettingStarted.rdoc +44 -0
- data/Guide.rdoc +47 -0
- data/History.rdoc +15 -0
- data/Manifest.txt +7 -2
- data/README.rdoc +9 -10
- data/Rakefile +23 -10
- data/Tags.rdoc +561 -0
- data/lib/inversion.rb +2 -2
- data/lib/inversion/renderstate.rb +46 -11
- data/lib/inversion/template.rb +85 -7
- data/lib/inversion/template/attrtag.rb +1 -1
- data/lib/inversion/template/begintag.rb +8 -8
- data/lib/inversion/template/fragmenttag.rb +60 -0
- data/lib/inversion/template/rescuetag.rb +1 -1
- data/spec/{lib/helpers.rb → helpers.rb} +7 -30
- data/spec/inversion/mixins_spec.rb +55 -65
- data/spec/inversion/monkeypatches_spec.rb +2 -12
- data/spec/inversion/parser_spec.rb +34 -44
- data/spec/inversion/renderstate_spec.rb +123 -69
- data/spec/inversion/sinatra_spec.rb +6 -19
- data/spec/inversion/template/attrtag_spec.rb +56 -76
- data/spec/inversion/template/begintag_spec.rb +24 -41
- data/spec/inversion/template/calltag_spec.rb +1 -18
- data/spec/inversion/template/codetag_spec.rb +6 -24
- data/spec/inversion/template/commenttag_spec.rb +9 -27
- data/spec/inversion/template/configtag_spec.rb +5 -16
- data/spec/inversion/template/containertag_spec.rb +4 -21
- data/spec/inversion/template/defaulttag_spec.rb +6 -23
- data/spec/inversion/template/elsetag_spec.rb +9 -26
- data/spec/inversion/template/elsiftag_spec.rb +7 -24
- data/spec/inversion/template/endtag_spec.rb +6 -23
- data/spec/inversion/template/escapetag_spec.rb +10 -25
- data/spec/inversion/template/fortag_spec.rb +20 -37
- data/spec/inversion/template/fragmenttag_spec.rb +40 -0
- data/spec/inversion/template/iftag_spec.rb +23 -40
- data/spec/inversion/template/importtag_spec.rb +8 -25
- data/spec/inversion/template/includetag_spec.rb +27 -42
- data/spec/inversion/template/node_spec.rb +6 -15
- data/spec/inversion/template/pptag_spec.rb +10 -23
- data/spec/inversion/template/publishtag_spec.rb +4 -21
- data/spec/inversion/template/rescuetag_spec.rb +12 -29
- data/spec/inversion/template/subscribetag_spec.rb +8 -25
- data/spec/inversion/template/tag_spec.rb +24 -37
- data/spec/inversion/template/textnode_spec.rb +8 -24
- data/spec/inversion/template/timedeltatag_spec.rb +31 -43
- data/spec/inversion/template/unlesstag_spec.rb +7 -24
- data/spec/inversion/template/uriencodetag_spec.rb +6 -23
- data/spec/inversion/template/yieldtag_spec.rb +3 -20
- data/spec/inversion/template_spec.rb +155 -108
- data/spec/inversion/tilt_spec.rb +7 -16
- data/spec/inversion_spec.rb +7 -22
- metadata +63 -40
- metadata.gz.sig +0 -0
- 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
|
-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
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 =
|
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.
|
18
|
+
expect( @attribute_object ).to receive( :bar ).with( no_args() ).
|
36
19
|
and_return( " 25% Sparta!" )
|
37
20
|
|
38
|
-
template.render.
|
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.
|
27
|
+
expect( @attribute_object ).to receive( :bar ).with( no_args() ).
|
45
28
|
and_return( 99.999 )
|
46
29
|
|
47
|
-
template.render.
|
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
|
-
|
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.
|
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.
|
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
|
-
|
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
|
-
|
22
|
-
setup_logging( :fatal )
|
23
|
-
end
|
12
|
+
context "created from a simple string" do
|
24
13
|
|
25
|
-
|
26
|
-
Inversion::Template.new( "a template" ).source.should == 'a template'
|
27
|
-
end
|
14
|
+
let( :template ) { described_class.new("a template") }
|
28
15
|
|
29
|
-
|
30
|
-
|
31
|
-
|
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 =
|
34
|
+
tmpl = described_class.new( '' )
|
41
35
|
tmpl.node_tree << node
|
42
36
|
|
43
|
-
node.
|
44
|
-
node.
|
45
|
-
node.
|
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 =
|
47
|
+
tmpl = described_class.new( '' )
|
54
48
|
tmpl.node_tree << node
|
55
49
|
|
56
50
|
renderblock = Proc.new {}
|
57
|
-
node.
|
58
|
-
renderstate.block.
|
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 =
|
67
|
-
|
60
|
+
orig_config = described_class.config
|
61
|
+
described_class.configure( :ignore_unknown_tags => false )
|
68
62
|
|
69
63
|
expect {
|
70
|
-
|
64
|
+
described_class.new( '<?rumple an unknown tag ?>' )
|
71
65
|
}.to raise_error( Inversion::ParseError, /unknown tag/i )
|
72
66
|
ensure
|
73
|
-
|
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.
|
79
|
-
tmpl =
|
80
|
-
tmpl.inspect.
|
81
|
-
tmpl.inspect.
|
82
|
-
tmpl.inspect.
|
83
|
-
tmpl.inspect.
|
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 =
|
92
|
-
tmpl.inspect.
|
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 =
|
109
|
+
tmpl = described_class.new( '' )
|
100
110
|
tmpl.foo = :bar
|
101
|
-
tmpl.foo.
|
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.
|
107
|
-
template =
|
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.
|
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.
|
119
|
-
@template =
|
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.
|
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.
|
139
|
+
expect( IO ).to receive( :read ).with( '/tmp/hooowat' ).and_return( newcontent )
|
130
140
|
@template.reload
|
131
|
-
@template.source.
|
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.
|
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.
|
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.
|
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.
|
166
|
+
expect( @template.source_file ).to receive( :mtime ).and_return( @timestamp - 30 )
|
157
167
|
@template.instance_variable_set( :@last_checked, @timestamp - 30 )
|
158
|
-
@template.
|
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.
|
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.
|
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.
|
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.
|
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 =
|
206
|
+
@template = described_class.new( 'some stuff' )
|
197
207
|
end
|
198
208
|
|
199
209
|
it "never says it has changed" do
|
200
|
-
@template.
|
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
|
-
|
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.
|
221
|
-
|
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.
|
227
|
-
IO.
|
228
|
-
|
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
|
-
|
246
|
+
described_class.template_paths = [ '/tmp', '/fun' ]
|
237
247
|
end
|
238
248
|
|
239
249
|
after( :each ) do
|
240
|
-
|
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.
|
254
|
+
expect( FileTest ).to_not receive( :exist? )
|
245
255
|
|
246
|
-
IO.
|
247
|
-
|
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.
|
254
|
-
FileTest.
|
255
|
-
FileTest.
|
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
|
-
|
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.
|
264
|
-
FileTest.
|
265
|
-
IO.
|
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
|
-
|
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.
|
274
|
-
FileTest.
|
275
|
-
FileTest.
|
276
|
-
IO.
|
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
|
-
|
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 ) {
|
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.
|
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.
|
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.
|
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.
|
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 ) {
|
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.
|
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.
|
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.
|
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
|
-
|
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.
|
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
|
-
|
357
|
+
described_class.configure( config.templates )
|
348
358
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
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.
|
363
|
-
@tmpl =
|
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.
|
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.
|
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
|
-
|
381
|
-
|
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
|
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
|
|