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_runo.rb
ADDED
|
@@ -0,0 +1,742 @@
|
|
|
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_Runo < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def teardown
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_session
|
|
17
|
+
assert(
|
|
18
|
+
Runo.session.respond_to?(:[]),
|
|
19
|
+
'Runo.session should be a Session or Hash'
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_client
|
|
24
|
+
Runo.client = nil
|
|
25
|
+
assert_equal(
|
|
26
|
+
'nobody',
|
|
27
|
+
Runo.client,
|
|
28
|
+
'Runo.client should return nobody before login'
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
Runo.client = 'frank'
|
|
32
|
+
assert_equal(
|
|
33
|
+
'frank',
|
|
34
|
+
Runo.client,
|
|
35
|
+
'Runo.client should return the user who logged in'
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
Runo.client = nil
|
|
39
|
+
assert_equal(
|
|
40
|
+
'nobody',
|
|
41
|
+
Runo.client,
|
|
42
|
+
'Runo.client should return nobody after logout'
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_rebuild_params
|
|
47
|
+
runo = Runo.new
|
|
48
|
+
|
|
49
|
+
hash = runo.instance_eval {
|
|
50
|
+
rebuild_params(
|
|
51
|
+
'.action' => 'update'
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
assert_equal(
|
|
55
|
+
{:action => :update},
|
|
56
|
+
hash,
|
|
57
|
+
'Runo#rebuild_params should be able to rebuild special symbols'
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
hash = runo.instance_eval {
|
|
61
|
+
rebuild_params(
|
|
62
|
+
'.action-update' => 'submit'
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
assert_equal(
|
|
66
|
+
{:action => :update},
|
|
67
|
+
hash,
|
|
68
|
+
'Runo#rebuild_params should be able to rebuild special symbols'
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
hash = runo.instance_eval {
|
|
72
|
+
rebuild_params(
|
|
73
|
+
'noo' => 'what?',
|
|
74
|
+
'noo.action-update' => 'submit',
|
|
75
|
+
'noo.conds-id' => '4567'
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
assert_equal(
|
|
79
|
+
{
|
|
80
|
+
'noo' => {
|
|
81
|
+
:self => 'what?',
|
|
82
|
+
:action => :update,
|
|
83
|
+
:conds => {:id => '4567'},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
hash,
|
|
87
|
+
'Runo#rebuild_params should rebuild both the special symbols and regular items'
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
hash = runo.instance_eval {
|
|
91
|
+
rebuild_params(
|
|
92
|
+
'moo.conds-p' => '9',
|
|
93
|
+
'moo-4567-addr.conds-zip-upper' => '110'
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
assert_equal(
|
|
97
|
+
{
|
|
98
|
+
'moo' => {
|
|
99
|
+
:conds => {:p => '9'},
|
|
100
|
+
'4567' => {
|
|
101
|
+
'addr' => {
|
|
102
|
+
:conds => {:'zip-upper' => '110'},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
hash,
|
|
108
|
+
'Runo#rebuild_params should be able to rebuild any combination of symbols and items'
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
hash = runo.instance_eval {
|
|
112
|
+
rebuild_params(
|
|
113
|
+
'foo-bar.conds-id' => '1234',
|
|
114
|
+
'foo-bar.conds-p' => ['42'],
|
|
115
|
+
'foo-bar.action' => 'update',
|
|
116
|
+
'foo-baz' => ['boo', 'bee'],
|
|
117
|
+
'foo' => 'oops',
|
|
118
|
+
'qux.action-create' => 'submit',
|
|
119
|
+
'qux.status-public' => 'oops'
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
assert_equal(
|
|
123
|
+
{
|
|
124
|
+
'foo' => {
|
|
125
|
+
:self => 'oops',
|
|
126
|
+
'bar' => {
|
|
127
|
+
:action => :update,
|
|
128
|
+
:conds => {
|
|
129
|
+
:id => '1234',
|
|
130
|
+
:p => ['42'],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
'baz' => ['boo', 'bee'],
|
|
134
|
+
},
|
|
135
|
+
'qux' => {
|
|
136
|
+
:action => :create,
|
|
137
|
+
:status => :public,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
hash,
|
|
141
|
+
'Runo#rebuild_params should be able to rebuild any combination of symbols and items'
|
|
142
|
+
)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_steps_of
|
|
146
|
+
assert_equal(
|
|
147
|
+
['foo', 'bar'],
|
|
148
|
+
Runo::Path.steps_of('/foo/bar/'),
|
|
149
|
+
'Runo::Path.steps_of should be able to extract item steps from path_info'
|
|
150
|
+
)
|
|
151
|
+
assert_equal(
|
|
152
|
+
['foo', 'bar'],
|
|
153
|
+
Runo::Path.steps_of('/foo/bar/create.html'),
|
|
154
|
+
'Runo::Path.steps_of should ignore the pseudo-filename'
|
|
155
|
+
)
|
|
156
|
+
assert_equal(
|
|
157
|
+
['foo'],
|
|
158
|
+
Runo::Path.steps_of('/foo/bar'),
|
|
159
|
+
'Runo::Path.steps_of should ignore the last step without a following slash'
|
|
160
|
+
)
|
|
161
|
+
assert_equal(
|
|
162
|
+
['foo', 'bar'],
|
|
163
|
+
Runo::Path.steps_of('/foo//bar/baz=123/'),
|
|
164
|
+
'Runo::Path.steps_of should distinguish item steps from conds'
|
|
165
|
+
)
|
|
166
|
+
assert_equal(
|
|
167
|
+
['foo', 'bar'],
|
|
168
|
+
Runo::Path.steps_of('/1234567890.123456/foo/bar/'),
|
|
169
|
+
'Runo::Path.steps_of should distinguish item steps from a tid'
|
|
170
|
+
)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def test_steps_of_with_empty_steps
|
|
174
|
+
assert_equal(
|
|
175
|
+
[],
|
|
176
|
+
Runo::Path.steps_of(''),
|
|
177
|
+
'Runo::Path.steps_of should return empty array when there is no item steps'
|
|
178
|
+
)
|
|
179
|
+
assert_equal(
|
|
180
|
+
[],
|
|
181
|
+
Runo::Path.steps_of('/'),
|
|
182
|
+
'Runo::Path.steps_of should return empty array when there is no item steps'
|
|
183
|
+
)
|
|
184
|
+
assert_equal(
|
|
185
|
+
[],
|
|
186
|
+
Runo::Path.steps_of('/index.html'),
|
|
187
|
+
'Runo::Path.steps_of should return empty array when there is no item steps'
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_steps_of_with_cond_d
|
|
192
|
+
assert_equal(
|
|
193
|
+
['foo', 'bar'],
|
|
194
|
+
Runo::Path.steps_of('/foo/bar/2009/'),
|
|
195
|
+
'Runo::Path.steps_of should distinguish item steps from ambiguous conds[:d]'
|
|
196
|
+
)
|
|
197
|
+
assert_equal(
|
|
198
|
+
['foo', 'bar'],
|
|
199
|
+
Runo::Path.steps_of('/foo/bar/1970/'),
|
|
200
|
+
'Runo::Path.steps_of should distinguish item steps from ambiguous conds[:d]'
|
|
201
|
+
)
|
|
202
|
+
assert_equal(
|
|
203
|
+
['foo', 'bar', '3001'],
|
|
204
|
+
Runo::Path.steps_of('/foo/bar/3001/'),
|
|
205
|
+
'Runo::Path.steps_of should be patched in the next millennium :-)'
|
|
206
|
+
)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def test_conds_of
|
|
210
|
+
assert_equal(
|
|
211
|
+
{},
|
|
212
|
+
Runo::Path.conds_of('/foo/bar/'),
|
|
213
|
+
'Runo::Path.conds_of should return empty hash when there is no conds'
|
|
214
|
+
)
|
|
215
|
+
assert_equal(
|
|
216
|
+
{
|
|
217
|
+
:baz => '123',
|
|
218
|
+
:qux => '456',
|
|
219
|
+
},
|
|
220
|
+
Runo::Path.conds_of('/foo/bar/baz=123/qux=456/'),
|
|
221
|
+
'Runo::Path.conds_of should be able to extract conds from path_info'
|
|
222
|
+
)
|
|
223
|
+
assert_equal(
|
|
224
|
+
{
|
|
225
|
+
:baz => '123',
|
|
226
|
+
:qux => '456',
|
|
227
|
+
},
|
|
228
|
+
Runo::Path.conds_of('/foo/bar/baz=123/qux=456/create.html'),
|
|
229
|
+
'Runo::Path.conds_of should ignore the pseudo-filename'
|
|
230
|
+
)
|
|
231
|
+
assert_equal(
|
|
232
|
+
{
|
|
233
|
+
:baz => '1234',
|
|
234
|
+
},
|
|
235
|
+
Runo::Path.conds_of('/foo/bar//baz=1234//qux=4567'),
|
|
236
|
+
'Runo::Path.conds_of should ignore the item steps and the last step without a slash'
|
|
237
|
+
)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_conds_of_with_empty_conds
|
|
241
|
+
assert_equal(
|
|
242
|
+
{},
|
|
243
|
+
Runo::Path.conds_of(''),
|
|
244
|
+
'Runo::Path.conds_of should return empty hash when there is no conds'
|
|
245
|
+
)
|
|
246
|
+
assert_equal(
|
|
247
|
+
{},
|
|
248
|
+
Runo::Path.conds_of('/'),
|
|
249
|
+
'Runo::Path.conds_of should return empty hash when there is no conds'
|
|
250
|
+
)
|
|
251
|
+
assert_equal(
|
|
252
|
+
{},
|
|
253
|
+
Runo::Path.conds_of('/index.html'),
|
|
254
|
+
'Runo::Path.conds_of should return empty hash when there is no conds'
|
|
255
|
+
)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def test_conds_of_with_cond_d
|
|
259
|
+
assert_equal(
|
|
260
|
+
{
|
|
261
|
+
:d => '200911',
|
|
262
|
+
:baz => '1234',
|
|
263
|
+
:qux => '4567',
|
|
264
|
+
},
|
|
265
|
+
Runo::Path.conds_of('/foo/bar/200911/baz=1234/qux=4567/'),
|
|
266
|
+
'Runo::Path.conds_of should be able to distinguish ambiguous conds[:d]'
|
|
267
|
+
)
|
|
268
|
+
assert_equal(
|
|
269
|
+
{
|
|
270
|
+
:baz => '1234',
|
|
271
|
+
:qux => '4567',
|
|
272
|
+
},
|
|
273
|
+
Runo::Path.conds_of('/foo/bar/20091129_0001/baz=1234/qux=4567/'),
|
|
274
|
+
'Runo::Path.conds_of should ignore the full-formatted id'
|
|
275
|
+
)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def test_conds_of_with_cond_id
|
|
279
|
+
assert_equal(
|
|
280
|
+
['foo', 'bar'],
|
|
281
|
+
Runo::Path.steps_of('/foo/bar/20091205/9/baz=1234/qux=4567/'),
|
|
282
|
+
'Runo::Path.steps_of should ignore conds[:id]'
|
|
283
|
+
)
|
|
284
|
+
assert_equal(
|
|
285
|
+
{
|
|
286
|
+
:id => '20091205_0009',
|
|
287
|
+
:baz => '1234',
|
|
288
|
+
:qux => '4567',
|
|
289
|
+
},
|
|
290
|
+
Runo::Path.conds_of('/foo/bar/20091205/9/baz=1234/qux=4567/'),
|
|
291
|
+
'Runo::Path.conds_of should extract conds[:id] from the path sequence'
|
|
292
|
+
)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def test_action_of
|
|
296
|
+
assert_equal(
|
|
297
|
+
:create,
|
|
298
|
+
Runo::Path.action_of('/foo/bar/create.html'),
|
|
299
|
+
'Runo::Path.action_of should extract the action from path_info'
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
assert_nil(
|
|
303
|
+
Runo::Path.action_of('/foo/bar/index.html'),
|
|
304
|
+
'Runo::Path.action_of should return nil if the pseudo-filename is index.*'
|
|
305
|
+
)
|
|
306
|
+
assert_nil(
|
|
307
|
+
Runo::Path.action_of('/foo/bar/'),
|
|
308
|
+
'Runo::Path.action_of should return nil if no pseudo-filename is given'
|
|
309
|
+
)
|
|
310
|
+
assert_nil(
|
|
311
|
+
Runo::Path.action_of('/foo/bar/_detail.html'),
|
|
312
|
+
"Runo::Path.action_of should return nil if the pseudo-filename begins with '_'"
|
|
313
|
+
)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def test_sub_action_of
|
|
317
|
+
assert_equal(
|
|
318
|
+
:detail,
|
|
319
|
+
Runo::Path.sub_action_of('/foo/bar/read_detail.html'),
|
|
320
|
+
'Runo::Path.sub_action_of should extract the sub_action from path_info'
|
|
321
|
+
)
|
|
322
|
+
assert_nil(
|
|
323
|
+
Runo::Path.sub_action_of('/foo/bar/read.html'),
|
|
324
|
+
"Runo::Path.sub_action_of should return nil if the pseudo-filename does not include '_'"
|
|
325
|
+
)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def test_base_of
|
|
329
|
+
sd = Runo::Path.base_of '/foo/bar/main/index.html'
|
|
330
|
+
assert_instance_of(
|
|
331
|
+
Runo::Set::Dynamic,
|
|
332
|
+
sd,
|
|
333
|
+
'Runo::Path.base_of should return a set_dynamic'
|
|
334
|
+
)
|
|
335
|
+
assert_equal(
|
|
336
|
+
'-foo-bar-main',
|
|
337
|
+
sd[:full_name],
|
|
338
|
+
'Runo::Path.base_of should return a set_dynamic at the bottom of the given steps'
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
sd = Runo::Path.base_of '/foo/bar/index.html'
|
|
342
|
+
assert_instance_of(
|
|
343
|
+
Runo::Set::Dynamic,
|
|
344
|
+
sd,
|
|
345
|
+
'Runo::Path.base_of should return a set_dynamic'
|
|
346
|
+
)
|
|
347
|
+
assert_equal(
|
|
348
|
+
'-foo-bar-main',
|
|
349
|
+
sd[:full_name],
|
|
350
|
+
"Runo::Path.base_of should return the item('main') if the given steps point at a folder"
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
sd = Runo::Path.base_of '/foo/bar/20091120_0001/comment/index.html'
|
|
354
|
+
assert_instance_of(
|
|
355
|
+
Runo::Text,
|
|
356
|
+
sd,
|
|
357
|
+
'Runo::Path.base_of should return a text if designated'
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
sd = Runo::Path.base_of '/foo/bar/20091120_0001/files/index.html'
|
|
361
|
+
assert_instance_of(
|
|
362
|
+
Runo::Set::Dynamic,
|
|
363
|
+
sd,
|
|
364
|
+
'Runo::Path.base_of should return a set_dynamic'
|
|
365
|
+
)
|
|
366
|
+
assert_equal(
|
|
367
|
+
'-foo-bar-main-20091120_0001-files',
|
|
368
|
+
sd[:full_name],
|
|
369
|
+
"Runo::Path.base_of should be able to dive into any depth from the folder"
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
sd = Runo::Path.base_of '/foo/bar/20091120_0002/files/index.html'
|
|
373
|
+
assert_nil(
|
|
374
|
+
sd,
|
|
375
|
+
'Runo::Path.base_of should return nil if there is no set_dynamic at the steps'
|
|
376
|
+
)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def test_path_of
|
|
380
|
+
assert_equal(
|
|
381
|
+
'20091224/123/',
|
|
382
|
+
Runo::Path.path_of(:id => '20091224_0123'),
|
|
383
|
+
'Runo::Path.path_of should return a special combination of pseudo-steps for conds[:id]'
|
|
384
|
+
)
|
|
385
|
+
assert_equal(
|
|
386
|
+
'20091224/123/',
|
|
387
|
+
Runo::Path.path_of(:d => '2009', :id => '20091224_0123'),
|
|
388
|
+
'Runo::Path.path_of should ignore the other conds if there is conds[:id]'
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
assert_equal(
|
|
392
|
+
'20091224/123/',
|
|
393
|
+
Runo::Path.path_of(:id => ['20091224_0123']),
|
|
394
|
+
'Runo::Path.path_of should return a special combination of pseudo-steps for conds[:id]'
|
|
395
|
+
)
|
|
396
|
+
assert_equal(
|
|
397
|
+
'id=20091224_0123,20100222_1234/',
|
|
398
|
+
Runo::Path.path_of(:id => ['20091224_0123', '20100222_1234']),
|
|
399
|
+
'Runo::Path.path_of should return multiple ids as a comma-separated form'
|
|
400
|
+
)
|
|
401
|
+
assert_equal(
|
|
402
|
+
'',
|
|
403
|
+
Runo::Path.path_of(:id => []),
|
|
404
|
+
'Runo::Path.path_of should return an empty string when given an empty conds[:id]'
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
assert_equal(
|
|
408
|
+
'id=carl/',
|
|
409
|
+
Runo::Path.path_of(:id => '00000000_carl'),
|
|
410
|
+
"Runo::Path.path_of should use '/id=xxx/' form for a short id"
|
|
411
|
+
)
|
|
412
|
+
assert_equal(
|
|
413
|
+
'id=20091224_0123,carl/',
|
|
414
|
+
Runo::Path.path_of(:id => ['20091224_0123', '00000000_carl']),
|
|
415
|
+
"Runo::Path.path_of should use short ids in a comma-separated form"
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
assert_equal(
|
|
419
|
+
'foo=bar/',
|
|
420
|
+
Runo::Path.path_of(:foo => 'bar'),
|
|
421
|
+
'Runo::Path.path_of should return a path of which steps represent the conds'
|
|
422
|
+
)
|
|
423
|
+
assert_equal(
|
|
424
|
+
'foo=bar/p=123/',
|
|
425
|
+
Runo::Path.path_of(:p => 123, :foo => 'bar'),
|
|
426
|
+
'Runo::Path.path_of should return the step for conds[:p] at the tail end'
|
|
427
|
+
)
|
|
428
|
+
assert_equal(
|
|
429
|
+
'foo=bar/order=desc/p=123/',
|
|
430
|
+
Runo::Path.path_of(:p => 123, :order =>'desc', :foo => 'bar'),
|
|
431
|
+
'Runo::Path.path_of should return the step for conds[:order] at the tail end'
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
assert_equal(
|
|
435
|
+
'foo=bar/',
|
|
436
|
+
Runo::Path.path_of(:p => 1, :foo => 'bar'),
|
|
437
|
+
'Runo::Path.path_of should omit the step for conds[:p] when conds[:p] == 1'
|
|
438
|
+
)
|
|
439
|
+
assert_equal(
|
|
440
|
+
'p=1/',
|
|
441
|
+
Runo::Path.path_of(:p => 1),
|
|
442
|
+
'Runo::Path.path_of should not omit the step for conds[:p] when there is no other conds'
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
assert_equal(
|
|
446
|
+
'foo=1,2,3/',
|
|
447
|
+
Runo::Path.path_of(:foo => [1, 2, 3]),
|
|
448
|
+
'Runo::Path.path_of should return multiple values as a comma-separated form'
|
|
449
|
+
)
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
def test_params_from_request
|
|
453
|
+
runo = Runo.new
|
|
454
|
+
|
|
455
|
+
env = Rack::MockRequest.env_for(
|
|
456
|
+
'http://example.com/foo/bar/main/qux=456/read_detail.html?acorn=round',
|
|
457
|
+
{
|
|
458
|
+
:method => 'post',
|
|
459
|
+
:script_name => '',
|
|
460
|
+
:input => 'coax=true&some-doors=open',
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
req = Rack::Request.new env
|
|
464
|
+
params = runo.instance_eval {
|
|
465
|
+
params_from_request req
|
|
466
|
+
}
|
|
467
|
+
assert_equal(
|
|
468
|
+
{
|
|
469
|
+
:conds => {:qux => '456'},
|
|
470
|
+
:action => :read,
|
|
471
|
+
:sub_action => :detail,
|
|
472
|
+
'acorn' => 'round',
|
|
473
|
+
'coax' => 'true',
|
|
474
|
+
'some' => {'doors' => 'open'},
|
|
475
|
+
},
|
|
476
|
+
params,
|
|
477
|
+
'Runo#params_from_request should build params from req.path_info and req.params'
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
env = Rack::MockRequest.env_for(
|
|
481
|
+
'http://example.com/foo/bar/qux=456/index.html?acorn=round',
|
|
482
|
+
{
|
|
483
|
+
:method => 'post',
|
|
484
|
+
:script_name => '',
|
|
485
|
+
:input => 'coax=true&some-doors=open',
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
req = Rack::Request.new env
|
|
489
|
+
params = runo.instance_eval {
|
|
490
|
+
params_from_request req
|
|
491
|
+
}
|
|
492
|
+
assert_equal(
|
|
493
|
+
{
|
|
494
|
+
:conds => {:qux => '456'},
|
|
495
|
+
:action => nil,
|
|
496
|
+
:sub_action => nil,
|
|
497
|
+
'acorn' => 'round',
|
|
498
|
+
'coax' => 'true',
|
|
499
|
+
'some' => {'doors' => 'open'},
|
|
500
|
+
},
|
|
501
|
+
params,
|
|
502
|
+
'Runo#params_from_request should build params from req.path_info and req.params'
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
env = Rack::MockRequest.env_for(
|
|
506
|
+
'http://example.com/foo/bar/20091120_0001/files/qux=456/index.html?acorn=round',
|
|
507
|
+
{
|
|
508
|
+
:method => 'post',
|
|
509
|
+
:script_name => '',
|
|
510
|
+
:input => 'coax=true&some-doors=open',
|
|
511
|
+
}
|
|
512
|
+
)
|
|
513
|
+
req = Rack::Request.new env
|
|
514
|
+
params = runo.instance_eval {
|
|
515
|
+
params_from_request req
|
|
516
|
+
}
|
|
517
|
+
assert_equal(
|
|
518
|
+
{
|
|
519
|
+
:conds => {:qux => '456'},
|
|
520
|
+
:action => nil,
|
|
521
|
+
:sub_action => nil,
|
|
522
|
+
'acorn' => 'round',
|
|
523
|
+
'coax' => 'true',
|
|
524
|
+
'some' => {'doors' => 'open'},
|
|
525
|
+
},
|
|
526
|
+
params,
|
|
527
|
+
'Runo#params_from_request should attach the params from path_info to the base SD'
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
env = Rack::MockRequest.env_for(
|
|
531
|
+
'http://example.com/foo/bar/qux=456/index.html?acorn=round',
|
|
532
|
+
{
|
|
533
|
+
:method => 'post',
|
|
534
|
+
:script_name => '',
|
|
535
|
+
:input => 'some-doors=open&some.action-open=submit',
|
|
536
|
+
}
|
|
537
|
+
)
|
|
538
|
+
req = Rack::Request.new env
|
|
539
|
+
params = runo.instance_eval {
|
|
540
|
+
params_from_request req
|
|
541
|
+
}
|
|
542
|
+
assert_equal(
|
|
543
|
+
{
|
|
544
|
+
:conds => {:qux => '456'},
|
|
545
|
+
:action => nil,
|
|
546
|
+
:sub_action => nil,
|
|
547
|
+
'acorn' => 'round',
|
|
548
|
+
'some' => {'doors' => 'open', :action => :open},
|
|
549
|
+
},
|
|
550
|
+
params,
|
|
551
|
+
'Runo#params_from_request should build params from req.path_info and req.params'
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
env = Rack::MockRequest.env_for(
|
|
555
|
+
'http://example.com/foo/bar/update.html',
|
|
556
|
+
{
|
|
557
|
+
:method => 'post',
|
|
558
|
+
:script_name => '',
|
|
559
|
+
:input => '.action=open_sesami',
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
req = Rack::Request.new env
|
|
563
|
+
params = runo.instance_eval {
|
|
564
|
+
params_from_request req
|
|
565
|
+
}
|
|
566
|
+
assert_equal(
|
|
567
|
+
{
|
|
568
|
+
:conds => {},
|
|
569
|
+
:action => :open,
|
|
570
|
+
:sub_action => :sesami,
|
|
571
|
+
},
|
|
572
|
+
params,
|
|
573
|
+
'Runo#params_from_request should override path_info by :input'
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
env = Rack::MockRequest.env_for(
|
|
577
|
+
'http://example.com/foo/bar/update.html',
|
|
578
|
+
{
|
|
579
|
+
:method => 'post',
|
|
580
|
+
:script_name => '',
|
|
581
|
+
:input => '.action-open_sesami=submit',
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
req = Rack::Request.new env
|
|
585
|
+
params = runo.instance_eval {
|
|
586
|
+
params_from_request req
|
|
587
|
+
}
|
|
588
|
+
assert_equal(
|
|
589
|
+
{
|
|
590
|
+
:conds => {},
|
|
591
|
+
:action => :open,
|
|
592
|
+
:sub_action => :sesami,
|
|
593
|
+
},
|
|
594
|
+
params,
|
|
595
|
+
'Runo#params_from_request should override path_info by :input'
|
|
596
|
+
)
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
def test_current
|
|
600
|
+
Runo.current[:foo] = 'main foo'
|
|
601
|
+
main_current = Runo.current
|
|
602
|
+
|
|
603
|
+
t = Thread.new {
|
|
604
|
+
assert_not_equal(
|
|
605
|
+
main_current,
|
|
606
|
+
Runo.current,
|
|
607
|
+
'Runo.current should be unique per a thread'
|
|
608
|
+
)
|
|
609
|
+
assert_not_equal(
|
|
610
|
+
'main foo',
|
|
611
|
+
Runo.current[:foo],
|
|
612
|
+
'Runo.current should be unique per a thread'
|
|
613
|
+
)
|
|
614
|
+
Runo.current[:foo] = 'child foo'
|
|
615
|
+
}
|
|
616
|
+
t.join
|
|
617
|
+
|
|
618
|
+
assert_equal(
|
|
619
|
+
'main foo',
|
|
620
|
+
Runo.current[:foo],
|
|
621
|
+
'Runo.current should be unique per a thread'
|
|
622
|
+
)
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
def test_login
|
|
626
|
+
Runo.client = nil
|
|
627
|
+
res = Runo.new.send(
|
|
628
|
+
:login,
|
|
629
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
630
|
+
{'id' => 'test', 'pw' => 'test', :conds => {:id => '20100222_0123'}, 'dest_action' => 'update'}
|
|
631
|
+
)
|
|
632
|
+
assert_equal(
|
|
633
|
+
'test',
|
|
634
|
+
Runo.client,
|
|
635
|
+
'Runo#login should set Runo.client given a valid pair of user/password'
|
|
636
|
+
)
|
|
637
|
+
assert_match(
|
|
638
|
+
%r{/foo/20100222/123/update.html},
|
|
639
|
+
res[1]['Location'],
|
|
640
|
+
'Runo#login should return a proper location header'
|
|
641
|
+
)
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
def test_login_default_action
|
|
645
|
+
Runo.client = nil
|
|
646
|
+
res = Runo.new.send(
|
|
647
|
+
:login,
|
|
648
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
649
|
+
{'id' => 'test', 'pw' => 'test', :conds => {:id => '20100222_0123'}}
|
|
650
|
+
)
|
|
651
|
+
assert_match(
|
|
652
|
+
%r{/foo/20100222/123/index.html},
|
|
653
|
+
res[1]['Location'],
|
|
654
|
+
"Runo#login should set 'index' as the default action of a location"
|
|
655
|
+
)
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
def test_login_with_wrong_account
|
|
659
|
+
Runo.client = nil
|
|
660
|
+
|
|
661
|
+
assert_raise(
|
|
662
|
+
Runo::Error::Forbidden,
|
|
663
|
+
'Runo#login should raise Error::Forbidden given a non-existent user'
|
|
664
|
+
) {
|
|
665
|
+
Runo.new.send(
|
|
666
|
+
:login,
|
|
667
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
668
|
+
{'id' => 'non-existent', 'pw' => 'test'}
|
|
669
|
+
)
|
|
670
|
+
}
|
|
671
|
+
assert_equal(
|
|
672
|
+
'nobody',
|
|
673
|
+
Runo.client,
|
|
674
|
+
'Runo#login should not set Runo.client with a non-existent user'
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
assert_raise(
|
|
678
|
+
Runo::Error::Forbidden,
|
|
679
|
+
'Runo#login should raise Error::Forbidden given a empty password'
|
|
680
|
+
) {
|
|
681
|
+
Runo.new.send(
|
|
682
|
+
:login,
|
|
683
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
684
|
+
{'id' => 'test', 'pw' => nil}
|
|
685
|
+
)
|
|
686
|
+
}
|
|
687
|
+
assert_equal(
|
|
688
|
+
'nobody',
|
|
689
|
+
Runo.client,
|
|
690
|
+
'Runo#login should not set Runo.client with an empty password'
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
assert_raise(
|
|
694
|
+
Runo::Error::Forbidden,
|
|
695
|
+
'Runo#login should raise Error::Forbidden given a wrong password'
|
|
696
|
+
) {
|
|
697
|
+
res = Runo.new.send(
|
|
698
|
+
:login,
|
|
699
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
700
|
+
{
|
|
701
|
+
'id' => 'test',
|
|
702
|
+
'pw' => 'wrong',
|
|
703
|
+
:conds => {:id => '20100222_0123'},
|
|
704
|
+
'dest_action' => 'update'
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
}
|
|
708
|
+
assert_equal(
|
|
709
|
+
'nobody',
|
|
710
|
+
Runo.client,
|
|
711
|
+
'Runo#login should not set Runo.client with a wrong password'
|
|
712
|
+
)
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
def test_logout
|
|
716
|
+
Runo.client = 'frank'
|
|
717
|
+
res = Runo.new.send(
|
|
718
|
+
:logout,
|
|
719
|
+
Runo::Set::Static::Folder.root.item('foo', 'main'),
|
|
720
|
+
{'id' => 'test', 'pw' => 'test', :conds => {:id => '20100222_0123'}}
|
|
721
|
+
)
|
|
722
|
+
assert_equal(
|
|
723
|
+
'nobody',
|
|
724
|
+
Runo.client,
|
|
725
|
+
'Runo#logout should clear Runo.client'
|
|
726
|
+
)
|
|
727
|
+
assert_match(
|
|
728
|
+
%r{/foo/20100222/123/index.html},
|
|
729
|
+
res[1]['Location'],
|
|
730
|
+
'Runo#logout should return a proper location header'
|
|
731
|
+
)
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
def test_libdir
|
|
735
|
+
assert_match(
|
|
736
|
+
%r{^.*/lib$},
|
|
737
|
+
Runo.libdir,
|
|
738
|
+
'Runo#libdir should return the lib/ directory where the runo.rb is in'
|
|
739
|
+
)
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
end
|