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,17 +1,7 @@
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'
8
-
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'
4
+ require_relative '../helpers'
15
5
 
16
6
  require 'inversion/mixins'
17
7
 
@@ -30,15 +20,15 @@ describe Inversion, "mixins" do
30
20
 
31
21
  result = Inversion::HashUtilities.stringify_keys( testhash )
32
22
 
33
- result.should be_an_instance_of( Hash )
34
- result.should_not be_equal( testhash )
35
- result.should == {
23
+ expect( result ).to be_an_instance_of( Hash )
24
+ expect( result ).to_not be_equal( testhash )
25
+ expect( result ).to eq({
36
26
  'foo' => 1,
37
27
  'bar' => {
38
28
  'klang' => 'klong',
39
29
  'barang' => { 'kerklang' => 'dumdumdum' },
40
30
  }
41
- }
31
+ })
42
32
  end
43
33
 
44
34
 
@@ -53,15 +43,15 @@ describe Inversion, "mixins" do
53
43
 
54
44
  result = Inversion::HashUtilities.symbolify_keys( testhash )
55
45
 
56
- result.should be_an_instance_of( Hash )
57
- result.should_not be_equal( testhash )
58
- result.should == {
46
+ expect( result ).to be_an_instance_of( Hash )
47
+ expect( result ).to_not be_equal( testhash )
48
+ expect( result ).to eq({
59
49
  :foo => 1,
60
50
  :bar => {
61
51
  :klang => 'klong',
62
52
  :barang => { :kerklang => 'dumdumdum' },
63
53
  }
64
- }
54
+ })
65
55
  end
66
56
 
67
57
  end
@@ -125,17 +115,17 @@ describe Inversion, "mixins" do
125
115
 
126
116
  it "adds configurable escaping to including classes" do
127
117
  render_state = Inversion::RenderState.new( {}, :escape_format => :html )
128
- @obj.render( render_state ).should == "<something>"
118
+ expect( @obj.render( render_state ) ).to eq( "<something>" )
129
119
  end
130
120
 
131
121
  it "doesn't escape anything if escaping is disabled" do
132
122
  render_state = Inversion::RenderState.new( {}, :escape_format => nil )
133
- @obj.render( render_state ).should == "<something>"
123
+ expect( @obj.render( render_state ) ).to eq( "<something>" )
134
124
  end
135
125
 
136
126
  it "doesn't escape anything if escaping is set to ':none'" do
137
127
  render_state = Inversion::RenderState.new( {}, :escape_format => :none )
138
- @obj.render( render_state ).should == "<something>"
128
+ expect( @obj.render( render_state ) ).to eq( "<something>" )
139
129
  end
140
130
  end
141
131
 
@@ -143,26 +133,26 @@ describe Inversion, "mixins" do
143
133
  describe Inversion::DataUtilities do
144
134
 
145
135
  it "doesn't try to dup immediate objects" do
146
- Inversion::DataUtilities.deep_copy( nil ).should be( nil )
147
- Inversion::DataUtilities.deep_copy( 112 ).should be( 112 )
148
- Inversion::DataUtilities.deep_copy( true ).should be( true )
149
- Inversion::DataUtilities.deep_copy( false ).should be( false )
150
- Inversion::DataUtilities.deep_copy( :a_symbol ).should be( :a_symbol )
136
+ expect( Inversion::DataUtilities.deep_copy( nil ) ).to be( nil )
137
+ expect( Inversion::DataUtilities.deep_copy( 112 ) ).to be( 112 )
138
+ expect( Inversion::DataUtilities.deep_copy( true ) ).to be( true )
139
+ expect( Inversion::DataUtilities.deep_copy( false ) ).to be( false )
140
+ expect( Inversion::DataUtilities.deep_copy( :a_symbol ) ).to be( :a_symbol )
151
141
  end
152
142
 
153
143
  it "doesn't try to dup modules/classes" do
154
144
  klass = Class.new
155
- Inversion::DataUtilities.deep_copy( klass ).should be( klass )
145
+ expect( Inversion::DataUtilities.deep_copy( klass ) ).to be( klass )
156
146
  end
157
147
 
158
148
  it "doesn't try to dup IOs" do
159
149
  data = [ $stdin ]
160
- Inversion::DataUtilities.deep_copy( data[0] ).should be( $stdin )
150
+ expect( Inversion::DataUtilities.deep_copy( data[0] ) ).to be( $stdin )
161
151
  end
162
152
 
163
153
  it "doesn't try to dup Tempfiles" do
164
154
  data = Tempfile.new( 'inversion_deepcopy.XXXXX' )
165
- Inversion::DataUtilities.deep_copy( data ).should be( data )
155
+ expect( Inversion::DataUtilities.deep_copy( data ) ).to be( data )
166
156
  end
