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_file.rb
ADDED
|
@@ -0,0 +1,900 @@
|
|
|
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_File < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
Runo.current[:uri] = nil
|
|
12
|
+
|
|
13
|
+
@file = Class.new
|
|
14
|
+
@file.stubs(:rewind).returns(nil)
|
|
15
|
+
@file.stubs(:read).returns('this is file body')
|
|
16
|
+
@file.stubs(:length).returns(@file.read.length)
|
|
17
|
+
|
|
18
|
+
meta = nil
|
|
19
|
+
Runo::Parser.gsub_scalar('$(foo file 1..50 jpg, gif, png)') {|id, m|
|
|
20
|
+
meta = m
|
|
21
|
+
''
|
|
22
|
+
}
|
|
23
|
+
@f = Runo::Field.instance meta.merge(:id => 'foo')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_meta
|
|
27
|
+
assert_equal(
|
|
28
|
+
1,
|
|
29
|
+
@f[:min],
|
|
30
|
+
'File#initialize should set :min from the range token'
|
|
31
|
+
)
|
|
32
|
+
assert_equal(
|
|
33
|
+
50,
|
|
34
|
+
@f[:max],
|
|
35
|
+
'File#initialize should set :max from the range token'
|
|
36
|
+
)
|
|
37
|
+
assert_equal(
|
|
38
|
+
['jpg', 'gif', 'png'],
|
|
39
|
+
@f[:options],
|
|
40
|
+
'File#initialize should set :options from the csv token'
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_meta_options
|
|
45
|
+
meta = nil
|
|
46
|
+
Runo::Parser.gsub_scalar('$(foo file jpg, GIF, Png)') {|id, m|
|
|
47
|
+
meta = m
|
|
48
|
+
''
|
|
49
|
+
}
|
|
50
|
+
@f = Runo::Field.instance meta.merge(:id => 'foo')
|
|
51
|
+
assert_equal(
|
|
52
|
+
['jpg', 'gif', 'png'],
|
|
53
|
+
@f[:options],
|
|
54
|
+
'File#initialize should downcase :options'
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_meta_path
|
|
59
|
+
@f[:parent] = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
60
|
+
assert_equal(
|
|
61
|
+
'/t_file/main/foo',
|
|
62
|
+
@f[:path],
|
|
63
|
+
'File#meta_path should return the full path to the field'
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_meta_tmp_path
|
|
68
|
+
@f[:parent] = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
69
|
+
Runo.current[:base] = @f[:parent]
|
|
70
|
+
tid = @f[:parent][:tid]
|
|
71
|
+
|
|
72
|
+
assert_equal(
|
|
73
|
+
"/t_file/#{tid}/foo",
|
|
74
|
+
@f[:tmp_path],
|
|
75
|
+
'File#meta_tmp_path should return the short path from the tid'
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
Runo.current[:base] = nil
|
|
79
|
+
assert_nil(
|
|
80
|
+
@f[:tmp_path],
|
|
81
|
+
'File#meta_tmp_path should return nil unless Runo.base is set'
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_meta_persistent_sd
|
|
86
|
+
root = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
87
|
+
parent = Runo::Set::Dynamic.new(:id => 'boo', :parent => root)
|
|
88
|
+
@f[:parent] = parent
|
|
89
|
+
assert_equal(
|
|
90
|
+
root,
|
|
91
|
+
@f[:persistent_sd],
|
|
92
|
+
'File#persistent_sd should return the nearest persient sd'
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_meta_persistent_name
|
|
97
|
+
root = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
98
|
+
parent = Runo::Set::Dynamic.new(:id => 'boo', :parent => root)
|
|
99
|
+
@f[:parent] = parent
|
|
100
|
+
assert_equal(
|
|
101
|
+
'boo-foo',
|
|
102
|
+
@f[:persistent_name],
|
|
103
|
+
'File#persistent_name should return the path to [:persistent_sd]'
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_val_cast_from_rack
|
|
108
|
+
@f.create(
|
|
109
|
+
:type => 'image/jpeg',
|
|
110
|
+
:tempfile => @file,
|
|
111
|
+
:head => <<'_eos',
|
|
112
|
+
Content-Disposition: form-data; name="t_file"; filename="baz.jpg"
|
|
113
|
+
Content-Type: image/jpeg
|
|
114
|
+
_eos
|
|
115
|
+
:filename => 'baz.jpg',
|
|
116
|
+
:name => 't_file'
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
assert_equal(
|
|
120
|
+
{
|
|
121
|
+
'basename' => 'baz.jpg',
|
|
122
|
+
'type' => 'image/jpeg',
|
|
123
|
+
'size' => @file.length,
|
|
124
|
+
},
|
|
125
|
+
@f.val,
|
|
126
|
+
'File#val_cast should re-map a hash from Rack'
|
|
127
|
+
)
|
|
128
|
+
assert_equal(
|
|
129
|
+
@file.read,
|
|
130
|
+
@f.body,
|
|
131
|
+
'File#val_cast should store the file body in @body'
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_val_cast_load
|
|
136
|
+
@f.load(
|
|
137
|
+
'basename' => 'baz.jpg',
|
|
138
|
+
'type' => 'image/jpeg',
|
|
139
|
+
'size' => 123
|
|
140
|
+
)
|
|
141
|
+
assert_equal(
|
|
142
|
+
{
|
|
143
|
+
'basename' => 'baz.jpg',
|
|
144
|
+
'type' => 'image/jpeg',
|
|
145
|
+
'size' => 123,
|
|
146
|
+
},
|
|
147
|
+
@f.val,
|
|
148
|
+
'File#val_cast should load() a hash without :tempfile like Set#load'
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
@f.load(
|
|
152
|
+
{}
|
|
153
|
+
)
|
|
154
|
+
assert_equal(
|
|
155
|
+
{},
|
|
156
|
+
@f.val,
|
|
157
|
+
'File#val_cast should load() a hash without :tempfile like Set#load'
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_get
|
|
162
|
+
@f[:parent] = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
163
|
+
Runo.current[:base] = @f[:parent]
|
|
164
|
+
tid = @f[:parent][:tid]
|
|
165
|
+
|
|
166
|
+
@f.load({})
|
|
167
|
+
assert_nil(
|
|
168
|
+
@f.get,
|
|
169
|
+
'File#get should return nil when the val is empty'
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
@f.load(
|
|
173
|
+
'basename' => 'baz.jpg',
|
|
174
|
+
'type' => 'image/jpeg',
|
|
175
|
+
'size' => 12
|
|
176
|
+
)
|
|
177
|
+
assert_equal(
|
|
178
|
+
'<a href="/t_file/main/foo/baz.jpg">baz.jpg (12 bytes)</a>',
|
|
179
|
+
@f.get,
|
|
180
|
+
'File#get should return proper string'
|
|
181
|
+
)
|
|
182
|
+
assert_equal(
|
|
183
|
+
<<"_html",
|
|
184
|
+
<span class="file">
|
|
185
|
+
<a href="/t_file/#{tid}/foo/baz.jpg">baz.jpg (12 bytes)</a>
|
|
186
|
+
<input type="file" name="foo" size="" class="file" />
|
|
187
|
+
</span>
|
|
188
|
+
_html
|
|
189
|
+
@f.get(:action => :update),
|
|
190
|
+
'File#get should return proper string'
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
@f.load(
|
|
194
|
+
'basename' => '<baz>.jpg',
|
|
195
|
+
'type' => 'image/<jpeg>',
|
|
196
|
+
'size' => 12
|
|
197
|
+
)
|
|
198
|
+
assert_equal(
|
|
199
|
+
'<a href="/t_file/main/foo/<baz>.jpg"><baz>.jpg (12 bytes)</a>',
|
|
200
|
+
@f.get,
|
|
201
|
+
'File#get should escape the special characters in file information'
|
|
202
|
+
)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_get_hidden
|
|
206
|
+
Runo.client = 'root'
|
|
207
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
208
|
+
sd.update(
|
|
209
|
+
'_1' => {
|
|
210
|
+
'baz' => {
|
|
211
|
+
'_1' => {},
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
Runo.current[:base] = sd
|
|
216
|
+
sd[:tid] = '1234.567'
|
|
217
|
+
|
|
218
|
+
assert_equal(
|
|
219
|
+
<<'_html',
|
|
220
|
+
<span class="file">
|
|
221
|
+
|
|
222
|
+
<input type="file" name="_1-foo" size="" class="file" />
|
|
223
|
+
</span>
|
|
224
|
+
_html
|
|
225
|
+
sd.item('_1', 'foo').get(:action => :create),
|
|
226
|
+
'File#get should not include a hidden input if the field is not required'
|
|
227
|
+
)
|
|
228
|
+
assert_equal(
|
|
229
|
+
<<'_html',
|
|
230
|
+
<span class="file">
|
|
231
|
+
|
|
232
|
+
<input type="hidden" name="_1-baz-_1-qux" value="" />
|
|
233
|
+
<input type="file" name="_1-baz-_1-qux" size="" class="file" />
|
|
234
|
+
</span>
|
|
235
|
+
_html
|
|
236
|
+
sd.item('_1', 'baz', '_1', 'qux').get(:action => :create),
|
|
237
|
+
'File#get should include a hidden input to supplement an empty field'
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
sd.update(
|
|
241
|
+
'_1' => {
|
|
242
|
+
'baz' => {
|
|
243
|
+
'_1' => {
|
|
244
|
+
'qux' => {
|
|
245
|
+
:type => 'image/jpeg',
|
|
246
|
+
:tempfile => @file,
|
|
247
|
+
:head => <<'_eos',
|
|
248
|
+
Content-Disposition: form-data; name="t_file"; filename="qux.jpg"
|
|
249
|
+
Content-Type: image/jpeg
|
|
250
|
+
_eos
|
|
251
|
+
:filename => 'qux.jpg',
|
|
252
|
+
:name => 't_file'
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
)
|
|
258
|
+
assert_equal(
|
|
259
|
+
<<"_html",
|
|
260
|
+
<span class="file">
|
|
261
|
+
<a href="/t_file/1234.567/_1/baz/_1/qux/qux.jpg">qux.jpg (#{@file.length} bytes)</a>
|
|
262
|
+
<input type="file" name="_1-baz-_1-qux" size="" class="file" />
|
|
263
|
+
</span>
|
|
264
|
+
_html
|
|
265
|
+
sd.item('_1', 'baz', '_1', 'qux').get(:action => :update),
|
|
266
|
+
'File#get should not include a hidden if the field is not empty'
|
|
267
|
+
)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def test_get_delete
|
|
271
|
+
Runo.client = 'root'
|
|
272
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
273
|
+
sd.update(
|
|
274
|
+
'_1' => {
|
|
275
|
+
'baz' => {
|
|
276
|
+
'_1' => {},
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
Runo.current[:base] = sd
|
|
281
|
+
sd[:tid] = '1234.567'
|
|
282
|
+
|
|
283
|
+
assert_equal(
|
|
284
|
+
<<'_html',
|
|
285
|
+
<span class="file">
|
|
286
|
+
|
|
287
|
+
<input type="file" name="_1-foo" size="" class="file" />
|
|
288
|
+
</span>
|
|
289
|
+
_html
|
|
290
|
+
sd.item('_1', 'foo').get(:action => :create),
|
|
291
|
+
'File#get should not include a delete submit if the field is empty'
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
sd.update(
|
|
295
|
+
'_1' => {
|
|
296
|
+
'foo' => {
|
|
297
|
+
:type => 'image/jpeg',
|
|
298
|
+
:tempfile => @file,
|
|
299
|
+
:head => <<'_eos',
|
|
300
|
+
Content-Disposition: form-data; name="t_file"; filename="foo.jpg"
|
|
301
|
+
Content-Type: image/jpeg
|
|
302
|
+
_eos
|
|
303
|
+
:filename => 'foo.jpg',
|
|
304
|
+
:name => 't_file'
|
|
305
|
+
},
|
|
306
|
+
}
|
|
307
|
+
)
|
|
308
|
+
assert_equal(
|
|
309
|
+
<<"_html",
|
|
310
|
+
<span class="file">
|
|
311
|
+
<a href="/t_file/1234.567/_1/foo/foo.jpg">foo.jpg (#{@file.length} bytes)</a>
|
|
312
|
+
<input type="file" name="_1-foo" size="" class="file" />
|
|
313
|
+
<input type="submit" name="_1-foo.action-delete" value="delete" />
|
|
314
|
+
</span>
|
|
315
|
+
_html
|
|
316
|
+
sd.item('_1', 'foo').get(:action => :update),
|
|
317
|
+
'File#get should include a delete submit if the field is not empty'
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
sd.item('_1', 'foo')[:min] = 1
|
|
321
|
+
assert_equal(
|
|
322
|
+
<<"_html",
|
|
323
|
+
<span class="file">
|
|
324
|
+
<a href="/t_file/1234.567/_1/foo/foo.jpg">foo.jpg (#{@file.length} bytes)</a>
|
|
325
|
+
<input type="file" name="_1-foo" size="" class="file" />
|
|
326
|
+
</span>
|
|
327
|
+
_html
|
|
328
|
+
sd.item('_1', 'foo').get(:action => :update),
|
|
329
|
+
'File#get should not include a delete submit if the field is mandatory'
|
|
330
|
+
)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# TODO: test on all available storages.
|
|
334
|
+
def test_select
|
|
335
|
+
Runo.client = 'root'
|
|
336
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
337
|
+
sd.storage.clear
|
|
338
|
+
sd.update(
|
|
339
|
+
'20100425_1234' => {
|
|
340
|
+
'foo' => {
|
|
341
|
+
:type => 'image/jpeg',
|
|
342
|
+
:tempfile => @file,
|
|
343
|
+
:filename => 'foo.jpg',
|
|
344
|
+
:name => 't_file'
|
|
345
|
+
},
|
|
346
|
+
}
|
|
347
|
+
).commit :persistent
|
|
348
|
+
|
|
349
|
+
assert_equal(
|
|
350
|
+
['20100425_1234'],
|
|
351
|
+
sd.collect {|item| item[:id] },
|
|
352
|
+
'storages should distinguish between data and files'
|
|
353
|
+
)
|
|
354
|
+
assert_equal(
|
|
355
|
+
['20100425_1234'],
|
|
356
|
+
sd.instance_eval {
|
|
357
|
+
collect_item(:id => '20100425_1234') {|item| item[:id] }
|
|
358
|
+
},
|
|
359
|
+
'storages should distinguish between data and files'
|
|
360
|
+
)
|
|
361
|
+
assert_equal(
|
|
362
|
+
['20100425_1234'],
|
|
363
|
+
sd.instance_eval {
|
|
364
|
+
collect_item(:d => '201004') {|item| item[:id] }
|
|
365
|
+
},
|
|
366
|
+
'storages should distinguish between data and files'
|
|
367
|
+
)
|
|
368
|
+
assert_equal(
|
|
369
|
+
['20100425_1234'],
|
|
370
|
+
sd.instance_eval {
|
|
371
|
+
collect_item({}) {|item| item[:id] }
|
|
372
|
+
},
|
|
373
|
+
'storages should distinguish between data and files'
|
|
374
|
+
)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def test_call_body
|
|
378
|
+
Runo.client = 'root'
|
|
379
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
380
|
+
sd.storage.clear
|
|
381
|
+
|
|
382
|
+
# post a multipart request
|
|
383
|
+
input = <<"_eos".gsub(/\r?\n/, "\r\n")
|
|
384
|
+
---foobarbaz
|
|
385
|
+
Content-Disposition: form-data; name="_1-foo"; filename="foo.jpg"
|
|
386
|
+
Content-Type: image/jpeg
|
|
387
|
+
|
|
388
|
+
#{@file.read}
|
|
389
|
+
---foobarbaz
|
|
390
|
+
Content-Disposition: form-data; name="_token"
|
|
391
|
+
|
|
392
|
+
#{Runo.token}
|
|
393
|
+
---foobarbaz--
|
|
394
|
+
_eos
|
|
395
|
+
res = Rack::MockRequest.new(Runo.new).post(
|
|
396
|
+
'http://example.com/t_file/main/update.html',
|
|
397
|
+
{
|
|
398
|
+
:input => input,
|
|
399
|
+
'CONTENT_TYPE' => 'multipart/form-data; boundary=-foobarbaz',
|
|
400
|
+
'CONTENT_LENGTH' => input.length,
|
|
401
|
+
}
|
|
402
|
+
)
|
|
403
|
+
tid = res.headers['Location'][Runo::REX::TID]
|
|
404
|
+
|
|
405
|
+
assert_equal(
|
|
406
|
+
@file.read,
|
|
407
|
+
Runo.transaction[tid].item('_1', 'foo').body,
|
|
408
|
+
'Runo#call should keep suspended field in Runo.transaction'
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
412
|
+
"http://example.com/#{tid}/_1/foo/foo.jpg"
|
|
413
|
+
)
|
|
414
|
+
assert_equal(
|
|
415
|
+
@file.read,
|
|
416
|
+
res.body,
|
|
417
|
+
'Runo#call should be able to access suspended file bodies'
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
# commit the base
|
|
421
|
+
res = Rack::MockRequest.new(Runo.new).post(
|
|
422
|
+
"http://example.com/#{tid}/update.html",
|
|
423
|
+
{
|
|
424
|
+
:input => ".status-public=create&_token=#{Runo.token}",
|
|
425
|
+
}
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
res.headers['Location'] =~ Runo::REX::PATH_ID
|
|
429
|
+
new_id = sprintf('%.8d_%.4d', $1, $2)
|
|
430
|
+
|
|
431
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
432
|
+
"http://example.com/t_file/#{new_id}/foo/foo.jpg"
|
|
433
|
+
)
|
|
434
|
+
assert_equal(
|
|
435
|
+
'image/jpeg',
|
|
436
|
+
res.headers['Content-Type'],
|
|
437
|
+
'Runo#call to a file item should return the mime type of the file'
|
|
438
|
+
)
|
|
439
|
+
assert_equal(
|
|
440
|
+
@file.length.to_s,
|
|
441
|
+
res.headers['Content-Length'],
|
|
442
|
+
'Runo#call to a file item should return the content length of the file'
|
|
443
|
+
)
|
|
444
|
+
assert_equal(
|
|
445
|
+
@file.read,
|
|
446
|
+
res.body,
|
|
447
|
+
'Runo#call to a file item should return the binary body of the file'
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# move
|
|
451
|
+
Rack::MockRequest.new(Runo.new).post(
|
|
452
|
+
'http://example.com/t_file/update.html',
|
|
453
|
+
{
|
|
454
|
+
:input => "#{new_id}-_timestamp=1981-12-02&.status-public=update&_token=#{Runo.token}",
|
|
455
|
+
}
|
|
456
|
+
)
|
|
457
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
458
|
+
"http://example.com/t_file/#{new_id}/foo/foo.jpg"
|
|
459
|
+
)
|
|
460
|
+
assert_equal(
|
|
461
|
+
404,
|
|
462
|
+
res.status,
|
|
463
|
+
'Runo#call should move child files as well'
|
|
464
|
+
)
|
|
465
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
466
|
+
'http://example.com/t_file/19811202_0001/foo/foo.jpg'
|
|
467
|
+
)
|
|
468
|
+
assert_equal(
|
|
469
|
+
@file.read,
|
|
470
|
+
res.body,
|
|
471
|
+
'Runo#call should move child files as well'
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
# delete
|
|
475
|
+
Rack::MockRequest.new(Runo.new).post(
|
|
476
|
+
'http://example.com/t_file/update.html',
|
|
477
|
+
{
|
|
478
|
+
:input => "19811202_0001.action=delete&.status-public=delete&_token=#{Runo.token}",
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
res = Rack::MockRequest.new(Runo.new).get(
|
|
482
|
+
'http://example.com/t_file/19811202_0001/foo/foo.jpg'
|
|
483
|
+
)
|
|
484
|
+
assert_equal(
|
|
485
|
+
404,
|
|
486
|
+
res.status,
|
|
487
|
+
'Runo#call should delete child files as well'
|
|
488
|
+
)
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def test_errors
|
|
492
|
+
@f.create({})
|
|
493
|
+
@f[:min] = 0
|
|
494
|
+
assert_equal(
|
|
495
|
+
[],
|
|
496
|
+
@f.errors,
|
|
497
|
+
'File#errors should return the errors of the current body'
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
@f[:min] = 1
|
|
501
|
+
@f.create({})
|
|
502
|
+
assert_equal(
|
|
503
|
+
['mandatory'],
|
|
504
|
+
@f.errors,
|
|
505
|
+
'File#errors should return the errors of the current body'
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
@f[:min] = 1
|
|
509
|
+
@f.delete
|
|
510
|
+
@f.commit :temp
|
|
511
|
+
@f.commit :persistent
|
|
512
|
+
assert_equal(
|
|
513
|
+
['mandatory'],
|
|
514
|
+
@f.errors,
|
|
515
|
+
'File#errors should return the errors of the current body'
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
@f.update(
|
|
519
|
+
:type => 'image/jpeg',
|
|
520
|
+
:tempfile => @file,
|
|
521
|
+
:head => <<'_eos',
|
|
522
|
+
Content-Disposition: form-data; name="t_file"; filename="baz.jpg"
|
|
523
|
+
Content-Type: image/jpeg
|
|
524
|
+
_eos
|
|
525
|
+
:filename => 'baz.jpg',
|
|
526
|
+
:name => 't_file'
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
@f[:min] = 0
|
|
530
|
+
assert_equal(
|
|
531
|
+
[],
|
|
532
|
+
@f.errors,
|
|
533
|
+
'File#errors should return the errors of the current body'
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
@f[:min] = @file.length + 1
|
|
537
|
+
@f[:max] = nil
|
|
538
|
+
assert_equal(
|
|
539
|
+
["too small: #{@file.length + 1} bytes minimum"],
|
|
540
|
+
@f.errors,
|
|
541
|
+
'File#errors should return the errors of the current body'
|
|
542
|
+
)
|
|
543
|
+
|
|
544
|
+
@f[:min] = nil
|
|
545
|
+
@f[:max] = @file.length - 1
|
|
546
|
+
assert_equal(
|
|
547
|
+
["too large: #{@file.length - 1} bytes maximum"],
|
|
548
|
+
@f.errors,
|
|
549
|
+
'File#errors should return the errors of the current body'
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
@f[:min] = nil
|
|
553
|
+
@f[:max] = nil
|
|
554
|
+
@f[:options] = ['txt', 'pdf', 'doc']
|
|
555
|
+
assert_equal(
|
|
556
|
+
['wrong file type: should be txt/pdf/doc'],
|
|
557
|
+
@f.errors,
|
|
558
|
+
'File#errors should return the errors of the current body'
|
|
559
|
+
)
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
def test_errors_options
|
|
563
|
+
@f.create(
|
|
564
|
+
:type => 'image/jpeg',
|
|
565
|
+
:tempfile => @file,
|
|
566
|
+
:head => <<'_eos',
|
|
567
|
+
Content-Disposition: form-data; name="t_file"; filename="BAZ.JPG"
|
|
568
|
+
Content-Type: image/jpeg
|
|
569
|
+
_eos
|
|
570
|
+
:filename => 'BAZ.JPG',
|
|
571
|
+
:name => 't_file'
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
@f[:min] = nil
|
|
575
|
+
@f[:max] = nil
|
|
576
|
+
@f[:options] = ['jpg']
|
|
577
|
+
assert_equal(
|
|
578
|
+
[],
|
|
579
|
+
@f.errors,
|
|
580
|
+
'File#errors should ignore the case of extentions'
|
|
581
|
+
)
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
def test_save_file
|
|
585
|
+
Runo.client = 'root'
|
|
586
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
587
|
+
sd.storage.clear
|
|
588
|
+
|
|
589
|
+
# create a new set with file items
|
|
590
|
+
sd.update(
|
|
591
|
+
'_1' => {
|
|
592
|
+
'foo' => {
|
|
593
|
+
:type => 'image/jpeg',
|
|
594
|
+
:tempfile => @file,
|
|
595
|
+
:head => <<'_eos',
|
|
596
|
+
Content-Disposition: form-data; name="t_file"; filename="foo.jpg"
|
|
597
|
+
Content-Type: image/jpeg
|
|
598
|
+
_eos
|
|
599
|
+
:filename => 'foo.jpg',
|
|
600
|
+
:name => 't_file'
|
|
601
|
+
},
|
|
602
|
+
}
|
|
603
|
+
)
|
|
604
|
+
assert_nothing_raised(
|
|
605
|
+
'File#commit should commit files nicely'
|
|
606
|
+
) {
|
|
607
|
+
sd.commit :persistent
|
|
608
|
+
}
|
|
609
|
+
id = sd.result.values.first[:id]
|
|
610
|
+
|
|
611
|
+
item = Runo::Set::Static::Folder.root.item('t_file', 'main', id, 'foo')
|
|
612
|
+
assert_instance_of(
|
|
613
|
+
Runo::File,
|
|
614
|
+
item,
|
|
615
|
+
'File#commit should commit the file item'
|
|
616
|
+
)
|
|
617
|
+
assert_equal(
|
|
618
|
+
@file.read,
|
|
619
|
+
item.body,
|
|
620
|
+
'File#commit should store the body of the file item'
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
# update the sibling file item
|
|
624
|
+
sd.update(
|
|
625
|
+
id => {
|
|
626
|
+
'bar' => {
|
|
627
|
+
:type => 'image/png',
|
|
628
|
+
:tempfile => @file,
|
|
629
|
+
:head => <<'_eos',
|
|
630
|
+
Content-Disposition: form-data; name="t_file"; filename="bar.png"
|
|
631
|
+
Content-Type: image/png
|
|
632
|
+
_eos
|
|
633
|
+
:filename => 'bar.png',
|
|
634
|
+
:name => 't_file'
|
|
635
|
+
},
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
sd.commit :persistent
|
|
639
|
+
|
|
640
|
+
assert_equal(
|
|
641
|
+
@file.read,
|
|
642
|
+
Runo::Set::Static::Folder.root.item('t_file', 'main', id, 'bar').body,
|
|
643
|
+
'File#commit should store the body of the file item'
|
|
644
|
+
)
|
|
645
|
+
assert_equal(
|
|
646
|
+
@file.read,
|
|
647
|
+
Runo::Set::Static::Folder.root.item('t_file', 'main', id, 'foo').body,
|
|
648
|
+
'File#commit should keep the body of the untouched file item'
|
|
649
|
+
)
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
def test_delete_file
|
|
653
|
+
Runo.client = 'root'
|
|
654
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
655
|
+
sd.storage.clear
|
|
656
|
+
|
|
657
|
+
sd.update(
|
|
658
|
+
'_1' => {
|
|
659
|
+
'foo' => {
|
|
660
|
+
:type => 'image/jpeg',
|
|
661
|
+
:tempfile => @file,
|
|
662
|
+
:head => <<'_eos',
|
|
663
|
+
Content-Disposition: form-data; name="t_file"; filename="foo.jpg"
|
|
664
|
+
Content-Type: image/jpeg
|
|
665
|
+
_eos
|
|
666
|
+
:filename => 'foo.jpg',
|
|
667
|
+
:name => 't_file'
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
)
|
|
671
|
+
sd.commit :persistent
|
|
672
|
+
|
|
673
|
+
id = sd.result.values.first[:id]
|
|
674
|
+
|
|
675
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
676
|
+
sd.update(
|
|
677
|
+
id => {'foo' => {:action => :delete}}
|
|
678
|
+
)
|
|
679
|
+
assert_equal(:delete, sd.item(id, 'foo').action)
|
|
680
|
+
sd.commit :temp
|
|
681
|
+
|
|
682
|
+
assert_equal(
|
|
683
|
+
{},
|
|
684
|
+
sd.item(id, 'foo').val,
|
|
685
|
+
'File#delete should clear the val of the field'
|
|
686
|
+
)
|
|
687
|
+
assert_equal(
|
|
688
|
+
:delete,
|
|
689
|
+
sd.item(id, 'foo').action,
|
|
690
|
+
'File#delete should set @action'
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
another_sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
694
|
+
assert_not_equal(
|
|
695
|
+
{},
|
|
696
|
+
another_sd.item(id, 'foo').val,
|
|
697
|
+
'File#delete should not clear the persistent val before commit(:persistent)'
|
|
698
|
+
)
|
|
699
|
+
assert_equal(
|
|
700
|
+
@file.read,
|
|
701
|
+
another_sd.item(id, 'foo').body,
|
|
702
|
+
'File#delete should not delete the persistent body before commit(:persistent)'
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
sd.commit :persistent
|
|
706
|
+
|
|
707
|
+
another_sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
708
|
+
assert_equal(
|
|
709
|
+
{},
|
|
710
|
+
another_sd.item(id, 'foo').val,
|
|
711
|
+
'File#delete should clear the persistent val after commit(:persistent)'
|
|
712
|
+
)
|
|
713
|
+
assert_nil(
|
|
714
|
+
another_sd.item(id, 'foo').body,
|
|
715
|
+
'File#delete should clear the persistent body after commit(:persistent)'
|
|
716
|
+
)
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
def test_delete_parent_set
|
|
720
|
+
Runo.client = 'root'
|
|
721
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
722
|
+
sd.storage.clear
|
|
723
|
+
|
|
724
|
+
sd.update(
|
|
725
|
+
'_1' => {
|
|
726
|
+
'foo' => {
|
|
727
|
+
:type => 'image/jpeg',
|
|
728
|
+
:tempfile => @file,
|
|
729
|
+
:head => <<'_eos',
|
|
730
|
+
Content-Disposition: form-data; name="t_file"; filename="foo.jpg"
|
|
731
|
+
Content-Type: image/jpeg
|
|
732
|
+
_eos
|
|
733
|
+
:filename => 'baz.jpg',
|
|
734
|
+
:name => 't_file'
|
|
735
|
+
},
|
|
736
|
+
'bar' => {
|
|
737
|
+
:type => 'image/jpeg',
|
|
738
|
+
:tempfile => @file,
|
|
739
|
+
:head => <<'_eos',
|
|
740
|
+
Content-Disposition: form-data; name="t_file"; filename="bar.jpg"
|
|
741
|
+
Content-Type: image/jpeg
|
|
742
|
+
_eos
|
|
743
|
+
:filename => 'bar.jpg',
|
|
744
|
+
:name => 't_file'
|
|
745
|
+
},
|
|
746
|
+
}
|
|
747
|
+
)
|
|
748
|
+
sd.commit :persistent
|
|
749
|
+
|
|
750
|
+
id = sd.result.values.first[:id]
|
|
751
|
+
|
|
752
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
753
|
+
sd.update(
|
|
754
|
+
id => {:action => :delete}
|
|
755
|
+
)
|
|
756
|
+
sd.commit :persistent
|
|
757
|
+
|
|
758
|
+
assert_equal(
|
|
759
|
+
{},
|
|
760
|
+
sd.val,
|
|
761
|
+
'Set#delete should delete body of the file items'
|
|
762
|
+
)
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
def test_save_file_attachment
|
|
766
|
+
Runo.client = 'root'
|
|
767
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
768
|
+
sd.storage.clear
|
|
769
|
+
|
|
770
|
+
# create an attachment file item
|
|
771
|
+
sd.update(
|
|
772
|
+
'_1' => {
|
|
773
|
+
'baz' => {
|
|
774
|
+
'_1' => {
|
|
775
|
+
'qux' => {
|
|
776
|
+
:type => 'image/gif',
|
|
777
|
+
:tempfile => @file,
|
|
778
|
+
:head => <<'_eos',
|
|
779
|
+
Content-Disposition: form-data; name="t_file"; filename="qux.gif"
|
|
780
|
+
Content-Type: image/gif
|
|
781
|
+
_eos
|
|
782
|
+
:filename => 'qux.gif',
|
|
783
|
+
:name => 't_file'
|
|
784
|
+
},
|
|
785
|
+
},
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
sd.commit :persistent
|
|
791
|
+
baz_id = sd.result.values.first[:id]
|
|
792
|
+
qux_id = sd.result.values.first.item('baz').val.keys.first
|
|
793
|
+
|
|
794
|
+
item = Runo::Set::Static::Folder.root.item('t_file', 'main', baz_id, 'baz', qux_id, 'qux')
|
|
795
|
+
assert_instance_of(
|
|
796
|
+
Runo::File,
|
|
797
|
+
item,
|
|
798
|
+
'File#commit should commit the attachment file item'
|
|
799
|
+
)
|
|
800
|
+
assert_equal(
|
|
801
|
+
@file.read,
|
|
802
|
+
item.body,
|
|
803
|
+
'File#commit should store the body of the attachment file item'
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
# delete the attachment
|
|
807
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
808
|
+
sd.update(
|
|
809
|
+
baz_id => {
|
|
810
|
+
'baz' => {
|
|
811
|
+
qux_id => {:action => :delete},
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
)
|
|
815
|
+
sd.commit :persistent
|
|
816
|
+
|
|
817
|
+
assert_equal(
|
|
818
|
+
{},
|
|
819
|
+
Runo::Set::Static::Folder.root.item('t_file', 'main', baz_id, 'baz').storage.val,
|
|
820
|
+
'File#commit should delete the body of the attachment file item'
|
|
821
|
+
)
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
def test_delete_attachment_parent
|
|
825
|
+
Runo.client = 'root'
|
|
826
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
827
|
+
sd.storage.clear
|
|
828
|
+
|
|
829
|
+
# create an attachment file item
|
|
830
|
+
sd.update(
|
|
831
|
+
'_1' => {
|
|
832
|
+
'baz' => {
|
|
833
|
+
'_1' => {
|
|
834
|
+
'qux' => {
|
|
835
|
+
:type => 'image/gif',
|
|
836
|
+
:tempfile => @file,
|
|
837
|
+
:head => <<'_eos',
|
|
838
|
+
Content-Disposition: form-data; name="t_file"; filename="qux.gif"
|
|
839
|
+
Content-Type: image/gif
|
|
840
|
+
_eos
|
|
841
|
+
:filename => 'qux.gif',
|
|
842
|
+
:name => 't_file'
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
sd.commit :persistent
|
|
850
|
+
assert_not_equal({}, sd.val)
|
|
851
|
+
|
|
852
|
+
baz_id = sd.result.values.first[:id]
|
|
853
|
+
qux_id = sd.result.values.first.item('baz').val.keys.first
|
|
854
|
+
|
|
855
|
+
item = Runo::Set::Static::Folder.root.item('t_file', 'main', baz_id, 'baz', qux_id, 'qux')
|
|
856
|
+
item_persistent_name = item[:persistent_name]
|
|
857
|
+
assert_equal(
|
|
858
|
+
@file.read,
|
|
859
|
+
Runo::Set::Static::Folder.root.item('t_file', 'main').storage.val(item_persistent_name),
|
|
860
|
+
'the body of the file should be stored in the storage'
|
|
861
|
+
)
|
|
862
|
+
|
|
863
|
+
# delete the parent set
|
|
864
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
865
|
+
sd[:item]['default'][:item].delete '_timestamp'
|
|
866
|
+
sd.update(
|
|
867
|
+
baz_id => {:action => :delete}
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
sd.commit :temp
|
|
871
|
+
assert_equal(
|
|
872
|
+
<<"_eos",
|
|
873
|
+
<"main" @action=:update @result={"#{baz_id}"}>
|
|
874
|
+
<"#{baz_id}" @action=:delete @result=:delete>
|
|
875
|
+
<"_group" @action=nil @result=nil @val=nil>
|
|
876
|
+
<"_owner" @action=nil @result=nil @val="root">
|
|
877
|
+
<"bar" @action=:delete @result=:delete @val={}>
|
|
878
|
+
<"baz" @action=:delete @result=:delete>
|
|
879
|
+
<"foo" @action=:delete @result=:delete @val={}>
|
|
880
|
+
_eos
|
|
881
|
+
sd.inspect_items
|
|
882
|
+
)
|
|
883
|
+
|
|
884
|
+
sd.commit :persistent
|
|
885
|
+
assert_equal(
|
|
886
|
+
<<"_eos",
|
|
887
|
+
<"main" @action=nil @result={"#{baz_id}"}>
|
|
888
|
+
_eos
|
|
889
|
+
sd.inspect_items
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
sd = Runo::Set::Static::Folder.root.item('t_file', 'main')
|
|
893
|
+
assert_equal({}, sd.val)
|
|
894
|
+
assert_nil(
|
|
895
|
+
Runo::Set::Static::Folder.root.item('t_file', 'main').storage.val(item_persistent_name),
|
|
896
|
+
'the body of the file should be deleted from the storage'
|
|
897
|
+
)
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
end
|