ohm 0.1.0.rc5 → 0.1.0.rc6
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/Rakefile +2 -13
- data/lib/ohm.rb +54 -97
- data/lib/ohm/key.rb +4 -31
- data/lib/ohm/version.rb +1 -1
- data/test/1.8.6_test.rb +18 -18
- data/test/associations_test.rb +100 -0
- data/test/connection_test.rb +33 -21
- data/test/errors_test.rb +88 -88
- data/test/hash_key_test.rb +16 -23
- data/test/helper.rb +25 -0
- data/test/indices_test.rb +177 -183
- data/test/json_test.rb +67 -0
- data/test/model_test.rb +675 -868
- data/test/mutex_test.rb +65 -70
- data/test/pattern_test.rb +8 -6
- data/test/upgrade_script_test.rb +41 -47
- data/test/validations_test.rb +180 -164
- data/test/wrapper_test.rb +7 -5
- metadata +26 -10
- data/test/all_tests.rb +0 -2
- data/test/test_helper.rb +0 -53
data/test/connection_test.rb
CHANGED
@@ -1,33 +1,45 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
4
|
-
test "connects lazily" do
|
5
|
-
assert_nothing_raised do
|
6
|
-
Ohm.connect(:port => 9876)
|
7
|
-
end
|
3
|
+
require File.expand_path("./helper", File.dirname(__FILE__))
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
prepare.clear
|
6
|
+
|
7
|
+
test "connects lazily" do
|
8
|
+
Ohm.connect(:port => 9876)
|
9
|
+
|
10
|
+
begin
|
11
|
+
Ohm.redis.get "foo"
|
12
|
+
rescue => e
|
13
|
+
assert Errno::ECONNREFUSED == e.class
|
12
14
|
end
|
15
|
+
end
|
16
|
+
|
17
|
+
test "provides a separate connection for each thread" do
|
18
|
+
assert Ohm.redis == Ohm.redis
|
13
19
|
|
14
|
-
|
15
|
-
assert Ohm.redis == Ohm.redis
|
20
|
+
conn1, conn2 = nil
|
16
21
|
|
17
|
-
|
22
|
+
threads = []
|
18
23
|
|
19
|
-
|
24
|
+
threads << Thread.new do
|
25
|
+
conn1 = Ohm.redis
|
26
|
+
end
|
27
|
+
|
28
|
+
threads << Thread.new do
|
29
|
+
conn2 = Ohm.redis
|
30
|
+
end
|
20
31
|
|
21
|
-
|
22
|
-
conn1 = Ohm.redis
|
23
|
-
end
|
32
|
+
threads.each { |t| t.join }
|
24
33
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
34
|
+
assert conn1 != conn2
|
35
|
+
end
|
28
36
|
|
29
|
-
|
37
|
+
test "supports connecting by URL" do
|
38
|
+
Ohm.connect(:url => "redis://localhost:9876")
|
30
39
|
|
31
|
-
|
40
|
+
begin
|
41
|
+
Ohm.redis.get "foo"
|
42
|
+
rescue => e
|
43
|
+
assert Errno::ECONNREFUSED == e.class
|
32
44
|
end
|
33
45
|
end
|
data/test/errors_test.rb
CHANGED
@@ -1,120 +1,120 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
4
|
-
class User < Ohm::Model
|
5
|
-
attribute :name
|
6
|
-
attribute :account
|
3
|
+
require File.expand_path("./helper", File.dirname(__FILE__))
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
assert false, :terrible_error
|
12
|
-
end
|
13
|
-
end
|
5
|
+
class User < Ohm::Model
|
6
|
+
attribute :name
|
7
|
+
attribute :account
|
14
8
|
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def validate
|
10
|
+
assert_present :name
|
11
|
+
assert_present :account
|
12
|
+
assert false, :terrible_error
|
18
13
|
end
|
14
|
+
end
|
15
|
+
|
16
|
+
setup do
|
17
|
+
@model = User.new(:account => "")
|
18
|
+
@model.valid?
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
e.on :terrible_error do
|
25
|
-
end
|
26
|
-
end
|
21
|
+
test "raise an error if the errors are not handled" do
|
22
|
+
begin
|
23
|
+
@model.errors.present do |e|
|
24
|
+
e.on :terrible_error do
|
27
25
|
end
|
28
26
|
end
|
27
|
+
rescue => e
|
28
|
+
assert e.class == Ohm::Validations::Presenter::UnhandledErrors
|
29
|
+
end
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@model.errors.present do |e|
|
34
|
-
e.on [:name, :not_present] do
|
35
|
-
values << 1
|
36
|
-
end
|
32
|
+
test "evaluate blocks when errors match" do
|
33
|
+
values = []
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
@model.errors.present do |e|
|
36
|
+
e.on [:name, :not_present] do
|
37
|
+
values << 1
|
38
|
+
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
40
|
+
e.on [:account, :not_present] do
|
41
|
+
values << 2
|
42
|
+
end
|
46
43
|
|
47
|
-
|
44
|
+
e.on :terrible_error do
|
45
|
+
values << 3
|
48
46
|
end
|
47
|
+
end
|
49
48
|
|
50
|
-
|
51
|
-
|
49
|
+
assert [1, 2, 3] == values
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
values << 1
|
56
|
-
end
|
52
|
+
test "accept case-like matches for an error" do
|
53
|
+
values = []
|
57
54
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
@model.errors.present do |e|
|
56
|
+
e.on Array do
|
57
|
+
values << 1
|
58
|
+
end
|
62
59
|
|
63
|
-
|
60
|
+
e.on :terrible_error do
|
61
|
+
values << 3
|
64
62
|
end
|
63
|
+
end
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
e.on [:name, :not_present], "A"
|
69
|
-
e.on [:account, :not_present] do
|
70
|
-
"B"
|
71
|
-
end
|
72
|
-
e.on :terrible_error, "C"
|
73
|
-
end
|
65
|
+
assert [1, 3] == values
|
66
|
+
end
|
74
67
|
|
75
|
-
|
68
|
+
test "accept multiple matches for an error" do
|
69
|
+
values = @model.errors.present do |e|
|
70
|
+
e.on [:name, :not_present], "A"
|
71
|
+
e.on [:account, :not_present] do
|
72
|
+
"B"
|
76
73
|
end
|
74
|
+
e.on :terrible_error, "C"
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
assert %w{A B C} == values
|
78
|
+
end
|
79
|
+
|
80
|
+
class MyPresenter < Ohm::Validations::Presenter
|
81
|
+
def on(*args)
|
82
|
+
super(*args) do
|
83
|
+
yield.downcase
|
84
84
|
end
|
85
|
+
end
|
86
|
+
end
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
88
|
+
test "take a custom presenter" do
|
89
|
+
values = @model.errors.present(MyPresenter) do |e|
|
90
|
+
e.on([:name, :not_present]) { "A" }
|
91
|
+
e.on([:account, :not_present]) { "B" }
|
92
|
+
e.on(:terrible_error) { "C" }
|
93
|
+
end
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
+
assert %w{a b c} == values
|
96
|
+
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
98
|
+
test "raise an error if neither a message nor a block are supplied" do
|
99
|
+
begin
|
100
|
+
Ohm::Validations::Presenter.new([:custom]).present do |e|
|
101
|
+
e.on(:custom)
|
102
102
|
end
|
103
|
+
rescue => e
|
104
|
+
assert e.class == ArgumentError
|
105
|
+
end
|
106
|
+
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
test "not raise an error if the message passed is nil" do
|
109
|
+
values = Ohm::Validations::Presenter.new([:custom]).present do |e|
|
110
|
+
e.on(:custom, nil)
|
111
|
+
end
|
108
112
|
|
109
|
-
|
113
|
+
assert [nil] == values
|
110
114
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
raise "Should not call block"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
115
|
+
Ohm::Validations::Presenter.new([:custom]).present do |e|
|
116
|
+
e.on(:custom, nil) do
|
117
|
+
raise "Should not call block"
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
data/test/hash_key_test.rb
CHANGED
@@ -1,36 +1,29 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require File.expand_path(File.
|
3
|
+
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
4
|
|
5
5
|
class Tag < Ohm::Model
|
6
6
|
attribute :name
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
test "using a new record as a hash key" do
|
10
|
+
tag = Tag.new
|
11
|
+
hash = { tag => "Ruby" }
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
assert_equal "Ruby", hash[tag]
|
19
|
-
assert_nil hash[Tag.new]
|
20
|
-
end
|
13
|
+
assert "Ruby" == hash[tag]
|
14
|
+
assert hash[Tag.new].nil?
|
15
|
+
end
|
21
16
|
|
22
|
-
|
23
|
-
|
17
|
+
test "on a persisted model" do
|
18
|
+
tag = Tag.create(:name => "Ruby")
|
24
19
|
|
25
|
-
|
26
|
-
|
20
|
+
assert "Ruby" == { tag => "Ruby" }[tag]
|
21
|
+
end
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
test "on a reloaded model" do
|
24
|
+
tag = Tag.create(:name => "Ruby")
|
25
|
+
hash = { tag => "Ruby" }
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
27
|
+
tag = Tag[tag.id]
|
28
|
+
assert "Ruby" == hash[tag]
|
35
29
|
end
|
36
|
-
|
data/test/helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "ruby-debug"
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
require "cutest"
|
11
|
+
|
12
|
+
def silence_warnings
|
13
|
+
original_verbose, $VERBOSE = $VERBOSE, nil
|
14
|
+
yield
|
15
|
+
ensure
|
16
|
+
$VERBOSE = original_verbose
|
17
|
+
end
|
18
|
+
|
19
|
+
$VERBOSE = true
|
20
|
+
|
21
|
+
require "ohm"
|
22
|
+
|
23
|
+
prepare do
|
24
|
+
Ohm.flush
|
25
|
+
end
|
data/test/indices_test.rb
CHANGED
@@ -1,219 +1,213 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class User < Ohm::Model
|
6
|
+
attribute :email
|
7
|
+
attribute :update
|
8
|
+
attribute :activation_code
|
9
|
+
attribute :sandunga
|
10
|
+
|
11
|
+
index :email
|
12
|
+
index :email_provider
|
13
|
+
index :working_days
|
14
|
+
index :update
|
15
|
+
index :activation_code
|
16
|
+
|
17
|
+
def email_provider
|
18
|
+
email.split("@").last
|
6
19
|
end
|
7
20
|
|
8
|
-
|
9
|
-
|
10
|
-
attribute :update
|
11
|
-
attribute :activation_code
|
12
|
-
attribute :sandunga
|
13
|
-
|
14
|
-
index :email
|
15
|
-
index :email_provider
|
16
|
-
index :working_days
|
17
|
-
index :update
|
18
|
-
index :activation_code
|
19
|
-
|
20
|
-
def email_provider
|
21
|
-
email.split("@").last
|
22
|
-
end
|
23
|
-
|
24
|
-
def working_days
|
25
|
-
@working_days ||= []
|
26
|
-
end
|
27
|
-
|
28
|
-
def write
|
29
|
-
self.activation_code ||= "user:#{id}"
|
30
|
-
super
|
31
|
-
end
|
21
|
+
def working_days
|
22
|
+
@working_days ||= []
|
32
23
|
end
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
25
|
+
def write
|
26
|
+
self.activation_code ||= "user:#{id}"
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
40
30
|
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
setup do
|
32
|
+
@user1 = User.create(:email => "foo", :activation_code => "bar", :update => "baz")
|
33
|
+
@user2 = User.create(:email => "bar")
|
34
|
+
@user3 = User.create(:email => "baz qux")
|
35
|
+
end
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
37
|
+
test "be able to find by the given attribute" do
|
38
|
+
assert @user1 == User.find(:email => "foo").first
|
39
|
+
end
|
50
40
|
|
51
|
-
|
52
|
-
|
41
|
+
test "raise an error if the parameter supplied is not a hash" do
|
42
|
+
begin
|
43
|
+
User.find(1)
|
44
|
+
rescue => ex
|
45
|
+
ensure
|
46
|
+
assert ex.kind_of?(ArgumentError)
|
47
|
+
assert ex.message == "You need to supply a hash with filters. If you want to find by ID, use User[id] instead."
|
48
|
+
end
|
49
|
+
end
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
test "avoid intersections with the all collection" do
|
52
|
+
assert "User:email:#{Ohm::Model.encode "foo"}" == User.find(:email => "foo").key.to_s
|
56
53
|
|
57
|
-
|
58
|
-
|
59
|
-
end
|
54
|
+
assert "~:User:email:Zm9v+User:activation_code:" ==
|
55
|
+
User.find(:email => "foo").find(:activation_code => "").key.to_s
|
60
56
|
|
61
|
-
|
62
|
-
|
57
|
+
assert "~:User:email:Zm9v+User:activation_code:YmFy+User:update:YmF6" ==
|
58
|
+
result = User.find(:email => "foo").find(:activation_code => "bar").find(:update => "baz").key.to_s
|
59
|
+
end
|
63
60
|
|
64
|
-
|
65
|
-
|
61
|
+
test "use a special namespace for set operations" do
|
62
|
+
assert User.find(:email => "foo", :activation_code => "bar").key.to_s.match(/^~:/)
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
64
|
+
assert Ohm.redis.keys("~:*").size > 0
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
67
|
+
test "allow multiple chained finds" do
|
68
|
+
assert 1 == User.find(:email => "foo").find(:activation_code => "bar").find(:update => "baz").size
|
69
|
+
end
|
76
70
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
71
|
+
test "raise if the field is not indexed" do
|
72
|
+
assert_raise(Ohm::Model::IndexNotFound) do
|
73
|
+
User.find(:sandunga => "foo")
|
74
|
+
end
|
75
|
+
end
|
81
76
|
|
82
|
-
|
83
|
-
|
84
|
-
|
77
|
+
test "return nil if no results are found" do
|
78
|
+
assert User.find(:email => "foobar").empty?
|
79
|
+
assert nil == User.find(:email => "foobar").first
|
80
|
+
end
|
85
81
|
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
test "update indices when changing attribute values" do
|
83
|
+
@user1.email = "baz"
|
84
|
+
@user1.save
|
89
85
|
|
90
|
-
|
91
|
-
|
86
|
+
assert [] == User.find(:email => "foo").all
|
87
|
+
assert [@user1] == User.find(:email => "baz").all
|
88
|
+
end
|
92
89
|
|
93
|
-
|
94
|
-
|
90
|
+
test "remove from the index after deleting" do
|
91
|
+
@user2.delete
|
95
92
|
|
96
|
-
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
93
|
+
assert [] == User.find(:email => "bar").all
|
94
|
+
end
|
100
95
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
should "allow indexing by an attribute that is lazily set" do
|
114
|
-
assert_equal [@user1], User.find(:activation_code => "user:1").to_a
|
115
|
-
end
|
116
|
-
end
|
96
|
+
test "work with attributes that contain spaces" do
|
97
|
+
assert [@user3] == User.find(:email => "baz qux").all
|
98
|
+
end
|
99
|
+
|
100
|
+
# Indexing arbitrary attributes
|
101
|
+
setup do
|
102
|
+
@user1 = User.create(:email => "foo@gmail.com")
|
103
|
+
@user2 = User.create(:email => "bar@gmail.com")
|
104
|
+
@user3 = User.create(:email => "bazqux@yahoo.com")
|
105
|
+
end
|
117
106
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
107
|
+
test "allow indexing by an arbitrary attribute" do
|
108
|
+
assert [@user1, @user2] == User.find(:email_provider => "gmail.com").to_a.sort_by { |u| u.id }
|
109
|
+
assert [@user3] == User.find(:email_provider => "yahoo.com").all
|
110
|
+
end
|
111
|
+
|
112
|
+
test "allow indexing by an attribute that is lazily set" do
|
113
|
+
assert [@user1] == User.find(:activation_code => "user:1").to_a
|
114
|
+
end
|
115
|
+
|
116
|
+
# Indexing enumerables
|
117
|
+
setup do
|
118
|
+
@user1 = User.create(:email => "foo@gmail.com")
|
119
|
+
@user2 = User.create(:email => "bar@gmail.com")
|
120
|
+
|
121
|
+
@user1.working_days << "Mon"
|
122
|
+
@user1.working_days << "Tue"
|
123
|
+
@user2.working_days << "Mon"
|
124
|
+
@user2.working_days << "Wed"
|
125
|
+
|
126
|
+
@user1.save
|
127
|
+
@user2.save
|
128
|
+
end
|
129
|
+
|
130
|
+
test "index each item" do
|
131
|
+
assert [@user1, @user2] == User.find(:working_days => "Mon").to_a.sort_by { |u| u.id }
|
132
|
+
end
|
133
|
+
|
134
|
+
# TODO If we deal with Ohm collections, the updates are atomic but the reindexing never happens.
|
135
|
+
# One solution may be to reindex after inserts or deletes in collection.
|
136
|
+
test "remove the indices when the object changes" do
|
137
|
+
@user2.working_days.delete "Mon"
|
138
|
+
@user2.save
|
139
|
+
assert [@user1] == User.find(:working_days => "Mon").all
|
140
|
+
end
|
141
|
+
|
142
|
+
# Intersection and difference
|
143
|
+
class Event < Ohm::Model
|
144
|
+
attr_writer :days
|
145
|
+
|
146
|
+
attribute :timeline
|
147
|
+
index :timeline
|
148
|
+
index :days
|
149
|
+
|
150
|
+
def days
|
151
|
+
@days ||= []
|
143
152
|
end
|
153
|
+
end
|
144
154
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
should "intersect multiple sets of results" do
|
166
|
-
assert_equal [@event1], Event.find(:days => [1, 2]).all
|
167
|
-
assert_equal [@event1], Event.find(:timeline => 1, :days => [1, 2]).all
|
168
|
-
assert_equal [@event1], Event.find(:timeline => 1).find(:days => [1, 2]).all
|
169
|
-
end
|
170
|
-
|
171
|
-
should "compute the difference between sets" do
|
172
|
-
assert_equal [@event2], Event.find(:timeline => 1).except(:days => 1).all
|
173
|
-
end
|
174
|
-
|
175
|
-
should "raise if the argument is not an index" do
|
176
|
-
assert_raises(Ohm::Model::IndexNotFound) do
|
177
|
-
Event.find(:timeline => 1).except(:not_an_index => 1)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
should "work with strings that generate a new line when encoded" do
|
182
|
-
user = User.create(:email => "foo@bar", :update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan")
|
183
|
-
assert_equal [user], User.find(:update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan").all
|
184
|
-
end
|
155
|
+
setup do
|
156
|
+
@event1 = Event.create(:timeline => 1).update(:days => [1, 2])
|
157
|
+
@event2 = Event.create(:timeline => 1).update(:days => [2, 3])
|
158
|
+
@event3 = Event.create(:timeline => 2).update(:days => [3, 4])
|
159
|
+
@event4 = Event.create(:timeline => 2).update(:days => [1, 3])
|
160
|
+
end
|
161
|
+
|
162
|
+
test "intersect multiple sets of results" do
|
163
|
+
assert [@event1] == Event.find(:days => [1, 2]).all
|
164
|
+
assert [@event1] == Event.find(:timeline => 1, :days => [1, 2]).all
|
165
|
+
assert [@event1] == Event.find(:timeline => 1).find(:days => [1, 2]).all
|
166
|
+
end
|
167
|
+
|
168
|
+
test "compute the difference between sets" do
|
169
|
+
assert [@event2] == Event.find(:timeline => 1).except(:days => 1).all
|
170
|
+
end
|
171
|
+
|
172
|
+
test "raise if the argument is not an index" do
|
173
|
+
assert_raise(Ohm::Model::IndexNotFound) do
|
174
|
+
Event.find(:timeline => 1).except(:not_an_index => 1)
|
185
175
|
end
|
176
|
+
end
|
177
|
+
|
178
|
+
test "work with strings that generate a new line when encoded" do
|
179
|
+
user = User.create(:email => "foo@bar", :update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan")
|
180
|
+
assert [user] == User.find(:update => "CORRECTED - UPDATE 2-Suspected US missile strike kills 5 in Pakistan").all
|
181
|
+
end
|
186
182
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
183
|
+
# New indices
|
184
|
+
test "populate a new index when the model is saved" do
|
185
|
+
class Event < Ohm::Model
|
186
|
+
attribute :name
|
187
|
+
end
|
192
188
|
|
193
|
-
|
189
|
+
foo = Event.create(:name => "Foo")
|
194
190
|
|
195
|
-
|
191
|
+
assert_raise(Ohm::Model::IndexNotFound) { Event.find(:name => "Foo") }
|
196
192
|
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
class Event < Ohm::Model
|
194
|
+
index :name
|
195
|
+
end
|
200
196
|
|
201
|
-
|
202
|
-
|
197
|
+
# Find works correctly once the index is added.
|
198
|
+
Event.find(:name => "Foo")
|
203
199
|
|
204
|
-
|
205
|
-
|
200
|
+
# The index was added after foo was created.
|
201
|
+
assert Event.find(:name => "Foo").empty?
|
206
202
|
|
207
|
-
|
203
|
+
bar = Event.create(:name => "Bar")
|
208
204
|
|
209
|
-
|
210
|
-
|
205
|
+
# Bar was indexed properly.
|
206
|
+
assert bar == Event.find(:name => "Bar").first
|
211
207
|
|
212
|
-
|
213
|
-
|
208
|
+
# Saving all the objects populates the indices.
|
209
|
+
Event.all.each { |e| e.save }
|
214
210
|
|
215
|
-
|
216
|
-
|
217
|
-
end
|
218
|
-
end
|
211
|
+
# Now foo is indexed.
|
212
|
+
assert foo == Event.find(:name => "Foo").first
|
219
213
|
end
|