167
157
 
168
158
  it "makes distinct copies of arrays and their members" do
@@ -170,14 +160,14 @@ describe Inversion, "mixins" do
170
160
 
171
161
  copy = Inversion::DataUtilities.deep_copy( original )
172
162
 
173
- copy.should == original
174
- copy.should_not be( original )
175
- copy[0].should == original[0]
176
- copy[0].should_not be( original[0] )
177
- copy[1].should == original[1]
178
- copy[1].should_not be( original[1] )
179
- copy[2].should == original[2]
180
- copy[2].should be( original[2] ) # Immediate
163
+ expect( copy ).to eq( original )
164
+ expect( copy ).to_not be( original )
165
+ expect( copy[0] ).to eq( original[0] )
166
+ expect( copy[0] ).to_not be( original[0] )
167
+ expect( copy[1] ).to eq( original[1] )
168
+ expect( copy[1] ).to_not be( original[1] )
169
+ expect( copy[2] ).to eq( original[2] )
170
+ expect( copy[2] ).to be( original[2] ) # Immediate
181
171
  end
182
172
 
183
173
  it "makes recursive copies of deeply-nested Arrays" do
@@ -185,12 +175,12 @@ describe Inversion, "mixins" do
185
175
 
186
176
  copy = Inversion::DataUtilities.deep_copy( original )
187
177
 
188
- copy.should == original
189
- copy.should_not be( original )
190
- copy[1].should_not be( original[1] )
191
- copy[1][2].should_not be( original[1][2] )
192
- copy[3].should_not be( original[3] )
193
- copy[3][1].should_not be( original[3][1] )
178
+ expect( copy ).to eq( original )
179
+ expect( copy ).to_not be( original )
180
+ expect( copy[1] ).to_not be( original[1] )
181
+ expect( copy[1][2] ).to_not be( original[1][2] )
182
+ expect( copy[3] ).to_not be( original[3] )
183
+ expect( copy[3][1] ).to_not be( original[3][1] )
194
184
  end
195
185
 
196
186
  it "makes distinct copies of Hashes and their members" do
@@ -202,13 +192,13 @@ describe Inversion, "mixins" do
202
192
 
203
193
  copy = Inversion::DataUtilities.deep_copy( original )
204
194
 
205
- copy.should == original
206
- copy.should_not be( original )
207
- copy[:a].should == 1
208
- copy.key( 2 ).should == 'b'
209
- copy.key( 2 ).should_not be( original.key(2) )
210
- copy[3].should == 'c'
211
- copy[3].should_not be( original[3] )
195
+ expect( copy ).to eq( original )
196
+ expect( copy ).to_not be( original )
197
+ expect( copy[:a] ).to eq( 1 )
198
+ expect( copy.key( 2 ) ).to eq( 'b' )
199
+ expect( copy.key( 2 ) ).to_not be( original.key(2) )
200
+ expect( copy[3] ).to eq( 'c' )
201
+ expect( copy[3] ).to_not be( original[3] )
212
202
  end
213
203
 
214
204
  it "makes distinct copies of deeply-nested Hashes" do
@@ -225,15 +215,15 @@ describe Inversion, "mixins" do
225
215
 
226
216
  copy = Inversion::DataUtilities.deep_copy( original )
227
217
 
228
- copy.should == original
229
- copy[:a][:b][:c].should == 'd'
230
- copy[:a][:b][:c].should_not be( original[:a][:b][:c] )
231
- copy[:a][:b][:e].should == 'f'
232
- copy[:a][:b][:e].should_not be( original[:a][:b][:e] )
233
- copy[:a][:g].should == 'h'
234
- copy[:a][:g].should_not be( original[:a][:g] )
235
- copy[:i].should == 'j'
236
- copy[:i].should_not be( original[:i] )
218
+ expect( copy ).to eq( original )
219
+ expect( copy[:a][:b][:c] ).to eq( 'd' )
220
+ expect( copy[:a][:b][:c] ).to_not be( original[:a][:b][:c] )
221
+ expect( copy[:a][:b][:e] ).to eq( 'f' )
222
+ expect( copy[:a][:b][:e] ).to_not be( original[:a][:b][:e] )
223
+ expect( copy[:a][:g] ).to eq( 'h' )
224
+ expect( copy[:a][:g] ).to_not be( original[:a][:g] )
225
+ expect( copy[:i] ).to eq( 'j' )
226
+ expect( copy[:i] ).to_not be( original[:i] )
237
227
  end
238
228
 
239
229
  it "copies the default proc of copied Hashes" do
@@ -241,7 +231,7 @@ describe Inversion, "mixins" do
241
231
 
242
232
  copy = Inversion::DataUtilities.deep_copy( original )
243
233
 
