runo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README.rdoc +120 -0
- data/bin/runo +35 -0
- data/lib/_error.rb +14 -0
- data/lib/_field.rb +260 -0
- data/lib/_i18n.rb +141 -0
- data/lib/_parser.rb +243 -0
- data/lib/_path.rb +86 -0
- data/lib/_storage/_storage.rb +213 -0
- data/lib/_storage/file.rb +200 -0
- data/lib/_storage/sequel.rb +174 -0
- data/lib/_storage/temp.rb +73 -0
- data/lib/_widget/action_create.rb +23 -0
- data/lib/_widget/action_login.rb +22 -0
- data/lib/_widget/action_signup.rb +16 -0
- data/lib/_widget/action_update.rb +16 -0
- data/lib/_widget/crumb.rb +24 -0
- data/lib/_widget/done.rb +16 -0
- data/lib/_widget/login.rb +25 -0
- data/lib/_widget/me.rb +31 -0
- data/lib/_widget/message.rb +51 -0
- data/lib/_widget/navi.rb +88 -0
- data/lib/_widget/submit.rb +49 -0
- data/lib/_widget/view_ym.rb +77 -0
- data/lib/_workflow/_workflow.rb +89 -0
- data/lib/_workflow/attachment.rb +50 -0
- data/lib/_workflow/blog.rb +28 -0
- data/lib/_workflow/contact.rb +23 -0
- data/lib/_workflow/forum.rb +26 -0
- data/lib/_workflow/register.rb +39 -0
- data/lib/meta/_meta.rb +20 -0
- data/lib/meta/group.rb +19 -0
- data/lib/meta/id.rb +59 -0
- data/lib/meta/owner.rb +21 -0
- data/lib/meta/timestamp.rb +118 -0
- data/lib/runo.rb +396 -0
- data/lib/scalar/checkbox.rb +68 -0
- data/lib/scalar/file.rb +144 -0
- data/lib/scalar/img.rb +112 -0
- data/lib/scalar/password.rb +58 -0
- data/lib/scalar/radio.rb +47 -0
- data/lib/scalar/select.rb +47 -0
- data/lib/scalar/text.rb +38 -0
- data/lib/scalar/textarea.rb +35 -0
- data/lib/scalar/textarea_pre.rb +14 -0
- data/lib/scalar/textarea_wiki.rb +173 -0
- data/lib/set/_set.rb +195 -0
- data/lib/set/dynamic.rb +177 -0
- data/lib/set/static.rb +102 -0
- data/lib/set/static_folder.rb +96 -0
- data/locale/en/index.po +242 -0
- data/locale/index.pot +243 -0
- data/locale/ja/index.po +242 -0
- data/locale/lazy_parser.rb +54 -0
- data/skel/config.ru +27 -0
- data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_frank.yaml +12 -0
- data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_root.yaml +11 -0
- data/skel/skin/_users/css/users.css +21 -0
- data/skel/skin/_users/css/users.less +25 -0
- data/skel/skin/_users/done.html +42 -0
- data/skel/skin/_users/index.html +46 -0
- data/skel/skin/_users/index.yaml +3 -0
- data/skel/skin/_users/summary.html +40 -0
- data/skel/skin/css/base.css +93 -0
- data/skel/skin/css/base.less +139 -0
- data/skel/skin/css/coax.css +199 -0
- data/skel/skin/css/coax.less +244 -0
- data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
- data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
- data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
- data/skel/skin/examples/blog/frank/index.yaml +4 -0
- data/skel/skin/examples/blog/index.html +51 -0
- data/skel/skin/examples/blog/rss.xml +18 -0
- data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
- data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
- data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
- data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
- data/skel/skin/examples/contact/index.html +47 -0
- data/skel/skin/examples/contact/js/contact.js +13 -0
- data/skel/skin/examples/contact/summary.html +54 -0
- data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
- data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
- data/skel/skin/examples/forum/index.html +68 -0
- data/skel/skin/examples/forum/summary.html +47 -0
- data/skel/skin/examples/index.html +75 -0
- data/skel/skin/index.html +41 -0
- data/skel/skin/js/base.js +50 -0
- data/t/locale/de/index.po +19 -0
- data/t/locale/en-GB/index.po +25 -0
- data/t/locale/ja/index.po +30 -0
- data/t/skin/_users/00000000_test.yaml +3 -0
- data/t/skin/_users/index.html +13 -0
- data/t/skin/foo/20091120_0001.yaml +7 -0
- data/t/skin/foo/bar/20091120_0001.yaml +5 -0
- data/t/skin/foo/bar/index.yaml +5 -0
- data/t/skin/foo/baz/css/baz.css +1 -0
- data/t/skin/foo/css/foo.css +1 -0
- data/t/skin/foo/index.html +14 -0
- data/t/skin/foo/index.yaml +7 -0
- data/t/skin/foo/not_css/foo.css +1 -0
- data/t/skin/foo/sub-20100306_0001.yaml +3 -0
- data/t/skin/index.yaml +3 -0
- data/t/skin/t_attachment/index.html +13 -0
- data/t/skin/t_contact/done.html +6 -0
- data/t/skin/t_contact/index.html +9 -0
- data/t/skin/t_file/index.html +16 -0
- data/t/skin/t_img/index.html +14 -0
- data/t/skin/t_img/test.jpg +0 -0
- data/t/skin/t_select/index.html +9 -0
- data/t/skin/t_store/index.html +9 -0
- data/t/skin/t_summary/20100326_0001.yaml +3 -0
- data/t/skin/t_summary/create.html +9 -0
- data/t/skin/t_summary/index.html +9 -0
- data/t/skin/t_summary/summary.html +9 -0
- data/t/t.rb +27 -0
- data/t/test_checkbox.rb +273 -0
- data/t/test_field.rb +330 -0
- data/t/test_file.rb +900 -0
- data/t/test_id.rb +215 -0
- data/t/test_img.rb +328 -0
- data/t/test_meta.rb +57 -0
- data/t/test_parser.rb +1266 -0
- data/t/test_password.rb +188 -0
- data/t/test_radio.rb +226 -0
- data/t/test_role.rb +249 -0
- data/t/test_runo.rb +742 -0
- data/t/test_runo_call.rb +1286 -0
- data/t/test_runo_i18n.rb +318 -0
- data/t/test_select.rb +182 -0
- data/t/test_set_complex.rb +527 -0
- data/t/test_set_dynamic.rb +1504 -0
- data/t/test_set_folder.rb +515 -0
- data/t/test_set_permit.rb +246 -0
- data/t/test_set_static.rb +445 -0
- data/t/test_storage.rb +915 -0
- data/t/test_text.rb +125 -0
- data/t/test_textarea.rb +138 -0
- data/t/test_timestamp.rb +473 -0
- data/t/test_workflow.rb +367 -0
- metadata +345 -0
data/t/test_meta.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
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
|
data/t/test_parser.rb
ADDED
|
@@ -0,0 +1,1266 @@
|
|
|
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_obscure_markup
|
|
81
|
+
result = Runo::Parser.parse_html('hello $(foo = bar $(baz=1) baz) world')
|
|
82
|
+
assert_equal(
|
|
83
|
+
{'foo' => {:klass => 'bar', :tokens => ['$(baz=1']}},
|
|
84
|
+
result[:item],
|
|
85
|
+
'Parser.parse_html should not parse nested empty tag'
|
|
86
|
+
)
|
|
87
|
+
assert_equal(
|
|
88
|
+
{:index => 'hello $(foo) baz) world'},
|
|
89
|
+
result[:tmpl],
|
|
90
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
result = Runo::Parser.parse_html('hello $(foo = bar baz world')
|
|
94
|
+
assert_equal(
|
|
95
|
+
{'foo' => {:klass => 'bar', :tokens => ['baz', 'world']}},
|
|
96
|
+
result[:item],
|
|
97
|
+
'Parser.parse_html should be able to parse a tag that is not closed'
|
|
98
|
+
)
|
|
99
|
+
assert_equal(
|
|
100
|
+
{:index => 'hello $(foo)'},
|
|
101
|
+
result[:tmpl],
|
|
102
|
+
'Parser.parse_html should be able to parse a tag that is not closed'
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
result = Runo::Parser.parse_html('hello $(foo = bar "baz"world)')
|
|
106
|
+
assert_equal(
|
|
107
|
+
{'foo' => {:klass => 'bar', :tokens => ['baz', 'world']}},
|
|
108
|
+
result[:item],
|
|
109
|
+
'Parser.parse_html should be able to parse tokens without a delimiter'
|
|
110
|
+
)
|
|
111
|
+
assert_equal(
|
|
112
|
+
{:index => 'hello $(foo)'},
|
|
113
|
+
result[:tmpl],
|
|
114
|
+
'Parser.parse_html should be able to parse tokens without a delimiter'
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
result = Runo::Parser.parse_html('hello $(foo = bar, "baz")')
|
|
118
|
+
assert_equal(
|
|
119
|
+
{'foo' => {:klass => 'bar', :options => ['baz']}},
|
|
120
|
+
result[:item],
|
|
121
|
+
'The first token should be regarded as [:klass]'
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_parse_token
|
|
126
|
+
assert_equal(
|
|
127
|
+
{:width => 160, :height => 120},
|
|
128
|
+
Runo::Parser.parse_token(nil, '160*120', {}),
|
|
129
|
+
'Parser.parse_token should be able to parse dimension tokens'
|
|
130
|
+
)
|
|
131
|
+
assert_equal(
|
|
132
|
+
{:min => 1, :max => 32},
|
|
133
|
+
Runo::Parser.parse_token(nil, '1..32', {}),
|
|
134
|
+
'Parser.parse_token should be able to parse range tokens'
|
|
135
|
+
)
|
|
136
|
+
assert_equal(
|
|
137
|
+
{:max => 32},
|
|
138
|
+
Runo::Parser.parse_token(nil, '..32', {}),
|
|
139
|
+
'Parser.parse_token should be able to parse partial range tokens'
|
|
140
|
+
)
|
|
141
|
+
assert_equal(
|
|
142
|
+
{:min => 1},
|
|
143
|
+
Runo::Parser.parse_token(nil, '1..', {}),
|
|
144
|
+
'Parser.parse_token should be able to parse partial range tokens'
|
|
145
|
+
)
|
|
146
|
+
assert_equal(
|
|
147
|
+
{:min => -32, :max => -1},
|
|
148
|
+
Runo::Parser.parse_token(nil, '-32..-1', {}),
|
|
149
|
+
'Parser.parse_token should be able to parse minus range tokens'
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
assert_equal(
|
|
153
|
+
{:options => ['foo']},
|
|
154
|
+
Runo::Parser.parse_token(',', 'foo', {}),
|
|
155
|
+
'Parser.parse_token should be able to parse option tokens'
|
|
156
|
+
)
|
|
157
|
+
assert_equal(
|
|
158
|
+
{:options => ['foo', 'bar']},
|
|
159
|
+
Runo::Parser.parse_token(',', 'bar', {:options => ['foo']}),
|
|
160
|
+
'Parser.parse_token should be able to parse option tokens'
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
assert_equal(
|
|
164
|
+
{:default => 'bar'},
|
|
165
|
+
Runo::Parser.parse_token(':', 'bar', {}),
|
|
166
|
+
'Parser.parse_token should be able to parse default tokens'
|
|
167
|
+
)
|
|
168
|
+
assert_equal(
|
|
169
|
+
{:defaults => ['bar', 'baz']},
|
|
170
|
+
Runo::Parser.parse_token(';', 'baz', {:defaults => ['bar']}),
|
|
171
|
+
'Parser.parse_token should be able to parse defaults tokens'
|
|
172
|
+
)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_parse_options
|
|
176
|
+
result = Runo::Parser.parse_html('hello $(foo = bar , "baz baz", "world", hi qux)')
|
|
177
|
+
assert_equal(
|
|
178
|
+
{'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
179
|
+
result[:item],
|
|
180
|
+
'Parser.parse_html should be able to parse a sequence of CSV'
|
|
181
|
+
)
|
|
182
|
+
result = Runo::Parser.parse_html('hello $(foo = bar "baz baz", "world", hi qux)')
|
|
183
|
+
assert_equal(
|
|
184
|
+
{'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
185
|
+
result[:item],
|
|
186
|
+
'Parser.parse_html should be able to parse a sequence of CSV'
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def test_parse_options_with_spaces
|
|
191
|
+
result = Runo::Parser.parse_html('hello $(foo = bar world, qux)')
|
|
192
|
+
assert_equal(
|
|
193
|
+
{'foo' => {:klass => 'bar', :options => ['world', 'qux']}},
|
|
194
|
+
result[:item],
|
|
195
|
+
'Parser.parse_html should allow spaces after the comma'
|
|
196
|
+
)
|
|
197
|
+
result = Runo::Parser.parse_html('hello $(foo = bar world , qux)')
|
|
198
|
+
assert_equal(
|
|
199
|
+
{'foo' => {:klass => 'bar', :options => ['qux'], :tokens => ['world']}},
|
|
200
|
+
result[:item],
|
|
201
|
+
'Parser.parse_html should not allow spaces before the comma'
|
|
202
|
+
)
|
|
203
|
+
result = Runo::Parser.parse_html('hello $(foo = bar "baz baz", "world", hi qux)')
|
|
204
|
+
assert_equal(
|
|
205
|
+
{'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
206
|
+
result[:item],
|
|
207
|
+
'Parser.parse_html should allow spaces after the comma'
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
result = Runo::Parser.parse_html(<<'_eos')
|
|
211
|
+
hello $(foo =
|
|
212
|
+
bar
|
|
213
|
+
"baz baz",
|
|
214
|
+
"world",
|
|
215
|
+
hi
|
|
216
|
+
qux)
|
|
217
|
+
_eos
|
|
218
|
+
assert_equal(
|
|
219
|
+
{'foo' => {:klass => 'bar', :options => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
220
|
+
result[:item],
|
|
221
|
+
'Parser.parse_html should allow spaces after the comma'
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_parse_defaults
|
|
226
|
+
result = Runo::Parser.parse_html('hello $(foo = bar ;"baz baz";"world";hi qux)')
|
|
227
|
+
assert_equal(
|
|
228
|
+
{'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
229
|
+
result[:item],
|
|
230
|
+
'Parser.parse_html should be able to parse a sequence of CSV as [:defaults]'
|
|
231
|
+
)
|
|
232
|
+
result = Runo::Parser.parse_html('hello $(foo = bar "baz baz";"world";hi qux)')
|
|
233
|
+
assert_equal(
|
|
234
|
+
{'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
235
|
+
result[:item],
|
|
236
|
+
'Parser.parse_html should be able to parse a sequence of CSV as [:defaults]'
|
|
237
|
+
)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_parse_defaults_with_spaces
|
|
241
|
+
result = Runo::Parser.parse_html('hello $(foo=bar world; qux)')
|
|
242
|
+
assert_equal(
|
|
243
|
+
{'foo' => {:klass => 'bar', :defaults => ['world', 'qux']}},
|
|
244
|
+
result[:item],
|
|
245
|
+
'Parser.parse_html should allow spaces after the semicolon'
|
|
246
|
+
)
|
|
247
|
+
result = Runo::Parser.parse_html('hello $(foo=bar world ;qux)')
|
|
248
|
+
assert_equal(
|
|
249
|
+
{'foo' => {:klass => 'bar', :defaults => ['qux'], :tokens => ['world']}},
|
|
250
|
+
result[:item],
|
|
251
|
+
'Parser.parse_html should not allow spaces before the semicolon'
|
|
252
|
+
)
|
|
253
|
+
result = Runo::Parser.parse_html('hello $(foo=bar "baz baz"; "world"; hi qux)')
|
|
254
|
+
assert_equal(
|
|
255
|
+
{'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
256
|
+
result[:item],
|
|
257
|
+
'Parser.parse_html should allow spaces after the comma'
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
result = Runo::Parser.parse_html(<<'_eos')
|
|
261
|
+
hello $(foo =
|
|
262
|
+
bar
|
|
263
|
+
"baz baz";
|
|
264
|
+
"world";
|
|
265
|
+
hi
|
|
266
|
+
qux)
|
|
267
|
+
_eos
|
|
268
|
+
assert_equal(
|
|
269
|
+
{'foo' => {:klass => 'bar', :defaults => ['baz baz', 'world', 'hi'], :tokens => ['qux']}},
|
|
270
|
+
result[:item],
|
|
271
|
+
'Parser.parse_html should allow spaces after the comma'
|
|
272
|
+
)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def test_parse_meta_tag
|
|
276
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
277
|
+
<html>
|
|
278
|
+
<meta name="runo-owner" content="frank" />
|
|
279
|
+
</html>
|
|
280
|
+
_html
|
|
281
|
+
assert_equal(
|
|
282
|
+
{
|
|
283
|
+
:tmpl => {
|
|
284
|
+
:index => <<'_html',
|
|
285
|
+
<html>
|
|
286
|
+
</html>
|
|
287
|
+
_html
|
|
288
|
+
},
|
|
289
|
+
:item => {},
|
|
290
|
+
:owner => 'frank',
|
|
291
|
+
:label => nil,
|
|
292
|
+
},
|
|
293
|
+
result,
|
|
294
|
+
'Parser.parse_html should scrape meta vals from <meta>'
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
298
|
+
<html>
|
|
299
|
+
<meta name="runo-owner" content="frank" />
|
|
300
|
+
<meta name="runo-group" content="bob,carl" />
|
|
301
|
+
<meta name="runo-foo" content="bar, baz" />
|
|
302
|
+
<meta name="runo-label" content="Qux" />
|
|
303
|
+
</html>
|
|
304
|
+
_html
|
|
305
|
+
assert_equal(
|
|
306
|
+
{
|
|
307
|
+
:tmpl => {
|
|
308
|
+
:index => <<'_html',
|
|
309
|
+
<html>
|
|
310
|
+
</html>
|
|
311
|
+
_html
|
|
312
|
+
},
|
|
313
|
+
:item => {},
|
|
314
|
+
:owner => 'frank',
|
|
315
|
+
:group => %w(bob carl),
|
|
316
|
+
:foo => %w(bar baz),
|
|
317
|
+
:label => 'Qux',
|
|
318
|
+
},
|
|
319
|
+
result,
|
|
320
|
+
'Parser.parse_html should scrape meta vals from <meta>'
|
|
321
|
+
)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def test_parse_duplicate_tag
|
|
325
|
+
result = Runo::Parser.parse_html('hello $(foo = bar "baz baz") world $(foo=boo) $(foo)!')
|
|
326
|
+
assert_equal(
|
|
327
|
+
{'foo' => {:klass => 'boo'}},
|
|
328
|
+
result[:item],
|
|
329
|
+
'definition tags are overridden by a preceding definition'
|
|
330
|
+
)
|
|
331
|
+
assert_equal(
|
|
332
|
+
{:index => 'hello $(foo) world $(foo) $(foo)!'},
|
|
333
|
+
result[:tmpl],
|
|
334
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
335
|
+
)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def test_scan_inner_html
|
|
339
|
+
s = StringScanner.new 'bar</foo>bar'
|
|
340
|
+
inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
|
|
341
|
+
assert_equal(
|
|
342
|
+
'bar',
|
|
343
|
+
inner_html,
|
|
344
|
+
'Parser.scan_inner_html should extract the inner html from the scanner'
|
|
345
|
+
)
|
|
346
|
+
assert_equal(
|
|
347
|
+
'</foo>',
|
|
348
|
+
close_tag,
|
|
349
|
+
'Parser.scan_inner_html should extract the inner html from the scanner'
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
s = StringScanner.new '<foo>bar</foo></foo>'
|
|
353
|
+
inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
|
|
354
|
+
assert_equal(
|
|
355
|
+
'<foo>bar</foo>',
|
|
356
|
+
inner_html,
|
|
357
|
+
'Parser.scan_inner_html should be aware of nested tags'
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
s = StringScanner.new "baz\n <foo>bar</foo>\n</foo>"
|
|
361
|
+
inner_html, close_tag = Runo::Parser.scan_inner_html(s, 'foo')
|
|
362
|
+
assert_equal(
|
|
363
|
+
"baz\n <foo>bar</foo>\n",
|
|
364
|
+
inner_html,
|
|
365
|
+
'Parser.scan_inner_html should be aware of nested tags'
|
|
366
|
+
)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def test_parse_block_tag
|
|
370
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
371
|
+
<ul class="runo-blog" id="foo"><li>hello</li></ul>
|
|
372
|
+
_html
|
|
373
|
+
assert_equal(
|
|
374
|
+
{
|
|
375
|
+
'foo' => {
|
|
376
|
+
:klass => 'set-dynamic',
|
|
377
|
+
:workflow => 'blog',
|
|
378
|
+
:tmpl => {
|
|
379
|
+
:index => <<'_tmpl'.chomp,
|
|
380
|
+
<ul class="runo-blog" id="@(name)">$()</ul>
|
|
381
|
+
$(.navi)$(.submit)$(.action_create)
|
|
382
|
+
_tmpl
|
|
383
|
+
},
|
|
384
|
+
:item => {
|
|
385
|
+
'default' => {
|
|
386
|
+
:label => nil,
|
|
387
|
+
:tmpl => {:index => '<li>hello</li>'},
|
|
388
|
+
:item => {},
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
result[:item],
|
|
394
|
+
'Parser.parse_html should be able to parse block runo tags'
|
|
395
|
+
)
|
|
396
|
+
assert_equal(
|
|
397
|
+
{:index => '$(foo.message)$(foo)'},
|
|
398
|
+
result[:tmpl],
|
|
399
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
403
|
+
<ul class="runo-blog" id="foo">
|
|
404
|
+
<li>hello</li>
|
|
405
|
+
</ul>
|
|
406
|
+
_html
|
|
407
|
+
assert_equal(
|
|
408
|
+
{
|
|
409
|
+
'foo' => {
|
|
410
|
+
:klass => 'set-dynamic',
|
|
411
|
+
:workflow => 'blog',
|
|
412
|
+
:tmpl => {
|
|
413
|
+
:index => <<'_tmpl'.chomp,
|
|
414
|
+
<ul class="runo-blog" id="@(name)">
|
|
415
|
+
$()</ul>
|
|
416
|
+
$(.navi)$(.submit)$(.action_create)
|
|
417
|
+
_tmpl
|
|
418
|
+
},
|
|
419
|
+
:item => {
|
|
420
|
+
'default' => {
|
|
421
|
+
:label => nil,
|
|
422
|
+
:tmpl => {:index => " <li>hello</li>\n"},
|
|
423
|
+
:item => {},
|
|
424
|
+
},
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
result[:item],
|
|
429
|
+
'Parser.parse_html should be able to parse block runo tags'
|
|
430
|
+
)
|
|
431
|
+
assert_equal(
|
|
432
|
+
{:index => '$(foo.message)$(foo)'},
|
|
433
|
+
result[:tmpl],
|
|
434
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
438
|
+
hello <ul class="runo-blog" id="foo"><li>hello</li></ul> world
|
|
439
|
+
_html
|
|
440
|
+
assert_equal(
|
|
441
|
+
{
|
|
442
|
+
'foo' => {
|
|
443
|
+
:klass => 'set-dynamic',
|
|
444
|
+
:workflow => 'blog',
|
|
445
|
+
:tmpl => {
|
|
446
|
+
:index => <<'_tmpl'.chomp,
|
|
447
|
+
<ul class="runo-blog" id="@(name)">$()</ul>$(.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 => <<'_html'},
|
|
464
|
+
hello$(foo.message)$(foo) world
|
|
465
|
+
_html
|
|
466
|
+
result[:tmpl],
|
|
467
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
468
|
+
)
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def test_look_a_like_block_tag
|
|
472
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
473
|
+
hello <ul class="not-runo-blog" id="foo"><li>hello</li></ul> world
|
|
474
|
+
_html
|
|
475
|
+
assert_equal(
|
|
476
|
+
{:index => <<'_tmpl'},
|
|
477
|
+
hello <ul class="not-runo-blog" id="foo"><li>hello</li></ul> world
|
|
478
|
+
_tmpl
|
|
479
|
+
result[:tmpl],
|
|
480
|
+
"Parser.parse_html[:tmpl] should skip a class which does not start with 'runo'"
|
|
481
|
+
)
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def test_block_tags_with_options
|
|
485
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
486
|
+
hello
|
|
487
|
+
<table class="runo-blog" id="foo">
|
|
488
|
+
<!-- 1..20 barbaz -->
|
|
489
|
+
<tbody class="body"><!-- qux --><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody>
|
|
490
|
+
</table>
|
|
491
|
+
world
|
|
492
|
+
_html
|
|
493
|
+
assert_equal(
|
|
494
|
+
{
|
|
495
|
+
'foo' => {
|
|
496
|
+
:min => 1,
|
|
497
|
+
:max => 20,
|
|
498
|
+
:tokens => ['barbaz'],
|
|
499
|
+
:klass => 'set-dynamic',
|
|
500
|
+
:workflow => 'blog',
|
|
501
|
+
:tmpl => {
|
|
502
|
+
:index => <<'_tmpl'.chomp,
|
|
503
|
+
<table class="runo-blog" id="@(name)">
|
|
504
|
+
<!-- 1..20 barbaz -->
|
|
505
|
+
$() </table>
|
|
506
|
+
$(.navi)$(.submit)$(.action_create)
|
|
507
|
+
_tmpl
|
|
508
|
+
},
|
|
509
|
+
:item => {
|
|
510
|
+
'default' => {
|
|
511
|
+
:label => nil,
|
|
512
|
+
:tmpl => {
|
|
513
|
+
:index => <<'_tmpl',
|
|
514
|
+
<tbody class="body"><!-- qux --><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody>
|
|
515
|
+
_tmpl
|
|
516
|
+
},
|
|
517
|
+
:item => {
|
|
518
|
+
'bar' => {:klass => 'text'},
|
|
519
|
+
'baz' => {:klass => 'text'},
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
result[:item],
|
|
526
|
+
'Parser.parse_html should aware of <tbody class="body">'
|
|
527
|
+
)
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def test_block_tags_with_tbody
|
|
531
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
532
|
+
hello
|
|
533
|
+
<table class="runo-blog" id="foo">
|
|
534
|
+
<thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
|
|
535
|
+
<tbody class="body"><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody>
|
|
536
|
+
</table>
|
|
537
|
+
world
|
|
538
|
+
_html
|
|
539
|
+
assert_equal(
|
|
540
|
+
{
|
|
541
|
+
'foo' => {
|
|
542
|
+
:klass => 'set-dynamic',
|
|
543
|
+
:workflow => 'blog',
|
|
544
|
+
:tmpl => {
|
|
545
|
+
:index => <<'_tmpl'.chomp,
|
|
546
|
+
<table class="runo-blog" id="@(name)">
|
|
547
|
+
<thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
|
|
548
|
+
$() </table>
|
|
549
|
+
$(.navi)$(.submit)$(.action_create)
|
|
550
|
+
_tmpl
|
|
551
|
+
},
|
|
552
|
+
:item => {
|
|
553
|
+
'default' => {
|
|
554
|
+
:label => nil,
|
|
555
|
+
:tmpl => {
|
|
556
|
+
:index => <<'_tmpl',
|
|
557
|
+
<tbody class="body"><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody>
|
|
558
|
+
_tmpl
|
|
559
|
+
},
|
|
560
|
+
:item => {
|
|
561
|
+
'bar' => {:klass => 'text'},
|
|
562
|
+
'baz' => {:klass => 'text'},
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
result[:item],
|
|
569
|
+
'Parser.parse_html should aware of <tbody class="body">'
|
|
570
|
+
)
|
|
571
|
+
assert_equal(
|
|
572
|
+
{:index => <<'_tmpl'},
|
|
573
|
+
hello
|
|
574
|
+
$(foo.message)$(foo)world
|
|
575
|
+
_tmpl
|
|
576
|
+
result[:tmpl],
|
|
577
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
578
|
+
)
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
def test_parse_xml
|
|
582
|
+
result = Runo::Parser.parse_xml <<'_html'
|
|
583
|
+
<channel class="runo-rss">
|
|
584
|
+
<link>@(href)</link>
|
|
585
|
+
<item class="body">
|
|
586
|
+
<title>$(title)</title>
|
|
587
|
+
</item>
|
|
588
|
+
</channel>
|
|
589
|
+
_html
|
|
590
|
+
assert_equal(
|
|
591
|
+
{
|
|
592
|
+
:label => nil,
|
|
593
|
+
:tmpl => {:index => '$(main)'},
|
|
594
|
+
:item => {
|
|
595
|
+
'main' => {
|
|
596
|
+
:item => {
|
|
597
|
+
'default' => {
|
|
598
|
+
:label => nil,
|
|
599
|
+
:item => {},
|
|
600
|
+
:tmpl => {
|
|
601
|
+
:index => <<'_xml'
|
|
602
|
+
<item>
|
|
603
|
+
<title>$(title)</title>
|
|
604
|
+
</item>
|
|
605
|
+
_xml
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
},
|
|
609
|
+
:tmpl => {
|
|
610
|
+
:index => <<'_xml',
|
|
611
|
+
<channel>
|
|
612
|
+
<link>@(href)</link>
|
|
613
|
+
$()</channel>
|
|
614
|
+
_xml
|
|
615
|
+
},
|
|
616
|
+
:klass => 'set-dynamic',
|
|
617
|
+
:workflow => 'rss',
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
result,
|
|
622
|
+
'Parser.parse_html should aware of <item>'
|
|
623
|
+
)
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
def test_parse_item_label
|
|
627
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
628
|
+
<ul class="runo-blog" id="foo"><li title="Greeting">hello</li></ul>
|
|
629
|
+
_html
|
|
630
|
+
assert_equal(
|
|
631
|
+
'Greeting',
|
|
632
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
633
|
+
'Parser.parse_html should pick up item labels from title attrs'
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
637
|
+
<ul class="runo-blog" id="foo"><!-- foo --><li title="Greeting">hello</li></ul>
|
|
638
|
+
_html
|
|
639
|
+
assert_equal(
|
|
640
|
+
'Greeting',
|
|
641
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
642
|
+
'Parser.parse_html should pick up item labels from title attrs'
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
646
|
+
<ul class="runo-blog" id="foo"><!-- foo --><li><div title="Foo">hello</div></li></ul>
|
|
647
|
+
_html
|
|
648
|
+
assert_nil(
|
|
649
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
650
|
+
'Parser.parse_html should pick up item labels only from the first tags'
|
|
651
|
+
)
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
def test_parse_item_label_plural
|
|
655
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
656
|
+
<ul class="runo-blog" id="foo"><li title="tEntry, tEntries">hello</li></ul>
|
|
657
|
+
_html
|
|
658
|
+
assert_equal(
|
|
659
|
+
'tEntry',
|
|
660
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
661
|
+
'Parser.parse_html should split plural item labels'
|
|
662
|
+
)
|
|
663
|
+
assert_equal(
|
|
664
|
+
['tEntry', 'tEntries'],
|
|
665
|
+
Runo::I18n.msg['tEntry'],
|
|
666
|
+
'Parser.parse_html should I18n.merge_msg! the plural item labels'
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
670
|
+
<ul class="runo-blog" id="foo"><li title="tFooFoo, BarBar, BazBaz">hello</li></ul>
|
|
671
|
+
_html
|
|
672
|
+
assert_equal(
|
|
673
|
+
'tFooFoo',
|
|
674
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
675
|
+
'Parser.parse_html should split plural item labels'
|
|
676
|
+
)
|
|
677
|
+
assert_equal(
|
|
678
|
+
['tFooFoo', 'BarBar', 'BazBaz'],
|
|
679
|
+
Runo::I18n.msg['tFooFoo'],
|
|
680
|
+
'Parser.parse_html should I18n.merge_msg! the plural item labels'
|
|
681
|
+
)
|
|
682
|
+
|
|
683
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
684
|
+
<ul class="runo-blog" id="foo"><li title="tQux">hello</li></ul>
|
|
685
|
+
_html
|
|
686
|
+
assert_equal(
|
|
687
|
+
'tQux',
|
|
688
|
+
result[:item]['foo'][:item]['default'][:label],
|
|
689
|
+
'Parser.parse_html should split plural item labels'
|
|
690
|
+
)
|
|
691
|
+
assert_equal(
|
|
692
|
+
['tQux', 'tQux', 'tQux', 'tQux'],
|
|
693
|
+
Runo::I18n.msg['tQux'],
|
|
694
|
+
'Parser.parse_html should repeat a singular label to fill all possible plural forms'
|
|
695
|
+
)
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
def test_block_tags_with_nested_tbody
|
|
699
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
700
|
+
hello
|
|
701
|
+
<table class="runo-blog" id="foo">
|
|
702
|
+
<thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
|
|
703
|
+
<tbody class="body"><tbody><tr><th>$(bar=text)</th><th>$(baz=text)</th></tr></tbody></tbody>
|
|
704
|
+
</table>
|
|
705
|
+
world
|
|
706
|
+
_html
|
|
707
|
+
assert_equal(
|
|
708
|
+
{
|
|
709
|
+
'foo' => {
|
|
710
|
+
:klass => 'set-dynamic',
|
|
711
|
+
:workflow => 'blog',
|
|
712
|
+
:tmpl => {
|
|
713
|
+
:index => <<'_tmpl'.chomp,
|
|
714
|
+
<table class="runo-blog" id="@(name)">
|
|
715
|
+
<thead><tr><th>BAR</th><th>BAZ</th></tr></thead>
|
|
716
|
+
$() </table>
|
|
717
|
+
$(.navi)$(.submit)$(.action_create)
|
|
718
|
+
_tmpl
|
|
719
|
+
},
|
|
720
|
+
:item => {
|
|
721
|
+
'default' => {
|
|
722
|
+
:label => nil,
|
|
723
|
+
:tmpl => {
|
|
724
|
+
:index => <<'_tmpl',
|
|
725
|
+
<tbody class="body"><tbody><tr><th>$(.a_update)$(bar)</a></th><th>$(baz)$(.hidden)</th></tr></tbody></tbody>
|
|
726
|
+
_tmpl
|
|
727
|
+
},
|
|
728
|
+
:item => {
|
|
729
|
+
'bar' => {:klass => 'text'},
|
|
730
|
+
'baz' => {:klass => 'text'},
|
|
731
|
+
},
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
result[:item],
|
|
737
|
+
'Parser.parse_html should aware of nested <tbody class="body">'
|
|
738
|
+
)
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
def test_nested_block_tags
|
|
742
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
743
|
+
<ul class="runo-blog" id="foo">
|
|
744
|
+
<li>
|
|
745
|
+
<ul class="runo-blog" id="bar"><li>baz</li></ul>
|
|
746
|
+
</li>
|
|
747
|
+
</ul>
|
|
748
|
+
_html
|
|
749
|
+
assert_equal(
|
|
750
|
+
{
|
|
751
|
+
'foo' => {
|
|
752
|
+
:klass => 'set-dynamic',
|
|
753
|
+
:workflow => 'blog',
|
|
754
|
+
:tmpl => {
|
|
755
|
+
:index => <<'_tmpl'.chomp,
|
|
756
|
+
<ul class="runo-blog" id="@(name)">
|
|
757
|
+
$()</ul>
|
|
758
|
+
$(.navi)$(.submit)$(.action_create)
|
|
759
|
+
_tmpl
|
|
760
|
+
},
|
|
761
|
+
:item => {
|
|
762
|
+
'default' => {
|
|
763
|
+
:label => nil,
|
|
764
|
+
:tmpl => {
|
|
765
|
+
:index => <<'_tmpl',
|
|
766
|
+
<li>
|
|
767
|
+
$(bar.message)$(.a_update)$(bar)$(.hidden)</a> </li>
|
|
768
|
+
_tmpl
|
|
769
|
+
},
|
|
770
|
+
:item => {
|
|
771
|
+
'bar' => {
|
|
772
|
+
:klass => 'set-dynamic',
|
|
773
|
+
:workflow => 'blog',
|
|
774
|
+
:tmpl => {
|
|
775
|
+
:index => <<'_tmpl'.chomp,
|
|
776
|
+
<ul class="runo-blog" id="@(name)">$()</ul>
|
|
777
|
+
$(.navi)$(.submit)$(.action_create)
|
|
778
|
+
_tmpl
|
|
779
|
+
},
|
|
780
|
+
:item => {
|
|
781
|
+
'default' => {
|
|
782
|
+
:label => nil,
|
|
783
|
+
:tmpl => {:index => '<li>baz</li>'},
|
|
784
|
+
:item => {},
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
result[:item],
|
|
794
|
+
'Parser.parse_html should be able to parse nested block runo tags'
|
|
795
|
+
)
|
|
796
|
+
assert_equal(
|
|
797
|
+
{:index => '$(foo.message)$(foo)'},
|
|
798
|
+
result[:tmpl],
|
|
799
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
800
|
+
)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
def test_combination
|
|
804
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
805
|
+
<html>
|
|
806
|
+
<h1>$(title=text 32)</h1>
|
|
807
|
+
<ul id="foo" class="runo-blog">
|
|
808
|
+
<li>
|
|
809
|
+
$(subject=text 64)
|
|
810
|
+
$(body=textarea 72*10)
|
|
811
|
+
<ul><li>qux</li></ul>
|
|
812
|
+
</li>
|
|
813
|
+
</ul>
|
|
814
|
+
</html>
|
|
815
|
+
_html
|
|
816
|
+
assert_equal(
|
|
817
|
+
{
|
|
818
|
+
'title' => {:klass => 'text', :tokens => ['32']},
|
|
819
|
+
'foo' => {
|
|
820
|
+
:klass => 'set-dynamic',
|
|
821
|
+
:workflow => 'blog',
|
|
822
|
+
:tmpl => {
|
|
823
|
+
:index => <<'_tmpl'.chomp,
|
|
824
|
+
<ul id="@(name)" class="runo-blog">
|
|
825
|
+
$() </ul>
|
|
826
|
+
$(.navi)$(.submit)$(.action_create)
|
|
827
|
+
_tmpl
|
|
828
|
+
},
|
|
829
|
+
:item => {
|
|
830
|
+
'default' => {
|
|
831
|
+
:label => nil,
|
|
832
|
+
:tmpl => {
|
|
833
|
+
:index => <<'_tmpl',
|
|
834
|
+
<li>
|
|
835
|
+
$(.a_update)$(subject)</a>
|
|
836
|
+
$(body)$(.hidden)
|
|
837
|
+
<ul><li>qux</li></ul>
|
|
838
|
+
</li>
|
|
839
|
+
_tmpl
|
|
840
|
+
},
|
|
841
|
+
:item => {
|
|
842
|
+
'body' => {
|
|
843
|
+
:width => 72,
|
|
844
|
+
:height => 10,
|
|
845
|
+
:klass => 'textarea',
|
|
846
|
+
},
|
|
847
|
+
'subject' => {
|
|
848
|
+
:tokens => ['64'],
|
|
849
|
+
:klass => 'text',
|
|
850
|
+
},
|
|
851
|
+
},
|
|
852
|
+
},
|
|
853
|
+
},
|
|
854
|
+
},
|
|
855
|
+
},
|
|
856
|
+
result[:item],
|
|
857
|
+
'Parser.parse_html should be able to parse combination of mixed runo tags'
|
|
858
|
+
)
|
|
859
|
+
assert_equal(
|
|
860
|
+
{:index => <<'_tmpl'},
|
|
861
|
+
<html>
|
|
862
|
+
<h1>$(title)</h1>
|
|
863
|
+
$(foo.message)$(foo)</html>
|
|
864
|
+
_tmpl
|
|
865
|
+
result[:tmpl],
|
|
866
|
+
'Parser.parse_html[:tmpl] should be a proper template'
|
|
867
|
+
)
|
|
868
|
+
end
|
|
869
|
+
|
|
870
|
+
def test_gsub_block
|
|
871
|
+
match = nil
|
|
872
|
+
result = Runo::Parser.gsub_block('a<div class="foo">bar</div>c', 'foo') {|open, inner, close|
|
|
873
|
+
match = [open, inner, close]
|
|
874
|
+
'b'
|
|
875
|
+
}
|
|
876
|
+
assert_equal(
|
|
877
|
+
'abc',
|
|
878
|
+
result,
|
|
879
|
+
'Parser.gsub_block should replace tag blocks of the matching class with the given value'
|
|
880
|
+
)
|
|
881
|
+
assert_equal(
|
|
882
|
+
['<div class="foo">', 'bar', '</div>'],
|
|
883
|
+
match,
|
|
884
|
+
'Parser.gsub_block should pass the matching element to its block'
|
|
885
|
+
)
|
|
886
|
+
|
|
887
|
+
result = Runo::Parser.gsub_block('<p><div class="foo">bar</div></p>', 'foo') {|open, inner, close|
|
|
888
|
+
match = [open, inner, close]
|
|
889
|
+
'b'
|
|
890
|
+
}
|
|
891
|
+
assert_equal(
|
|
892
|
+
'<p>b</p>',
|
|
893
|
+
result,
|
|
894
|
+
'Parser.gsub_block should replace tag blocks of the matching class with the given value'
|
|
895
|
+
)
|
|
896
|
+
assert_equal(
|
|
897
|
+
['<div class="foo">', 'bar', '</div>'],
|
|
898
|
+
match,
|
|
899
|
+
'Parser.gsub_block should pass the matching element to its block'
|
|
900
|
+
)
|
|
901
|
+
|
|
902
|
+
result = Runo::Parser.gsub_block('a<p><div class="foo">bar</div></p>c', 'foo') {|open, inner, close|
|
|
903
|
+
match = [open, inner, close]
|
|
904
|
+
'b'
|
|
905
|
+
}
|
|
906
|
+
assert_equal(
|
|
907
|
+
'a<p>b</p>c',
|
|
908
|
+
result,
|
|
909
|
+
'Parser.gsub_block should replace tag blocks of the matching class with the given value'
|
|
910
|
+
)
|
|
911
|
+
assert_equal(
|
|
912
|
+
['<div class="foo">', 'bar', '</div>'],
|
|
913
|
+
match,
|
|
914
|
+
'Parser.gsub_block should pass the matching element to its block'
|
|
915
|
+
)
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
def _test_gsub_action_tmpl(html)
|
|
919
|
+
result = {}
|
|
920
|
+
html = Runo::Parser.gsub_action_tmpl(html) {|id, action, *tmpl|
|
|
921
|
+
result[:id] = id
|
|
922
|
+
result[:action] = action
|
|
923
|
+
result[:tmpl] = tmpl.join
|
|
924
|
+
'b'
|
|
925
|
+
}
|
|
926
|
+
[result, html]
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
def test_gsub_action_tmpl
|
|
930
|
+
result, html = _test_gsub_action_tmpl 'a<div class="foo-navi">Foo</div>c'
|
|
931
|
+
assert_equal(
|
|
932
|
+
{
|
|
933
|
+
:id => 'foo',
|
|
934
|
+
:action => :navi,
|
|
935
|
+
:tmpl => '<div class="foo-navi">Foo</div>',
|
|
936
|
+
},
|
|
937
|
+
result,
|
|
938
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
939
|
+
)
|
|
940
|
+
assert_equal(
|
|
941
|
+
'abc',
|
|
942
|
+
html,
|
|
943
|
+
'Parser.gsub_action_tmpl should replace the action template with a value from the block'
|
|
944
|
+
)
|
|
945
|
+
|
|
946
|
+
result, html = _test_gsub_action_tmpl 'a<div class="bar foo-navi">Foo</div>c'
|
|
947
|
+
assert_equal(
|
|
948
|
+
{
|
|
949
|
+
:id => 'foo',
|
|
950
|
+
:action => :navi,
|
|
951
|
+
:tmpl => '<div class="bar foo-navi">Foo</div>',
|
|
952
|
+
},
|
|
953
|
+
result,
|
|
954
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
955
|
+
)
|
|
956
|
+
|
|
957
|
+
result, html = _test_gsub_action_tmpl 'a<div class="bar foo-navi baz">Foo</div>c'
|
|
958
|
+
assert_equal(
|
|
959
|
+
{
|
|
960
|
+
:id => 'foo',
|
|
961
|
+
:action => :navi,
|
|
962
|
+
:tmpl => '<div class="bar foo-navi baz">Foo</div>',
|
|
963
|
+
},
|
|
964
|
+
result,
|
|
965
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
result, html = _test_gsub_action_tmpl 'a<div class="bar foo-done baz">Foo</div>c'
|
|
969
|
+
assert_equal(
|
|
970
|
+
{
|
|
971
|
+
:id => 'foo',
|
|
972
|
+
:action => :done,
|
|
973
|
+
:tmpl => '<div class="bar foo-done baz">Foo</div>',
|
|
974
|
+
},
|
|
975
|
+
result,
|
|
976
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
977
|
+
)
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
def test_gsub_action_tmpl_with_empty_id
|
|
981
|
+
result, html = _test_gsub_action_tmpl 'a<div class="navi">Foo</div>c'
|
|
982
|
+
assert_equal(
|
|
983
|
+
{
|
|
984
|
+
:id => nil,
|
|
985
|
+
:action => :navi,
|
|
986
|
+
:tmpl => '<div class="navi">Foo</div>',
|
|
987
|
+
},
|
|
988
|
+
result,
|
|
989
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
result, html = _test_gsub_action_tmpl 'a<div class="foo navi">Foo</div>c'
|
|
993
|
+
assert_equal(
|
|
994
|
+
{
|
|
995
|
+
:id => nil,
|
|
996
|
+
:action => :navi,
|
|
997
|
+
:tmpl => '<div class="foo navi">Foo</div>',
|
|
998
|
+
},
|
|
999
|
+
result,
|
|
1000
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
1001
|
+
)
|
|
1002
|
+
|
|
1003
|
+
result, html = _test_gsub_action_tmpl 'a<div class="foo navi baz">Foo</div>c'
|
|
1004
|
+
assert_equal(
|
|
1005
|
+
{
|
|
1006
|
+
:id => nil,
|
|
1007
|
+
:action => :navi,
|
|
1008
|
+
:tmpl => '<div class="foo navi baz">Foo</div>',
|
|
1009
|
+
},
|
|
1010
|
+
result,
|
|
1011
|
+
'Parser.gsub_action_tmpl should yield action templates'
|
|
1012
|
+
)
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1015
|
+
def test_gsub_action_tmpl_with_ambiguous_klass
|
|
1016
|
+
result, html = _test_gsub_action_tmpl 'a<div class="not_navi">Foo</div>c'
|
|
1017
|
+
assert_equal(
|
|
1018
|
+
{},
|
|
1019
|
+
result,
|
|
1020
|
+
'Parser.gsub_action_tmpl should ignore classes other than action, view, navi or submit'
|
|
1021
|
+
)
|
|
1022
|
+
|
|
1023
|
+
result, html = _test_gsub_action_tmpl 'a<div class="navi_bar">Foo</div>c'
|
|
1024
|
+
assert_equal(
|
|
1025
|
+
{
|
|
1026
|
+
:id => nil,
|
|
1027
|
+
:action => :navi_bar,
|
|
1028
|
+
:tmpl => '<div class="navi_bar">Foo</div>',
|
|
1029
|
+
},
|
|
1030
|
+
result,
|
|
1031
|
+
'Parser.gsub_action_tmpl should yield an action template if the klass looks like special'
|
|
1032
|
+
)
|
|
1033
|
+
end
|
|
1034
|
+
|
|
1035
|
+
def test_action_tmpl_in_ss
|
|
1036
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1037
|
+
<html>
|
|
1038
|
+
<ul id="foo" class="runo-blog">
|
|
1039
|
+
<li>$(subject=text)</li>
|
|
1040
|
+
</ul>
|
|
1041
|
+
<div class="foo-navi">bar</div>
|
|
1042
|
+
</html>
|
|
1043
|
+
_html
|
|
1044
|
+
assert_equal(
|
|
1045
|
+
<<'_tmpl',
|
|
1046
|
+
<div class="foo-navi">bar</div>
|
|
1047
|
+
_tmpl
|
|
1048
|
+
result[:item]['foo'][:tmpl][:navi],
|
|
1049
|
+
'Parser.parse_html should parse action templates in the html'
|
|
1050
|
+
)
|
|
1051
|
+
assert_equal(
|
|
1052
|
+
{:index => <<'_tmpl'},
|
|
1053
|
+
<html>
|
|
1054
|
+
$(foo.message)$(foo)$(foo.navi)</html>
|
|
1055
|
+
_tmpl
|
|
1056
|
+
result[:tmpl],
|
|
1057
|
+
'Parser.parse_html should replace action templates with proper tags'
|
|
1058
|
+
)
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
def test_action_tmpl_in_ss_with_nil_id
|
|
1062
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1063
|
+
<html>
|
|
1064
|
+
<ul id="main" class="runo-blog">
|
|
1065
|
+
<li>$(subject=text)</li>
|
|
1066
|
+
</ul>
|
|
1067
|
+
<div class="navi">bar</div>
|
|
1068
|
+
</html>
|
|
1069
|
+
_html
|
|
1070
|
+
assert_equal(
|
|
1071
|
+
<<'_tmpl',
|
|
1072
|
+
<div class="navi">bar</div>
|
|
1073
|
+
_tmpl
|
|
1074
|
+
result[:item]['main'][:tmpl][:navi],
|
|
1075
|
+
"Parser.parse_html should set action templates to item['main'] by default"
|
|
1076
|
+
)
|
|
1077
|
+
assert_equal(
|
|
1078
|
+
{:index => <<'_tmpl'},
|
|
1079
|
+
<html>
|
|
1080
|
+
$(main.message)$(main)$(main.navi)</html>
|
|
1081
|
+
_tmpl
|
|
1082
|
+
result[:tmpl],
|
|
1083
|
+
"Parser.parse_html should set action templates to item['main'] by default"
|
|
1084
|
+
)
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
def test_action_tmpl_in_ss_with_non_existent_id
|
|
1088
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1089
|
+
<html>
|
|
1090
|
+
<ul id="main" class="runo-blog">
|
|
1091
|
+
<li>$(subject=text)</li>
|
|
1092
|
+
</ul>
|
|
1093
|
+
<div class="non_existent-navi">bar</div>
|
|
1094
|
+
</html>
|
|
1095
|
+
_html
|
|
1096
|
+
assert_nil(
|
|
1097
|
+
result[:item]['non_existent'],
|
|
1098
|
+
'Parser.parse_html should ignore the action template without a corresponding SD'
|
|
1099
|
+
)
|
|
1100
|
+
assert_equal(
|
|
1101
|
+
{:index => <<'_tmpl'},
|
|
1102
|
+
<html>
|
|
1103
|
+
$(main.message)$(main) <div class="non_existent-navi">bar</div>
|
|
1104
|
+
</html>
|
|
1105
|
+
_tmpl
|
|
1106
|
+
result[:tmpl],
|
|
1107
|
+
'Parser.parse_html should ignore the action template without a corresponding SD'
|
|
1108
|
+
)
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
def test_action_tmpl_in_ss_with_nested_action_tmpl
|
|
1112
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1113
|
+
<html>
|
|
1114
|
+
<ul id="foo" class="runo-blog">
|
|
1115
|
+
<li>$(subject=text)</li>
|
|
1116
|
+
</ul>
|
|
1117
|
+
<div class="foo-navi"><span class="navi_prev">prev</span></div>
|
|
1118
|
+
</html>
|
|
1119
|
+
_html
|
|
1120
|
+
assert_equal(
|
|
1121
|
+
<<'_html',
|
|
1122
|
+
<div class="foo-navi">$(.navi_prev)</div>
|
|
1123
|
+
_html
|
|
1124
|
+
result[:item]['foo'][:tmpl][:navi],
|
|
1125
|
+
'Parser.parse_html should parse nested action templates'
|
|
1126
|
+
)
|
|
1127
|
+
assert_equal(
|
|
1128
|
+
'<span class="navi_prev">prev</span>',
|
|
1129
|
+
result[:item]['foo'][:tmpl][:navi_prev],
|
|
1130
|
+
'Parser.parse_html should parse nested action templates'
|
|
1131
|
+
)
|
|
1132
|
+
assert_equal(
|
|
1133
|
+
{
|
|
1134
|
+
:index => <<'_html'.chomp,
|
|
1135
|
+
<ul id="@(name)" class="runo-blog">
|
|
1136
|
+
$() </ul>
|
|
1137
|
+
$(.submit)$(.action_create)
|
|
1138
|
+
_html
|
|
1139
|
+
:navi => <<'_html',
|
|
1140
|
+
<div class="foo-navi">$(.navi_prev)</div>
|
|
1141
|
+
_html
|
|
1142
|
+
:navi_prev => '<span class="navi_prev">prev</span>',
|
|
1143
|
+
},
|
|
1144
|
+
result[:item]['foo'][:tmpl],
|
|
1145
|
+
'Parser.parse_html should parse nested action templates'
|
|
1146
|
+
)
|
|
1147
|
+
|
|
1148
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1149
|
+
<html>
|
|
1150
|
+
<ul id="foo" class="runo-blog">
|
|
1151
|
+
<li>$(subject=text)</li>
|
|
1152
|
+
</ul>
|
|
1153
|
+
<div class="foo-navi"><span class="bar-navi_prev">prev</span></div>
|
|
1154
|
+
</html>
|
|
1155
|
+
_html
|
|
1156
|
+
assert_equal(
|
|
1157
|
+
'<span class="bar-navi_prev">prev</span>',
|
|
1158
|
+
result[:item]['foo'][:tmpl][:navi_prev],
|
|
1159
|
+
'Parser.parse_html should ignore the id of a nested action template'
|
|
1160
|
+
)
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
def test_action_tmpl_in_sd
|
|
1164
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1165
|
+
<ul id="foo" class="runo-blog">
|
|
1166
|
+
<li class="body">$(text)</li>
|
|
1167
|
+
<div class="navi">bar</div>
|
|
1168
|
+
</ul>
|
|
1169
|
+
_html
|
|
1170
|
+
assert_equal(
|
|
1171
|
+
<<'_html',
|
|
1172
|
+
<div class="navi">bar</div>
|
|
1173
|
+
_html
|
|
1174
|
+
result[:item]['foo'][:tmpl][:navi],
|
|
1175
|
+
'Parser.parse_html should parse action templates in sd[:tmpl]'
|
|
1176
|
+
)
|
|
1177
|
+
assert_match(
|
|
1178
|
+
%r{\$\(\.navi\)},
|
|
1179
|
+
result[:item]['foo'][:tmpl][:index],
|
|
1180
|
+
'Parser.parse_html should parse action templates in sd[:tmpl]'
|
|
1181
|
+
)
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
def test_action_tmpl_in_sd_with_nested_action_tmpl
|
|
1185
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1186
|
+
<ul id="foo" class="runo-blog">
|
|
1187
|
+
<li class="body">$(text)</li>
|
|
1188
|
+
<div class="navi"><span class="navi_prev">prev</span></div>
|
|
1189
|
+
</ul>
|
|
1190
|
+
_html
|
|
1191
|
+
assert_equal(
|
|
1192
|
+
<<'_html',
|
|
1193
|
+
<div class="navi">$(.navi_prev)</div>
|
|
1194
|
+
_html
|
|
1195
|
+
result[:item]['foo'][:tmpl][:navi],
|
|
1196
|
+
'Parser.parse_html should parse nested action templates in sd[:tmpl]'
|
|
1197
|
+
)
|
|
1198
|
+
assert_equal(
|
|
1199
|
+
'<span class="navi_prev">prev</span>',
|
|
1200
|
+
result[:item]['foo'][:tmpl][:navi_prev],
|
|
1201
|
+
'Parser.parse_html should parse nested action templates in sd[:tmpl]'
|
|
1202
|
+
)
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
def test_supplement_sd
|
|
1206
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1207
|
+
<ul id="foo" class="runo-blog">
|
|
1208
|
+
<li class="body">$(text)</li>
|
|
1209
|
+
</ul>
|
|
1210
|
+
_html
|
|
1211
|
+
assert_match(
|
|
1212
|
+
/\$\(\.navi\)/,
|
|
1213
|
+
result[:item]['foo'][:tmpl][:index],
|
|
1214
|
+
'Parser.supplement_sd should supplement sd[:tmpl] with default menus'
|
|
1215
|
+
)
|
|
1216
|
+
|
|
1217
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1218
|
+
<ul id="foo" class="runo-blog">
|
|
1219
|
+
<div class="navi">bar</div>
|
|
1220
|
+
<li class="body">$(text)</li>
|
|
1221
|
+
</ul>
|
|
1222
|
+
_html
|
|
1223
|
+
assert_no_match(
|
|
1224
|
+
/\$\(\.navi\).*\$\(\.navi\)/m,
|
|
1225
|
+
result[:item]['foo'][:tmpl][:index],
|
|
1226
|
+
'Parser.supplement_sd should not supplement sd[:tmpl] when it already has the menu'
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1230
|
+
<div class="foo-navi">bar</div>
|
|
1231
|
+
<ul id="foo" class="runo-blog">
|
|
1232
|
+
<li class="body">$(text)</li>
|
|
1233
|
+
</ul>
|
|
1234
|
+
_html
|
|
1235
|
+
assert_no_match(
|
|
1236
|
+
/\$\(\.navi\)/,
|
|
1237
|
+
result[:item]['foo'][:tmpl][:index],
|
|
1238
|
+
'Parser.supplement_sd should not supplement sd[:tmpl] when it already has the menu'
|
|
1239
|
+
)
|
|
1240
|
+
end
|
|
1241
|
+
|
|
1242
|
+
def test_supplement_ss
|
|
1243
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1244
|
+
<ul id="foo" class="runo-blog">
|
|
1245
|
+
<li class="body">$(text)</li>
|
|
1246
|
+
</ul>
|
|
1247
|
+
_html
|
|
1248
|
+
assert_match(
|
|
1249
|
+
/\$\(\.a_update\)/,
|
|
1250
|
+
result[:item]['foo'][:item]['default'][:tmpl][:index],
|
|
1251
|
+
'Parser.supplement_ss should supplement ss[:tmpl] with default menus'
|
|
1252
|
+
)
|
|
1253
|
+
|
|
1254
|
+
result = Runo::Parser.parse_html <<'_html'
|
|
1255
|
+
<ul id="foo" class="runo-blog">
|
|
1256
|
+
<li class="body">$(text) $(.action_update)</li>
|
|
1257
|
+
</ul>
|
|
1258
|
+
_html
|
|
1259
|
+
assert_no_match(
|
|
1260
|
+
/\$\(\.a_update\)/,
|
|
1261
|
+
result[:item]['foo'][:item]['default'][:tmpl][:index],
|
|
1262
|
+
'Parser.supplement_ss should not supplement ss[:tmpl] when it already has the menu'
|
|
1263
|
+
)
|
|
1264
|
+
end
|
|
1265
|
+
|
|
1266
|
+
end
|