runo 0.2.1 → 0.2.2

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 (151) hide show
  1. data/README.rdoc +1 -118
  2. data/bin/runo +4 -29
  3. data/lib/dummy.rb +0 -0
  4. metadata +12 -278
  5. data/lib/_error.rb +0 -14
  6. data/lib/_field.rb +0 -260
  7. data/lib/_i18n.rb +0 -144
  8. data/lib/_parser.rb +0 -256
  9. data/lib/_path.rb +0 -86
  10. data/lib/_storage/_storage.rb +0 -215
  11. data/lib/_storage/file.rb +0 -201
  12. data/lib/_storage/sequel.rb +0 -174
  13. data/lib/_storage/temp.rb +0 -73
  14. data/lib/_widget/action_create.rb +0 -23
  15. data/lib/_widget/action_login.rb +0 -22
  16. data/lib/_widget/action_signup.rb +0 -16
  17. data/lib/_widget/action_update.rb +0 -16
  18. data/lib/_widget/crumb.rb +0 -24
  19. data/lib/_widget/done.rb +0 -16
  20. data/lib/_widget/login.rb +0 -25
  21. data/lib/_widget/me.rb +0 -31
  22. data/lib/_widget/message.rb +0 -51
  23. data/lib/_widget/navi.rb +0 -88
  24. data/lib/_widget/submit.rb +0 -49
  25. data/lib/_widget/view_ym.rb +0 -77
  26. data/lib/_workflow/_workflow.rb +0 -89
  27. data/lib/_workflow/attachment.rb +0 -50
  28. data/lib/_workflow/blog.rb +0 -28
  29. data/lib/_workflow/contact.rb +0 -23
  30. data/lib/_workflow/forum.rb +0 -26
  31. data/lib/_workflow/register.rb +0 -39
  32. data/lib/meta/_meta.rb +0 -20
  33. data/lib/meta/group.rb +0 -19
  34. data/lib/meta/id.rb +0 -59
  35. data/lib/meta/owner.rb +0 -21
  36. data/lib/meta/timestamp.rb +0 -118
  37. data/lib/runo.rb +0 -396
  38. data/lib/scalar/checkbox.rb +0 -68
  39. data/lib/scalar/file.rb +0 -144
  40. data/lib/scalar/img.rb +0 -112
  41. data/lib/scalar/password.rb +0 -58
  42. data/lib/scalar/radio.rb +0 -47
  43. data/lib/scalar/select.rb +0 -47
  44. data/lib/scalar/text.rb +0 -38
  45. data/lib/scalar/textarea.rb +0 -35
  46. data/lib/scalar/textarea_pre.rb +0 -14
  47. data/lib/scalar/textarea_wiki.rb +0 -173
  48. data/lib/set/_set.rb +0 -196
  49. data/lib/set/dynamic.rb +0 -177
  50. data/lib/set/static.rb +0 -102
  51. data/lib/set/static_folder.rb +0 -96
  52. data/locale/en/index.po +0 -242
  53. data/locale/index.pot +0 -243
  54. data/locale/ja/index.po +0 -242
  55. data/locale/lazy_parser.rb +0 -54
  56. data/skel/config.ru +0 -27
  57. data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
  58. data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
  59. data/skel/skin/_users/00000000_frank.yaml +0 -12
  60. data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
  61. data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
  62. data/skel/skin/_users/00000000_root.yaml +0 -11
  63. data/skel/skin/_users/css/users.css +0 -21
  64. data/skel/skin/_users/css/users.less +0 -25
  65. data/skel/skin/_users/done.html +0 -42
  66. data/skel/skin/_users/index.html +0 -46
  67. data/skel/skin/_users/index.yaml +0 -3
  68. data/skel/skin/_users/summary.html +0 -40
  69. data/skel/skin/css/base.css +0 -93
  70. data/skel/skin/css/base.less +0 -139
  71. data/skel/skin/css/coax.css +0 -199
  72. data/skel/skin/css/coax.less +0 -244
  73. data/skel/skin/examples/blog/20091214_0001.yaml +0 -8
  74. data/skel/skin/examples/blog/20100630_0001.yaml +0 -8
  75. data/skel/skin/examples/blog/20100630_0002.yaml +0 -14
  76. data/skel/skin/examples/blog/20100701_0001.yaml +0 -8
  77. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
  78. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
  79. data/skel/skin/examples/blog/20100701_0002.yaml +0 -19
  80. data/skel/skin/examples/blog/frank/20100701_0001.yaml +0 -10
  81. data/skel/skin/examples/blog/frank/index.yaml +0 -4
  82. data/skel/skin/examples/blog/index.html +0 -51
  83. data/skel/skin/examples/blog/rss.xml +0 -18
  84. data/skel/skin/examples/contact/20100701_0001-file.txt +0 -1
  85. data/skel/skin/examples/contact/20100701_0001.yaml +0 -15
  86. data/skel/skin/examples/contact/20100701_0002.yaml +0 -8
  87. data/skel/skin/examples/contact/20100701_0003.yaml +0 -9
  88. data/skel/skin/examples/contact/index.html +0 -47
  89. data/skel/skin/examples/contact/js/contact.js +0 -13
  90. data/skel/skin/examples/contact/summary.html +0 -54
  91. data/skel/skin/examples/forum/20100701_0001.yaml +0 -41
  92. data/skel/skin/examples/forum/20100701_0002.yaml +0 -25
  93. data/skel/skin/examples/forum/index.html +0 -68
  94. data/skel/skin/examples/forum/summary.html +0 -47
  95. data/skel/skin/examples/index.html +0 -73
  96. data/skel/skin/index.html +0 -39
  97. data/skel/skin/js/base.js +0 -50
  98. data/t/locale/de/index.po +0 -19
  99. data/t/locale/en-GB/index.po +0 -25
  100. data/t/locale/ja/index.po +0 -30
  101. data/t/skin/_users/00000000_test.yaml +0 -3
  102. data/t/skin/_users/index.html +0 -13
  103. data/t/skin/foo/20091120_0001.yaml +0 -7
  104. data/t/skin/foo/bar/20091120_0001.yaml +0 -5
  105. data/t/skin/foo/bar/index.yaml +0 -5
  106. data/t/skin/foo/baz/css/baz.css +0 -1
  107. data/t/skin/foo/css/foo.css +0 -1
  108. data/t/skin/foo/index.html +0 -14
  109. data/t/skin/foo/index.yaml +0 -7
  110. data/t/skin/foo/not_css/foo.css +0 -1
  111. data/t/skin/foo/qux/index.html +0 -8
  112. data/t/skin/foo/qux/moo/index.html +0 -6
  113. data/t/skin/foo/sub-20100306_0001.yaml +0 -3
  114. data/t/skin/index.yaml +0 -3
  115. data/t/skin/t_attachment/index.html +0 -13
  116. data/t/skin/t_contact/done.html +0 -6
  117. data/t/skin/t_contact/index.html +0 -9
  118. data/t/skin/t_file/index.html +0 -16
  119. data/t/skin/t_img/index.html +0 -14
  120. data/t/skin/t_img/test.jpg +0 -0
  121. data/t/skin/t_select/index.html +0 -9
  122. data/t/skin/t_store/index.html +0 -9
  123. data/t/skin/t_summary/20100326_0001.yaml +0 -3
  124. data/t/skin/t_summary/create.html +0 -9
  125. data/t/skin/t_summary/index.html +0 -9
  126. data/t/skin/t_summary/summary.html +0 -9
  127. data/t/t.rb +0 -27
  128. data/t/test_checkbox.rb +0 -273
  129. data/t/test_field.rb +0 -330
  130. data/t/test_file.rb +0 -900
  131. data/t/test_id.rb +0 -215
  132. data/t/test_img.rb +0 -328
  133. data/t/test_meta.rb +0 -57
  134. data/t/test_parser.rb +0 -1516
  135. data/t/test_password.rb +0 -188
  136. data/t/test_radio.rb +0 -226
  137. data/t/test_role.rb +0 -249
  138. data/t/test_runo.rb +0 -768
  139. data/t/test_runo_call.rb +0 -1281
  140. data/t/test_runo_i18n.rb +0 -325
  141. data/t/test_select.rb +0 -182
  142. data/t/test_set_complex.rb +0 -527
  143. data/t/test_set_dynamic.rb +0 -1504
  144. data/t/test_set_folder.rb +0 -515
  145. data/t/test_set_permit.rb +0 -246
  146. data/t/test_set_static.rb +0 -468
  147. data/t/test_storage.rb +0 -915
  148. data/t/test_text.rb +0 -125
  149. data/t/test_textarea.rb +0 -138
  150. data/t/test_timestamp.rb +0 -473
  151. data/t/test_workflow.rb +0 -367