244
- copy.default_proc.should == original.default_proc
234
+ expect( copy.default_proc ).to eq( original.default_proc )
245
235
  end
246
236
 
247
237
  it "preserves taintedness of copied objects" do
@@ -250,8 +240,8 @@ describe Inversion, "mixins" do
250
240
 
251
241
  copy = Inversion::DataUtilities.deep_copy( original )
252
242
 
253
- copy.should_not be( original )
254
- copy.should be_tainted()
243
+ expect( copy ).to_not be( original )
244
+ expect( copy ).to be_tainted()
255
245
  end
256
246
 
257
247
  it "preserves frozen-ness of copied objects" do
@@ -260,8 +250,8 @@ describe Inversion, "mixins" do
260
250
 
261
251
  copy = Inversion::DataUtilities.deep_copy( original )
262
252
 
263
- copy.should_not be( original )
264
- copy.should be_frozen()
253
+ expect( copy ).to_not be( original )
254
+ expect( copy ).to be_frozen()
265
255
  end
266
256
  end
267
257
  end
@@ -1,20 +1,10 @@
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'
8
4
 
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
- }
5
+ require_relative '../helpers'
12
6
 
13
7
  require 'ripper'
14
-
15
- require 'rspec'
16
- require 'spec/lib/helpers'
17
-
18
8
  require 'inversion/monkeypatches'
19
9
 
20
10
 
@@ -25,7 +15,7 @@ describe Inversion, "monkeypatches" do
25
15
  it "exposes the Ripper::TokenPattern::MatchData's #tokens array" do
26
16
  tagpattern = Ripper::TokenPattern.compile( '$(ident) $(sp) $(ident)' )
27
17
  matchdata = tagpattern.match( "foo bar" )
28
- matchdata.tokens.map {|tok| tok[1] }.should == [ :on_ident, :on_sp, :on_ident ]
18
+ expect( matchdata.tokens.map {|tok| tok[1]} ).to eq([ :on_ident, :on_sp, :on_ident ])
29
19
  end
30
20
 
31
21
  end
@@ -1,23 +1,13 @@
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
- require 'spec/lib/helpers'
15
6
  require 'inversion/parser'
16
7
 
17
8
  describe Inversion::Parser do
18
9
 
19
10
  before( :all ) do
20
- setup_logging( :fatal )
21
11
  Inversion::Template::Tag.load_all
22
12
  end
23
13
 
@@ -28,14 +18,14 @@ describe Inversion::Parser do
28
18
  it "parses a string with no PIs as a single text node" do
29
19
  result = Inversion::Parser.new( @template ).parse( "render unto Caesar" )
30
20
 
31
- result.should have( 1 ).member
32
- result.first.should be_a( Inversion::Template::TextNode )
33
- result.first.body.should == 'render unto Caesar'
21
+ expect( result.size ).to eq( 1 )
22
+ expect( result.first ).to be_a( Inversion::Template::TextNode )
23
+ expect( result.first.body ).to eq( 'render unto Caesar' )
34
24
  end
35
25
 
36
26
  it "parses an empty string as a empty tree" do
37
27
  result = Inversion::Parser.new( @template ).parse( "" )
38
- result.should be_empty
28
+ expect( result ).to be_empty
39
29
  end
40
30
 
41
31
  it "raises a ParseError on mismatched tag brackets" do
@@ -47,47 +37,47 @@ describe Inversion::Parser do
47
37
  it "parses a string with a single 'attr' tag as a single AttrTag node" do
48
38
  result = Inversion::Parser.new( @template ).parse( "<?attr foo ?>" )
49
39
 
50
- result.should have( 1 ).member
51
- result.first.should be_a( Inversion::Template::AttrTag )
52
- result.first.body.should == 'foo'
40
+ expect( result.size ).to eq( 1 )
41
+ expect( result.first ).to be_a( Inversion::Template::AttrTag )
42
+ expect( result.first.body ).to eq( 'foo' )
53
43
  end
54
44
 
55
45
  it "parses a single 'attr' tag surrounded by plain text" do
56
46
  result = Inversion::Parser.new( @template ).parse( "beginning<?attr foo ?>end" )
57
47
 
58
- result.should have( 3 ).members
59
- result[0].should be_a( Inversion::Template::TextNode )
60
- result[1].should be_a( Inversion::Template::AttrTag )
61
- result[1].body.should == 'foo'
62
- result[2].should be_a( Inversion::Template::TextNode )
48
+ expect( result.size ).to eq( 3 )
49
+ expect( result[0] ).to be_a( Inversion::Template::TextNode )
50
+ expect( result[1] ).to be_a( Inversion::Template::AttrTag )
51
+ expect( result[1].body ).to eq( 'foo' )
52
+ expect( result[2] ).to be_a( Inversion::Template::TextNode )
63
53
  end
