tiny_ds 0.0.1
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 +20 -0
- data/README.rdoc +25 -0
- data/Rakefile +45 -0
- data/lib/tiny_ds/base.rb +290 -0
- data/lib/tiny_ds/base.rb~ +115 -0
- data/lib/tiny_ds/base_tx.rb +161 -0
- data/lib/tiny_ds/base_tx.rb~ +180 -0
- data/lib/tiny_ds/low_ds.rb +77 -0
- data/lib/tiny_ds/low_ds.rb~ +80 -0
- data/lib/tiny_ds/property_definition.rb +68 -0
- data/lib/tiny_ds/property_definition.rb~ +54 -0
- data/lib/tiny_ds/query.rb +76 -0
- data/lib/tiny_ds/query.rb~ +68 -0
- data/lib/tiny_ds/validations.rb +26 -0
- data/lib/tiny_ds/validations.rb~ +9 -0
- data/lib/tiny_ds/version.rb +3 -0
- data/lib/tiny_ds.rb +16 -0
- data/lib/tiny_ds.rb~ +2 -0
- data/lib/tinyds.rb~ +2 -0
- data/spec/basic_spec.rb +648 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/spec_helper.rb~ +0 -0
- metadata +86 -0
data/spec/basic_spec.rb
ADDED
@@ -0,0 +1,648 @@
|
|
1
|
+
#require File.dirname(File.expand_path(__FILE__)) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
4
|
+
|
5
|
+
class Comment < TinyDS::Base
|
6
|
+
#property :ekey, String, :key=>true
|
7
|
+
property :num, :integer
|
8
|
+
property :title, :string
|
9
|
+
property :body, :text
|
10
|
+
property :flag, :integer, :default=>5
|
11
|
+
property :new_at, :time, :default=>proc{ Time.now }
|
12
|
+
property :updated_at, :time
|
13
|
+
property :created_at, :time
|
14
|
+
property :view_at, :time
|
15
|
+
end
|
16
|
+
|
17
|
+
class Animal < TinyDS::Base
|
18
|
+
property :nickname, :string
|
19
|
+
property :color, :string
|
20
|
+
end
|
21
|
+
|
22
|
+
class User < TinyDS::Base
|
23
|
+
property :nickname, :string
|
24
|
+
property :age, :integer
|
25
|
+
property :favorites, :list
|
26
|
+
end
|
27
|
+
|
28
|
+
describe TinyDS::Base do
|
29
|
+
before :all do
|
30
|
+
AppEngine::Testing.install_test_env
|
31
|
+
AppEngine::Testing.install_test_datastore
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return class name as kind" do
|
35
|
+
Comment.kind.should == "Comment"
|
36
|
+
end
|
37
|
+
|
38
|
+
#describe "tx" do
|
39
|
+
# # todo
|
40
|
+
#end
|
41
|
+
|
42
|
+
describe :property_definitions do
|
43
|
+
it "should convert to Text" do
|
44
|
+
text = Comment.property_definitions[:body].to_ds_value("x"*1024)
|
45
|
+
text.class.should == com.google.appengine.api.datastore.Text
|
46
|
+
end
|
47
|
+
it "should correct properties count" do
|
48
|
+
Comment.property_definitions.size.should == 8
|
49
|
+
end
|
50
|
+
it "should initialized with default value" do
|
51
|
+
a = Comment.new
|
52
|
+
a.flag.should == 5
|
53
|
+
end
|
54
|
+
it "should default by proc" do
|
55
|
+
a = Comment.new
|
56
|
+
(Time.now-a.new_at).should <= 2.0
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "key" do
|
61
|
+
it "should be got id/name" do
|
62
|
+
k1 = AppEngine::Datastore::Key.from_path("Com", 9999)
|
63
|
+
a1 = Comment.create({:title=>"ccccc"}, :key=>k1)
|
64
|
+
a1.key.inspect.should == "Com(9999)"
|
65
|
+
a1.id.should == 9999
|
66
|
+
a1.name.should == nil
|
67
|
+
|
68
|
+
k2 = AppEngine::Datastore::Key.from_path("Com", "9999")
|
69
|
+
a2 = Comment.create({:title=>"ccccc"}, :key=>k2)
|
70
|
+
a2.key.inspect.should == 'Com("9999")'
|
71
|
+
a2.name.should == "9999"
|
72
|
+
a2.id.should == 0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'create' do
|
77
|
+
it "should be saved" do
|
78
|
+
a1 = Comment.create(:num=>123, :title=>"hey")
|
79
|
+
|
80
|
+
a2 = Comment.get(a1.key)
|
81
|
+
a2.num.should == a1.num
|
82
|
+
a2.num.should == 123
|
83
|
+
a2.title.should == a1.title
|
84
|
+
a2.title.should == "hey"
|
85
|
+
end
|
86
|
+
it 'should support Text' do
|
87
|
+
a1 = Comment.new(:body => "a"*1024)
|
88
|
+
a1.save
|
89
|
+
|
90
|
+
a2 = Comment.get(a1.key)
|
91
|
+
a2.body.should == "a"*1024
|
92
|
+
a2.body.should == a1.body
|
93
|
+
end
|
94
|
+
it "should support opts[:parent]" do
|
95
|
+
a1 = Comment.create({:title=>"ppppp"})
|
96
|
+
a2 = Comment.create({:title=>"ccccc"}, :parent=>a1)
|
97
|
+
|
98
|
+
a1 = Comment.get(a1.key)
|
99
|
+
a2 = Comment.get(a2.key)
|
100
|
+
a2.parent_key.should == a1.key
|
101
|
+
end
|
102
|
+
it "should support opts[:key]" do
|
103
|
+
k1 = AppEngine::Datastore::Key.from_path("Com", 9999)
|
104
|
+
a1 = Comment.create({:title=>"ccccc"}, :key=>k1)
|
105
|
+
a1.key.inspect.should == "Com(9999)"
|
106
|
+
|
107
|
+
k2 = AppEngine::Datastore::Key.from_path("Com", "9999")
|
108
|
+
a2 = Comment.create({:title=>"ccccc"}, :key=>k2)
|
109
|
+
a2.key.inspect.should == 'Com("9999")'
|
110
|
+
end
|
111
|
+
it "should support opts[:id]" do
|
112
|
+
a1 = Comment.create({:title=>"ccccc"}, :id=>99999)
|
113
|
+
a1.key.inspect.should == 'Comment(99999)'
|
114
|
+
end
|
115
|
+
it "should support opts[:name]" do
|
116
|
+
a1 = Comment.create({:title=>"ccccc"}, :name=>"hello")
|
117
|
+
a1.key.inspect.should == 'Comment("hello")'
|
118
|
+
end
|
119
|
+
it "should support opts[:parent] + opts[:name]" do
|
120
|
+
a1 = Comment.create({:title=>"aaaaa"}, :id=>456789)
|
121
|
+
a2 = Comment.create({:title=>"ccccc"}, {:parent=>a1, :name=>"hey"})
|
122
|
+
a2.key.inspect.should == 'Comment(456789)/Comment("hey")'
|
123
|
+
end
|
124
|
+
it "should not be new_record" do
|
125
|
+
c = Comment.create
|
126
|
+
c.new_record?.should_not be_true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "new" do
|
131
|
+
it "should keep unsaved attrs" do
|
132
|
+
a1 = Comment.new({:title=>"aaa", :num=>444, :body=>"x"*2000})
|
133
|
+
a1.title.should == "aaa"
|
134
|
+
a1.num.should == 444
|
135
|
+
a1.body.should == "x"*2000
|
136
|
+
end
|
137
|
+
it "should be nil" do
|
138
|
+
c1 = Comment.new
|
139
|
+
c1.title.should == nil
|
140
|
+
c1.num.should == nil
|
141
|
+
c1.body.should == nil
|
142
|
+
c1.updated_at.should == nil
|
143
|
+
c1.created_at.should == nil
|
144
|
+
|
145
|
+
c2 = Comment.create
|
146
|
+
c2.title.should == nil
|
147
|
+
c2.num.should == nil
|
148
|
+
c2.body.should == nil
|
149
|
+
c2.updated_at.should be_a_kind_of(Time)
|
150
|
+
c2.created_at.should be_a_kind_of(Time)
|
151
|
+
|
152
|
+
c3 = Comment.get(c2.key)
|
153
|
+
c3.title.should == nil
|
154
|
+
c3.num.should == nil
|
155
|
+
c3.body.should == nil
|
156
|
+
c3.updated_at.should be_a_kind_of(Time)
|
157
|
+
c3.created_at.should be_a_kind_of(Time)
|
158
|
+
end
|
159
|
+
it "should be new_record" do
|
160
|
+
c = Comment.new
|
161
|
+
c.new_record?.should be_true
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "new_from_entity" do
|
166
|
+
it "should build from low-entity" do
|
167
|
+
ent = Comment.create({:title=>"aaa", :num=>444, :body=>"x"*2000}).entity
|
168
|
+
|
169
|
+
a1 = Comment.new_from_entity(ent)
|
170
|
+
a1.title.should == "aaa"
|
171
|
+
a1.num.should == 444
|
172
|
+
a1.body.should == "x"*2000
|
173
|
+
end
|
174
|
+
it "should not be new_record" do
|
175
|
+
ent = Comment.create({:title=>"aaa", :num=>444, :body=>"x"*2000}).entity
|
176
|
+
c = Comment.new_from_entity(ent)
|
177
|
+
c.new_record?.should_not be_true
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "get" do
|
182
|
+
it "should saved" do
|
183
|
+
k1 = Comment.create({:title=>"aaa", :num=>444, :body=>"x"*2000}).key
|
184
|
+
a1 = Comment.get(k1)
|
185
|
+
a1.title.should == "aaa"
|
186
|
+
a1.num.should == 444
|
187
|
+
a1.body.should == "x"*2000
|
188
|
+
end
|
189
|
+
it "should not be new_record" do
|
190
|
+
k1 = Comment.create({}).key
|
191
|
+
a1 = Comment.get(k1)
|
192
|
+
a1.new_record?.should_not be_true
|
193
|
+
end
|
194
|
+
it "should be got by id" do
|
195
|
+
k1 = Comment.create({}).key
|
196
|
+
|
197
|
+
a1 = Comment.get_by_id(k1.id)
|
198
|
+
a1.key.to_s.should == k1.to_s
|
199
|
+
a1 = Comment.get_by_id(k1.id.to_s)
|
200
|
+
a1.key.to_s.should == k1.to_s
|
201
|
+
a1 = Comment.get_by_id(k1.id+1)
|
202
|
+
a1.should be_nil
|
203
|
+
|
204
|
+
a1 = Comment.get_by_id!(k1.id)
|
205
|
+
a1.key.to_s.should == k1.to_s
|
206
|
+
proc{ Comment.get_by_id!(k1.id+1) }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
207
|
+
|
208
|
+
proc{ Comment.get_by_id!("a") }.should raise_error
|
209
|
+
end
|
210
|
+
it "should be got by name" do
|
211
|
+
k1 = Comment.create({}, :name=>"asdfg").key
|
212
|
+
|
213
|
+
a1 = Comment.get_by_name(k1.name)
|
214
|
+
a1.key.to_s.should == k1.to_s
|
215
|
+
a1 = Comment.get_by_name(k1.name+"x")
|
216
|
+
a1.should be_nil
|
217
|
+
|
218
|
+
a1 = Comment.get_by_name!(k1.name)
|
219
|
+
a1.key.to_s.should == k1.to_s
|
220
|
+
proc{ Comment.get_by_name!(k1.name+"x") }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
221
|
+
|
222
|
+
proc{ Comment.get_by_name!(1) }.should raise_error
|
223
|
+
end
|
224
|
+
it "should be got by id+parent" do
|
225
|
+
c0 = Comment.create
|
226
|
+
k1 = Comment.create({}, :parent=>c0).key
|
227
|
+
|
228
|
+
a1 = Comment.get_by_id(k1.id, c0)
|
229
|
+
a1.key.to_s.should == k1.to_s
|
230
|
+
a1 = Comment.get_by_id(k1.id.to_s, c0)
|
231
|
+
a1.key.to_s.should == k1.to_s
|
232
|
+
a1 = Comment.get_by_id(k1.id)
|
233
|
+
a1.should be_nil
|
234
|
+
a1 = Comment.get_by_id(k1.id+1, c0)
|
235
|
+
a1.should be_nil
|
236
|
+
|
237
|
+
a1 = Comment.get_by_id!(k1.id, c0)
|
238
|
+
a1.key.to_s.should == k1.to_s
|
239
|
+
proc{ Comment.get_by_id!(k1.id) }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
240
|
+
proc{ Comment.get_by_id!(k1.id+1, c0) }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
241
|
+
end
|
242
|
+
it "should be got by name+parent" do
|
243
|
+
c0 = Comment.create
|
244
|
+
k1 = Comment.create({}, :parent=>c0, :name=>"zzz").key
|
245
|
+
|
246
|
+
a1 = Comment.get_by_name(k1.name, c0)
|
247
|
+
a1.key.to_s.should == k1.to_s
|
248
|
+
a1 = Comment.get_by_name(k1.name)
|
249
|
+
a1.should be_nil
|
250
|
+
a1 = Comment.get_by_name(k1.name+"x", c0)
|
251
|
+
a1.should be_nil
|
252
|
+
|
253
|
+
a1 = Comment.get_by_name!(k1.name, c0)
|
254
|
+
a1.key.to_s.should == k1.to_s
|
255
|
+
proc{ Comment.get_by_name!(k1.name) }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
256
|
+
proc{ Comment.get_by_name!(k1.name+"x", c0) }.should raise_error(AppEngine::Datastore::EntityNotFound)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "save" do
|
261
|
+
it "should updated" do
|
262
|
+
a1 = Comment.create({:title=>"aaa", :num=>444, :body=>"x"*2000})
|
263
|
+
k1 = a1.key
|
264
|
+
a1.title.should == "aaa"
|
265
|
+
a1.num.should == 444
|
266
|
+
a1.body.should == "x"*2000
|
267
|
+
|
268
|
+
a1.title = "bbb"
|
269
|
+
a1.num = 666
|
270
|
+
a1.body = "y"*4000
|
271
|
+
a1.save
|
272
|
+
|
273
|
+
a1.title.should == "bbb"
|
274
|
+
a1.num.should == 666
|
275
|
+
a1.body.should == "y"*4000
|
276
|
+
|
277
|
+
a1 = Comment.get(k1)
|
278
|
+
a1.title.should == "bbb"
|
279
|
+
a1.num.should == 666
|
280
|
+
a1.body.should == "y"*4000
|
281
|
+
end
|
282
|
+
it "should not be new_record after save" do
|
283
|
+
a1 = Comment.new(:title=>"zzzz")
|
284
|
+
a1.new_record?.should be_true
|
285
|
+
|
286
|
+
a1.save
|
287
|
+
a1.new_record?.should be_false
|
288
|
+
|
289
|
+
a1 = Comment.get(a1.key)
|
290
|
+
a1.new_record?.should be_false
|
291
|
+
|
292
|
+
a1 = Comment.query.filter(:title, "==", "zzzz").one
|
293
|
+
a1.new_record?.should be_false
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe "auto convert types" do
|
298
|
+
it "should convert to string" do
|
299
|
+
Comment.new(:title => "zzzz").title.should be_kind_of(String)
|
300
|
+
Comment.new(:title => "zzzz").title.should == "zzzz"
|
301
|
+
Comment.new(:title => 123 ).title.should be_kind_of(String)
|
302
|
+
Comment.new(:title => 123 ).title.should == "123"
|
303
|
+
Comment.new(:title => "123" ).title.should be_kind_of(String)
|
304
|
+
Comment.new(:title => "123" ).title.should == "123"
|
305
|
+
Comment.new(:title => nil ).title.should be_kind_of(NilClass)
|
306
|
+
Comment.new(:title => nil ).title.should == nil
|
307
|
+
Comment.new( ).title.should be_kind_of(NilClass)
|
308
|
+
Comment.new( ).title.should == nil
|
309
|
+
end
|
310
|
+
it "should convert to integer" do
|
311
|
+
Comment.new(:num => "zzzz").num.should be_kind_of(Integer)
|
312
|
+
Comment.new(:num => "zzzz").num.should == 0
|
313
|
+
Comment.new(:num => 123 ).num.should be_kind_of(Integer)
|
314
|
+
Comment.new(:num => 123 ).num.should == 123
|
315
|
+
Comment.new(:num => "123" ).num.should be_kind_of(Integer)
|
316
|
+
Comment.new(:num => "123" ).num.should == 123
|
317
|
+
Comment.new(:num => nil ).num.should be_kind_of(NilClass)
|
318
|
+
Comment.new(:num => nil ).num.should == nil
|
319
|
+
Comment.new( ).num.should be_kind_of(NilClass)
|
320
|
+
Comment.new( ).num.should == nil
|
321
|
+
end
|
322
|
+
it "should convert to text" do
|
323
|
+
Comment.new(:body => "zzzz").body.should be_kind_of(String)
|
324
|
+
Comment.new(:body => "zzzz").body.should == "zzzz"
|
325
|
+
Comment.new(:body => 123 ).body.should be_kind_of(String)
|
326
|
+
Comment.new(:body => 123 ).body.should == "123"
|
327
|
+
Comment.new(:body => "123" ).body.should be_kind_of(String)
|
328
|
+
Comment.new(:body => "123" ).body.should == "123"
|
329
|
+
Comment.new(:body => nil ).body.should be_kind_of(NilClass)
|
330
|
+
Comment.new(:body => nil ).body.should == nil
|
331
|
+
Comment.new( ).body.should be_kind_of(NilClass)
|
332
|
+
Comment.new( ).body.should == nil
|
333
|
+
end
|
334
|
+
it "should not convert from str/int to time" do
|
335
|
+
proc{ Comment.new(:view_at => "zzzz" ) }.should raise_error
|
336
|
+
proc{ Comment.new(:view_at => 123 ) }.should raise_error
|
337
|
+
|
338
|
+
now = Time.now
|
339
|
+
Comment.new(:view_at => now).view_at.should == now
|
340
|
+
Comment.new(:view_at => nil).view_at.should == nil
|
341
|
+
Comment.new( ).view_at.should == nil
|
342
|
+
end
|
343
|
+
it "should not convert to array" do
|
344
|
+
proc{ User.new(:favorites => "zzzz" ) }.should raise_error
|
345
|
+
proc{ User.new(:favorites => 123 ) }.should raise_error
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
describe "query(1) basic" do
|
350
|
+
before :all do
|
351
|
+
Comment.destroy_all
|
352
|
+
raise if Comment.count!=0
|
353
|
+
3.times do
|
354
|
+
Comment.create(:num=>10, :title=>"BBB")
|
355
|
+
end
|
356
|
+
5.times do
|
357
|
+
Comment.create(:num=>10, :title=>"AAA")
|
358
|
+
end
|
359
|
+
7.times do
|
360
|
+
Comment.create(:num=>50, :title=>"AAA")
|
361
|
+
end
|
362
|
+
end
|
363
|
+
it "should fetched all" do
|
364
|
+
Comment.query.count.should == 15
|
365
|
+
Comment.query.keys.size.should == 15
|
366
|
+
Comment.query.keys.each do |k|
|
367
|
+
k.should be_a_kind_of(AppEngine::Datastore::Key)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
it "should fetched by eq" do
|
371
|
+
Comment.query.filter(:num, "==", 10).count.should == 8
|
372
|
+
Comment.query.filter(:title, "==", "AAA").all.size.should == 12
|
373
|
+
Comment.query.filter(:num, "==", 10).filter(:title, "==", "AAA").all.size.should == 5
|
374
|
+
end
|
375
|
+
it "should fetched by eq (hash)" do
|
376
|
+
Comment.query.filter(:num=>10).count.should == 8
|
377
|
+
Comment.query.filter(:title=>"AAA").all.size.should == 12
|
378
|
+
Comment.query.filter(:num=>10).filter(:title=>"AAA").all.size.should == 5
|
379
|
+
Comment.query.filter(:num=>10, :title=>"AAA").all.size.should == 5
|
380
|
+
end
|
381
|
+
it "should fetched by gt/lt" do
|
382
|
+
Comment.query.filter(:num, ">=", 20).count.should == 7
|
383
|
+
Comment.query.filter(:num, "<=", 20).count.should == 8
|
384
|
+
Comment.query.filter(:num, ">=", 20).all.all?{|c| c.num==50 }.should be_true
|
385
|
+
Comment.query.filter(:num, "<=", 20).all.all?{|c| c.num==10 }.should be_true
|
386
|
+
end
|
387
|
+
it "should be sorted" do
|
388
|
+
comments = Comment.query.sort(:title).sort(:num).all
|
389
|
+
comments[ 0, 5].all?{|c| c.title=="AAA" && c.num==10 }.should be_true
|
390
|
+
comments[ 5, 7].all?{|c| c.title=="AAA" && c.num==50 }.should be_true
|
391
|
+
comments[12, 3].all?{|c| c.title=="BBB" && c.num==10 }.should be_true
|
392
|
+
|
393
|
+
comments = Comment.query.sort(:num).sort(:title).all
|
394
|
+
comments[ 0, 5].all?{|c| c.num==10 && c.title=="AAA" }.should be_true
|
395
|
+
comments[ 5, 3].all?{|c| c.num==10 && c.title=="BBB" }.should be_true
|
396
|
+
comments[ 8, 7].all?{|c| c.num==50 && c.title=="AAA" }.should be_true
|
397
|
+
end
|
398
|
+
it "should be limited/offseted" do
|
399
|
+
Comment.query.sort(:title).sort(:num).all(:limit=>5).each do |c|
|
400
|
+
c.title.should == "AAA"; c.num.should == 10
|
401
|
+
end
|
402
|
+
Comment.query.sort(:title).sort(:num).all(:offset=>5, :limit=>7).each do |c|
|
403
|
+
c.title.should == "AAA"; c.num.should == 50
|
404
|
+
end
|
405
|
+
end
|
406
|
+
it "should not indexed nil as exist value" do
|
407
|
+
Comment.destroy_all
|
408
|
+
Comment.create(:num=>nil)
|
409
|
+
Comment.create( )
|
410
|
+
Comment.count.should == 2
|
411
|
+
Comment.query.filter(:num, "<", 0).count.should == 0
|
412
|
+
end
|
413
|
+
end
|
414
|
+
describe "query(2) parent-children" do
|
415
|
+
before :all do
|
416
|
+
Comment.destroy_all
|
417
|
+
raise if Comment.count!=0
|
418
|
+
gparent = Comment.create(:title=>"GP")
|
419
|
+
parent = Comment.create({:title=>"P"}, {:parent=>gparent})
|
420
|
+
child1 = Comment.create({:title=>"C1", :num=>10}, {:parent=>parent})
|
421
|
+
child2 = Comment.create({:title=>"C2", :num=>10}, {:parent=>parent})
|
422
|
+
other1 = Comment.create({:title=>"O1"})
|
423
|
+
other2 = Comment.create({:title=>"O1", :num=>10})
|
424
|
+
end
|
425
|
+
it "should fetched all" do
|
426
|
+
Comment.query.count.should == 6
|
427
|
+
end
|
428
|
+
it "should fetch only keys" do
|
429
|
+
Comment.query.keys_only.all.all?{|m|
|
430
|
+
m.key != nil && m.title==nil
|
431
|
+
}.should be_true
|
432
|
+
Comment.query.all.all?{|m|
|
433
|
+
m.key != nil && m.title!=nil
|
434
|
+
}.should be_true
|
435
|
+
end
|
436
|
+
it "should fetched only children" do
|
437
|
+
parent = Comment.query.filter(:title, "==", "P").one
|
438
|
+
Comment.query.ancestor(parent).count.should == 3
|
439
|
+
Comment.query.ancestor(parent).each{|c| # [P,C1,C2]
|
440
|
+
c.key.inspect.index(parent.key.inspect).should == 0
|
441
|
+
if c.key!=parent.key
|
442
|
+
c.parent_key.to_s.should == parent.key.to_s
|
443
|
+
end
|
444
|
+
}
|
445
|
+
Comment.query. filter(:num, "==", 10).count.should == 3
|
446
|
+
Comment.query.ancestor(parent).filter(:num, "==", 10).count.should == 2
|
447
|
+
Comment.query.ancestor(parent).filter(:num, "==", 10).each{|c| # [C1,C2]
|
448
|
+
c.key.inspect.index(parent.key.inspect).should == 0
|
449
|
+
c.parent_key.to_s.should == parent.key.to_s
|
450
|
+
c.title.should match(/^C/)
|
451
|
+
}
|
452
|
+
end
|
453
|
+
end
|
454
|
+
describe "query(3) raise" do
|
455
|
+
before :all do
|
456
|
+
Comment.destroy_all
|
457
|
+
raise if Comment.count!=0
|
458
|
+
child1 = Comment.create({:title=>"C1", :num=>10})
|
459
|
+
child2 = Comment.create({:title=>"C2", :num=>10})
|
460
|
+
end
|
461
|
+
it "should raise error from one" do
|
462
|
+
proc{
|
463
|
+
Comment.query.one
|
464
|
+
}.should raise_error(AppEngine::Datastore::TooManyResults)
|
465
|
+
proc{
|
466
|
+
Comment.query.filter(:num, "==", 10).one
|
467
|
+
}.should raise_error(AppEngine::Datastore::TooManyResults)
|
468
|
+
proc{
|
469
|
+
Comment.query.filter(:title, "==", "C1").one
|
470
|
+
}.should_not raise_error(AppEngine::Datastore::TooManyResults)
|
471
|
+
end
|
472
|
+
it "should be raised if filter/sort by invalid property name" do
|
473
|
+
proc{
|
474
|
+
Comment.query.filter(:aaaa, "==", 123)
|
475
|
+
}.should raise_error
|
476
|
+
proc{
|
477
|
+
Comment.query.sort(:bbbb)
|
478
|
+
}.should raise_error
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
describe "count" do
|
483
|
+
it "should incr 1" do
|
484
|
+
c0 = Comment.count
|
485
|
+
a1 = Comment.create
|
486
|
+
c1 = Comment.count
|
487
|
+
c1.should == c0+1
|
488
|
+
end
|
489
|
+
it "should not incr" do
|
490
|
+
c0 = Comment.count
|
491
|
+
a1 = Comment.new
|
492
|
+
c1 = Comment.count
|
493
|
+
c1.should == c0
|
494
|
+
end
|
495
|
+
end
|
496
|
+
describe "#destroy" do
|
497
|
+
it "should deleted" do
|
498
|
+
k1 = Comment.create({:title=>"aaa", :num=>444, :body=>"x"*2000}).key
|
499
|
+
a1 = Comment.get(k1)
|
500
|
+
a1.title.should == "aaa"
|
501
|
+
|
502
|
+
a1.destroy
|
503
|
+
|
504
|
+
a1 = Comment.get(k1)
|
505
|
+
a1.should be_nil
|
506
|
+
|
507
|
+
proc{
|
508
|
+
Comment.get!(k1)
|
509
|
+
}.should raise_error(AppEngine::Datastore::EntityNotFound)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
describe ".destroy" do
|
513
|
+
it "should deleted " do
|
514
|
+
5.times{ Comment.create(:num=>10) }
|
515
|
+
10.times{ Comment.create(:num=>20) }
|
516
|
+
20.times{ Comment.create(:num=>30) }
|
517
|
+
|
518
|
+
Comment.count.should == 35
|
519
|
+
Comment.destroy(Comment.query.keys_only.filter(:num, "==", 10).all)
|
520
|
+
Comment.count.should == 30
|
521
|
+
Comment.destroy(Comment.query.keys_only.filter(:num, "==", 20).collect{|c| c.key })
|
522
|
+
Comment.count.should == 20
|
523
|
+
Comment.destroy(Comment.query.keys_only.filter(:num, "==", 30).collect{|c| c.key.to_s })
|
524
|
+
Comment.count.should == 0
|
525
|
+
end
|
526
|
+
end
|
527
|
+
describe "destroy_all" do
|
528
|
+
it "should destroied all" do
|
529
|
+
c1 = Comment.create
|
530
|
+
c2 = Comment.create
|
531
|
+
Comment.count.should == 2
|
532
|
+
Comment.destroy_all
|
533
|
+
Comment.count.should == 0
|
534
|
+
end
|
535
|
+
end
|
536
|
+
describe "attributes=" do
|
537
|
+
it "should set attrs" do
|
538
|
+
a1 = Comment.new
|
539
|
+
a1.attributes = {:title=>"x", :num=>3, :body=>"h"*3000}
|
540
|
+
a1.title.should == "x"
|
541
|
+
a1.num.should == 3
|
542
|
+
a1.body.should == "h"*3000
|
543
|
+
end
|
544
|
+
end
|
545
|
+
describe "set/get property" do
|
546
|
+
it "should set/get" do
|
547
|
+
a1 = Comment.new
|
548
|
+
a1.title = "EEE"
|
549
|
+
a1.title.should == "EEE"
|
550
|
+
a1.body = "XXX"
|
551
|
+
a1.body.should == "XXX"
|
552
|
+
a1.num = 777
|
553
|
+
a1.num.should == 777
|
554
|
+
end
|
555
|
+
end
|
556
|
+
describe "list property" do
|
557
|
+
before :each do
|
558
|
+
User.destroy_all
|
559
|
+
raise if User.count!=0
|
560
|
+
end
|
561
|
+
it "should stored list of values" do
|
562
|
+
u1 = User.new(:favorites=>["car", "dog", 777])
|
563
|
+
u1.favorites.size.should == 3
|
564
|
+
u1.favorites.should include("car")
|
565
|
+
u1.favorites.should include("dog")
|
566
|
+
u1.favorites.should include(777)
|
567
|
+
u1.favorites.should_not include(666)
|
568
|
+
|
569
|
+
u1.save
|
570
|
+
u1.favorites.size.should == 3
|
571
|
+
u1.favorites.should include("car")
|
572
|
+
u1.favorites.should include("dog")
|
573
|
+
u1.favorites.should include(777)
|
574
|
+
u1.favorites.should_not include(666)
|
575
|
+
|
576
|
+
u1 = User.get(u1.key)
|
577
|
+
u1.favorites.size.should == 3
|
578
|
+
u1.favorites.should include("car")
|
579
|
+
u1.favorites.should include("dog")
|
580
|
+
u1.favorites.should include(777)
|
581
|
+
u1.favorites.should_not include(666)
|
582
|
+
end
|
583
|
+
it "should raise if not array" do
|
584
|
+
proc{
|
585
|
+
User.create(:favorites=>"car")
|
586
|
+
}.should raise_error
|
587
|
+
end
|
588
|
+
it "should found by array item query eq" do
|
589
|
+
u1 = User.create(:favorites=>["car", "dog", 777])
|
590
|
+
u2 = User.create(:favorites=>[ "dog", 777])
|
591
|
+
u3 = User.create(:favorites=>["car", 777])
|
592
|
+
u4 = User.create(:favorites=>["car", "dog" ])
|
593
|
+
u5 = User.create(:favorites=>["car" ])
|
594
|
+
u6 = User.create(:favorites=>[ "dog" ])
|
595
|
+
u7 = User.create(:favorites=>[ 777])
|
596
|
+
User.query.filter(:favorites=>"car").all.size.should == 4
|
597
|
+
User.query.filter(:favorites=>"dog").all.size.should == 4
|
598
|
+
User.query.filter(:favorites=> 777 ).all.size.should == 4
|
599
|
+
User.query.filter(:favorites=>"777").all.size.should == 0
|
600
|
+
# User.query.filter(:favorites=>"car", :favorites=>"dog").all.size.should == 2
|
601
|
+
# User.query.filter(:favorites=>"dog", :favorites=> 777 ).all.size.should == 2
|
602
|
+
# User.query.filter(:favorites=>"car", :favorites=> 777 ).all.size.should == 2
|
603
|
+
User.query.filter(:favorites=>"car").filter(:favorites=>"dog").all.size.should == 2
|
604
|
+
User.query.filter(:favorites=>"dog").filter(:favorites=> 777 ).all.size.should == 2
|
605
|
+
User.query.filter(:favorites=>"car").filter(:favorites=> 777 ).all.size.should == 2
|
606
|
+
User.query.filter(:favorites=>"car").filter(:favorites=>"dog").filter(:favorites=>777).all.size.should == 1
|
607
|
+
end
|
608
|
+
it "should be empty list or nil" do
|
609
|
+
u0 = User.create()
|
610
|
+
u1 = User.create(:favorites=>[])
|
611
|
+
u2 = User.create(:favorites=>nil)
|
612
|
+
User.query.filter(:favorites, "==", 0).count.should == 0
|
613
|
+
User.query.filter(:favorites, "<=", 0).count.should == 0
|
614
|
+
User.query.filter(:favorites, ">=", 0).count.should == 0
|
615
|
+
|
616
|
+
User.new(:favorites=>[] ).favorites.should == []
|
617
|
+
User.new(:favorites=>nil).favorites.should == []
|
618
|
+
User.new( ).favorites.should == []
|
619
|
+
end
|
620
|
+
it "should found by array item query range" do
|
621
|
+
u0 = User.create(:favorites=>[ ])
|
622
|
+
u1 = User.create(:favorites=>[10, 20, 30])
|
623
|
+
u2 = User.create(:favorites=>[ 20, 30])
|
624
|
+
u3 = User.create(:favorites=>[10, 30])
|
625
|
+
u4 = User.create(:favorites=>[10, 20 ])
|
626
|
+
u5 = User.create(:favorites=>[10 ])
|
627
|
+
u6 = User.create(:favorites=>[ 20 ])
|
628
|
+
u7 = User.create(:favorites=>[ 30])
|
629
|
+
|
630
|
+
User.query.filter(:favorites, ">=", 0).count.should == 7
|
631
|
+
|
632
|
+
User.query.filter(:favorites, "<=", 10).count.should == 4
|
633
|
+
User.query.filter(:favorites, "<", 10).count.should == 0
|
634
|
+
User.query.filter(:favorites, ">=", 10).count.should == 7
|
635
|
+
User.query.filter(:favorites, ">", 10).count.should == 6
|
636
|
+
|
637
|
+
User.query.filter(:favorites, "<=", 15).count.should == 4
|
638
|
+
User.query.filter(:favorites, "<", 15).count.should == 4
|
639
|
+
User.query.filter(:favorites, ">=", 15).count.should == 6
|
640
|
+
User.query.filter(:favorites, ">", 15).count.should == 6
|
641
|
+
|
642
|
+
User.query.filter(:favorites, "<=", 20).count.should == 6
|
643
|
+
User.query.filter(:favorites, "<", 20).count.should == 4
|
644
|
+
User.query.filter(:favorites, ">=", 20).count.should == 6
|
645
|
+
User.query.filter(:favorites, ">", 20).count.should == 4
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "pp"
|
2
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
begin
|
4
|
+
require "java"
|
5
|
+
if false
|
6
|
+
puts "======="
|
7
|
+
puts "$LOAD_PATH"
|
8
|
+
pp $LOAD_PATH
|
9
|
+
puts "======="
|
10
|
+
puts "java.class.path"
|
11
|
+
pp java.lang.System.getProperty("java.class.path").split(":")
|
12
|
+
puts "======="
|
13
|
+
=begin
|
14
|
+
% appcfg.rb run -rpp -e 'pp java.lang.System.getProperty("java.class.path").split(":")'
|
15
|
+
[".../tiny_ds/WEB-INF/lib/appengine-api-1.0-sdk-1.3.0.jar",
|
16
|
+
".../tiny_ds/WEB-INF/lib/appengine-api-labs-1.3.0.jar",
|
17
|
+
".../tiny_ds/WEB-INF/lib/appengine-jruby-0.0.6.jar",
|
18
|
+
".../tiny_ds/WEB-INF/lib/gems.jar",
|
19
|
+
".../tiny_ds/WEB-INF/lib/jruby-rack-0.9.6-SNAPSHOT.jar",
|
20
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/shared/appengine-local-runtime-shared.jar",
|
21
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/impl/appengine-api-stubs.jar",
|
22
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/impl/appengine-local-runtime.jar"]
|
23
|
+
|
24
|
+
% source set_classpath_for_jruby.sh
|
25
|
+
|
26
|
+
% jruby -rjava -rpp -e 'pp java.lang.System.getProperty("java.class.path").split(":")'
|
27
|
+
["/Users/takeru/tmp/jruby-1.4.0/lib/jruby.jar",
|
28
|
+
"/Users/takeru/tmp/jruby-1.4.0/lib/profile.jar",
|
29
|
+
"",
|
30
|
+
".../tiny_ds/WEB-INF/lib/appengine-api-1.0-sdk-1.3.0.jar",
|
31
|
+
".../tiny_ds/WEB-INF/lib/appengine-api-labs-1.3.0.jar",
|
32
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/shared/appengine-local-runtime-shared.jar",
|
33
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/impl/appengine-api-stubs.jar",
|
34
|
+
"/opt/local/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.0/appengine-java-sdk-1.3.0/lib/impl/appengine-local-runtime.jar"]
|
35
|
+
=end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'rubygems'
|
39
|
+
# require 'appengine-sdk'
|
40
|
+
# AppEngine::SDK.load_apiproxy
|
41
|
+
require "tiny_ds"
|
42
|
+
|
43
|
+
require 'appengine-apis/testing'
|
44
|
+
begin
|
45
|
+
AppEngine::ApiProxy.get_app_id
|
46
|
+
rescue NoMethodError
|
47
|
+
AppEngine::Testing::install_test_env
|
48
|
+
end
|
49
|
+
AppEngine::Testing::install_test_datastore
|
50
|
+
rescue Object => e
|
51
|
+
puts e.inspect
|
52
|
+
pp e.backtrace
|
53
|
+
raise e
|
54
|
+
end
|
File without changes
|