ohm 0.0.32 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +71 -36
- data/lib/ohm/collection.rb +186 -0
- data/lib/ohm/compat-1.8.6.rb +9 -0
- data/lib/ohm/key.rb +46 -0
- data/lib/ohm/redis.rb +0 -1
- data/lib/ohm.rb +238 -202
- data/test/indices_test.rb +27 -21
- data/test/model_test.rb +181 -45
- data/test/redis_test.rb +1 -1
- metadata +4 -2
data/test/indices_test.rb
CHANGED
@@ -33,7 +33,7 @@ class IndicesTest < Test::Unit::TestCase
|
|
33
33
|
|
34
34
|
context "A model with an indexed attribute" do
|
35
35
|
setup do
|
36
|
-
@user1 = User.create(:email => "foo")
|
36
|
+
@user1 = User.create(:email => "foo", :activation_code => "bar")
|
37
37
|
@user2 = User.create(:email => "bar")
|
38
38
|
@user3 = User.create(:email => "baz qux")
|
39
39
|
end
|
@@ -42,6 +42,22 @@ class IndicesTest < Test::Unit::TestCase
|
|
42
42
|
assert_equal @user1, User.find(:email => "foo").first
|
43
43
|
end
|
44
44
|
|
45
|
+
should "avoid intersections with the all collection" do
|
46
|
+
assert_equal "IndicesTest::User:email:#{Ohm::Model.encode "foo"}", User.find(:email => "foo").key.to_s
|
47
|
+
|
48
|
+
assert_equal "~:IndicesTest::User:email:Zm9v+IndicesTest::User:activation_code:",
|
49
|
+
User.find(:email => "foo").find(:activation_code => "").key.to_s
|
50
|
+
|
51
|
+
assert_equal "~:IndicesTest::User:email:Zm9v+IndicesTest::User:activation_code:+IndicesTest::User:working_days:",
|
52
|
+
User.find(:email => "foo").find(:activation_code => "").find(:working_days => "").key.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
should "use a special namespace for set operations" do
|
56
|
+
assert_match /^~:/, User.find(:email => "foo", :activation_code => "bar").key.to_s
|
57
|
+
|
58
|
+
assert Ohm.redis.keys("~:*").size > 0
|
59
|
+
end
|
60
|
+
|
45
61
|
should "raise if the field is not indexed" do
|
46
62
|
assert_raises(Ohm::Model::IndexNotFound) do
|
47
63
|
User.find(:sandunga => "foo")
|
@@ -57,28 +73,18 @@ class IndicesTest < Test::Unit::TestCase
|
|
57
73
|
@user1.email = "baz"
|
58
74
|
@user1.save
|
59
75
|
|
60
|
-
assert_equal [], User.find(:email => "foo")
|
61
|
-
assert_equal [@user1], User.find(:email => "baz")
|
76
|
+
assert_equal [], User.find(:email => "foo").all
|
77
|
+
assert_equal [@user1], User.find(:email => "baz").all
|
62
78
|
end
|
63
79
|
|
64
80
|
should "remove from the index after deleting" do
|
65
81
|
@user2.delete
|
66
82
|
|
67
|
-
assert_equal [], User.find(:email => "bar")
|
83
|
+
assert_equal [], User.find(:email => "bar").all
|
68
84
|
end
|
69
85
|
|
70
86
|
should "work with attributes that contain spaces" do
|
71
|
-
assert_equal [@user3], User.find(:email => "baz qux")
|
72
|
-
end
|
73
|
-
|
74
|
-
should "not allow to manually clear an index" do
|
75
|
-
assert_raise Ohm::Model::CannotDeleteIndex do
|
76
|
-
User.find(:email => "bar").clear
|
77
|
-
end
|
78
|
-
|
79
|
-
assert_raise Ohm::Model::CannotDeleteIndex do
|
80
|
-
User.find(:email => "bar").find(:email => "baz").clear
|
81
|
-
end
|
87
|
+
assert_equal [@user3], User.find(:email => "baz qux").all
|
82
88
|
end
|
83
89
|
end
|
84
90
|
|
@@ -91,7 +97,7 @@ class IndicesTest < Test::Unit::TestCase
|
|
91
97
|
|
92
98
|
should "allow indexing by an arbitrary attribute" do
|
93
99
|
assert_equal [@user1, @user2], User.find(:email_provider => "gmail.com").to_a.sort_by { |u| u.id }
|
94
|
-
assert_equal [@user3], User.find(:email_provider => "yahoo.com")
|
100
|
+
assert_equal [@user3], User.find(:email_provider => "yahoo.com").all
|
95
101
|
end
|
96
102
|
|
97
103
|
should "allow indexing by an attribute that is lazily set" do
|
@@ -122,7 +128,7 @@ class IndicesTest < Test::Unit::TestCase
|
|
122
128
|
should "remove the indices when the object changes" do
|
123
129
|
@user2.working_days.delete "Mon"
|
124
130
|
@user2.save
|
125
|
-
assert_equal [@user1], User.find(:working_days => "Mon")
|
131
|
+
assert_equal [@user1], User.find(:working_days => "Mon").all
|
126
132
|
end
|
127
133
|
end
|
128
134
|
|
@@ -146,12 +152,12 @@ class IndicesTest < Test::Unit::TestCase
|
|
146
152
|
end
|
147
153
|
|
148
154
|
should "intersect multiple sets of results" do
|
149
|
-
assert_equal [@event1], Event.find(:timeline => 1, :days => [1, 2])
|
150
|
-
assert_equal [@event1], Event.find(:timeline => 1).find(:days => [1, 2])
|
155
|
+
assert_equal [@event1], Event.find(:timeline => 1, :days => [1, 2]).all
|
156
|
+
assert_equal [@event1], Event.find(:timeline => 1).find(:days => [1, 2]).all
|
151
157
|
end
|
152
158
|
|
153
159
|
should "compute the difference between sets" do
|
154
|
-
assert_equal [@event2], Event.find(:timeline => 1).except(:days => 1)
|
160
|
+
assert_equal [@event2], Event.find(:timeline => 1).except(:days => 1).all
|
155
161
|
end
|
156
162
|
|
157
163
|
should "raise if the argument is not an index" do
|
@@ -162,7 +168,7 @@ class IndicesTest < Test::Unit::TestCase
|
|
162
168
|
|
163
169
|
should "work with strings that generate a new line when encoded" do
|
164
170
|
user = User.create(:email => "foo@bar", :update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan")
|
165
|
-
assert_equal [user], User.find(:update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan")
|
171
|
+
assert_equal [user], User.find(:update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan").all
|
166
172
|
end
|
167
173
|
end
|
168
174
|
|
data/test/model_test.rb
CHANGED
@@ -96,6 +96,13 @@ class TestRedis < Test::Unit::TestCase
|
|
96
96
|
assert event.update(:location => nil)
|
97
97
|
assert_equal nil, Meetup[event.id].location
|
98
98
|
end
|
99
|
+
|
100
|
+
should "delete the attribute if set to an empty string" do
|
101
|
+
event = Meetup.create(:name => "Ruby Tuesday", :location => "Los Angeles")
|
102
|
+
assert_equal "Los Angeles", Meetup[event.id].location
|
103
|
+
assert event.update(:location => "")
|
104
|
+
assert_equal nil, Meetup[event.id].location
|
105
|
+
end
|
99
106
|
end
|
100
107
|
|
101
108
|
context "Model definition" do
|
@@ -331,7 +338,7 @@ class TestRedis < Test::Unit::TestCase
|
|
331
338
|
Person.create :name => "B"
|
332
339
|
Person.create :name => "A"
|
333
340
|
|
334
|
-
assert_equal "A", Person.all.sort_by(:name, :get =>
|
341
|
+
assert_equal "A", Person.all.sort_by(:name, :get => :name, :order => "ALPHA").first
|
335
342
|
end
|
336
343
|
end
|
337
344
|
|
@@ -360,62 +367,59 @@ class TestRedis < Test::Unit::TestCase
|
|
360
367
|
|
361
368
|
context "Attributes of type Set" do
|
362
369
|
setup do
|
370
|
+
Ohm.flush
|
371
|
+
|
372
|
+
@person1 = Person.create(:name => "Albert")
|
373
|
+
@person2 = Person.create(:name => "Bertrand")
|
374
|
+
@person3 = Person.create(:name => "Charles")
|
375
|
+
|
363
376
|
@event = Event.new
|
364
377
|
@event.name = "Ruby Tuesday"
|
365
378
|
end
|
366
379
|
|
367
380
|
should "not be available if the model is new" do
|
368
381
|
assert_raise Ohm::Model::MissingID do
|
369
|
-
@event.attendees <<
|
382
|
+
@event.attendees << Person.new
|
370
383
|
end
|
371
384
|
end
|
372
385
|
|
373
386
|
should "remove an element if sent :delete" do
|
374
387
|
@event.create
|
375
|
-
@event.attendees <<
|
376
|
-
@event.attendees <<
|
377
|
-
@event.attendees <<
|
388
|
+
@event.attendees << @person1
|
389
|
+
@event.attendees << @person2
|
390
|
+
@event.attendees << @person3
|
378
391
|
assert_equal ["1", "2", "3"], @event.attendees.raw.sort
|
379
|
-
@event.attendees.delete(
|
392
|
+
@event.attendees.delete(@person2)
|
380
393
|
assert_equal ["1", "3"], Event[@event.id].attendees.raw.sort
|
381
394
|
end
|
382
395
|
|
383
396
|
should "return true if the set includes some member" do
|
384
397
|
@event.create
|
385
|
-
@event.attendees <<
|
386
|
-
@event.attendees <<
|
387
|
-
@event.attendees
|
388
|
-
assert
|
389
|
-
assert_equal false, @event.attendees.include?("4")
|
398
|
+
@event.attendees << @person1
|
399
|
+
@event.attendees << @person2
|
400
|
+
assert @event.attendees.include?(@person2)
|
401
|
+
assert !@event.attendees.include?(@person3)
|
390
402
|
end
|
391
403
|
|
392
|
-
should "return instances of the passed model
|
393
|
-
@event.create
|
394
|
-
@person = Person.create :name => "albert"
|
395
|
-
@event.attendees << @person.id
|
396
|
-
|
397
|
-
assert_equal [@person], @event.attendees.all
|
398
|
-
end
|
399
|
-
|
400
|
-
should "insert the model instance id instead of the object if using add" do
|
404
|
+
should "return instances of the passed model" do
|
401
405
|
@event.create
|
402
|
-
@
|
403
|
-
@event.attendees.add(@person)
|
406
|
+
@event.attendees << @person1
|
404
407
|
|
405
|
-
assert_equal [@
|
408
|
+
assert_equal [@person1], @event.attendees.all
|
409
|
+
assert_equal @person1, @event.attendees[0]
|
406
410
|
end
|
407
411
|
|
408
412
|
should "return the size of the set" do
|
409
413
|
@event.create
|
410
|
-
@event.attendees <<
|
411
|
-
@event.attendees <<
|
412
|
-
@event.attendees <<
|
414
|
+
@event.attendees << @person1
|
415
|
+
@event.attendees << @person2
|
416
|
+
@event.attendees << @person3
|
413
417
|
assert_equal 3, @event.attendees.size
|
414
418
|
end
|
415
419
|
|
416
420
|
should "empty the set" do
|
417
421
|
@event.create
|
418
|
-
@event.attendees <<
|
422
|
+
@event.attendees << @person1
|
419
423
|
|
420
424
|
@event.attendees.clear
|
421
425
|
|
@@ -424,21 +428,23 @@ class TestRedis < Test::Unit::TestCase
|
|
424
428
|
|
425
429
|
should "replace the values in the set" do
|
426
430
|
@event.create
|
427
|
-
@event.attendees <<
|
431
|
+
@event.attendees << @person1
|
428
432
|
|
429
|
-
@event.attendees.
|
433
|
+
assert_equal [@person1], @event.attendees.all
|
430
434
|
|
431
|
-
|
435
|
+
@event.attendees.replace([@person2, @person3])
|
436
|
+
|
437
|
+
assert_equal [@person2, @person3], @event.attendees.sort
|
432
438
|
end
|
433
439
|
|
434
440
|
should "filter elements" do
|
435
441
|
@event.create
|
436
|
-
@event.attendees.add(
|
437
|
-
@event.attendees.add(
|
442
|
+
@event.attendees.add(@person1)
|
443
|
+
@event.attendees.add(@person2)
|
438
444
|
|
439
|
-
assert_equal [
|
440
|
-
assert_equal [
|
441
|
-
assert_equal [], @event.attendees.find(:initial => "Z").
|
445
|
+
assert_equal [@person1], @event.attendees.find(:initial => "A").all
|
446
|
+
assert_equal [@person2], @event.attendees.find(:initial => "B").all
|
447
|
+
assert_equal [], @event.attendees.find(:initial => "Z").all
|
442
448
|
end
|
443
449
|
end
|
444
450
|
|
@@ -528,7 +534,7 @@ class TestRedis < Test::Unit::TestCase
|
|
528
534
|
should "replace the values in the list" do
|
529
535
|
@post.comments.replace(["1", "2"])
|
530
536
|
|
531
|
-
assert_equal ["1", "2"], @post.comments
|
537
|
+
assert_equal ["1", "2"], @post.comments
|
532
538
|
end
|
533
539
|
|
534
540
|
should "add models" do
|
@@ -542,26 +548,46 @@ class TestRedis < Test::Unit::TestCase
|
|
542
548
|
|
543
549
|
@post.related.add(another_post)
|
544
550
|
|
545
|
-
assert @post.related.include?(another_post
|
546
|
-
assert !@post.related.include?(
|
551
|
+
assert @post.related.include?(another_post)
|
552
|
+
assert !@post.related.include?(Post.create)
|
547
553
|
end
|
548
554
|
end
|
549
555
|
|
550
556
|
context "Applying arbitrary transformations" do
|
551
557
|
require "date"
|
552
558
|
|
559
|
+
class MyActiveRecordModel
|
560
|
+
def self.find(id)
|
561
|
+
return new if id.to_i == 1
|
562
|
+
end
|
563
|
+
|
564
|
+
def id
|
565
|
+
1
|
566
|
+
end
|
567
|
+
|
568
|
+
def ==(other)
|
569
|
+
id == other.id
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
553
573
|
class Calendar < Ohm::Model
|
554
574
|
list :holidays, lambda { |v| Date.parse(v) }
|
575
|
+
list :subscribers, lambda { |id| MyActiveRecordModel.find(id) }
|
555
576
|
end
|
556
577
|
|
557
578
|
setup do
|
558
579
|
@calendar = Calendar.create
|
559
|
-
@calendar.holidays << "2009-05-25"
|
560
|
-
@calendar.holidays << "2009-07-09"
|
580
|
+
@calendar.holidays.raw << "2009-05-25"
|
581
|
+
@calendar.holidays.raw << "2009-07-09"
|
582
|
+
|
583
|
+
@calendar.subscribers << MyActiveRecordModel.find(1)
|
561
584
|
end
|
562
585
|
|
563
586
|
should "apply a transformation" do
|
564
|
-
assert_equal [Date.new(2009, 5, 25), Date.new(2009, 7, 9)], @calendar.holidays
|
587
|
+
assert_equal [Date.new(2009, 5, 25), Date.new(2009, 7, 9)], @calendar.holidays.all
|
588
|
+
|
589
|
+
assert_equal ["1"], @calendar.subscribers.raw.all
|
590
|
+
assert_equal [MyActiveRecordModel.find(1)], @calendar.subscribers.all
|
565
591
|
end
|
566
592
|
end
|
567
593
|
|
@@ -581,10 +607,10 @@ class TestRedis < Test::Unit::TestCase
|
|
581
607
|
context "Sorting lists and sets by model attributes" do
|
582
608
|
setup do
|
583
609
|
@event = Event.create(:name => "Ruby Tuesday")
|
584
|
-
@event.attendees << Person.create(:name => "D")
|
585
|
-
@event.attendees << Person.create(:name => "C")
|
586
|
-
@event.attendees << Person.create(:name => "B")
|
587
|
-
@event.attendees << Person.create(:name => "A")
|
610
|
+
@event.attendees << Person.create(:name => "D")
|
611
|
+
@event.attendees << Person.create(:name => "C")
|
612
|
+
@event.attendees << Person.create(:name => "B")
|
613
|
+
@event.attendees << Person.create(:name => "A")
|
588
614
|
end
|
589
615
|
|
590
616
|
should "sort the model instances by the values provided" do
|
@@ -710,4 +736,114 @@ class TestRedis < Test::Unit::TestCase
|
|
710
736
|
assert_equal "Foobar", Baz[baz.id].name
|
711
737
|
end
|
712
738
|
end
|
739
|
+
|
740
|
+
context "References to other objects" do
|
741
|
+
class ::Note < Ohm::Model
|
742
|
+
attribute :content
|
743
|
+
reference :source, Post
|
744
|
+
end
|
745
|
+
|
746
|
+
class ::Editor < Ohm::Model
|
747
|
+
attribute :name
|
748
|
+
reference :post, Post
|
749
|
+
end
|
750
|
+
|
751
|
+
class ::Post < Ohm::Model
|
752
|
+
reference :author, Person
|
753
|
+
collection :notes, Note, :source
|
754
|
+
collection :editors, Editor
|
755
|
+
end
|
756
|
+
|
757
|
+
setup do
|
758
|
+
@post = Post.create
|
759
|
+
end
|
760
|
+
|
761
|
+
context "a reference to another object" do
|
762
|
+
should "return an instance of Person if author_id has a valid id" do
|
763
|
+
@post.author_id = Person.create(:name => "Albert").id
|
764
|
+
@post.save
|
765
|
+
assert_equal "Albert", Post[@post.id].author.name
|
766
|
+
end
|
767
|
+
|
768
|
+
should "assign author_id if author is sent a valid instance" do
|
769
|
+
@post.author = Person.create(:name => "Albert")
|
770
|
+
@post.save
|
771
|
+
assert_equal "Albert", Post[@post.id].author.name
|
772
|
+
end
|
773
|
+
|
774
|
+
should "assign nil if nil is passed to author" do
|
775
|
+
@post.author = nil
|
776
|
+
@post.save
|
777
|
+
assert_nil Post[@post.id].author
|
778
|
+
end
|
779
|
+
|
780
|
+
should "be cached in an instance variable" do
|
781
|
+
@author = Person.create(:name => "Albert")
|
782
|
+
@post.update(:author => @author)
|
783
|
+
|
784
|
+
assert_equal @author, @post.author
|
785
|
+
assert @post.author.object_id == @post.author.object_id
|
786
|
+
|
787
|
+
@post.update(:author => Person.create(:name => "Bertrand"))
|
788
|
+
|
789
|
+
assert_equal "Bertrand", @post.author.name
|
790
|
+
assert @post.author.object_id == @post.author.object_id
|
791
|
+
|
792
|
+
@post.update(:author_id => Person.create(:name => "Charles").id)
|
793
|
+
|
794
|
+
assert_equal "Charles", @post.author.name
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
context "a collection of other objects" do
|
799
|
+
setup do
|
800
|
+
@note = Note.create(:content => "Interesting stuff", :source => @post)
|
801
|
+
end
|
802
|
+
|
803
|
+
should "return a set of notes" do
|
804
|
+
assert_equal @note.source, @post
|
805
|
+
assert_equal @note, @post.notes.first
|
806
|
+
end
|
807
|
+
|
808
|
+
should "default to the current class name" do
|
809
|
+
@editor = Editor.create(:name => "Albert", :post => @post)
|
810
|
+
|
811
|
+
assert_equal @editor, @post.editors.first
|
812
|
+
end
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
context "Models connected to different databases" do
|
817
|
+
class ::Car < Ohm::Model
|
818
|
+
attribute :name
|
819
|
+
end
|
820
|
+
|
821
|
+
class ::Make < Ohm::Model
|
822
|
+
attribute :name
|
823
|
+
end
|
824
|
+
|
825
|
+
setup do
|
826
|
+
Car.connect(:port => 6381, :db => 2)
|
827
|
+
end
|
828
|
+
|
829
|
+
teardown do
|
830
|
+
Car.db.flushdb
|
831
|
+
end
|
832
|
+
|
833
|
+
should "save to the selected database" do
|
834
|
+
car = Car.create(:name => "Twingo")
|
835
|
+
make = Make.create(:name => "Renault")
|
836
|
+
|
837
|
+
assert_equal 1, Make.db.instance_variable_get("@db")
|
838
|
+
assert_equal 2, Car.db.instance_variable_get("@db")
|
839
|
+
|
840
|
+
assert_equal car, Car[1]
|
841
|
+
assert_equal make, Make[1]
|
842
|
+
|
843
|
+
Make.db.flushdb
|
844
|
+
|
845
|
+
assert_equal car, Car[1]
|
846
|
+
assert_nil Make[1]
|
847
|
+
end
|
848
|
+
end
|
713
849
|
end
|
data/test/redis_test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ohm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.33
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-
|
13
|
+
date: 2010-03-03 00:00:00 -03:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -25,7 +25,9 @@ extensions: []
|
|
25
25
|
extra_rdoc_files: []
|
26
26
|
|
27
27
|
files:
|
28
|
+
- lib/ohm/collection.rb
|
28
29
|
- lib/ohm/compat-1.8.6.rb
|
30
|
+
- lib/ohm/key.rb
|
29
31
|
- lib/ohm/redis.rb
|
30
32
|
- lib/ohm/validations.rb
|
31
33
|
- lib/ohm.rb
|