64
54
 
65
55
  it "ignores unknown tags by default" do
66
56
  result = Inversion::Parser.new( @template ).parse( "Text <?hoooowhat ?>" )
67
57
 
68
- result.should have( 2 ).members
69
- result[0].should be_a( Inversion::Template::TextNode )
70
- result[1].should be_a( Inversion::Template::TextNode )
71
- result[1].body.should == '<?hoooowhat ?>'
58
+ expect( result.size ).to eq( 2 )
59
+ expect( result[0] ).to be_a( Inversion::Template::TextNode )
60
+ expect( result[1] ).to be_a( Inversion::Template::TextNode )
61
+ expect( result[1].body ).to eq( '<?hoooowhat ?>' )
72
62
  end
73
63
 
74
64
  it "can raise exceptions on unknown tags" do
75
65
  expect {
76
66
  Inversion::Parser.new( @template, :ignore_unknown_tags => false ).
77
67
  parse( "Text <?hoooowhat ?>" )
78
- }.to raise_exception( Inversion::ParseError, /unknown tag/i )
68
+ }.to raise_error( Inversion::ParseError, /unknown tag/i )
79
69
  end
80
70
 
81
71
  it "can raise exceptions on unclosed (nested) tags" do
82
72
  expect {
83
73
  Inversion::Parser.new( @template ).parse( "Text <?attr something <?attr something_else ?>" )
84
- }.to raise_exception( Inversion::ParseError, /unclosed or nested tag/i )
74
+ }.to raise_error( Inversion::ParseError, /unclosed or nested tag/i )
85
75
  end
86
76
 
87
77
  it "can raise exceptions on unclosed (eof) tags" do
88
78
  expect {
89
79
  Inversion::Parser.new( @template ).parse( "Text <?hoooowhat" )
90
- }.to raise_exception( Inversion::ParseError, /unclosed tag/i )
80
+ }.to raise_error( Inversion::ParseError, /unclosed tag/i )
91
81
  end
92
82
 
93
83
 
@@ -103,41 +93,41 @@ describe Inversion::Parser do
103
93
 
104
94
  @state << open_tag << end_tag
105
95
 
106
- @state.tree.should == [ open_tag, end_tag ]
96
+ expect( @state.tree ).to eq( [ open_tag, end_tag ] )
107
97
  end
108
98
 
109
99
  it "knows it is well-formed if there are no open tags" do
110
100
  @state << Inversion::Template::ForTag.new( 'foo in bar' )
111
- @state.should_not be_well_formed
101
+ expect( @state ).to_not be_well_formed
112
102
 
113
103
  @state << Inversion::Template::ForTag.new( 'foo in bar' )
114
- @state.should_not be_well_formed
104
+ expect( @state ).to_not be_well_formed
115
105
 
116
106
  @state << Inversion::Template::EndTag.new( 'for' )
117
- @state.should_not be_well_formed
107
+ expect( @state ).to_not be_well_formed
118
108
 
119
109
  @state << Inversion::Template::EndTag.new( 'for' )
120
- @state.should be_well_formed
110
+ expect( @state ).to be_well_formed
121
111
  end
122
112
 
123
113
  it "can pop a container tag off of the current context" do
124
114
  container = Inversion::Template::ForTag.new( 'foo in bar' )
125
115
  @state << container
126
- @state.pop.should == container
116
+ expect( @state.pop ).to eq( container )
127
117
  end
128
118
 
129
119
  it "calls the #after_appending hook of container nodes when they're popped" do
130
- container = mock( "container tag", :before_appending => false, :is_container? => true )
120
+ container = double( "container tag", :before_appending => false, :is_container? => true )
131
121
  @state << container
132
122
 
133
- container.should_receive( :after_appending ).with( @state )
123
+ expect( container ).to receive( :after_appending ).with( @state )
134
124
  @state.pop
135
125
  end
136
126
 
137
127
  it "raises an error when popping if there is no container tag" do
138
128
  expect {
139
129
  @state.pop
140
- }.to raise_exception( Inversion::ParseError, /unbalanced end: no open tag/i )
130
+ }.to raise_error( Inversion::ParseError, /unbalanced end: no open tag/i )
141
131
  end
142
132
 
143
133
  it "raises an error when the tree is fetched if it isn't well-formed" do
@@ -146,19 +136,19 @@ describe Inversion::Parser do
146
136
 
147
137
  expect {
148
138
  @state.tree
149
- }.to raise_exception( Inversion::ParseError, /unclosed/i )
139
+ }.to raise_error( Inversion::ParseError, /unclosed/i )
150
140
  end
151
141
 
152
142
  it "calls the #before_appending callback on nodes that are appended to it" do