@@ -1,57 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- # Author:: Akira FUNAI
4
- # Copyright:: Copyright (c) 2009 Akira FUNAI
5
-
6
- require "#{::File.dirname __FILE__}/t"
7
-
8
- class TC_Meta < Test::Unit::TestCase
9
-
10
- def setup
11
- end
12
-
13
- def teardown
14
- end
15
-
16
- def test_owner
17
- ss = Runo::Set::Static.new(
18
- :item => {
19
- '_owner' => {:klass => 'meta-owner'},
20
- }
21
- )
22
- assert_instance_of(
23
- Runo::Meta::Owner,
24
- ss.item('_owner'),
25
- "Set::Static#item('_owner') should be an instance of the meta field"
26
- )
27
-
28
- ss.item('_owner').load 'frank'
29
- assert_equal(
30
- 'frank',
31
- ss.val('_owner'),
32
- 'Meta::Owner#load should work like normal fields'
33
- )
34
- assert_equal(
35
- 'frank',
36
- ss[:owner],
37
- 'Meta::Owner#load should update the [:owner] of the parent set'
38
- )
39
-
40
- ss.item('_owner').update 'carl'
41
- assert_equal(
42
- 'frank',
43
- ss.val('_owner'),
44
- 'Meta::Owner should not be updated'
45
- )
46
- assert(
47
- !ss.item('_owner').pending?,
48
- 'Meta::Owner should not be updated'
49
- )
50
- assert_equal(
51
- 'frank',
52
- ss[:owner],
53
- 'Meta::Owner should not be updated'
54
- )
55
- end
56
-
57
- end
@@ -1,1516 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- # Author:: Akira FUNAI
4
- # Copyright:: Copyright (c) 2009 Akira FUNAI
5
-
6
- require "#{::File.dirname __FILE__}/t"
7
-
8
- class TC_Parser < Test::Unit::TestCase
9
-
10
- def setup
11
- end
12
-
13
- def teardown
14
- end
15
-
16
- def test_scan_tokens
17
- assert_equal(
18
- {:tokens => ['foo', 'bar', 'baz']},
19
- Runo::Parser.scan_tokens(StringScanner.new('foo bar baz')),
20
- 'Parser.scan_tokens should be able to parse unquoted tokens into array'
21
- )
22
- assert_equal(
23
- {:tokens => ['foo', 'bar', 'baz baz']},
24
- Runo::Parser.scan_tokens(StringScanner.new('foo "bar" "baz baz"')),
25
- 'Parser.scan_tokens should be able to parse quoted tokens'
26
- )
27
- assert_equal(
28
- {:tokens => ['foo', 'bar', 'baz']},
29
- Runo::Parser.scan_tokens(StringScanner.new("foo 'bar' baz")),
30
- 'Parser.scan_tokens should be able to parse quoted tokens'
31
- )
32
-
33
- assert_equal(
34
- {:tokens => ['foo', 'bar', 'baz']},
35
- Runo::Parser.scan_tokens(StringScanner.new("foo 'bar' baz) qux")),
36
- 'Parser.scan_tokens should stop scanning at an ending bracket'
37
- )
38
- assert_equal(
39
- {:tokens => ['foo', 'bar (bar?)', 'baz']},
40
- Runo::Parser.scan_tokens(StringScanner.new("foo 'bar (bar?)' baz) qux")),
41
- 'Parser.scan_tokens should ignore brackets inside quoted tokens'
42
- )
43
- end
44
-
45
- def test_parse_empty_tag
46
- result = Runo::Parser.parse_html('hello $(foo = bar "baz baz") world')
47
- assert_equal(
48
- {'foo' => {:klass => 'bar', :tokens => ['baz baz']}},
49
- result[:item],
50
- 'Parser.parse_html should be able to parse empty runo tags'
51
- )
52
- assert_equal(
53
- {:index => 'hello $(foo) world'},
54
- result[:tmpl],
55
- 'Parser.parse_html[:tmpl] should be a proper template'
56
- )
57
-
58
- result = Runo::Parser.parse_html <<'_html'
59
- <h1>$(foo=bar "baz baz")</h1>
60
- <p>$(bar=a b c)</p>
61
- _html
62
- assert_equal(
63
- {
64
- 'foo' => {:klass => 'bar', :tokens => ['baz baz']},
65
- 'bar' => {:klass => 'a', :tokens => ['b', 'c']},
66
- },
67
- result[:item],
68
- 'Parser.parse_html should be able to parse empty runo tags'
69
- )
70
- assert_equal(
71
- {:index => <<'_html'},
72
- <h1>$(foo)</h1>
73
- <p>$(bar)</p>
74
- _html
75
- result[:tmpl],
76
- 'Parser.parse_html[:tmpl] should be a proper template'
77
- )
78
- end
79
-
80
- def test_parse_empty_tag_in_comment
81
- html = 'hello <!-- $(foo = bar "baz baz") --> world'
82
- result = Runo::Parser.parse_html html
83
- assert_equal(
84
- {},
85
- result[:item],
86
- 'Parser.parse_html should skip runo tags in a comment'
87
- )
88
- assert_equal(
89
- {:index => html},
90
- result[:tmpl],
91
- 'Parser.parse_html should skip runo tags in a comment'
92
- )
93
-
94
- html = '<script><![CDATA[ $(foo = bar "baz baz") ]]></script>'
95
- result = Runo::Parser.parse_html html
96
- assert_equal(
97
- {},
98
- result[:item],
99
- 'Parser.parse_html should skip runo tags in a comment'
100
- )
101
- assert_equal(
102
- {:index => html},
103
- result[:tmpl],
104
- 'Parser.parse_html should skip runo tags in a comment'
105
- )
106
- end
107
-
108
- def test_obscure_markup
109
- result = Runo::Parser.parse_html('hello $(foo = bar $(baz=1) baz) world')
110
- assert_equal(
111
- {'foo' => {:klass => 'bar', :tokens => ['$(baz=1']}},
112
- result[:item],
113
- 'Parser.parse_html should not parse nested empty tag'
114
- )
115
- assert_equal(
116
- {:index => 'hello $(foo) baz) world'},
117
- result[:tmpl],
118
- 'Parser.parse_html[:tmpl] should be a proper template'
119
- )
120
-
121
- result = Runo::Parser.parse_html('hello $(foo = bar baz world')
122
- assert_equal(
123
- {'foo' => {:klass => 'bar', :tokens => ['baz', 'world']}},
124
- result[:item],
125
- 'Parser.parse_html should be able to parse a tag that is not closed'
126
- )
127
- assert_equal(
128
- {:index => 'hello $(foo)'},
129
- result[:tmpl],
130
- 'Parser.parse_html should be able to parse a tag that is not closed'
131
- )
132
-
133
- result = Runo::Parser.parse_html('hello $(foo = bar "baz"world)')
134
- assert_equal(
135
- {'foo' => {:klass => 'bar', :tokens => ['baz', 'world']}},
136
- result[:item],
137
- 'Parser.parse_html should be able to parse tokens without a delimiter'
138
- )
139
- assert_equal(
140
- {:index => 'hello $(foo)'},
141
- result[:tmpl],
142
- 'Parser.parse_html should be able to parse tokens without a delimiter'
143
- )
144
-
145
- result = Runo::Parser.parse_html('hello $(foo = bar, "baz")')
146
- assert_equal(
147
- {'foo' => {:klass => 'bar', :options => ['baz']}},
148
- result[:item],
149
- 'The first token should be regarded as [:klass]'
150
- )
151
- end
152
-
153
- def test_parse_token
154
- assert_equal(
155
- {:width => 160, :height => 120},
156
- Runo::Parser.parse_token(nil, '160*120', {}),
157
- 'Parser.parse_token should be able to parse dimension tokens'
158
- )
159
- assert_equal(
160
- {:min => 1, :max => 32},
161
- Runo::Parser.parse_token(nil, '1..32', {}),
162
- 'Parser.parse_token should be able to parse range tokens'
163
- )
164
- assert_equal(
165
- {:max => 32},
166
- Runo::Parser.parse_token(nil, '..32', {}),
167
- 'Parser.parse_token should be able to parse partial range tokens'
168
- )
169
- assert_equal(
170
- {:min => 1},
171
- Runo::Parser.parse_token(nil, '1..', {}),
172
- 'Parser.parse_token should be able to parse partial range tokens'
173
- )
174
- assert_equal(
175
- {:min => -32, :max => -1},
176
- Runo::Parser.parse_token(nil, '-32..-1', {}),
177
- 'Parser.parse_token should be able to parse minus range tokens'
178
- )
179
-
180
- assert_equal(
181
- {:options => ['foo']},
182
- Runo::Parser.parse_token(',', 'foo', {}),
183
- 'Parser.parse_token should be able to parse option tokens'
184
- )
185
- assert_equal(
186
- {:options => ['foo', 'bar']},
187
- Runo::Parser.parse_token(',', 'bar', {:options => ['foo']}),
188
- 'Parser.parse_token should be able to parse option tokens'
189
- )
190
-
191
- assert_equal(
192
- {:default => 'bar'},
193
- Runo::Parser.parse_token(':', 'bar', {}),
194
- 'Parser.parse_token should be able to parse default tokens'
195
- )
196
- assert_equal(
197
- {:defaults => ['bar', 'baz']},
198
- Runo::Parser.parse_token(';', 'baz', {:defaults => ['bar']}),
199
- 'Parser.parse_token should be able to parse defaults tokens'
200
- )
201
- end
202
-
203
- def test_parse_options
204
- result = Runo::Parser.parse_html('hello $(foo = bar , "baz baz", "world", hi qux)')
205
- assert_equal(
206
- {'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
207
- result[:item],
208
- 'Parser.parse_html should be able to parse a sequence of CSV'
209
- )
210
- result = Runo::Parser.parse_html('hello $(foo = bar "baz baz", "world", hi qux)')
211
- assert_equal(
212
- {'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
213
- result[:item],
214
- 'Parser.parse_html should be able to parse a sequence of CSV'
215
- )
216
- end
217
-
218
- def test_parse_options_with_spaces
219
- result = Runo::Parser.parse_html('hello $(foo = bar world, qux)')
220
- assert_equal(
221
- {'foo' => {:klass => 'bar', :options => ['world', 'qux']}},
222
- result[:item],
223
- 'Parser.parse_html should allow spaces after the comma'
224
- )
225
- result = Runo::Parser.parse_html('hello $(foo = bar world , qux)')
226
- assert_equal(
227
- {'foo' => {:klass => 'bar', :options => ['qux'], :tokens => ['world']}},
228
- result[:item],
229
- 'Parser.parse_html should not allow spaces before the comma'
230
- )
231
- result = Runo::Parser.parse_html('hello $(foo = bar "baz baz", "world", hi qux)')
232
- assert_equal(
233
- {'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
234
- result[:item],
235
- 'Parser.parse_html should allow spaces after the comma'
236
- )
237
-
238
- result = Runo::Parser.parse_html(<<'_eos')
239
- hello $(foo =
240
- bar
241
- "baz baz",
242
- "world",
243
- hi
244
- qux)
245
- _eos
246
- assert_equal(
247
- {'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
248
- result[:item],
249
- 'Parser.parse_html should allow spaces after the comma'
250
- )
251
- end
252
-
253
- def test_parse_defaults
254
- result = Runo::Parser.parse_html('hello $(foo = bar ;"baz baz";"world";hi qux)')
255
- assert_equal(
256
- {'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
257
- result[:item],
258
- 'Parser.parse_html should be able to parse a sequence of CSV as [:defaults]'
259
- )
260
- result = Runo::Parser.parse_html('hello $(foo = bar "baz baz";"world";hi qux)')
261
- assert_equal(
262
- {'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
263
- result[:item],
264
- 'Parser.parse_html should be able to parse a sequence of CSV as [:defaults]'
265
- )
266
- end
267
-
268
- def test_parse_defaults_with_spaces
269
- result = Runo::Parser.parse_html('hello $(foo=bar world; qux)')
270
- assert_equal(
271
- {'foo' => {:klass => 'bar', :defaults => ['world', 'qux']}},
272
- result[:item],
273
- 'Parser.parse_html should allow spaces after the semicolon'
274
- )
275
- result = Runo::Parser.parse_html('hello $(foo=bar world ;qux)')
276
- assert_equal(
277
- {'foo' => {:klass => 'bar', :defaults => ['qux'], :tokens => ['world']}},
278
- result[:item],
279
- 'Parser.parse_html should not allow spaces before the semicolon'
280
- )
281
- result = Runo::Parser.parse_html('hello $(foo=bar "baz baz"; "world"; hi qux)')
282
- assert_equal(
283
- {'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
284
- result[:item],
285
- 'Parser.parse_html should allow spaces after the comma'
286
- )
287
-
288
- result = Runo::Parser.parse_html(<<'_eos')
289
- hello $(foo =
290
- bar
291
- "baz baz";
292
- "world";
293
- hi
294
- qux)
295
- _eos
296
- assert_equal(
297
- {'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
298
- result[:item],
299
- 'Parser.parse_html should allow spaces after the comma'
300
- )
301
- end
302
-
303
- def test_parse_meta_tag
304
- result = Runo::Parser.parse_html <<'_html'
305
- <html>
306
- <meta name="runo-owner" content="frank" />
307
- </html>
308
- _html
309
- assert_equal(
310
- {
311
- :tmpl => {
312
- :index => <<'_html',
313
- <html>
314
- </html>
315
- _html
316
- },
317
- :item => {},
318
- :owner => 'frank',
319
- :label => nil,
320
- },
321
- result,
322
- 'Parser.parse_html should scrape meta vals from <meta>'
323
- )
324
-
325
- result = Runo::Parser.parse_html <<'_html'
326
- <html>
327
- <meta name="runo-owner" content="frank" />
328
- <meta name="runo-group" content="bob,carl" />
329
- <meta name="runo-foo" content="bar, baz" />
330
- <meta name="runo-label" content="Qux" />
331
- </html>
332
- _html
333
- assert_equal(
334
- {
335
- :tmpl => {
336
- :index => <<'_html',
337
- <html>
338
- </html>
339
- _html
340
- },
341
- :item => {},
342
- :owner => 'frank',
343
- :group => %w(bob carl),
344
- :foo => %w(bar baz),
345
- :label => 'Qux',
346
- },
347
- result,
348
- 'Parser.parse_html should scrape meta vals from <meta>'
349
- )
350
- end
351
-
352
- def test_parse_duplicate_tag
353
- result = Runo::Parser.parse_html('hello $(foo = bar "baz baz") world $(foo=boo) $(foo)!')
354
- assert_equal(
355
- {'foo' => {:klass => 'boo'}},
356
- result[:item],
357
- 'definition tags are overridden by a preceding definition'
358
- )
359
- assert_equal(
360
- {:index => 'hello $(foo) world $(foo) $(foo)!'},
361
- result[:tmpl],
362
- 'Parser.parse_html[:tmpl] should be a proper template'
363
- )
364
- end
365
-
366
- def test_scan_inner_html
367
- s = StringScanner.new 'bar</foo>bar'
368
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
369
- assert_equal(
370
- 'bar',
371
- inner_html,
372
- 'Parser.scan_inner_html should extract the inner html from the scanner'
373
- )
374
- assert_equal(
375
- '</foo>',
376
- close_tag,
377
- 'Parser.scan_inner_html should extract the inner html from the scanner'
378
- )
379
-
380
- s = StringScanner.new '<foo>bar</foo></foo>'
381
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
382
- assert_equal(
383
- '<foo>bar</foo>',
384
- inner_html,
385
- 'Parser.scan_inner_html should be aware of nested tags'
386
- )
387
-
388
- s = StringScanner.new "baz\n <foo>bar</foo>\n</foo>"
389
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
390
- assert_equal(
391
- "baz\n <foo>bar</foo>\n",
392
- inner_html,
393
- 'Parser.scan_inner_html should be aware of nested tags'
394
- )
395
- end
396
-
397
- def test_scan_comment
398
- s = StringScanner.new 'baz -->'
399
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, '!--')
400
- assert_equal(
401
- 'baz',
402
- inner_html,
403
- 'Parser.scan_inner_html should parse html comments'
404
- )
405
- assert_equal(
406
- ' -->',
407
- close_tag,
408
- 'Parser.scan_inner_html should parse html comments'
409
- )
410
-
411
- s = StringScanner.new "baz\n <!--bar-->\n-->"
412
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, '!--')
413
- assert_equal(
414
- "baz\n <!--bar-->\n",
415
- inner_html,
416
- 'Parser.scan_inner_html should parse nested comments'
417
- )
418
- end
419
-
420
- def test_scan_cdata
421
- s = StringScanner.new 'baz ]]>'
422
- inner_html, close_tag = Runo::Parser.scan_inner_html(s, '<![CDATA[')
423
- assert_equal(
424
- 'baz',
425
- inner_html,
426
- 'Parser.scan_inner_html should parse CDATA section'
427
- )
428
- assert_equal(
429
- ' ]]>',
430
- close_tag,
431
- 'Parser.scan_inner_html should parse CDATA section'
432
- )
433
- end
434
-
435
- def test_parse_block_tag
436
- result = Runo::Parser.parse_html <<'_html'
437
- <ul class="app-blog" id="foo"><li>hello</li></ul>
438
- _html
439
- assert_equal(
440
- {
441
- 'foo' => {
442
- :klass => 'set-dynamic',
443
- :workflow => 'blog',
444
- :tmpl => {
445
- :index => <<'_tmpl'.chomp,
446
- <ul class="app-blog" id="@(name)">$()</ul>
447
- $(.navi)$(.submit)$(.action_create)
448
- _tmpl
449
- },
450
- :item => {
451
- 'default' => {
452
- :label => nil,
453
- :tmpl => {:index => '<li>hello</li>'},
454
- :item => {},
455
- },
456
- },
457
- },
458
- },
459
- result[:item],
460
- 'Parser.parse_html should be able to parse block runo tags'
461
- )
462
- assert_equal(
463
- {:index => '$(foo.message)$(foo)'},
464
- result[:tmpl],
465
- 'Parser.parse_html[:tmpl] should be a proper template'
466
- )
467
-
468
- result = Runo::Parser.parse_html <<'_html'
469
- <ul class="app-blog" id="foo">
470
- <li>hello</li>
471
- </ul>
472
- _html
473
- assert_equal(
474
- {
475
- 'foo' => {
476
- :klass => 'set-dynamic',
477
- :workflow => 'blog',
478
- :tmpl => {
479
- :index => <<'_tmpl'.chomp,
480
- <ul class="app-blog" id="@(name)">
481
- $()</ul>
482
- $(.navi)$(.submit)$(.action_create)
483
- _tmpl
484
- },
485
- :item => {
486
- 'default' => {
487
- :label => nil,
488
- :tmpl => {:index => " <li>hello</li>\n"},
489
- :item => {},
490
- },
491
- }
492
- },
493
- },
494
- result[:item],
495
- 'Parser.parse_html should be able to parse block runo tags'
496
- )
497
- assert_equal(
498
- {:index => '$(foo.message)$(foo)'},
499
- result[:tmpl],
500
- 'Parser.parse_html[:tmpl] should be a proper template'
501
- )
502
-
503
- result = Runo::Parser.parse_html <<'_html'
504
- hello <ul class="app-blog" id="foo"><li>hello</li></ul> world
505
- _html
506
- assert_equal(
507
- {
508
- 'foo' => {
509
- :klass => 'set-dynamic',
510
- :workflow => 'blog',
511
- :tmpl => {
512
- :index => <<'_tmpl'.chomp,
513
- <ul class="app-blog" id="@(name)">$()</ul>$(.navi)$(.submit)$(.action_create)
514
- _tmpl
515
- },
516
- :item => {
517
- 'default' => {
518
- :label => nil,
519
- :tmpl => {:index => '<li>hello</li>'},
520
- :item => {},
521
- },
522
- },
523
- },
524
- },
525
- result[:item],
526
- 'Parser.parse_html should be able to parse block runo tags'
527
- )
528
- assert_equal(
529
- {:index => <<'_html'},
530
- hello$(foo.message)$(foo) world
531
- _html
532
- result[:tmpl],
533
- 'Parser.parse_html[:tmpl] should be a proper template'
534
- )
535
-
536
- result = Runo::Parser.parse_html <<'_html'
537
- hello <!-- cruel --> <ul class="app-blog" id="foo"><li>hello</li></ul> world
538
- _html
539
- assert_equal(
540
- {
541
- 'foo' => {
542
- :klass => 'set-dynamic',
543
- :workflow => 'blog',
544
- :tmpl => {
545
- :index => <<'_tmpl'.chomp,
546
- <ul class="app-blog" id="@(name)">$()</ul>$(.navi)$(.submit)$(.action_create)
547
- _tmpl
548
- },
549
- :item => {
550
- 'default' => {
551
- :label => nil,
552
- :tmpl => {:index => '<li>hello</li>'},
553
- :item => {},
554
- },
555
- },
556
- },
557
- },
558
- result[:item],
559
- 'Parser.parse_html should be able to parse block runo tags'
560
- )
561
- assert_equal(
562
- {:index => <<'_html'},
563
- hello <!-- cruel -->$(foo.message)$(foo) world
564
- _html
565
- result[:tmpl],
566
- 'Parser.parse_html[:tmpl] should be a proper template'
567
- )
568
- end
569
-
570
- def test_parse_block_tag_in_comment
571
- [
572
- <<'_html',
573
- hello <!--<ul class="app-blog" id="test1"><li>hello</li></ul>--> world
574
- _html
575
- <<'_html',
576
- <!--
577
- <ul class="app-blog" id="test2">
578
- <li>hello</li>
579
- </ul>
580
- -->
581
- _html
582
- <<'_html',
583
- foo <!--
584
- <ul class="app-blog" id="test3">
585
- <li>hello</li>
586
- </ul>
587
- --> bar
588
- _html
589
- <<'_html',
590
- foo <!--
591
- <ul class="app-blog" id="test4">
592
- <li>hello</li>
593
- </ul>
594
- --> bar
595
- _html
596
- <<'_html',
597
- foo <!--
598
- <ul class="app-blog" id="test5">
599
- <!-- may_preview -->
600
- <li>hello</li>
601
- </ul>
602
- --> bar
603
- _html
604
- <<'_html',
605
- <![CDATA[
606
- <ul class="app-blog" id="test6">
607
- <!-- may_preview -->
608
- <li>hello</li>
609
- </ul>
610
- ]]>
611
- _html
612
- <<'_html',
613
- <!--
614
- <ul class="app-blog" id="test7">
615
- <!-- may_preview -->
616
- <li>hello</li>
617
- </ul>
618
- _html
619
- ].each {|html|
620
- result = Runo::Parser.parse_html html
621
- assert_equal(
622
- {},
623
- result[:item],
624
- 'Parser.parse_html should skip runo tags in a comment'
625
- )
626
- assert_equal(
627
- {:index => html},
628
- result[:tmpl],
629
- 'Parser.parse_html should skip runo tags in a comment'
630
- )
631
- }
632
- end
633
-
634
- def test_parse_block_tag_obsolete_runo_class
635
- result = Runo::Parser.parse_html <<'_html'
636
- <ul class="runo-blog" id="foo"><li>hello</li></ul>
637
- _html
638
- assert_equal(
639
- {
640
- 'foo' => {
641
- :klass => 'set-dynamic',
642
- :workflow => 'blog',
643
- :tmpl => {
644
- :index => <<'_html'.chomp,
645
- <ul class="runo-blog" id="@(name)">$()</ul>
646
- $(.navi)$(.submit)$(.action_create)
647
- _html
648
- },
649
- :item => {
650
- 'default' => {
651
- :label => nil,
652
- :tmpl => {:index => '<li>hello</li>'},
653
- :item => {},
654
- },
655
- },
656
- },
657
- },
658
- result[:item],
659
- 'Parser.parse_html should be able to parse block runo tags'
660
- )
661
- end
662
-
663
- def test_parse_block_tag_obsolete_body_class
664
- result = Runo::Parser.parse_html <<'_html'
665
- <ul class="app-blog" id="foo"><div>oops.</div><li class="body">hello</li></ul>
666
- _html
667
- assert_equal(
668
- {
669
- 'foo' => {
670
- :klass => 'set-dynamic',
671
- :workflow => 'blog',
672
- :tmpl => {
673
- :index => <<'_html'.chomp,
674
- <ul class="app-blog" id="@(name)"><div>oops.</div>$()</ul>
675
- $(.navi)$(.submit)$(.action_create)
676
- _html
677
- },
678
- :item => {
679
- 'default' => {
680
- :label => nil,
681
- :tmpl => {:index => '<li class="body">hello</li>'},
682
- :item => {},
683
- },
684
- },
685
- },
686
- },
687
- result[:item],
688
- 'Parser.parse_html should be able to parse block runo tags'
689
- )
690
- end
691
-
692
- def test_look_a_like_block_tag
693
- result = Runo::Parser.parse_html <<'_html'
694
- hello <ul class="not-app-blog" id="foo"><li>hello</li></ul> world
695
- _html
696
- assert_equal(
697
- {:index => <<'_tmpl'},
698
- hello <ul class="not-app-blog" id="foo"><li>hello</li></ul> world
699
- _tmpl
700
- result[:tmpl],
701
- "Parser.parse_html[:tmpl] should skip a class which does not start with 'runo'"
702
- )
703
- end
704
-
705
- def test_block_tags_with_options
706
- result = Runo::Parser.parse_html <<'_html'
707
- hello
708
- <table class="app-blog" id="foo">
709
- <!-- 1..20 barbaz -->
710
- <tbody class="model"><!-- qux --><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody>
711
- </table>
712
- world
713
- _html
714
- assert_equal(
715
- {
716
- 'foo' => {
717
- :min => 1,
718
- :max => 20,
719
- :tokens => ['barbaz'],
720
- :klass => 'set-dynamic',
721
- :workflow => 'blog',
722
- :tmpl => {
723
- :index => <<'_tmpl'.chomp,
724
- <table class="app-blog" id="@(name)">
725
- <!-- 1..20 barbaz -->
726
- $() </table>
727
- $(.navi)$(.submit)$(.action_create)
728
- _tmpl
729
- },
730
- :item => {
731
- 'default' => {
732
- :label => nil,
733
- :tmpl => {
734
- :index => <<'_tmpl',
735
- <tbody class="model"><!-- qux --><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody>
736
- _tmpl
737
- },
738
- :item => {
739
- 'bar' => {:klass => 'text'},
740
- 'baz' => {:klass => 'text'},
741
- },
742
- },
743
- },
744
- },
745
- },
746
- result[:item],
747
- 'Parser.parse_html should aware of <tbody class="model">'
748
- )
749
- end
750
-
751
- def test_block_tags_with_tbody
752
- result = Runo::Parser.parse_html <<'_html'
753
- hello
754
- <table class="app-blog" id="foo">
755
- <thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
756
- <tbody class="model"><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody>
757
- </table>
758
- world
759
- _html
760
- assert_equal(
761
- {
762
- 'foo' => {
763
- :klass => 'set-dynamic',
764
- :workflow => 'blog',
765
- :tmpl => {
766
- :index => <<'_tmpl'.chomp,
767
- <table class="app-blog" id="@(name)">
768
- <thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
769
- $() </table>
770
- $(.navi)$(.submit)$(.action_create)
771
- _tmpl
772
- },
773
- :item => {
774
- 'default' => {
775
- :label => nil,
776
- :tmpl => {
777
- :index => <<'_tmpl',
778
- <tbody class="model"><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody>
779
- _tmpl
780
- },
781
- :item => {
782
- 'bar' => {:klass => 'text'},
783
- 'baz' => {:klass => 'text'},
784
- },
785
- },
786
- },
787
- },
788
- },
789
- result[:item],
790
- 'Parser.parse_html should aware of <tbody class="model">'
791
- )
792
- assert_equal(
793
- {:index => <<'_tmpl'},
794
- hello
795
- $(foo.message)$(foo)world
796
- _tmpl
797
- result[:tmpl],
798
- 'Parser.parse_html[:tmpl] should be a proper template'
799
- )
800
- end
801
-
802
- def test_parse_xml
803
- result = Runo::Parser.parse_xml <<'_html'
804
- <channel class="app-rss">
805
- <link>@(href)</link>
806
- <item class="model">
807
- <title>$(title)</title>
808
- </item>
809
- </channel>
810
- _html
811
- assert_equal(
812
- {
813
- :label => nil,
814
- :tmpl => {:index => '$(main)'},
815
- :item => {
816
- 'main' => {
817
- :item => {
818
- 'default' => {
819
- :label => nil,
820
- :item => {},
821
- :tmpl => {
822
- :index => <<'_xml'
823
- <item>
824
- <title>$(title)</title>
825
- </item>
826
- _xml
827
- },
828
- },
829
- },
830
- :tmpl => {
831
- :index => <<'_xml',
832
- <channel>
833
- <link>@(href)</link>
834
- $()</channel>
835
- _xml
836
- },
837
- :klass => 'set-dynamic',
838
- :workflow => 'rss',
839
- }
840
- },
841
- },
842
- result,
843
- 'Parser.parse_html should aware of <item>'
844
- )
845
- end
846
-
847
- def test_parse_item_label
848
- result = Runo::Parser.parse_html <<'_html'
849
- <ul class="app-blog" id="foo"><li title="Greeting">hello</li></ul>
850
- _html
851
- assert_equal(
852
- 'Greeting',
853
- result[:item]['foo'][:item]['default'][:label],
854
- 'Parser.parse_html should pick up item labels from title attrs'
855
- )
856
-
857
- result = Runo::Parser.parse_html <<'_html'
858
- <ul class="app-blog" id="foo"><!-- foo --><li title="Greeting">hello</li></ul>
859
- _html
860
- assert_equal(
861
- 'Greeting',
862
- result[:item]['foo'][:item]['default'][:label],
863
- 'Parser.parse_html should pick up item labels from title attrs'
864
- )
865
-
866
- result = Runo::Parser.parse_html <<'_html'
867
- <ul class="app-blog" id="foo"><!-- foo --><li><div title="Foo">hello</div></li></ul>
868
- _html
869
- assert_nil(
870
- result[:item]['foo'][:item]['default'][:label],
871
- 'Parser.parse_html should pick up item labels only from the first tags'
872
- )
873
- end
874
-
875
- def test_parse_item_label_plural
876
- result = Runo::Parser.parse_html <<'_html'
877
- <ul class="app-blog" id="foo"><li title="tEntry, tEntries">hello</li></ul>
878
- _html
879
- assert_equal(
880
- 'tEntry',
881
- result[:item]['foo'][:item]['default'][:label],
882
- 'Parser.parse_html should split plural item labels'
883
- )
884
- assert_equal(
885
- ['tEntry', 'tEntries'],
886
- Runo::I18n.msg['tEntry'],
887
- 'Parser.parse_html should I18n.merge_msg! the plural item labels'
888
- )
889
-
890
- result = Runo::Parser.parse_html <<'_html'
891
- <ul class="app-blog" id="foo"><li title="tFooFoo, BarBar, BazBaz">hello</li></ul>
892
- _html
893
- assert_equal(
894
- 'tFooFoo',
895
- result[:item]['foo'][:item]['default'][:label],
896
- 'Parser.parse_html should split plural item labels'
897
- )
898
- assert_equal(
899
- ['tFooFoo', 'BarBar', 'BazBaz'],
900
- Runo::I18n.msg['tFooFoo'],
901
- 'Parser.parse_html should I18n.merge_msg! the plural item labels'
902
- )
903
-
904
- result = Runo::Parser.parse_html <<'_html'
905
- <ul class="app-blog" id="foo"><li title="tQux">hello</li></ul>
906
- _html
907
- assert_equal(
908
- 'tQux',
909
- result[:item]['foo'][:item]['default'][:label],
910
- 'Parser.parse_html should split plural item labels'
911
- )
912
- assert_equal(
913
- ['tQux', 'tQux', 'tQux', 'tQux'],
914
- Runo::I18n.msg['tQux'],
915
- 'Parser.parse_html should repeat a singular label to fill all possible plural forms'
916
- )
917
- end
918
-
919
- def test_block_tags_with_nested_tbody
920
- result = Runo::Parser.parse_html <<'_html'
921
- hello
922
- <table class="app-blog" id="foo">
923
- <thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
924
- <tbody class="model"><tbody><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody></tbody>
925
- </table>
926
- world
927
- _html
928
- assert_equal(
929
- {
930
- 'foo' => {
931
- :klass => 'set-dynamic',
932
- :workflow => 'blog',
933
- :tmpl => {
934
- :index => <<'_tmpl'.chomp,
935
- <table class="app-blog" id="@(name)">
936
- <thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
937
- $() </table>
938
- $(.navi)$(.submit)$(.action_create)
939
- _tmpl
940
- },
941
- :item => {
942
- 'default' => {
943
- :label => nil,
944
- :tmpl => {
945
- :index => <<'_tmpl',
946
- <tbody class="model"><tbody><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody></tbody>
947
- _tmpl
948
- },
949
- :item => {
950
- 'bar' => {:klass => 'text'},
951
- 'baz' => {:klass => 'text'},
952
- },
953
- },
954
- },
955
- },
956
- },
957
- result[:item],
958
- 'Parser.parse_html should aware of nested <tbody class="model">'
959
- )
960
- end
961
-
962
- def test_nested_block_tags
963
- result = Runo::Parser.parse_html <<'_html'
964
- <ul class="app-blog" id="foo">
965
- <li>
966
- <ul class="app-blog" id="bar"><li>baz</li></ul>
967
- </li>
968
- </ul>
969
- _html
970
- assert_equal(
971
- {
972
- 'foo' => {
973
- :klass => 'set-dynamic',
974
- :workflow => 'blog',
975
- :tmpl => {
976
- :index => <<'_tmpl'.chomp,
977
- <ul class="app-blog" id="@(name)">
978
- $()</ul>
979
- $(.navi)$(.submit)$(.action_create)
980
- _tmpl
981
- },
982
- :item => {
983
- 'default' => {
984
- :label => nil,
985
- :tmpl => {
986
- :index => <<'_tmpl',
987
- <li>
988
- $(bar.message)$(.a_update)$(bar)$(.hidden)</a> </li>
989
- _tmpl
990
- },
991
- :item => {
992
- 'bar' => {
993
- :klass => 'set-dynamic',
994
- :workflow => 'blog',
995
- :tmpl => {
996
- :index => <<'_tmpl'.chomp,
997
- <ul class="app-blog" id="@(name)">$()</ul>
998
- $(.navi)$(.submit)$(.action_create)
999
- _tmpl
1000
- },
1001
- :item => {
1002
- 'default' => {
1003
- :label => nil,
1004
- :tmpl => {:index => '<li>baz</li>'},
1005
- :item => {},
1006
- },
1007
- },
1008
- },
1009
- },
1010
- },
1011
- },
1012
- },
1013
- },
1014
- result[:item],
1015
- 'Parser.parse_html should be able to parse nested block runo tags'
1016
- )
1017
- assert_equal(
1018
- {:index => '$(foo.message)$(foo)'},
1019
- result[:tmpl],
1020
- 'Parser.parse_html[:tmpl] should be a proper template'
1021
- )
1022
- end
1023
-
1024
- def test_combination
1025
- result = Runo::Parser.parse_html <<'_html'
1026
- <html>
1027
- <h1>$(title=text 32)</h1>
1028
- <ul id="foo" class="app-blog">
1029
- <li>
1030
- $(subject=text 64)
1031
- $(body=textarea 72*10)
1032
- <ul><li>qux</li></ul>
1033
- </li>
1034
- </ul>
1035
- </html>
1036
- _html
1037
- assert_equal(
1038
- {
1039
- 'title' => {:klass => 'text', :tokens => ['32']},
1040
- 'foo' => {
1041
- :klass => 'set-dynamic',
1042
- :workflow => 'blog',
1043
- :tmpl => {
1044
- :index => <<'_tmpl'.chomp,
1045
- <ul id="@(name)" class="app-blog">
1046
- $() </ul>
1047
- $(.navi)$(.submit)$(.action_create)
1048
- _tmpl
1049
- },
1050
- :item => {
1051
- 'default' => {
1052
- :label => nil,
1053
- :tmpl => {
1054
- :index => <<'_tmpl',
1055
- <li>
1056
- $(.a_update)$(subject)</a>
1057
- $(body)$(.hidden)
1058
- <ul><li>qux</li></ul>
1059
- </li>
1060
- _tmpl
1061
- },
1062
- :item => {
1063
- 'body' => {
1064
- :width => 72,
1065
- :height => 10,
1066
- :klass => 'textarea',
1067
- },
1068
- 'subject' => {
1069
- :tokens => ['64'],
1070
- :klass => 'text',
1071
- },
1072
- },
1073
- },
1074
- },
1075
- },
1076
- },
1077
- result[:item],
1078
- 'Parser.parse_html should be able to parse combination of mixed runo tags'
1079
- )
1080
- assert_equal(
1081
- {:index => <<'_tmpl'},
1082
- <html>
1083
- <h1>$(title)</h1>
1084
- $(foo.message)$(foo)</html>
1085
- _tmpl
1086
- result[:tmpl],
1087
- 'Parser.parse_html[:tmpl] should be a proper template'
1088
- )
1089
- end
1090
-
1091
- def test_gsub_block
1092
- match = nil
1093
- result = Runo::Parser.gsub_block('a<div class="foo">bar</div>c', 'foo') {|open, inner, close|
1094
- match = [open, inner, close]
1095
- 'b'
1096
- }
1097
- assert_equal(
1098
- 'abc',
1099
- result,
1100
- 'Parser.gsub_block should replace tag blocks of the matching class with the given value'
1101
- )
1102
- assert_equal(
1103
- ['<div class="foo">', 'bar', '</div>'],
1104
- match,
1105
- 'Parser.gsub_block should pass the matching element to its block'
1106
- )
1107
-
1108
- result = Runo::Parser.gsub_block('<p><div class="foo">bar</div></p>', 'foo') {|open, inner, close|
1109
- match = [open, inner, close]
1110
- 'b'
1111
- }
1112
- assert_equal(
1113
- '<p>b</p>',
1114
- result,
1115
- 'Parser.gsub_block should replace tag blocks of the matching class with the given value'
1116
- )
1117
- assert_equal(
1118
- ['<div class="foo">', 'bar', '</div>'],
1119
- match,
1120
- 'Parser.gsub_block should pass the matching element to its block'
1121
- )
1122
-
1123
- result = Runo::Parser.gsub_block('a<p><div class="foo">bar</div></p>c', 'foo') {|open, inner, close|
1124
- match = [open, inner, close]
1125
- 'b'
1126
- }
1127
- assert_equal(
1128
- 'a<p>b</p>c',
1129
- result,
1130
- 'Parser.gsub_block should replace tag blocks of the matching class with the given value'
1131
- )
1132
- assert_equal(
1133
- ['<div class="foo">', 'bar', '</div>'],
1134
- match,
1135
- 'Parser.gsub_block should pass the matching element to its block'
1136
- )
1137
- end
1138
-
1139
- def _test_gsub_action_tmpl(html)
1140
- result = {}
1141
- html = Runo::Parser.gsub_action_tmpl(html) {|id, action, *tmpl|
1142
- result[:id] = id
1143
- result[:action] = action
1144
- result[:tmpl] = tmpl.join
1145
- 'b'
1146
- }
1147
- [result, html]
1148
- end
1149
-
1150
- def test_gsub_action_tmpl
1151
- result, html = _test_gsub_action_tmpl 'a<div class="foo-navi">Foo</div>c'
1152
- assert_equal(
1153
- {
1154
- :id => 'foo',
1155
- :action => :navi,
1156
- :tmpl => '<div class="foo-navi">Foo</div>',
1157
- },
1158
- result,
1159
- 'Parser.gsub_action_tmpl should yield action templates'
1160
- )
1161
- assert_equal(
1162
- 'abc',
1163
- html,
1164
- 'Parser.gsub_action_tmpl should replace the action template with a value from the block'
1165
- )
1166
-
1167
- result, html = _test_gsub_action_tmpl 'a<div class="bar foo-navi">Foo</div>c'
1168
- assert_equal(
1169
- {
1170
- :id => 'foo',
1171
- :action => :navi,
1172
- :tmpl => '<div class="bar foo-navi">Foo</div>',
1173
- },
1174
- result,
1175
- 'Parser.gsub_action_tmpl should yield action templates'
1176
- )
1177
-
1178
- result, html = _test_gsub_action_tmpl 'a<div class="bar foo-navi baz">Foo</div>c'
1179
- assert_equal(
1180
- {
1181
- :id => 'foo',
1182
- :action => :navi,
1183
- :tmpl => '<div class="bar foo-navi baz">Foo</div>',
1184
- },
1185
- result,
1186
- 'Parser.gsub_action_tmpl should yield action templates'
1187
- )
1188
-
1189
- result, html = _test_gsub_action_tmpl 'a<div class="bar foo-done baz">Foo</div>c'
1190
- assert_equal(
1191
- {
1192
- :id => 'foo',
1193
- :action => :done,
1194
- :tmpl => '<div class="bar foo-done baz">Foo</div>',
1195
- },
1196
- result,
1197
- 'Parser.gsub_action_tmpl should yield action templates'
1198
- )
1199
- end
1200
-
1201
- def test_gsub_action_tmpl_with_empty_id
1202
- result, html = _test_gsub_action_tmpl 'a<div class="navi">Foo</div>c'
1203
- assert_equal(
1204
- {
1205
- :id => nil,
1206
- :action => :navi,
1207
- :tmpl => '<div class="navi">Foo</div>',
1208
- },
1209
- result,
1210
- 'Parser.gsub_action_tmpl should yield action templates'
1211
- )
1212
-
1213
- result, html = _test_gsub_action_tmpl 'a<div class="foo navi">Foo</div>c'
1214
- assert_equal(
1215
- {
1216
- :id => nil,
1217
- :action => :navi,
1218
- :tmpl => '<div class="foo navi">Foo</div>',
1219
- },
1220
- result,
1221
- 'Parser.gsub_action_tmpl should yield action templates'
1222
- )
1223
-
1224
- result, html = _test_gsub_action_tmpl 'a<div class="foo navi baz">Foo</div>c'
1225
- assert_equal(
1226
- {
1227
- :id => nil,
1228
- :action => :navi,
1229
- :tmpl => '<div class="foo navi baz">Foo</div>',
1230
- },
1231
- result,
1232
- 'Parser.gsub_action_tmpl should yield action templates'
1233
- )
1234
- end
1235
-
1236
- def test_gsub_action_tmpl_with_ambiguous_klass
1237
- result, html = _test_gsub_action_tmpl 'a<div class="not_navi">Foo</div>c'
1238
- assert_equal(
1239
- {},
1240
- result,
1241
- 'Parser.gsub_action_tmpl should ignore classes other than action, view, navi or submit'
1242
- )
1243
-
1244
- result, html = _test_gsub_action_tmpl 'a<div class="navi_bar">Foo</div>c'
1245
- assert_equal(
1246
- {
1247
- :id => nil,
1248
- :action => :navi_bar,
1249
- :tmpl => '<div class="navi_bar">Foo</div>',
1250
- },
1251
- result,
1252
- 'Parser.gsub_action_tmpl should yield an action template if the klass looks like special'
1253
- )
1254
- end
1255
-
1256
- def test_action_tmpl_in_ss
1257
- result = Runo::Parser.parse_html <<'_html'
1258
- <html>
1259
- <ul id="foo" class="app-blog">
1260
- <li>$(subject=text)</li>
1261
- </ul>
1262
- <div class="foo-navi">bar</div>
1263
- </html>
1264
- _html
1265
- assert_equal(
1266
- <<'_tmpl',
1267
- <div class="foo-navi">bar</div>
1268
- _tmpl
1269
- result[:item]['foo'][:tmpl][:navi],
1270
- 'Parser.parse_html should parse action templates in the html'
1271
- )
1272
- assert_equal(
1273
- {:index => <<'_tmpl'},
1274
- <html>
1275
- $(foo.message)$(foo)$(foo.navi)</html>
1276
- _tmpl
1277
- result[:tmpl],
1278
- 'Parser.parse_html should replace action templates with proper tags'
1279
- )
1280
- end
1281
-
1282
- def test_action_tmpl_in_ss_with_nil_id
1283
- result = Runo::Parser.parse_html <<'_html'
1284
- <html>
1285
- <ul id="main" class="app-blog">
1286
- <li>$(subject=text)</li>
1287
- </ul>
1288
- <div class="navi">bar</div>
1289
- </html>
1290
- _html
1291
- assert_equal(
1292
- <<'_tmpl',
1293
- <div class="navi">bar</div>
1294
- _tmpl
1295
- result[:item]['main'][:tmpl][:navi],
1296
- "Parser.parse_html should set action templates to item['main'] by default"
1297
- )
1298
- assert_equal(
1299
- {:index => <<'_tmpl'},
1300
- <html>
1301
- $(main.message)$(main)$(main.navi)</html>
1302
- _tmpl
1303
- result[:tmpl],
1304
- "Parser.parse_html should set action templates to item['main'] by default"
1305
- )
1306
- end
1307
-
1308
- def test_action_tmpl_in_ss_with_non_existent_id
1309
- result = Runo::Parser.parse_html <<'_html'
1310
- <html>
1311
- <ul id="main" class="app-blog">
1312
- <li>$(subject=text)</li>
1313
- </ul>
1314
- <div class="non_existent-navi">bar</div>
1315
- </html>
1316
- _html
1317
- assert_nil(
1318
- result[:item]['non_existent'],
1319
- 'Parser.parse_html should ignore the action template without a corresponding SD'
1320
- )
1321
- assert_equal(
1322
- {:index => <<'_tmpl'},
1323
- <html>
1324
- $(main.message)$(main) <div class="non_existent-navi">bar</div>
1325
- </html>
1326
- _tmpl
1327
- result[:tmpl],
1328
- 'Parser.parse_html should ignore the action template without a corresponding SD'
1329
- )
1330
- end
1331
-
1332
- def test_action_tmpl_in_ss_with_nested_action_tmpl
1333
- result = Runo::Parser.parse_html <<'_html'
1334
- <html>
1335
- <ul id="foo" class="app-blog">
1336
- <li>$(subject=text)</li>
1337
- </ul>
1338
- <div class="foo-navi"><span class="navi_prev">prev</span></div>
1339
- </html>
1340
- _html
1341
- assert_equal(
1342
- <<'_html',
1343
- <div class="foo-navi">$(.navi_prev)</div>
1344
- _html
1345
- result[:item]['foo'][:tmpl][:navi],
1346
- 'Parser.parse_html should parse nested action templates'
1347
- )
1348
- assert_equal(
1349
- '<span class="navi_prev">prev</span>',
1350
- result[:item]['foo'][:tmpl][:navi_prev],
1351
- 'Parser.parse_html should parse nested action templates'
1352
- )
1353
- assert_equal(
1354
- {
1355
- :index => <<'_html'.chomp,
1356
- <ul id="@(name)" class="app-blog">
1357
- $() </ul>
1358
- $(.submit)$(.action_create)
1359
- _html
1360
- :navi => <<'_html',
1361
- <div class="foo-navi">$(.navi_prev)</div>
1362
- _html
1363
- :navi_prev => '<span class="navi_prev">prev</span>',
1364
- },
1365
- result[:item]['foo'][:tmpl],
1366
- 'Parser.parse_html should parse nested action templates'
1367
- )
1368
-
1369
- result = Runo::Parser.parse_html <<'_html'
1370
- <html>
1371
- <ul id="foo" class="app-blog">
1372
- <li>$(subject=text)</li>
1373
- </ul>
1374
- <div class="foo-navi"><span class="bar-navi_prev">prev</span></div>
1375
- </html>
1376
- _html
1377
- assert_equal(
1378
- '<span class="bar-navi_prev">prev</span>',
1379
- result[:item]['foo'][:tmpl][:navi_prev],
1380
- 'Parser.parse_html should ignore the id of a nested action template'
1381
- )
1382
- end
1383
-
1384
- def test_action_tmpl_in_sd
1385
- result = Runo::Parser.parse_html <<'_html'
1386
- <ul id="foo" class="app-blog">
1387
- <li class="model">$(text)</li>
1388
- <div class="navi">bar</div>
1389
- </ul>
1390
- _html
1391
- assert_equal(
1392
- <<'_html',
1393
- <div class="navi">bar</div>
1394
- _html
1395
- result[:item]['foo'][:tmpl][:navi],
1396
- 'Parser.parse_html should parse action templates in sd[:tmpl]'
1397
- )
1398
- assert_match(
1399
- %r{\$\(\.navi\)},
1400
- result[:item]['foo'][:tmpl][:index],
1401
- 'Parser.parse_html should parse action templates in sd[:tmpl]'
1402
- )
1403
- end
1404
-
1405
- def test_action_tmpl_in_sd_with_nested_action_tmpl
1406
- result = Runo::Parser.parse_html <<'_html'
1407
- <ul id="foo" class="app-blog">
1408
- <li class="model">$(text)</li>
1409
- <div class="navi"><span class="navi_prev">prev</span></div>
1410
- </ul>
1411
- _html
1412
- assert_equal(
1413
- <<'_html',
1414
- <div class="navi">$(.navi_prev)</div>
1415
- _html
1416
- result[:item]['foo'][:tmpl][:navi],
1417
- 'Parser.parse_html should parse nested action templates in sd[:tmpl]'
1418
- )
1419
- assert_equal(
1420
- '<span class="navi_prev">prev</span>',
1421
- result[:item]['foo'][:tmpl][:navi_prev],
1422
- 'Parser.parse_html should parse nested action templates in sd[:tmpl]'
1423
- )
1424
- end
1425
-
1426
- def test_action_tmpl_in_comment
1427
- result = Runo::Parser.parse_html <<'_html'
1428
- <ul id="foo" class="app-blog">
1429
- <li class="model">$(text)</li>
1430
- <!--
1431
- <div class="navi"><span class="navi_prev">prev</span></div>
1432
- -->
1433
- </ul>
1434
- _html
1435
- assert_nil(
1436
- result[:item]['foo'][:tmpl][:navi],
1437
- 'Parser.parse_html should skip action templates in a comment'
1438
- )
1439
-
1440
- result = Runo::Parser.parse_html <<'_html'
1441
- <ul id="foo" class="app-blog">
1442
- <li class="model">$(text)</li>
1443
- <div class="navi"><!--<span class="navi_prev">prev</span>--></div>
1444
- </ul>
1445
- _html
1446
- assert_equal(
1447
- <<'_html',
1448
- <div class="navi"><!--<span class="navi_prev">prev</span>--></div>
1449
- _html
1450
- result[:item]['foo'][:tmpl][:navi],
1451
- 'Parser.parse_html should skip action templates in a comment'
1452
- )
1453
- end
1454
-
1455
- def test_supplement_sd
1456
- result = Runo::Parser.parse_html <<'_html'
1457
- <ul id="foo" class="app-blog">
1458
- <li class="model">$(text)</li>
1459
- </ul>
1460
- _html
1461
- assert_match(
1462
- /\$\(\.navi\)/,
1463
- result[:item]['foo'][:tmpl][:index],
1464
- 'Parser.supplement_sd should supplement sd[:tmpl] with default menus'
1465
- )
1466
-
1467
- result = Runo::Parser.parse_html <<'_html'
1468
- <ul id="foo" class="app-blog">
1469
- <div class="navi">bar</div>
1470
- <li class="model">$(text)</li>
1471
- </ul>
1472
- _html
1473
- assert_no_match(
1474
- /\$\(\.navi\).*\$\(\.navi\)/m,
1475
- result[:item]['foo'][:tmpl][:index],
1476
- 'Parser.supplement_sd should not supplement sd[:tmpl] when it already has the menu'
1477
- )
1478
-
1479
- result = Runo::Parser.parse_html <<'_html'
1480
- <div class="foo-navi">bar</div>
1481
- <ul id="foo" class="app-blog">
1482
- <li class="model">$(text)</li>
1483
- </ul>
1484
- _html
1485
- assert_no_match(
1486
- /\$\(\.navi\)/,
1487
- result[:item]['foo'][:tmpl][:index],
1488
- 'Parser.supplement_sd should not supplement sd[:tmpl] when it already has the menu'
1489
- )
1490
- end
1491
-
1492
- def test_supplement_ss
1493
- result = Runo::Parser.parse_html <<'_html'
1494
- <ul id="foo" class="app-blog">
1495
- <li class="model">$(text)</li>
1496
- </ul>
1497
- _html
1498
- assert_match(
1499
- /\$\(\.a_update\)/,
1500
- result[:item]['foo'][:item]['default'][:tmpl][:index],
1501
- 'Parser.supplement_ss should supplement ss[:tmpl] with default menus'
1502
- )
1503
-
1504
- result = Runo::Parser.parse_html <<'_html'
1505
- <ul id="foo" class="app-blog">
1506
- <li class="model">$(text) $(.action_update)</li>
1507
- </ul>
1508
- _html
1509
- assert_no_match(
1510
- /\$\(\.a_update\)/,
1511
- result[:item]['foo'][:item]['default'][:tmpl][:index],
1512
- 'Parser.supplement_ss should not supplement ss[:tmpl] when it already has the menu'
1513
- )
1514
- end
1515
-
1516
- end