arrow 1.0.7

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 (198) hide show
  1. data/ChangeLog +1590 -0
  2. data/LICENSE +28 -0
  3. data/README +75 -0
  4. data/Rakefile +366 -0
  5. data/Rakefile.local +63 -0
  6. data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
  7. data/data/arrow/applets/args.rb +50 -0
  8. data/data/arrow/applets/config.rb +55 -0
  9. data/data/arrow/applets/error.rb +63 -0
  10. data/data/arrow/applets/files.rb +46 -0
  11. data/data/arrow/applets/inspect.rb +46 -0
  12. data/data/arrow/applets/nosuchapplet.rb +31 -0
  13. data/data/arrow/applets/status.rb +92 -0
  14. data/data/arrow/applets/test.rb +133 -0
  15. data/data/arrow/applets/tutorial/counter.rb +96 -0
  16. data/data/arrow/applets/tutorial/dingus.rb +67 -0
  17. data/data/arrow/applets/tutorial/hello.rb +34 -0
  18. data/data/arrow/applets/tutorial/hello2.rb +73 -0
  19. data/data/arrow/applets/tutorial/imgtext.rb +90 -0
  20. data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
  21. data/data/arrow/applets/tutorial/index.rb +36 -0
  22. data/data/arrow/applets/tutorial/logo.rb +98 -0
  23. data/data/arrow/applets/tutorial/memcache.rb +61 -0
  24. data/data/arrow/applets/tutorial/missing.rb +37 -0
  25. data/data/arrow/applets/tutorial/protected.rb +100 -0
  26. data/data/arrow/applets/tutorial/redirector.rb +52 -0
  27. data/data/arrow/applets/tutorial/rndimages.rb +159 -0
  28. data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
  29. data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
  30. data/data/arrow/applets/tutorial/superhello.rb +72 -0
  31. data/data/arrow/applets/tutorial/timeclock.rb +78 -0
  32. data/data/arrow/applets/view-applet.rb +123 -0
  33. data/data/arrow/applets/view-template.rb +85 -0
  34. data/data/arrow/applets/wiki.rb +274 -0
  35. data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
  36. data/data/arrow/templates/applet-status.tmpl +153 -0
  37. data/data/arrow/templates/args-display.tmpl +120 -0
  38. data/data/arrow/templates/config/display-table.tmpl +36 -0
  39. data/data/arrow/templates/config/display.tmpl +36 -0
  40. data/data/arrow/templates/counter-deleted.tmpl +33 -0
  41. data/data/arrow/templates/counter.tmpl +59 -0
  42. data/data/arrow/templates/dingus.tmpl +55 -0
  43. data/data/arrow/templates/enumtable.tmpl +8 -0
  44. data/data/arrow/templates/error-display.tmpl +92 -0
  45. data/data/arrow/templates/filemap.tmpl +89 -0
  46. data/data/arrow/templates/hello-world-src.tmpl +34 -0
  47. data/data/arrow/templates/hello-world.tmpl +60 -0
  48. data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
  49. data/data/arrow/templates/imgtext/form.tmpl +70 -0
  50. data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
  51. data/data/arrow/templates/imgtext/reload.tmpl +55 -0
  52. data/data/arrow/templates/inspect/display.tmpl +80 -0
  53. data/data/arrow/templates/loginform.tmpl +64 -0
  54. data/data/arrow/templates/logout.tmpl +32 -0
  55. data/data/arrow/templates/memcache/display.tmpl +41 -0
  56. data/data/arrow/templates/navbar.incl +27 -0
  57. data/data/arrow/templates/nosuchapplet.tmpl +32 -0
  58. data/data/arrow/templates/printsource.tmpl +35 -0
  59. data/data/arrow/templates/protected.tmpl +36 -0
  60. data/data/arrow/templates/rndimages.tmpl +38 -0
  61. data/data/arrow/templates/service-response.tmpl +13 -0
  62. data/data/arrow/templates/sharenotes/display.tmpl +38 -0
  63. data/data/arrow/templates/status.tmpl +120 -0
  64. data/data/arrow/templates/templateviewer.tmpl +43 -0
  65. data/data/arrow/templates/test/harness.tmpl +57 -0
  66. data/data/arrow/templates/test/list.tmpl +48 -0
  67. data/data/arrow/templates/test/problem.tmpl +42 -0
  68. data/data/arrow/templates/tutorial/index.tmpl +37 -0
  69. data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
  70. data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
  71. data/data/arrow/templates/view-applet.tmpl +40 -0
  72. data/data/arrow/templates/view-template.tmpl +83 -0
  73. data/data/arrow/templates/wiki/formerror.tmpl +47 -0
  74. data/data/arrow/templates/wiki/markup_help.incl +6 -0
  75. data/data/arrow/templates/wiki/new.tmpl +56 -0
  76. data/data/arrow/templates/wiki/new_system.tmpl +122 -0
  77. data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
  78. data/data/arrow/templates/wiki/show.tmpl +34 -0
  79. data/docs/manual/layouts/default.page +43 -0
  80. data/docs/manual/lib/api-filter.rb +81 -0
  81. data/docs/manual/lib/editorial-filter.rb +64 -0
  82. data/docs/manual/lib/examples-filter.rb +244 -0
  83. data/docs/manual/lib/links-filter.rb +117 -0
  84. data/lib/apache/fakerequest.rb +448 -0
  85. data/lib/apache/logger.rb +33 -0
  86. data/lib/arrow.rb +51 -0
  87. data/lib/arrow/acceptparam.rb +207 -0
  88. data/lib/arrow/applet.rb +725 -0
  89. data/lib/arrow/appletmixins.rb +218 -0
  90. data/lib/arrow/appletregistry.rb +590 -0
  91. data/lib/arrow/applettestcase.rb +503 -0
  92. data/lib/arrow/broker.rb +255 -0
  93. data/lib/arrow/cache.rb +176 -0
  94. data/lib/arrow/config-loaders/yaml.rb +75 -0
  95. data/lib/arrow/config.rb +615 -0
  96. data/lib/arrow/constants.rb +24 -0
  97. data/lib/arrow/cookie.rb +359 -0
  98. data/lib/arrow/cookieset.rb +108 -0
  99. data/lib/arrow/dispatcher.rb +368 -0
  100. data/lib/arrow/dispatcherloader.rb +50 -0
  101. data/lib/arrow/exceptions.rb +61 -0
  102. data/lib/arrow/fallbackhandler.rb +48 -0
  103. data/lib/arrow/formvalidator.rb +631 -0
  104. data/lib/arrow/htmltokenizer.rb +343 -0
  105. data/lib/arrow/logger.rb +488 -0
  106. data/lib/arrow/logger/apacheoutputter.rb +69 -0
  107. data/lib/arrow/logger/arrayoutputter.rb +63 -0
  108. data/lib/arrow/logger/coloroutputter.rb +111 -0
  109. data/lib/arrow/logger/fileoutputter.rb +96 -0
  110. data/lib/arrow/logger/htmloutputter.rb +54 -0
  111. data/lib/arrow/logger/outputter.rb +123 -0
  112. data/lib/arrow/mixins.rb +425 -0
  113. data/lib/arrow/monkeypatches.rb +94 -0
  114. data/lib/arrow/object.rb +117 -0
  115. data/lib/arrow/path.rb +196 -0
  116. data/lib/arrow/service.rb +447 -0
  117. data/lib/arrow/session.rb +289 -0
  118. data/lib/arrow/session/dbstore.rb +100 -0
  119. data/lib/arrow/session/filelock.rb +160 -0
  120. data/lib/arrow/session/filestore.rb +132 -0
  121. data/lib/arrow/session/id.rb +98 -0
  122. data/lib/arrow/session/lock.rb +253 -0
  123. data/lib/arrow/session/md5id.rb +42 -0
  124. data/lib/arrow/session/nulllock.rb +42 -0
  125. data/lib/arrow/session/posixlock.rb +166 -0
  126. data/lib/arrow/session/sha1id.rb +54 -0
  127. data/lib/arrow/session/store.rb +366 -0
  128. data/lib/arrow/session/usertrackid.rb +52 -0
  129. data/lib/arrow/spechelpers.rb +73 -0
  130. data/lib/arrow/template.rb +713 -0
  131. data/lib/arrow/template/attr.rb +31 -0
  132. data/lib/arrow/template/call.rb +31 -0
  133. data/lib/arrow/template/comment.rb +33 -0
  134. data/lib/arrow/template/container.rb +118 -0
  135. data/lib/arrow/template/else.rb +41 -0
  136. data/lib/arrow/template/elsif.rb +44 -0
  137. data/lib/arrow/template/escape.rb +53 -0
  138. data/lib/arrow/template/export.rb +87 -0
  139. data/lib/arrow/template/for.rb +145 -0
  140. data/lib/arrow/template/if.rb +78 -0
  141. data/lib/arrow/template/import.rb +119 -0
  142. data/lib/arrow/template/include.rb +206 -0
  143. data/lib/arrow/template/iterator.rb +208 -0
  144. data/lib/arrow/template/nodes.rb +734 -0
  145. data/lib/arrow/template/parser.rb +571 -0
  146. data/lib/arrow/template/prettyprint.rb +53 -0
  147. data/lib/arrow/template/render.rb +191 -0
  148. data/lib/arrow/template/selectlist.rb +94 -0
  149. data/lib/arrow/template/set.rb +87 -0
  150. data/lib/arrow/template/timedelta.rb +81 -0
  151. data/lib/arrow/template/unless.rb +78 -0
  152. data/lib/arrow/template/urlencode.rb +51 -0
  153. data/lib/arrow/template/yield.rb +139 -0
  154. data/lib/arrow/templatefactory.rb +125 -0
  155. data/lib/arrow/testcase.rb +567 -0
  156. data/lib/arrow/transaction.rb +608 -0
  157. data/rake/191_compat.rb +26 -0
  158. data/rake/dependencies.rb +76 -0
  159. data/rake/documentation.rb +114 -0
  160. data/rake/helpers.rb +502 -0
  161. data/rake/hg.rb +282 -0
  162. data/rake/manual.rb +787 -0
  163. data/rake/packaging.rb +129 -0
  164. data/rake/publishing.rb +278 -0
  165. data/rake/style.rb +62 -0
  166. data/rake/svn.rb +668 -0
  167. data/rake/testing.rb +187 -0
  168. data/rake/verifytask.rb +64 -0
  169. data/spec/arrow/acceptparam_spec.rb +157 -0
  170. data/spec/arrow/applet_spec.rb +575 -0
  171. data/spec/arrow/appletmixins_spec.rb +409 -0
  172. data/spec/arrow/appletregistry_spec.rb +294 -0
  173. data/spec/arrow/broker_spec.rb +153 -0
  174. data/spec/arrow/config_spec.rb +224 -0
  175. data/spec/arrow/cookieset_spec.rb +164 -0
  176. data/spec/arrow/dispatcher_spec.rb +137 -0
  177. data/spec/arrow/dispatcherloader_spec.rb +65 -0
  178. data/spec/arrow/formvalidator_spec.rb +781 -0
  179. data/spec/arrow/logger_spec.rb +346 -0
  180. data/spec/arrow/mixins_spec.rb +120 -0
  181. data/spec/arrow/service_spec.rb +645 -0
  182. data/spec/arrow/session_spec.rb +121 -0
  183. data/spec/arrow/template/iterator_spec.rb +222 -0
  184. data/spec/arrow/templatefactory_spec.rb +185 -0
  185. data/spec/arrow/transaction_spec.rb +319 -0
  186. data/spec/arrow_spec.rb +37 -0
  187. data/spec/lib/appletmatchers.rb +281 -0
  188. data/spec/lib/constants.rb +77 -0
  189. data/spec/lib/helpers.rb +41 -0
  190. data/spec/lib/matchers.rb +44 -0
  191. data/tests/cookie.tests.rb +310 -0
  192. data/tests/path.tests.rb +157 -0
  193. data/tests/session.tests.rb +111 -0
  194. data/tests/session_id.tests.rb +82 -0
  195. data/tests/session_lock.tests.rb +191 -0
  196. data/tests/session_store.tests.rb +53 -0
  197. data/tests/template.tests.rb +1360 -0
  198. metadata +339 -0
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Unit test for the Arrow::Session::Store class
4
+ # $Id$
5
+ #
6
+ # Copyright (c) 2003 RubyCrafters, LLC. Most rights reserved.
7
+ #
8
+ # This work is licensed under the Creative Commons Attribution-ShareAlike
9
+ # License. To view a copy of this license, visit
10
+ # http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative
11
+ # Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
12
+ #
13
+ #
14
+
15
+ unless defined? Arrow::TestCase
16
+ testsdir = File.dirname( File.expand_path(__FILE__) )
17
+ basedir = File.dirname( testsdir )
18
+ $LOAD_PATH.unshift "#{basedir}/lib" unless
19
+ $LOAD_PATH.include?( "#{basedir}/lib" )
20
+ $LOAD_PATH.unshift "#{basedir}/tests/lib" unless
21
+ $LOAD_PATH.include?( "#{basedir}/tests/lib" )
22
+
23
+ require 'arrow/testcase'
24
+ end
25
+
26
+
27
+ ### Collection of tests for the Arrow::Session::Store class.
28
+ class Arrow::SessionStoreTestCase < Arrow::TestCase
29
+
30
+ SessionDir = File.dirname( File.expand_path(__FILE__) ) + "/sessions"
31
+ DefaultStoreUri = "file:#{SessionDir}"
32
+ DefaultStoreType = 'Arrow::Session::FileStore'
33
+
34
+ #################################################################
35
+ ### T E S T S
36
+ #################################################################
37
+
38
+ ### Instance test
39
+ def test_00_Class
40
+ printTestHeader "Session::Store: Class"
41
+
42
+ assert_block( "Arrow::Session::Store defined?" ) { defined? Arrow::Session::Store }
43
+ assert_instance_of Class, Arrow::Session::Store
44
+ end
45
+
46
+
47
+ ### Test storage of simple data
48
+ def test_10_Store
49
+
50
+ end
51
+
52
+ end
53
+
@@ -0,0 +1,1360 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Unit test for the Arrow::Template class
4
+ # $Id$
5
+ #
6
+ # Copyright (c) 2003-2006 RubyCrafters, LLC. Most rights reserved.
7
+ #
8
+ # This work is licensed under the Creative Commons Attribution-ShareAlike
9
+ # License. To view a copy of this license, visit
10
+ # http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative
11
+ # Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
12
+ #
13
+ #
14
+
15
+ unless defined? Arrow::TestCase
16
+ testsdir = File.dirname( File.expand_path(__FILE__) )
17
+ basedir = File.dirname( testsdir )
18
+ $LOAD_PATH.unshift "#{basedir}/lib" unless
19
+ $LOAD_PATH.include?( "#{basedir}/lib" )
20
+ $LOAD_PATH.unshift "#{basedir}/tests/lib" unless
21
+ $LOAD_PATH.include?( "#{basedir}/tests/lib" )
22
+
23
+ require 'arrow/testcase'
24
+ end
25
+
26
+ require 'flexmock'
27
+ require 'arrow/template'
28
+
29
+ ### Collection of tests for the Arrow::Template class.
30
+ class Arrow::TemplateTestCase < Arrow::TestCase
31
+
32
+ WHITESPACE_OR_COMMENT = '(\s|<!--(?:[^-]|-(?!->))+-->)*'
33
+
34
+ # The directory all test data files are located in
35
+ TestDataDir = File.join( File.dirname(__FILE__), "data" )
36
+ Arrow::Template.load_path << TestDataDir
37
+ Arrow::Template.load_path.freeze
38
+
39
+ # The instance variables which should have underbarred accessors
40
+ TemplateAttr = %w{
41
+ attributes syntax_tree config renderers file source creation_time
42
+ }
43
+
44
+
45
+ ### Build and return a Regexp to match the given +content+ in output that
46
+ ### only otherwise contains whitespace and HTML comments. If +content+ is
47
+ ### +nil+, match just whitespace and HTML comments.
48
+ def templateContentRe( *content )
49
+ parts = [ '\\A', WHITESPACE_OR_COMMENT ]
50
+ content.each do |pat|
51
+ case pat
52
+ when Regexp
53
+ parts << pat.to_s
54
+ else
55
+ parts << Regexp.quote( pat )
56
+ end
57
+ parts << WHITESPACE_OR_COMMENT
58
+ end
59
+ parts << '\\Z'
60
+
61
+ return Regexp.new( parts.join('') )
62
+ end
63
+
64
+
65
+ ### Read test data into a Hash for later
66
+ TestTemplates = {}
67
+ begin
68
+ inTemplate = seenEnd = false;
69
+ section, template, part = nil
70
+ linenum = 0
71
+
72
+ # Read this file, skipping lines until the __END__ token. Then start
73
+ # reading the tests.
74
+ File.foreach( __FILE__ ) do |line|
75
+ linenum += 1
76
+ if /^__END__/ =~ line then seenEnd = true; next end
77
+ debugMsg "#{linenum}: #{line.chomp}"
78
+ next unless seenEnd
79
+ line.chomp!
80
+
81
+ case line
82
+
83
+ # Directive changes look like:
84
+ # # Set directive
85
+ when /^### (\w+) directive/i
86
+ section = $1.downcase.to_sym
87
+ TestTemplates[ section ] ||= {}
88
+
89
+ when /^#/
90
+ next
91
+
92
+ # Subtests for current directive look like:
93
+ # === Simple
94
+ when /^===\s*(.+)/
95
+ next unless section
96
+ template = $1.downcase.gsub( /\W+/, '_' ).to_sym
97
+ TestTemplates[section][template] = {
98
+ :template => '',
99
+ :code => '',
100
+ :linenumber => linenum,
101
+ }
102
+ part = :template
103
+ debugMsg "Found template '%s' for the '%s' section at line %d" %
104
+ [ template.inspect, section.inspect, linenum ]
105
+ TestTemplates[ section ][ template ][:template] = ''
106
+
107
+ # Separator between template and test code looks like:
108
+ # ---
109
+ when /^---\s*$/
110
+ part = :code
111
+
112
+ # End of current subtest looks like:
113
+ # ===
114
+ when /^===\s*$/
115
+ template = nil
116
+
117
+ # Anything else is added to whatever's currently in scope, or
118
+ # skipped if nothing's in scope.
119
+ else
120
+ next unless section && template
121
+ TestTemplates[ section ][ template ][part] << line << "\n"
122
+ end
123
+ end
124
+
125
+ ### Generate methods for all of the test data
126
+ TestTemplates.each do |section, templates|
127
+ templates.each do |templateName, content|
128
+ methodName = "test_%s_%s" %
129
+ [ section, templateName ]
130
+ debugMsg "Generating test method #{methodName}"
131
+
132
+ # If there's no code with the template, then just expect a
133
+ # failure in instantiation.
134
+ if content[:code].empty?
135
+ code = %{
136
+ def #{methodName}
137
+ printTestHeader "Template: #{section} (#{templateName})"
138
+ rval = nil
139
+ source = <<-'TEMPLATE_END'.gsub(/^\t/, '')
140
+ #{content[:template]}
141
+ TEMPLATE_END
142
+
143
+ assert_raises( Arrow::ParseError ) {
144
+ template = Arrow::Template.new(source)
145
+ }
146
+ end
147
+ }.gsub( /^\t{6}/, '' )
148
+ else
149
+ code = %{
150
+ def #{methodName}
151
+ printTestHeader "Template: #{section} (#{templateName})"
152
+ rval = template = nil
153
+ source = <<-'TEMPLATE_END'.gsub(/^\t/, '')
154
+ #{content[:template]}
155
+ TEMPLATE_END
156
+
157
+ assert_nothing_raised do
158
+ template = Arrow::Template.new(source)
159
+ end
160
+ assert_instance_of Arrow::Template, template
161
+ template._config[:debuggingComments] = true if $DEBUG
162
+
163
+ # Make sure all the attr_underbarred_* methods work
164
+ TemplateAttr.each do |ivar|
165
+ assert_has_ivar ivar.to_sym, template
166
+ assert_nothing_raised do
167
+ rval = template.send( "_\#{ivar}".to_sym )
168
+ end
169
+ assert_ivar_equal rval, template, ivar.to_sym
170
+ end
171
+
172
+ # Test attribute hashish setting/getting
173
+ assert_nothing_raised do
174
+ rval = template._attributes['foo'] = 'bar'
175
+ end
176
+ assert_respond_to template, :[]
177
+ assert_nothing_raised do
178
+ rval = template['foo']
179
+ end
180
+ assert_equal 'bar', rval
181
+ assert_respond_to template, :[]=
182
+ assert_nothing_raised do
183
+ template['foo'] = 'tinkywinky'
184
+ end
185
+ assert_nothing_raised do
186
+ rval = template._attributes['foo']
187
+ end
188
+ assert_equal 'tinkywinky', rval
189
+
190
+ # Test #changed? to make sure it doesn't error even
191
+ # with templates not loaded from a file.
192
+ assert_nothing_raised do
193
+ rval = template.changed?
194
+ end
195
+ assert_equal false, rval
196
+
197
+ # Compare memsize with the length of the actual source.
198
+ assert_equal source.length, template.memsize
199
+
200
+ #{content[:code]}
201
+ end
202
+ }.gsub( /^\t{6}/, '' )
203
+ end
204
+
205
+ debugMsg "Installing test method (line #{content[:linenumber]}): #{code}"
206
+ eval( code, nil, __FILE__,
207
+ content[:linenumber] - code.count("\n") + content[:code].count("\n") )
208
+
209
+ end
210
+ end
211
+ end
212
+
213
+
214
+
215
+ #################################################################
216
+ ### T E S T S
217
+ #################################################################
218
+
219
+ ### Test template loading
220
+ def test_template_memsize_should_be_equal_to_the_source_length
221
+ template = size = nil
222
+ source = File.read( File.join(TestDataDir, "loadtest.tmpl") )
223
+
224
+ # Test the .load method loads template using the path
225
+ assert_nothing_raised do
226
+ template = Arrow::Template.load( "loadtest.tmpl" )
227
+ end
228
+ assert_instance_of Arrow::Template, template
229
+
230
+ # Test for source-size bug
231
+ assert_nothing_raised do
232
+ size = template.memsize
233
+ end
234
+ assert_equal source.length, size,
235
+ "Template memsize should equal source length"
236
+ end
237
+
238
+ def test_template_memsize_should_be_zero_for_blank_template
239
+ size = nil
240
+ template = Arrow::Template.new
241
+
242
+ assert_nothing_raised do
243
+ size = template.memsize
244
+ end
245
+
246
+ assert_equal 0, size
247
+ end
248
+
249
+ def test_loading_template_should_define_template_attributes
250
+ template = Arrow::Template.load( "loadtest.tmpl" )
251
+
252
+ assert template._attributes.key?( 'mooselips' ),
253
+ "Expect loaded template to have a 'mooselips' attribute"
254
+ assert template._attributes.key?( 'queenofallbroccoli' ),
255
+ "Expect loaded template to have a 'queenofallbroccoli' attribute"
256
+ end
257
+
258
+ def test_default_renderer_understands_arrays
259
+ template = Arrow::Template.new
260
+ rval = nil
261
+
262
+ assert_nothing_raised do
263
+ rval = template.render_objects( ["foo", "bar"] )
264
+ end
265
+
266
+ assert_equal "foobar", rval
267
+ end
268
+
269
+ def test_render_calls_pre_and_post_render_hook_for_nodes_that_respond_to_them
270
+ template = Arrow::Template.new
271
+ rval = nil
272
+
273
+ FlexMock.use( "node object" ) do |node|
274
+ node.should_receive( :respond_to? ).with( :before_rendering ).
275
+ and_return( true )
276
+ node.should_receive( :before_rendering ).
277
+ with( template )
278
+ node.should_receive( :respond_to? ).with( :after_rendering ).
279
+ and_return( true )
280
+ node.should_receive( :after_rendering ).
281
+ with( template )
282
+
283
+ template.render( [node] )
284
+ end
285
+ end
286
+
287
+
288
+ def test_render_uses_string_separator_when_joining_rendered_nodes
289
+ rval = nil
290
+ template = Arrow::Template.new( "<?attr foo ?><?attr bar ?>" )
291
+ template.foo = "[foo]"
292
+ template.bar = "[bar]"
293
+
294
+ begin
295
+ sep = $,
296
+ $, = ':'
297
+ assert_nothing_raised do
298
+ rval = template.render
299
+ end
300
+ ensure
301
+ $, = sep
302
+ end
303
+
304
+ assert_equal "[foo]:[bar]", rval
305
+ end
306
+ end
307
+
308
+
309
+ #####################################################################
310
+ ### T E S T D A T A
311
+ #####################################################################
312
+ __END__
313
+
314
+ ### Attribute directive
315
+ === Simple
316
+
317
+ <?attr test?>
318
+
319
+ ---
320
+ debugMsg "Testing getter"
321
+ assert_nothing_raised { rval = template.test }
322
+ assert_equal nil, rval
323
+
324
+ debugMsg "Testing setter"
325
+ assert_nothing_raised { template.test = "foo" }
326
+ assert_equal "foo", template.test
327
+
328
+ assert_nothing_raised { rval = template.render }
329
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
330
+ assert_match( templateContentRe('foo'), rval )
331
+ ===
332
+
333
+ === With format
334
+
335
+ <?attr '|%-15s|' % test?>
336
+
337
+ ---
338
+ testdata = ("x" * 5)
339
+
340
+ assert_nothing_raised { template.test = testdata }
341
+ assert_equal testdata, template.test
342
+
343
+ assert_nothing_raised { rval = template.render }
344
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
345
+ assert_match( templateContentRe(/\|x{5}\s{10}\|/), rval )
346
+ ===
347
+
348
+ === Malformed1
349
+
350
+ <?attr?>
351
+
352
+ ===
353
+
354
+
355
+ === Malformed2
356
+
357
+ <?attr '%s' test ?>
358
+
359
+ ===
360
+
361
+ ### Call directive
362
+ === Simple
363
+
364
+ <?call test?>
365
+
366
+ ---
367
+ debugMsg "Testing getter"
368
+ assert_nothing_raised { rval = template.test }
369
+ assert_equal nil, rval
370
+
371
+ debugMsg "Testing setter"
372
+ assert_nothing_raised { template.test = "foo" }
373
+ assert_equal "foo", template.test
374
+
375
+ assert_nothing_raised { rval = template.render }
376
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
377
+ assert_match( templateContentRe('foo'), rval )
378
+ ===
379
+
380
+
381
+
382
+ === With format
383
+
384
+ <?call '|%-15s|' % test?>
385
+
386
+ ---
387
+ testdata = ("x" * 5)
388
+
389
+ assert_nothing_raised { template.test = testdata }
390
+ assert_equal testdata, template.test
391
+
392
+ assert_nothing_raised { rval = template.render }
393
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
394
+ assert_match( templateContentRe(/\|x{5}\s{10}\|/), rval )
395
+ ===
396
+
397
+
398
+
399
+ === With format and additional quotes
400
+
401
+ <?call '|%-15s|' % test?>
402
+ 'Some more "quoted" stuff to make sure the match doesn't grab them.
403
+
404
+ ---
405
+ testdata = ("x" * 5)
406
+
407
+ assert_nothing_raised { template.test = testdata }
408
+ assert_equal testdata, template.test
409
+
410
+ assert_nothing_raised { rval = template.render }
411
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
412
+ assert_match( templateContentRe(/\|x{5}\s{10}\|.*them\./m), rval )
413
+ ===
414
+
415
+
416
+ === Malformed1
417
+
418
+ <?call?>
419
+
420
+ ===
421
+
422
+
423
+ === Malformed2
424
+
425
+ <?call "%s" tests ?>
426
+
427
+ ===
428
+
429
+
430
+ === IdSub Test
431
+
432
+ <?call test ? "test" : "no test"?>
433
+
434
+ ---
435
+ assert_nothing_raised { template.test = true }
436
+ assert_nothing_raised { rval = template.render }
437
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
438
+ assert_match( templateContentRe(/^test/), rval )
439
+ ===
440
+
441
+
442
+ ### Comment directive
443
+ === Single line
444
+ <?comment hungry mouth ?>
445
+ ---
446
+ assert_nothing_raised { rval = template.render }
447
+ assert_match( templateContentRe(/^$/), rval )
448
+
449
+ === Multiline
450
+ <?comment
451
+
452
+ You're a demanding consumer.
453
+
454
+ And you demand instant gratification.
455
+
456
+ ?>
457
+ ---
458
+ assert_nothing_raised { rval = template.render }
459
+ assert_match( templateContentRe(/^$/), rval )
460
+
461
+
462
+ ### Set directive
463
+ === Simple
464
+
465
+ <?set time = Time.now ?>
466
+
467
+ ---
468
+ assert_nothing_raised { rval = template['time'] }
469
+
470
+ assert_nothing_raised { rval = template.render }
471
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
472
+ assert_match( templateContentRe(), rval )
473
+ ===
474
+
475
+ === Method Chain
476
+
477
+ <?set time = Time.now.strftime( "%Y%m%d %H:%M:%S" ) ?>
478
+
479
+ ---
480
+ assert_nothing_raised { rval = template['time'] }
481
+ debugMsg "template['time'] => %p" % rval
482
+
483
+ assert_nothing_raised { rval = template.render }
484
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
485
+ assert_match( templateContentRe(), rval )
486
+ ===
487
+
488
+ === Rendered later
489
+
490
+ <?set val = "Passed."?>
491
+ <?attr val?>
492
+
493
+ ---
494
+ assert_respond_to template, :val
495
+ assert_nothing_raised { rval = template.render }
496
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
497
+ assert_not_match( /error/i, rval )
498
+ assert_match( templateContentRe("Passed."), rval )
499
+ ===
500
+
501
+ ### If directive
502
+ === Simple
503
+
504
+ <?if test?>
505
+ Passed.
506
+ <?end?>
507
+
508
+ ---
509
+ assert_nothing_raised { template.test = true }
510
+ assert_nothing_raised { rval = template.render }
511
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
512
+ assert_match( templateContentRe('Passed.'), rval )
513
+ ===
514
+
515
+ === Simple with explicit end
516
+
517
+ <?if test?>
518
+ Passed.
519
+ <?end if?>
520
+
521
+ ---
522
+ assert_nothing_raised { template.test = true }
523
+ assert_nothing_raised { rval = template.render }
524
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
525
+ assert_match( templateContentRe('Passed.'), rval )
526
+ ===
527
+
528
+ === Simple with mismatched end
529
+
530
+ <?if test?>
531
+ Passed.
532
+ <?end for?>
533
+
534
+ ---
535
+ assert_nothing_raised { template.test = true }
536
+ assert_nothing_raised { rval = template.render }
537
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
538
+ assert_match( templateContentRe('Passed.'), rval )
539
+ ===
540
+
541
+ === With match
542
+
543
+ <?if test.match(/foo/) ?>
544
+ Passed.
545
+ <?end?>
546
+
547
+ ---
548
+ assert_nothing_raised { template.test = "foo" }
549
+ assert_nothing_raised { rval = template.render }
550
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
551
+ assert_match( templateContentRe('Passed.'), rval )
552
+ ===
553
+
554
+ === With no match
555
+
556
+ <?if test.match(/foo/) ?>
557
+ Failed.
558
+ <?end?>
559
+
560
+ ---
561
+ assert_nothing_raised { template.test = "bar" }
562
+ assert_nothing_raised { rval = template.render }
563
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
564
+ assert_match( templateContentRe(), rval )
565
+ ===
566
+
567
+ === Match with binding operator
568
+
569
+ <?if test =~ /foo/ ?>
570
+ Passed.
571
+ <?end?>
572
+
573
+ ---
574
+ assert_nothing_raised { template.test = "foo" }
575
+ assert_nothing_raised { rval = template.render }
576
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
577
+ assert_match( templateContentRe('Passed.'), rval )
578
+ ===
579
+
580
+ === Simple with unexecuted else
581
+
582
+ <?if test?>
583
+ Passed.
584
+ <?else?>
585
+ Failed.
586
+ <?end?>
587
+
588
+ ---
589
+ assert_nothing_raised { template.test = true }
590
+ assert_nothing_raised { rval = template.render }
591
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
592
+ assert_match( templateContentRe('Passed.'), rval )
593
+ ===
594
+
595
+
596
+ === Simple with executed else
597
+
598
+ <?if test?>
599
+ Failed.
600
+ <?else?>
601
+ Passed.
602
+ <?end?>
603
+
604
+ ---
605
+ assert_nothing_raised { template.test = false }
606
+ assert_nothing_raised { rval = template.render }
607
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
608
+ assert_match( templateContentRe('Passed.'), rval )
609
+ ===
610
+
611
+ === Complex with success
612
+
613
+ <?if test > 5?>
614
+ Passed.
615
+ <?else?>
616
+ Failed.
617
+ <?end?>
618
+
619
+ ---
620
+ assert_nothing_raised { template.test = 15 }
621
+ assert_nothing_raised { rval = template.render }
622
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
623
+ assert_match( templateContentRe('Passed.'), rval )
624
+ ===
625
+
626
+ === Complex with failure
627
+
628
+ <?if test <= 5?>
629
+ Failed.
630
+ <?else?>
631
+ Passed.
632
+ <?end?>
633
+
634
+ ---
635
+ assert_nothing_raised { template.test = 15 }
636
+ assert_nothing_raised { rval = template.render }
637
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
638
+ assert_match( templateContentRe('Passed.'), rval )
639
+ ===
640
+
641
+ === Complex2
642
+
643
+ <?if test > 5 or test == 0?>
644
+ Passed.
645
+ <?else?>
646
+ Failed.
647
+ <?end?>
648
+
649
+ ---
650
+ assert_nothing_raised { template.test = 0 }
651
+ assert_nothing_raised { rval = template.render }
652
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
653
+ assert_match( templateContentRe('Passed.'), rval )
654
+ ===
655
+
656
+ === Inside iterator
657
+ <?yield foo from test.each?>
658
+ <?if foo?>
659
+ Passed.
660
+ <?else?>
661
+ Failed.
662
+ <?end?>
663
+ <?end yield?>
664
+ ---
665
+ assert_nothing_raised { template.test = [true] }
666
+ assert_nothing_raised { rval = template.render }
667
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
668
+ assert_match( templateContentRe('Passed.'), rval )
669
+ ===
670
+
671
+ === Inside iterator with comparison
672
+ <?yield foo from test.each?>
673
+ <?if foo == "bar"?>
674
+ Passed.
675
+ <?else?>
676
+ Failed.
677
+ <?end?>
678
+ <?end yield?>
679
+ ---
680
+ assert_nothing_raised { template.test = ["bar"] }
681
+ assert_nothing_raised { rval = template.render }
682
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
683
+ assert_match( templateContentRe('Passed.'), rval )
684
+ ===
685
+
686
+ # I think this is a general bug, not specific to 'if', but I'm testing it here
687
+ # because I first saw it in an 'if'.
688
+ === Methodchain with question mark
689
+ <?if test.is_a?( Arrow::Exception ) ?>
690
+ Passed.
691
+ <?else?>
692
+ Failed.
693
+ <?end?>
694
+ ---
695
+ # Nothing special about an exception -- it's just a class that can be
696
+ # instantiated easily.
697
+ obj = Arrow::Exception.new
698
+ assert_nothing_raised { template.test = obj }
699
+ assert_nothing_raised { rval = template.render }
700
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
701
+ assert_match( templateContentRe('Passed.'), rval )
702
+ ===
703
+
704
+ ### Unless directive
705
+ === Simple
706
+
707
+ <?unless test?>
708
+ Passed.
709
+ <?end?>
710
+
711
+ ---
712
+ assert_nothing_raised { template.test = false }
713
+ assert_nothing_raised { rval = template.render }
714
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
715
+ assert_match( templateContentRe('Passed.'), rval )
716
+ ===
717
+
718
+ === Simple with explicit end
719
+
720
+ <?unless test?>
721
+ Passed.
722
+ <?end unless?>
723
+
724
+ ---
725
+ assert_nothing_raised { template.test = false }
726
+ assert_nothing_raised { rval = template.render }
727
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
728
+ assert_match( templateContentRe('Passed.'), rval )
729
+ ===
730
+
731
+ === Simple with mismatched end
732
+
733
+ <?unless test?>
734
+ Passed.
735
+ <?end for?>
736
+
737
+ ---
738
+ assert_nothing_raised { template.test = false }
739
+ assert_nothing_raised { rval = template.render }
740
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
741
+ assert_match( templateContentRe('Passed.'), rval )
742
+ ===
743
+
744
+ === With no match
745
+
746
+ <?unless test.match(/foo/) ?>
747
+ Passed.
748
+ <?end?>
749
+
750
+ ---
751
+ assert_nothing_raised { template.test = "bar" }
752
+ assert_nothing_raised { rval = template.render }
753
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
754
+ assert_match( templateContentRe('Passed.'), rval )
755
+ ===
756
+
757
+ === With match
758
+
759
+ <?unless test.match(/foo/) ?>
760
+ Failed.
761
+ <?end?>
762
+
763
+ ---
764
+ assert_nothing_raised { template.test = "foo" }
765
+ assert_nothing_raised { rval = template.render }
766
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
767
+ assert_match( templateContentRe(), rval )
768
+ ===
769
+
770
+ === Match with binding operator
771
+
772
+ <?unless test =~ /foo/ ?>
773
+ Passed.
774
+ <?end?>
775
+
776
+ ---
777
+ assert_nothing_raised { template.test = "bar" }
778
+ assert_nothing_raised { rval = template.render }
779
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
780
+ assert_match( templateContentRe('Passed.'), rval )
781
+ ===
782
+
783
+ === Simple with unexecuted else
784
+
785
+ <?unless test?>
786
+ Passed.
787
+ <?else?>
788
+ Failed.
789
+ <?end?>
790
+
791
+ ---
792
+ assert_nothing_raised { template.test = false }
793
+ assert_nothing_raised { rval = template.render }
794
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
795
+ assert_match( templateContentRe('Passed.'), rval )
796
+ ===
797
+
798
+
799
+ === Simple with executed else
800
+
801
+ <?unless test?>
802
+ Failed.
803
+ <?else?>
804
+ Passed.
805
+ <?end?>
806
+
807
+ ---
808
+ assert_nothing_raised { template.test = true }
809
+ assert_nothing_raised { rval = template.render }
810
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
811
+ assert_match( templateContentRe('Passed.'), rval )
812
+ ===
813
+
814
+ === Complex with success
815
+
816
+ <?unless test > 5?>
817
+ Passed.
818
+ <?else?>
819
+ Failed.
820
+ <?end?>
821
+
822
+ ---
823
+ assert_nothing_raised { template.test = 2 }
824
+ assert_nothing_raised { rval = template.render }
825
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
826
+ assert_match( templateContentRe('Passed.'), rval )
827
+ ===
828
+
829
+ === Complex with failure
830
+
831
+ <?unless test <= 5?>
832
+ Failed.
833
+ <?else?>
834
+ Passed.
835
+ <?end?>
836
+
837
+ ---
838
+ assert_nothing_raised { template.test = 2 }
839
+ assert_nothing_raised { rval = template.render }
840
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
841
+ assert_match( templateContentRe('Passed.'), rval )
842
+ ===
843
+
844
+ === Complex2
845
+
846
+ <?unless test > 5 or test == 0?>
847
+ Failed.
848
+ <?else?>
849
+ Passed.
850
+ <?end?>
851
+
852
+ ---
853
+ assert_nothing_raised { template.test = 0 }
854
+ assert_nothing_raised { rval = template.render }
855
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
856
+ assert_match( templateContentRe('Passed.'), rval )
857
+ ===
858
+
859
+ === Inside iterator
860
+ <?yield foo from test.each?>
861
+ <?unless foo?>
862
+ Passed.
863
+ <?else?>
864
+ Failed.
865
+ <?end?>
866
+ <?end yield?>
867
+ ---
868
+ assert_nothing_raised { template.test = [false] }
869
+ assert_nothing_raised { rval = template.render }
870
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
871
+ assert_match( templateContentRe('Passed.'), rval )
872
+ ===
873
+
874
+ === Inside iterator with comparison
875
+ <?yield foo from test.each?>
876
+ <?unless foo == "bar"?>
877
+ Passed.
878
+ <?else?>
879
+ Failed.
880
+ <?end?>
881
+ <?end yield?>
882
+ ---
883
+ assert_nothing_raised { template.test = ["foo"] }
884
+ assert_nothing_raised { rval = template.render }
885
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
886
+ assert_match( templateContentRe('Passed.'), rval )
887
+ ===
888
+
889
+ === Methodchain with question mark
890
+ <?unless test.is_a?( Arrow::Exception ) ?>
891
+ Passed.
892
+ <?else?>
893
+ Failed.
894
+ <?end?>
895
+ ---
896
+ obj = Object.new
897
+ assert_nothing_raised { template.test = obj }
898
+ assert_nothing_raised { rval = template.render }
899
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
900
+ assert_match( templateContentRe('Passed.'), rval )
901
+ ===
902
+
903
+ ### For directive
904
+ === Simple
905
+
906
+ <?for item in tests ?>
907
+ <?attr item?>
908
+ <?end?>
909
+
910
+ ---
911
+ assert_nothing_raised { template.tests = %w{passed passed passed} }
912
+ assert_nothing_raised { rval = template.render }
913
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
914
+ assert_match( templateContentRe(/passed.*passed.*passed/m), rval )
915
+ ===
916
+
917
+ === Multiple items
918
+
919
+ <?for key, val in tests ?>
920
+ <?attr key?>: <?attr val?>
921
+ <?end for?>
922
+
923
+ ---
924
+ assert_nothing_raised { template.tests = {'uno' => 'Passed'} }
925
+ assert_nothing_raised { rval = template.render }
926
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
927
+ assert_match( templateContentRe(/uno:/,/Passed/), rval )
928
+ ===
929
+
930
+ === With methodchain
931
+
932
+ <?for word, length in tests.collect {|item| [item, item.length]}.
933
+ sort_by {|item| item[1]} ?>
934
+ <?attr word?>: <?attr length?>
935
+ <?end for?>
936
+
937
+ ---
938
+ assert_nothing_raised { template.tests = %w{gronk bizzle foo} }
939
+ assert_nothing_raised { rval = template.render }
940
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
941
+ assert_match( templateContentRe(/foo:/,/3/,/gronk:/,/5/,/bizzle:/,/6/), rval )
942
+ ===
943
+
944
+
945
+ === Array of Hashes
946
+
947
+ <?for entry in svn_ret?>
948
+ <?call entry.inspect?>
949
+ <?end for?>
950
+
951
+ ---
952
+ aoh = [{:foo => 1, :bar => 2}, {:baz => 3, :bim => 4}]
953
+ assert_nothing_raised { template.svn_ret = aoh }
954
+ assert_nothing_raised { rval = template.render }
955
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
956
+ assert_match( /\{/, rval )
957
+ assert_match( /:foo/, rval )
958
+ assert_match( /:bar/, rval )
959
+ assert_match( /:baz/, rval )
960
+ assert_match( /:bim/, rval )
961
+ ===
962
+
963
+ === Iterator in evaled region
964
+
965
+ <?for key in purchases.keys ?>
966
+ <?if foo.key?(key) ?>
967
+ Passed.
968
+ <?end if?>
969
+ <?end for ?>
970
+
971
+ ---
972
+ purchases = {"test" => 7}
973
+ foo = {"test" => 3}
974
+ assert_nothing_raised { template.purchases = purchases }
975
+ assert_nothing_raised { template.foo = foo }
976
+ assert_nothing_raised { rval = template.render }
977
+ assert_match( templateContentRe(/Passed\./), rval )
978
+
979
+ ===
980
+
981
+ # === Scope error
982
+ #
983
+ # <?for val in sarr ?>
984
+ # <?if foo == val ?>
985
+ # Key exists.
986
+ # <?end if ?>
987
+ # <?end for ?>
988
+ #
989
+ # <?if foo == val ?>
990
+ # Failed.
991
+ # <?end if?>
992
+ #
993
+ # ---
994
+ # sarr = [:something, :somethingElse, :something]
995
+ # template.sarr = sarr
996
+ # template.foo = :something
997
+ # assert_nothing_raised { rval = template.render }
998
+ # assert_match( templateContentRe(/Key exists\./, /Key exists\./), rval )
999
+ # assert_match( /<!--.*ScopeError.*-->/, rval )
1000
+ # ===
1001
+
1002
+ === Cannot override definitions ivar
1003
+
1004
+ <?for definitions in array ?>
1005
+ Failed.
1006
+ <?end for?>
1007
+
1008
+ ---
1009
+ array = [:foo]
1010
+ assert_nothing_raised { rval = template.render }
1011
+ assert_match( /<!--.*ScopeError.*-->/, rval )
1012
+ ===
1013
+
1014
+
1015
+ ### Yield directive
1016
+ === Simple
1017
+
1018
+ <?yield item from tests.each ?>
1019
+ <?attr item?>
1020
+ <?end?>
1021
+
1022
+ ---
1023
+ assert_nothing_raised { template.tests = %w{passed passed passed} }
1024
+ assert_nothing_raised { rval = template.render }
1025
+ assert_match( templateContentRe(/passed.*passed.*passed/m), rval )
1026
+ ===
1027
+
1028
+ === Simple Two Args
1029
+
1030
+ <?yield key, value from tests.each ?>
1031
+ <?attr key ?>: <?attr value ?>
1032
+ <?end?>
1033
+
1034
+ ---
1035
+ assert_nothing_raised { template.tests = {:foo => "passed", :bar => "passed"} }
1036
+ assert_nothing_raised { rval = template.render }
1037
+ assert_match( templateContentRe(/(foo|bar):.*passed.*(foo|bar):.*passed/m), rval )
1038
+ ===
1039
+
1040
+ === Non Each Iteration
1041
+
1042
+ <?yield match from tests.scan(%r{\w+}) ?>
1043
+ <?attr match?>
1044
+ <?end?>
1045
+
1046
+ ---
1047
+ assert_nothing_raised { template.tests = "passed the test" }
1048
+ assert_nothing_raised { rval = template.render }
1049
+ assert_match( templateContentRe(/passed.*the.*test/m), rval )
1050
+ ===
1051
+
1052
+
1053
+ ### Include directive
1054
+ === Simple
1055
+
1056
+ <?include test.incl?>
1057
+
1058
+ ---
1059
+ assert_nothing_raised { rval = template.render }
1060
+ assert_match( templateContentRe(/passed\./i), rval )
1061
+ ===
1062
+
1063
+ === Recursive
1064
+
1065
+ <?include outerTest.incl ?>
1066
+
1067
+ ---
1068
+ assert_nothing_raised { rval = template.render }
1069
+ assert_match( templateContentRe(/Outer\..*Passed\./m), rval )
1070
+ ===
1071
+
1072
+ === Circular
1073
+
1074
+ <?include circular1.incl ?>
1075
+
1076
+ ---
1077
+ assert_nothing_raised { rval = template.render }
1078
+ expected = /.*<!-- Template for circular include test -->.*circular1/m +
1079
+ /.*<!-- Template for circular include test -->.*circular2/m +
1080
+ /.*<!-- Arrow::TemplateError: Include circular1.incl: Circular include: /m +
1081
+ /circular1.incl -> circular2.incl -> circular1.incl -->.*/m
1082
+ assert_match( templateContentRe(expected), rval )
1083
+ ===
1084
+
1085
+ === With Identifier
1086
+
1087
+ <?include subtemplate.incl as sub?>
1088
+
1089
+ ---
1090
+ assert_nothing_raised { rval = template.sub }
1091
+ assert_instance_of Arrow::Template, rval
1092
+
1093
+ assert_nothing_raised { template.sub.test = "Passed." }
1094
+ assert_nothing_raised { rval = template.render }
1095
+ assert_match( templateContentRe(/Passed\./), rval )
1096
+ ===
1097
+
1098
+ === With Subdirectory
1099
+
1100
+ <?include subdir/include.incl?>
1101
+
1102
+ ---
1103
+ assert_nothing_raised { template.test = "Passed." }
1104
+ assert_nothing_raised { rval = template.render }
1105
+ assert_match( templateContentRe(/Passed\./), rval )
1106
+ ===
1107
+
1108
+
1109
+ === With Subdirectory And Identifier
1110
+
1111
+ <?include subdir/include.incl as sub?>
1112
+
1113
+ ---
1114
+ assert_nothing_raised { rval = template.sub }
1115
+ assert_instance_of Arrow::Template, rval
1116
+
1117
+ assert_nothing_raised { template.sub.test = "Passed." }
1118
+ assert_nothing_raised { rval = template.render }
1119
+ assert_match( templateContentRe(/Passed\./), rval )
1120
+ ===
1121
+
1122
+
1123
+ ### Import directive
1124
+ === Simple
1125
+
1126
+ <?import foo?>
1127
+ <?attr foo?>
1128
+
1129
+ ---
1130
+ superTemplate = Arrow::Template.new( "<?attr subtempl?>" )
1131
+ superTemplate.foo = "Passed."
1132
+ superTemplate.subtempl = template
1133
+
1134
+ assert_nothing_raised { rval = superTemplate.render }
1135
+ assert_match( templateContentRe(/Passed\./), rval )
1136
+ ===
1137
+
1138
+ === List
1139
+
1140
+ <?import foo, bar?>
1141
+ <?attr foo?> <?attr bar?>
1142
+
1143
+ ---
1144
+ superTemplate = Arrow::Template.new( "<?attr subtempl?>" )
1145
+ superTemplate.foo = "Passed foo."
1146
+ superTemplate.bar = "Passed bar."
1147
+ superTemplate.subtempl = template
1148
+
1149
+ assert_nothing_raised { rval = superTemplate.render }
1150
+ assert_match( templateContentRe(/Passed foo\./,/Passed bar\./), rval )
1151
+ ===
1152
+
1153
+ === Aliased
1154
+
1155
+ <?import foo as bar?>
1156
+ <?attr bar?>
1157
+
1158
+ ---
1159
+ superTemplate = Arrow::Template.new( "<?attr subtempl?>" )
1160
+ superTemplate.foo = "Passed."
1161
+ superTemplate.subtempl = template
1162
+
1163
+ assert_nothing_raised { rval = superTemplate.render }
1164
+ assert_match( templateContentRe(/Passed\./), rval )
1165
+ ===
1166
+
1167
+ === Aliased List
1168
+
1169
+ <?import foo as bar, bar as foo?>
1170
+ <?attr foo?> <?attr bar?>
1171
+
1172
+ ---
1173
+ superTemplate = Arrow::Template.new( "<?attr subtempl?>" )
1174
+ superTemplate.foo = "Passed foo."
1175
+ superTemplate.bar = "Passed bar."
1176
+ superTemplate.subtempl = template
1177
+
1178
+ assert_nothing_raised { rval = superTemplate.render }
1179
+ assert_match( templateContentRe(/Passed bar\./,/Passed foo\./), rval )
1180
+ ===
1181
+
1182
+ === Mixed List
1183
+
1184
+ <?import foo, bar as superbar?>
1185
+ <?attr foo?> <?attr bar?> <?attr superbar?>
1186
+
1187
+ ---
1188
+ superTemplate = Arrow::Template.new( "<?attr subtempl?>" )
1189
+ superTemplate.foo = "Passed foo."
1190
+ superTemplate.bar = "Passed bar."
1191
+ superTemplate.subtempl = template
1192
+
1193
+ template.bar = "Passed real bar."
1194
+
1195
+ assert_nothing_raised { rval = superTemplate.render }
1196
+ pat = templateContentRe(/Passed foo\./,/Passed real bar\./,/Passed bar\./)
1197
+ assert_match( pat, rval )
1198
+ ===
1199
+
1200
+ === Unknown PI (Ignored)
1201
+
1202
+ <?xml version="1.0" encoding="utf-8"?>
1203
+
1204
+ ---
1205
+ assert_instance_of Arrow::Template, template
1206
+ ===
1207
+
1208
+ ### Render directive
1209
+ === Simple
1210
+
1211
+ <?render foo as bar in simplerender.tmpl ?>
1212
+
1213
+ ---
1214
+ debugMsg "Setting outer template's 'foo' to 'baz'"
1215
+ assert_nothing_raised { template.foo = "baz" }
1216
+ assert_equal "baz", template.foo
1217
+
1218
+ assert_nothing_raised { rval = template.render }
1219
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1220
+ assert_match( templateContentRe('Simple Render: baz'), rval )
1221
+ ===
1222
+
1223
+ === With import
1224
+
1225
+ Something: <?attr something?>
1226
+ <?render foo as bar in importrender.tmpl ?>
1227
+
1228
+ ---
1229
+ debugMsg "Setting outer template's 'foo' to 'baz'"
1230
+ assert_nothing_raised { template.foo = "baz" }
1231
+ assert_equal "baz", template.foo
1232
+
1233
+ debugMsg "Setting outer template's 'something' to 'sasquatch'"
1234
+ assert_nothing_raised { template.something = "sasquatch" }
1235
+
1236
+ assert_nothing_raised { rval = template.render }
1237
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1238
+ assert_match( templateContentRe('Something:', 'sasquatch','Bar:',
1239
+ 'baz and sasquatch'), rval )
1240
+ ===
1241
+
1242
+ === Recursion
1243
+
1244
+ <?render pairs as pairs in recurse.tmpl ?>
1245
+
1246
+ ---
1247
+ pairs = {
1248
+ "integer" => 1,
1249
+ "hash" => {
1250
+ "bar" => 1,
1251
+ "foo" => 2,
1252
+ "subsubhash" => {"hope, faith" => "and charity"},
1253
+ },
1254
+ "string" => "A string",
1255
+ }
1256
+ debugMsg "Setting outer template's 'pairs' to %p" % pairs
1257
+ assert_nothing_raised { template.pairs = pairs }
1258
+
1259
+ assert_nothing_raised { rval = template.render }
1260
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1261
+ assert_match( /Key => integer\n Val => 1\n/m, rval )
1262
+ assert_match( /Key => hash\n Val => .*Key => subsubhash\n Val => \nKey => hope, faith\n Val => and charity/m, rval )
1263
+ ===
1264
+
1265
+ === With Complex Methodchain
1266
+
1267
+ <?render pairs['hash'] as pairs in recurse.tmpl ?>
1268
+
1269
+ ---
1270
+ pairs = {
1271
+ "integer" => 1,
1272
+ "hash" => {
1273
+ "bar" => 1,
1274
+ "foo" => 2,
1275
+ "subsubhash" => {"hope, faith" => "and charity"},
1276
+ },
1277
+ "string" => "A string",
1278
+ }
1279
+ debugMsg "Setting outer template's 'pairs' to %p" % pairs
1280
+ assert_nothing_raised { template.pairs = pairs }
1281
+
1282
+ assert_nothing_raised { rval = template.render }
1283
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1284
+ assert_match( templateContentRe("Key => subsubhash\n Val => \nKey => hope, faith\n Val => and charity\n\n\nKey => foo\n Val => 2\nKey => bar\n Val => 1"), rval )
1285
+ ===
1286
+
1287
+
1288
+ ### Export directive
1289
+ === Simple
1290
+
1291
+ <?attr headsections ?>
1292
+ <?attr subtemplate ?>
1293
+ <?attr tailsections ?>
1294
+
1295
+ ---
1296
+ template.subtemplate = Arrow::Template.load( "export.tmpl" )
1297
+
1298
+ assert_nothing_raised { rval = template.render }
1299
+ #pp template
1300
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1301
+ assert_match( templateContentRe("head", "content", "tail"), rval )
1302
+ ===
1303
+
1304
+ ## === Upwards Through Multiple Templates
1305
+ ##
1306
+ ## <?attr headsections ?>
1307
+ ## <?attr subtemplate ?>
1308
+ ## <?attr tailsections ?>
1309
+ ##
1310
+ ## ---
1311
+ ## template.subtemplate = Arrow::Template.load( "reexport.tmpl" )
1312
+ ##
1313
+ ## assert_nothing_raised { rval = template.render }
1314
+ ## debugMsg "\n" + hruleSection( rval, "Rendered" )
1315
+ ## assert_match( templateContentRe("head", "content", "tail"), rval )
1316
+ ## ===
1317
+ ##
1318
+
1319
+ ### Selectlist directive
1320
+ === Simple
1321
+ <?selectlist categories ?>
1322
+ <?end?>
1323
+ ---
1324
+ template.categories = %w[code rant music]
1325
+ assert_nothing_raised { rval = template.render }
1326
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1327
+
1328
+ list = <<EOF
1329
+ <select name="categories">
1330
+ <option value="code">code</option>
1331
+ <option value="rant">rant</option>
1332
+ <option value="music">music</option>
1333
+ </select>
1334
+ EOF
1335
+
1336
+ assert_match( templateContentRe(list), rval )
1337
+ ===
1338
+
1339
+
1340
+ === Named
1341
+ <?selectlist category FROM categories ?>
1342
+ <?end?>
1343
+ ---
1344
+ template.categories = %w[code rant music parrots]
1345
+ assert_nothing_raised { rval = template.render }
1346
+ debugMsg "\n" + hruleSection( rval, "Rendered" )
1347
+
1348
+ list = <<EOF
1349
+ <select name="category">
1350
+ <option value="code">code</option>
1351
+ <option value="rant">rant</option>
1352
+ <option value="music">music</option>
1353
+ <option value="parrots">parrots</option>
1354
+ </select>
1355
+ EOF
1356
+
1357
+ assert_match( templateContentRe(list), rval )
1358
+ ===
1359
+
1360
+