153
- node = mock( "node", :is_container? => false, :after_appending => nil )
154
- node.should_receive( :before_appending ).with( @state )
143
+ node = double( "node", :is_container? => false, :after_appending => nil )
144
+ expect( node ).to receive( :before_appending ).with( @state )
155
145
 
156
146
  @state << node
157
147
  end
158
148
 
159
149
  it "calls the #after_appending callback on nodes that are appended to it" do
160
- node = mock( "node", :is_container? => false, :before_appending => nil )
161
- node.should_receive( :after_appending ).with( @state )
150
+ node = double( "node", :is_container? => false, :before_appending => nil )
151
+ expect( node ).to receive( :after_appending ).with( @state )
162
152
 
163
153
  @state << node
164
154
  end
@@ -2,43 +2,28 @@
2
2
  # encoding: utf-8
3
3
  # vim: set noet nosta sw=4 ts=4 :
4
4
 
5
- BEGIN {
6
- require 'pathname'
7
- basedir = Pathname( __FILE__ ).dirname.parent.parent
8
- libdir = basedir + 'lib'
5
+ require_relative '../helpers'
9
6
 
10
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
11
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
12
- }
13
-
14
- require 'rspec'
15
-
16
- require 'spec/lib/helpers'
17
7
  require 'inversion/renderstate'
18
8
  require 'inversion/template/attrtag'
19
9
  require 'inversion/template/textnode'
10
+ require 'inversion/template/fragmenttag'
11
+ require 'inversion/template/subscribetag'
12
+ require 'inversion/template/publishtag'
20
13
 
21
14
  describe Inversion::RenderState do
22
15
 
23
- before( :all ) do
24
- setup_logging( :fatal )
25
- end
26
-
27
- after( :all ) do
28
- reset_logging()
29
- end
30
-
31
16
 
32
17
  it "provides access to the block it was constructed with if there was one" do
33
18
  block = Proc.new {}
34
19
  state = Inversion::RenderState.new( &block )
35
- state.block.should equal( block )
20
+ expect( state.block ).to equal( block )
36
21
  end
37
22
 
38
23
  it "can evaluate code in the context of itself" do
39
24
  attributes = { :foot => "in mouth", :bear => "in woods" }
40
25
  state = Inversion::RenderState.new( attributes )
41
- state.eval( "foot" ).should == 'in mouth'
26
+ expect( state.eval( "foot" ) ).to eq( 'in mouth' )
42
27
  end
43
28
 
44
29
 
@@ -49,11 +34,11 @@ describe Inversion::RenderState do
49
34
 
50
35
  state = Inversion::RenderState.new( attributes )
51
36
 
52
- state.scope.__locals__.should_not equal( attributes )
53
- state.scope[:foot].should == "in mouth"
54
- state.scope[:foot].should_not equal( attributes[:foot] )
55
- state.scope[:bear].should == "in woods"
56
- state.scope[:bear].should_not equal( attributes[:bear] )
37
+ expect( state.scope.__locals__ ).to_not equal( attributes )
38
+ expect( state.scope[:foot] ).to eq( "in mouth" )
39
+ expect( state.scope[:foot] ).to_not equal( attributes[:foot] )
40
+ expect( state.scope[:bear] ).to eq( "in woods" )
41
+ expect( state.scope[:bear] ).to_not equal( attributes[:bear] )
57
42
  end
58
43
 
59
44
  it "preserves tainted status when copying its attributes" do
@@ -62,7 +47,7 @@ describe Inversion::RenderState do
62
47
 
63
48
  state = Inversion::RenderState.new( attributes )
64
49
 
65
- state.scope[:danger].should be_tainted()
50
+ expect( state.scope[:danger] ).to be_tainted()
66
51
  end
67
52
 
68
53
  it "preserves singleton methods on attribute objects when copying" do
@@ -71,7 +56,7 @@ describe Inversion::RenderState do
71
56
 
72
57
  state = Inversion::RenderState.new( :foo => obj )
73
58
 
74
- state.scope[:foo].singleton_methods.map( &:to_sym ).should include( :foo )
59
+ expect( state.scope[:foo].singleton_methods.map( &:to_sym ) ).to include( :foo )
75
60
  end
76
61
 
77
62
  it "preserves frozen status when copying its attributes" do
@@ -80,7 +65,7 @@ describe Inversion::RenderState do
80
65
 
81
66
  state = Inversion::RenderState.new( attributes )
82
67
 
83
- state.scope[:danger].should be_frozen()
68
+ expect( state.scope[:danger] ).to be_frozen()
84
69
  end
85
70
 
86
71
  it "can override its attributes for the duration of a block" do
@@ -89,11 +74,11 @@ describe Inversion::RenderState do
89
74
  state = Inversion::RenderState.new( attributes )
