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.
@@ -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
@@ -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