ohm_util 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/makefile ADDED
@@ -0,0 +1,9 @@
1
+ .PHONY: all test examples
2
+
3
+ all: test
4
+
5
+ test:
6
+ cutest -r ./test/helper.rb ./test/*.rb
7
+
8
+ examples:
9
+ RUBYLIB="./lib" cutest ./examples/*.rb
data/ohm-util.gemspec ADDED
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "ohm_util"
3
+ s.version = "0.1"
4
+ s.summary = %{Object-hash mapping library for Redis.}
5
+ s.description = %Q{Ohm is a library that allows to store an object in Redis, a persistent key-value database. It has very good performance.}
6
+ s.authors = ["Travis Liu"]
7
+ s.email = ["travisliu.tw@gmail.com"]
8
+ s.homepage = "https://github.com/travisliu/ohm-util"
9
+ s.license = "MIT"
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_dependency "redic", "~> 1.5.0"
14
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "helper"
2
+
3
+ class User < Ohm::Model
4
+ collection :posts, :Post
5
+ end
6
+
7
+ class Post < Ohm::Model
8
+ reference :user, :User
9
+ end
10
+
11
+ setup do
12
+ u = User.create
13
+ p = Post.create(:user => u)
14
+
15
+ [u, p]
16
+ end
17
+
18
+ test "basic shake and bake" do |u, p|
19
+ assert u.posts.include?(p)
20
+
21
+ p = Post[p.id]
22
+ assert_equal u, p.user
23
+ end
24
+
25
+ test "memoization" do |u, p|
26
+ # This will read the user instance once.
27
+ p.user
28
+ assert_equal p.user, p.instance_variable_get(:@_memo)[:user]
29
+
30
+ # This will un-memoize the user instance
31
+ p.user = u
32
+ assert_equal nil, p.instance_variable_get(:@_memo)[:user]
33
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'helper'
2
+
3
+ test "model inherits Ohm.redis connection by default" do
4
+ class C < Ohm::Model
5
+ end
6
+
7
+ assert_equal C.redis.url, Ohm.redis.url
8
+ end
9
+
10
+ test "model can define its own connection" do
11
+ class B < Ohm::Model
12
+ self.redis = Redic.new("redis://localhost:6379/1")
13
+ end
14
+
15
+ assert B.redis.url != Ohm.redis.url
16
+ end
data/test/core.rb ADDED
@@ -0,0 +1,24 @@
1
+ require_relative "helper"
2
+
3
+ class Event < Ohm::Model
4
+ attribute :name
5
+ attribute :location
6
+ end
7
+
8
+ test "assign attributes from the hash" do
9
+ event = Event.new(name: "Ruby Tuesday")
10
+ assert_equal event.name, "Ruby Tuesday"
11
+ end
12
+
13
+ test "assign an ID and save the object" do
14
+ event1 = Event.create(name: "Ruby Tuesday")
15
+ event2 = Event.create(name: "Ruby Meetup")
16
+
17
+ assert_equal "1", event1.id
18
+ assert_equal "2", event2.id
19
+ end
20
+
21
+ test "save the attributes in UTF8" do
22
+ event = Event.create(name: "32° Kisei-sen")
23
+ assert_equal "32° Kisei-sen", Event[event.id].name
24
+ end
data/test/counters.rb ADDED
@@ -0,0 +1,67 @@
1
+ require_relative "helper"
2
+
3
+ $VERBOSE = false
4
+
5
+ class Ad < Ohm::Model
6
+ end
7
+
8
+ test "counters aren't overwritten by competing saves" do
9
+ Ad.counter :hits
10
+
11
+ instance1 = Ad.create
12
+ instance1.increment :hits
13
+
14
+ instance2 = Ad[instance1.id]
15
+
16
+ instance1.increment :hits
17
+ instance1.increment :hits
18
+
19
+ instance2.save
20
+
21
+ instance1 = Ad[instance1.id]
22
+ assert_equal 3, instance1.hits
23
+ end
24
+
25
+ test "you can increment counters even when attributes is empty" do
26
+ Ad.counter :hits
27
+
28
+ ad = Ad.create
29
+ ad = Ad[ad.id]
30
+
31
+ ex = nil
32
+
33
+ begin
34
+ ad.increment :hits
35
+ rescue ArgumentError => e
36
+ ex = e
37
+ end
38
+
39
+ assert_equal nil, ex
40
+ end
41
+
42
+ test "an attribute gets saved properly" do
43
+ Ad.attribute :name
44
+ Ad.counter :hits
45
+
46
+ ad = Ad.create(:name => "foo")
47
+ ad.increment :hits, 10
48
+ assert_equal 10, ad.hits
49
+
50
+ # Now let's just load and save it.
51
+ ad = Ad[ad.id]
52
+ ad.save
53
+
54
+ # The attributes should remain the same
55
+ ad = Ad[ad.id]
56
+ assert_equal "foo", ad.name
57
+ assert_equal 10, ad.hits
58
+
59
+ # If we load and save again while we incr behind the scenes,
60
+ # the latest counter values should be respected.
61
+ ad = Ad[ad.id]
62
+ ad.increment :hits, 5
63
+ ad.save
64
+
65
+ ad = Ad[ad.id]
66
+ assert_equal 15, ad.hits
67
+ end
@@ -0,0 +1,79 @@
1
+ require_relative "helper"
2
+
3
+ scope do
4
+ class Contact < Ohm::Model
5
+ attribute :name
6
+ end
7
+
8
+ setup do
9
+ john = Contact.create(name: "John Doe")
10
+ jane = Contact.create(name: "Jane Doe")
11
+
12
+ [john, jane]
13
+ end
14
+
15
+ test "Set#size doesn't do each" do
16
+ set = Contact.all
17
+
18
+ def set.each
19
+ raise "Failed"
20
+ end
21
+
22
+ assert_equal 2, set.size
23
+ end
24
+
25
+ test "Set#each as an Enumerator" do |john, jane|
26
+ enum = Contact.all.each
27
+
28
+ enum.each do |c|
29
+ assert c == john || c == jane
30
+ end
31
+ end
32
+
33
+ test "select" do |john, jane|
34
+ assert_equal 2, Contact.all.count
35
+ assert_equal [john], Contact.all.select { |c| c.id == john.id }
36
+ end
37
+ end
38
+
39
+ scope do
40
+ class Comment < Ohm::Model
41
+ end
42
+
43
+ class Post < Ohm::Model
44
+ list :comments, :Comment
45
+ end
46
+
47
+ setup do
48
+ c1 = Comment.create
49
+ c2 = Comment.create
50
+
51
+ post = Post.create
52
+ post.comments.push(c1)
53
+ post.comments.push(c2)
54
+
55
+ [post, c1, c2]
56
+ end
57
+
58
+ test "List#select" do |post, c1, c2|
59
+ assert_equal [c1], post.comments.select { |comment| comment == c1 }
60
+ end
61
+
62
+ test "List#each as Enumerator" do |post, c1, c2|
63
+ enum = post.comments.each
64
+
65
+ enum.each do |comment|
66
+ assert comment == c1 || comment == c2
67
+ end
68
+ end
69
+
70
+ test "List#size doesn't do each" do |post, c1, c2|
71
+ list = post.comments
72
+
73
+ def list.each
74
+ raise "Failed"
75
+ end
76
+
77
+ assert_equal 2, list.size
78
+ end
79
+ end
data/test/filtering.rb ADDED
@@ -0,0 +1,185 @@
1
+ require_relative "helper"
2
+
3
+ class User < Ohm::Model
4
+ attribute :fname
5
+ attribute :lname
6
+ attribute :status
7
+
8
+ index :fname
9
+ index :lname
10
+ index :status
11
+ end
12
+
13
+ setup do
14
+ u1 = User.create(:fname => "John", :lname => "Doe", :status => "active")
15
+ u2 = User.create(:fname => "Jane", :lname => "Doe", :status => "active")
16
+
17
+ [u1, u2]
18
+ end
19
+
20
+ test "findability" do |john, jane|
21
+ assert_equal 1, User.find(:lname => "Doe", :fname => "John").size
22
+ assert User.find(:lname => "Doe", :fname => "John").include?(john)
23
+
24
+ assert_equal 1, User.find(:lname => "Doe", :fname => "Jane").size
25
+ assert User.find(:lname => "Doe", :fname => "Jane").include?(jane)
26
+ end
27
+
28
+ test "sets aren't mutable" do |john, jane|
29
+ assert_raise NoMethodError do
30
+ User.find(:lname => "Doe").add(john)
31
+ end
32
+
33
+ assert_raise NoMethodError do
34
+ User.find(:lname => "Doe", :fname => "John").add(john)
35
+ end
36
+ end
37
+
38
+ test "#first" do |john, jane|
39
+ set = User.find(:lname => "Doe", :status => "active")
40
+
41
+ assert_equal jane, set.first(:by => "fname", :order => "ALPHA")
42
+ assert_equal john, set.first(:by => "fname", :order => "ALPHA DESC")
43
+
44
+ assert_equal "Jane", set.first(:by => "fname", :order => "ALPHA", :get => "fname")
45
+ assert_equal "John", set.first(:by => "fname", :order => "ALPHA DESC", :get => "fname")
46
+ end
47
+
48
+ test "#[]" do |john, jane|
49
+ set = User.find(:lname => "Doe", :status => "active")
50
+
51
+ assert_equal john, set[john.id]
52
+ assert_equal jane, set[jane.id]
53
+ end
54
+
55
+ test "#except" do |john, jane|
56
+ User.create(:status => "inactive", :lname => "Doe")
57
+
58
+ res = User.find(:lname => "Doe").except(:status => "inactive")
59
+
60
+ assert_equal 2, res.size
61
+ assert res.include?(john)
62
+ assert res.include?(jane)
63
+
64
+ res = User.all.except(:status => "inactive")
65
+
66
+ assert_equal 2, res.size
67
+ assert res.include?(john)
68
+ assert res.include?(jane)
69
+ end
70
+
71
+ test "#except unions keys when passing an array" do |john, jane|
72
+ expected = User.create(:fname => "Jean", :status => "inactive")
73
+
74
+ res = User.find(:status => "inactive").except(:fname => [john.fname, jane.fname])
75
+
76
+ assert_equal 1, res.size
77
+ assert res.include?(expected)
78
+
79
+ res = User.all.except(:fname => [john.fname, jane.fname])
80
+
81
+ assert_equal 1, res.size
82
+ assert res.include?(expected)
83
+ end
84
+
85
+ test "indices bug related to a nil attribute" do |john, jane|
86
+ # First we create a record with a nil attribute
87
+ out = User.create(:status => nil, :lname => "Doe")
88
+
89
+ # Then, we update the old nil attribute to a different
90
+ # non-nil, value.
91
+ out.update(status: "inactive")
92
+
93
+ # At this point, the index for the nil attribute should
94
+ # have been cleared.
95
+ assert_equal 0, User.redis.call("SCARD", "User:indices:status:")
96
+ end
97
+
98
+ test "#union" do |john, jane|
99
+ User.create(:status => "super", :lname => "Doe")
100
+ included = User.create(:status => "inactive", :lname => "Doe")
101
+
102
+ res = User.find(:status => "active").union(:status => "inactive")
103
+
104
+ assert_equal 3, res.size
105
+ assert res.include?(john)
106
+ assert res.include?(jane)
107
+ assert res.include?(included)
108
+
109
+ res = User.find(:status => "active").union(:status => "inactive").find(:lname => "Doe")
110
+
111
+ assert res.any? { |e| e.status == "inactive" }
112
+ end
113
+
114
+ test "#combine" do |john, jane|
115
+ res = User.find(:status => "active").combine(fname: ["John", "Jane"])
116
+
117
+ assert_equal 2, res.size
118
+ assert res.include?(john)
119
+ assert res.include?(jane)
120
+ end
121
+
122
+ # book author thing via @myobie
123
+ scope do
124
+ class Book < Ohm::Model
125
+ collection :authors, :Author
126
+ end
127
+
128
+ class Author < Ohm::Model
129
+ reference :book, :Book
130
+
131
+ attribute :mood
132
+ index :mood
133
+ end
134
+
135
+ setup do
136
+ book1 = Book.create
137
+ book2 = Book.create
138
+
139
+ Author.create(:book => book1, :mood => "happy")
140
+ Author.create(:book => book1, :mood => "sad")
141
+ Author.create(:book => book2, :mood => "sad")
142
+
143
+ [book1, book2]
144
+ end
145
+
146
+ test "straight up intersection + union" do |book1, book2|
147
+ result = book1.authors.find(:mood => "happy").
148
+ union(:book_id => book1.id, :mood => "sad")
149
+
150
+ assert_equal 2, result.size
151
+ end
152
+
153
+ test "appending an empty set via union" do |book1, book2|
154
+ res = Author.find(:book_id => book1.id, :mood => "happy").
155
+ union(:book_id => book2.id, :mood => "sad").
156
+ union(:book_id => book2.id, :mood => "happy")
157
+
158
+ assert_equal 2, res.size
159
+ end
160
+
161
+ test "revert by applying the original intersection" do |book1, book2|
162
+ res = Author.find(:book_id => book1.id, :mood => "happy").
163
+ union(:book_id => book2.id, :mood => "sad").
164
+ find(:book_id => book1.id, :mood => "happy")
165
+
166
+ assert_equal 1, res.size
167
+ end
168
+
169
+ test "remove original intersection by doing diff" do |book1, book2|
170
+ res = Author.find(:book_id => book1.id, :mood => "happy").
171
+ union(:book_id => book2.id, :mood => "sad").
172
+ except(:book_id => book1.id, :mood => "happy")
173
+
174
+ assert_equal 1, res.size
175
+ assert res.map(&:mood).include?("sad")
176
+ assert res.map(&:book_id).include?(book2.id)
177
+ end
178
+
179
+ test "@myobie usecase" do |book1, book2|
180
+ res = book1.authors.find(:mood => "happy").
181
+ union(:mood => "sad", :book_id => book1.id)
182
+
183
+ assert_equal 2, res.size
184
+ end
185
+ end
data/test/hash_key.rb ADDED
@@ -0,0 +1,31 @@
1
+ require_relative "helper"
2
+
3
+ class Tag < Ohm::Model
4
+ attribute :name
5
+ end
6
+
7
+ test "using a new record as a hash key" do
8
+ tag = Tag.new
9
+ hash = { tag => "Ruby" }
10
+
11
+ assert "Ruby" == hash[tag]
12
+ assert hash[Tag.new].nil?
13
+ end
14
+
15
+ test "on a persisted model" do
16
+ tag = Tag.create(:name => "Ruby")
17
+
18
+ assert "Ruby" == { tag => "Ruby" }[tag]
19
+ end
20
+
21
+ test "on a reloaded model" do
22
+ tag = Tag.create(:name => "Ruby")
23
+ hash = { tag => "Ruby" }
24
+
25
+ tag = Tag[tag.id]
26
+ assert "Ruby" == hash[tag]
27
+ end
28
+
29
+ test "on attributes class method" do
30
+ assert [:name] == Tag.attributes
31
+ end