90
75
 
91
76
  state.with_attributes( :foot => 'ball' ) do
92
- state.foot.should == 'ball'
93
- state.bear.should == 'in woods'
77
+ expect( state.foot ).to eq( 'ball' )
78
+ expect( state.bear ).to eq( 'in woods' )
94
79
  end
95
80
 
96
- state.scope[:foot].should == 'in mouth'
81
+ expect( state.scope[:foot] ).to eq( 'in mouth' )
97
82
  end
98
83
 
99
84
 
@@ -108,7 +93,7 @@ describe Inversion::RenderState do
108
93
  end
109
94
  }.to raise_error()
110
95
 
111
- state.scope[:foot].should == 'in mouth'
96
+ expect( state.scope[:foot] ).to eq( 'in mouth' )
112
97
  end
113
98
 
114
99
 
@@ -122,12 +107,12 @@ describe Inversion::RenderState do
122
107
 
123
108
  it "provides accessor methods for its attributes" do
124
109
  state = Inversion::RenderState.new( :bar => :the_attribute_value )
125
- state.scope.bar.should == :the_attribute_value
110
+ expect( state.scope.bar ).to eq( :the_attribute_value )
126
111
  end
127
112
 
128
113
  it "doesn't error if an accessor for a non-existant attribute is called" do
129
114
  state = Inversion::RenderState.new( :bar => :the_attribute_value )
130
- state.scope.foo.should be_nil()
115
+ expect( state.scope.foo ).to be_nil()
131
116
  end
132
117
 
133
118
  end
@@ -142,11 +127,11 @@ describe Inversion::RenderState do
142
127
 
143
128
  thirdstate = state.merge( anotherstate )
144
129
 
145
- thirdstate.attributes.should == {
130
+ expect( thirdstate.attributes ).to eq({
146
131
  :bar => :the_bar_value,
147
132
  :foo => :the_foo_value
148
- }
149
- thirdstate.options.should include(
133
+ })
134
+ expect( thirdstate.options ).to include(
150
135
  :debugging_comments => true,
151
136
  :on_render_error => :propagate
152
137
  )
@@ -162,7 +147,7 @@ describe Inversion::RenderState do
162
147
  end
163
148
 
164
149
  it "provides a mechanism for storing tag state for the current render" do
165
- @renderstate.tag_data.should be_a( Hash )
150
+ expect( @renderstate.tag_data ).to be_a( Hash )
166
151
  end
167
152
 
168
153
  it "can override tag state for the duration of a block" do
@@ -170,14 +155,14 @@ describe Inversion::RenderState do
170
155
  @renderstate.tag_data[ :colorado ] = 'fine fishing'
171
156
 
172
157
  @renderstate.with_tag_data( :alaska => 'good fishing' ) do
173
- @renderstate.tag_data[:alaska].should == 'good fishing'
158
+ expect( @renderstate.tag_data[:alaska] ).to eq( 'good fishing' )
174
159
  @renderstate.tag_data[:alaska] = 'blueberry bear poop'
175
160
  @renderstate.tag_data[:colorado] = 'Boulder has hippies'
176
161
  end
177
162
 
178
- @renderstate.tag_data.should_not have_key( :alaska )
179
- @renderstate.tag_data[:montana].should == 'excellent fishing'
180
- @renderstate.tag_data[:colorado].should == 'fine fishing'
163
+ expect( @renderstate.tag_data ).to_not have_key( :alaska )
164
+ expect( @renderstate.tag_data[:montana] ).to eq( 'excellent fishing' )
165
+ expect( @renderstate.tag_data[:colorado] ).to eq( 'fine fishing' )
181
166
  end
182
167
 
183
168
  end
@@ -194,11 +179,11 @@ describe Inversion::RenderState do
194
179
  rval = state.with_destination( newdest ) do
195
180
  state << node
196
181
  end
197
- rval.should equal( newdest )
182
+ expect( rval ).to equal( newdest )
198
183
 
199
- newdest.should have( 1 ).member
200
- newdest.should include( 'New!' )
201
- state.destination.should equal( original_dest )
184
+ expect( newdest.size ).to eq( 1 )
185
+ expect( newdest ).to include( 'New!' )
186
+ expect( state.destination ).to equal( original_dest )
202
187
  end
203
188
 
204
189
  it "restores the original destination if the block raises an exception" do
@@ -212,7 +197,7 @@ describe Inversion::RenderState do
212
197
  end
213
198
  }.to raise_error()
214
199
 
215
- state.destination.should equal( original_dest )
200
+ expect( state.destination ).to equal( original_dest )
216
201
  end
217
202
 
218
203
  it "raises an error if #with_destination is called without a block" do
@@ -232,7 +217,7 @@ describe Inversion::RenderState do
232
217
 
233
218
  state << node
234
219
 
235
- state.to_s.should == '<!-- Attr: { template.foo } -->'
220
+ expect( state.to_s ).to eq( '<!-- Attr: { template.foo } -->' )
236
221
  end
237
222
 
238
223
  it "doesn't add a debugging comment when appending a node if debugging comments are disabled" do
@@ -241,7 +226,7 @@ describe Inversion::RenderState do
241
226
 
242
227
  state << node
243
228
 
244
- state.to_s.should == ''
229
+ expect( state.to_s ).to eq( '' )
245
230
  end
246
231
 
247
232
  end
@@ -255,7 +240,7 @@ describe Inversion::RenderState do
255
240
 
256
241
  state << node
257
242
 
258
- state.to_s.should == ''
243
+ expect( state.to_s ).to eq( '' )
259
244
  end
260
245
 
261
246
  it "adds a comment for errors while rendering appended nodes in 'comment' mode" do
@@ -264,7 +249,7 @@ describe Inversion::RenderState do
264
249
 
265
250
  state << node
266
251
 
267
- state.to_s.should == "<!-- NoMethodError: undefined method `klang' for nil:NilClass -->"
252
+ expect( state.to_s ).to eq( "<!-- NoMethodError: undefined method `klang' for nil:NilClass -->" )
268
253
  end
269
254
 
270
255
  it "includes a backtrace when rendering errors in 'comment' mode with 'debugging_comments' enabled" do
@@ -274,8 +259,8 @@ describe Inversion::RenderState do
274
259
  state << node
275
260
  output = state.to_s
276
261
 
277
- output.should include( "<!-- NoMethodError: undefined method `klang' for nil:NilClass" )
278
- output.should include( "#{__FILE__}:#{__LINE__ - 4}" )
262
+ expect( output ).to include( "<!-- NoMethodError: undefined method `klang' for nil:NilClass" )
263
+ expect( output ).to include( "#{__FILE__}:#{__LINE__ - 4}" )
279
264
  end
280
265
 
281
266
  it "re-raises errors while rendering appended nodes in 'propagate' mode" do
@@ -302,8 +287,8 @@ describe Inversion::RenderState do
302
287
  end
303
288
  }.to_not raise_error()
304
289
 
305
- state.to_s.should =~ /yum, i eat nomethoderror/i
306
- state.errhandler.should equal( defhandler )
290
+ expect( state.to_s ).to match( /yum, i eat nomethoderror/i )
291
+ expect( state.errhandler ).to equal( defhandler )
307
292
  end
308
293
 
309
294
  it "raises an exception if the error handler is set to something that doesn't respond to #call" do
@@ -332,7 +317,7 @@ describe Inversion::RenderState do
332
317
  end
333
318
 
334
319
  it "doesn't have any subscriptions by default" do
335
- @state.subscriptions.should == {}
320
+ expect( @state.subscriptions ).to eq( {} )
336
321
  end
337
322
 
338
323
  it "allows an object to subscribe to node publications" do
@@ -340,8 +325,8 @@ describe Inversion::RenderState do
340
325
 
341
326
  @state.subscribe( :the_key, subscriber )
342
327
 
343
- @state.subscriptions.should have( 1 ).member
344
- @state.subscriptions[ :the_key ].should == [ subscriber ]
328
+ expect( @state.subscriptions.size ).to eq( 1 )
329
+ expect( @state.subscriptions[:the_key] ).to eq( [subscriber] )
345
330
  end
346
331
 
347
332
  end
@@ -354,19 +339,19 @@ describe Inversion::RenderState do
354
339
  end
355
340
 
356
341
  it "allows rendering to be explicitly enabled and disabled" do
357
- @state.rendering_enabled?.should be_true()
342
+ expect( @state.rendering_enabled? ).to be_truthy()
358
343
  @state.disable_rendering
359
- @state.rendering_enabled?.should be_false()
344
+ expect( @state.rendering_enabled? ).to be_falsey()
360
345
  @state.enable_rendering
361
- @state.rendering_enabled?.should be_true()
346
+ expect( @state.rendering_enabled? ).to be_truthy()
362
347
  end
363
348
 
364
349
  it "allows rendering to be toggled" do
365
- @state.rendering_enabled?.should be_true()
350
+ expect( @state.rendering_enabled? ).to be_truthy()
366
351
  @state.toggle_rendering
367
- @state.rendering_enabled?.should be_false()
352
+ expect( @state.rendering_enabled? ).to be_falsey()
368
353
  @state.toggle_rendering
369
- @state.rendering_enabled?.should be_true()
354
+ expect( @state.rendering_enabled? ).to be_truthy()
370
355
  end
371
356
 
372
357
  it "doesn't render nodes that are appended to it if rendering is disabled" do
@@ -376,7 +361,7 @@ describe Inversion::RenderState do
376
361
  @state.enable_rendering
377
362
  @state << Inversion::Template::TextNode.new( "after" )
378
363
 
379
- @state.to_s.should == 'beforeafter'
364
+ expect( @state.to_s ).to eq( 'beforeafter' )
380
365
  end
381
366
 
382
367
  end
@@ -390,7 +375,7 @@ describe Inversion::RenderState do
390
375
 
391
376
 
392
377
  it "knows how many floating-point seconds have passed since it was created" do
393
- @state.time_elapsed.should be_a( Float )
378
+ expect( @state.time_elapsed ).to be_a( Float )
394
379
  end
395
380
 
396
381
  end
@@ -409,7 +394,7 @@ describe Inversion::RenderState do
409
394
  state << Inversion::Template::AttrTag.new( 'good_doggie' )
410
395
  state << Inversion::Template::AttrTag.new( 'little' )
411
396
 
412
- state.to_s.encoding.should be( Encoding::UTF_8 )
397
+ expect( state.to_s.encoding ).to be( Encoding::UTF_8 )
413
398
  end
414
399
 
415
400
  it "replaces characters with undefined conversions instead of raising an encoding error" do
@@ -426,7 +411,76 @@ describe Inversion::RenderState do
426
411
  state << Inversion::Template::AttrTag.new( 'okay' )
427
412
  state << Inversion::Template::AttrTag.new( 'bogus' )
428
413
 
429
- state.to_s.encoding.should be( Encoding::UTF_8 )
414
+ expect( state.to_s.encoding ).to be( Encoding::UTF_8 )
415
+ end
416
+
417
+ end
418
+
419
+
420
+ describe "fragments" do
421
+
422
+ before( :each ) do
423
+ @state = Inversion::RenderState.new
424
+ end
425
+
426
+
427
+ it "can be set to an Array of rendered nodes" do
428
+ subscribe_node = Inversion::Template::SubscribeTag.new( 'brand' )
429
+ @state << subscribe_node
430
+
431
+ publish_node = Inversion::Template::PublishTag.new( 'brand' )
432
+ publish_node << Inversion::Template::TextNode.new( 'Acme' )
433
+ @state << publish_node
434
+
435
+ @state.add_fragment( :title, "Welcome to the ", subscribe_node, " website!" )
436
+
437
+ expect( @state.fragments ).to be_a( Hash )
438
+ expect( @state.fragments[:title] ).to eq([ "Welcome to the ", subscribe_node, " website!" ])
439
+ end
440
+
441
+
442
+ it "can be returned as a rendered Hash" do
443
+ subscribe_node = Inversion::Template::SubscribeTag.new( 'brand' )
444
+ @state << subscribe_node
445
+
446
+ publish_node = Inversion::Template::PublishTag.new( 'brand' )
447
+ publish_node << Inversion::Template::TextNode.new( 'Acme' )
448
+ @state << publish_node
449
+
450
+ @state.add_fragment( :title, "Welcome to the ", subscribe_node, " website!" )
451
+
452
+ expect( @state.rendered_fragments ).to be_a( Hash )
453
+ expect( @state.rendered_fragments[:title] ).to eq( "Welcome to the Acme website!" )
454
+ end
455
+
456
+
457
+ it "acts like a default if an attribute isn't set" do
458
+ node = Inversion::Template::FragmentTag.new( 'pork' )
459
+ node << Inversion::Template::AttrTag.new( 'bool' )
460
+ node << Inversion::Template::TextNode.new( ' please!' )
461
+
462
+ @state.scope[ :bool ] = 'yes'
463
+ @state << node
464
+ @state << Inversion::Template::TextNode.new( '--> ' )
465
+ @state << Inversion::Template::AttrTag.new( 'pork' )
466
+ @state << Inversion::Template::TextNode.new( ' <--' )
467
+
468
+ expect( @state.to_s ).to eq( '--> yes please! <--' )
469
+ end
470
+
471
+
472
+ it "don't override explicitly-set attributes" do
473
+ node = Inversion::Template::FragmentTag.new( 'pork' )
474
+ node << Inversion::Template::AttrTag.new( 'bool' )
475
+ node << Inversion::Template::TextNode.new( ' please!' )
476
+
477
+ @state.scope[ :pork ] = 'pie'
478
+ @state << node
479
+ @state << Inversion::Template::TextNode.new( '--> ' )
480
+ @state << Inversion::Template::AttrTag.new( 'pork' )
481
+ @state << Inversion::Template::TextNode.new( ' <--' )
482
+
483
+ expect( @state.to_s ).to eq( '--> pie <--' )
430
484
  end
431
485
 
432
486
  end