paulcarey-relaxdb 0.1.0
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.textile +98 -0
- data/Rakefile +52 -0
- data/docs/spec_results.html +602 -0
- data/lib/relaxdb/all_delegator.rb +48 -0
- data/lib/relaxdb/belongs_to_proxy.rb +29 -0
- data/lib/relaxdb/design_doc.rb +50 -0
- data/lib/relaxdb/document.rb +298 -0
- data/lib/relaxdb/has_many_proxy.rb +81 -0
- data/lib/relaxdb/has_one_proxy.rb +45 -0
- data/lib/relaxdb/query.rb +48 -0
- data/lib/relaxdb/references_many_proxy.rb +99 -0
- data/lib/relaxdb/relaxdb.rb +106 -0
- data/lib/relaxdb/server.rb +112 -0
- data/lib/relaxdb/sorted_by_view.rb +42 -0
- data/lib/relaxdb/uuid_generator.rb +21 -0
- data/lib/relaxdb/view_object.rb +34 -0
- data/lib/relaxdb/view_uploader.rb +47 -0
- data/lib/relaxdb/views.rb +42 -0
- data/lib/relaxdb.rb +33 -0
- data/spec/belongs_to_spec.rb +80 -0
- data/spec/design_doc_spec.rb +34 -0
- data/spec/document_spec.rb +301 -0
- data/spec/has_many_spec.rb +139 -0
- data/spec/has_one_spec.rb +121 -0
- data/spec/query_spec.rb +46 -0
- data/spec/references_many_spec.rb +141 -0
- data/spec/relaxdb_spec.rb +50 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/spec_models.rb +104 -0
- data/spec/view_object_spec.rb +47 -0
- metadata +111 -0
@@ -0,0 +1,301 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/spec_models.rb'
|
3
|
+
|
4
|
+
describe RelaxDB::Document do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
RelaxDB.configure(:host => "localhost", :port => 5984)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
|
12
|
+
RelaxDB.use_db "relaxdb_spec_db"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".new" do
|
16
|
+
|
17
|
+
it "should create an object with an id" do
|
18
|
+
p = Atom.new
|
19
|
+
p._id.should_not be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create an object with a nil revision" do
|
23
|
+
Atom.new._rev.should be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should convert attributes that end in _at to dates" do
|
27
|
+
now = Time.now
|
28
|
+
p = Post.new(:viewed_at => now).save
|
29
|
+
p = RelaxDB.load(p._id)
|
30
|
+
p.viewed_at.class.should == Time
|
31
|
+
p.viewed_at.should be_close(now, 1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "will silently ignore parameters that don't specify class attributes" do
|
35
|
+
# Consider this a feature or bug. It allows an object containing both request params
|
36
|
+
# and superflous data to be passed directly to a constructor.
|
37
|
+
Post.new(:foo => "").save
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#to_json" do
|
43
|
+
|
44
|
+
it "should not output nil attributes" do
|
45
|
+
Atom.new.to_json.should_not include("rev")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#save" do
|
51
|
+
|
52
|
+
it "should set an object's revision" do
|
53
|
+
p = Atom.new.save
|
54
|
+
p._rev.should_not be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should result in an object considered saved" do
|
58
|
+
Atom.new.save.should_not be_unsaved
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be invokable multiple times" do
|
62
|
+
p = Atom.new
|
63
|
+
p.save
|
64
|
+
p.save
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should set created_at when first saved" do
|
68
|
+
now = Time.now
|
69
|
+
created_at = Post.new.save.created_at
|
70
|
+
now.should be_close(created_at, 1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should set created_at when first saved unless supplied to the constructor" do
|
74
|
+
back_then = Time.now - 1000
|
75
|
+
p = Post.new(:created_at => back_then).save
|
76
|
+
p.created_at.should be_close(back_then, 1)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "loaded objects" do
|
82
|
+
|
83
|
+
it "should contain state as when saved" do
|
84
|
+
now = Time.now
|
85
|
+
p = Primitives.new(:str => "foo", :num => 19.30, :true_bool => true, :false_bool => false, :created_at => now).save
|
86
|
+
p = RelaxDB.load(p._id)
|
87
|
+
p.str.should == "foo"
|
88
|
+
p.num.should == 19.30
|
89
|
+
p.true_bool.should be_true
|
90
|
+
p.false_bool.should_not be_true
|
91
|
+
p.created_at.should be_close(now, 1)
|
92
|
+
p.empty.should be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be saveable" do
|
96
|
+
a = Atom.new.save
|
97
|
+
a = RelaxDB.load(a._id)
|
98
|
+
a.save
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#destroy" do
|
104
|
+
|
105
|
+
it "should delete the corresponding document from CouchDB" do
|
106
|
+
p = Atom.new.save.destroy!
|
107
|
+
lambda { RelaxDB.load(p._id) }.should raise_error
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should prevent the object from being resaved" do
|
111
|
+
p = Atom.new.save.destroy!
|
112
|
+
lambda { p.save }.should raise_error
|
113
|
+
end
|
114
|
+
|
115
|
+
it "will result in undefined behaviour when invoked on unsaved objects" do
|
116
|
+
Photo.new.destroy!
|
117
|
+
lambda { Atom.new.destroy! }.should raise_error
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#all.destroy!" do
|
123
|
+
|
124
|
+
it "should delete from CouchDB all documents of the corresponding class" do
|
125
|
+
Atom.new.save
|
126
|
+
Post.new.save
|
127
|
+
Post.new.save
|
128
|
+
Post.all.destroy!
|
129
|
+
Post.all.should be_empty
|
130
|
+
Atom.all.size.should == 1
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "==" do
|
136
|
+
|
137
|
+
it "should define equality based on CouchDB id" do
|
138
|
+
i1 = Atom.new.save
|
139
|
+
i2 = Atom.new.save
|
140
|
+
i3 = RelaxDB.load(i1._id)
|
141
|
+
i1.should_not == i2
|
142
|
+
i1.should == i3
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should return false when passed a nil object" do
|
146
|
+
(Atom.new == nil).should_not be_true
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#all" do
|
152
|
+
|
153
|
+
it "should return all instances of that class" do
|
154
|
+
Photo.new.save
|
155
|
+
Rating.new.save
|
156
|
+
Rating.new.save
|
157
|
+
Rating.all.size.should == 2
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should return an empty array when no instances exist" do
|
161
|
+
Atom.all.should be_an_instance_of(Array)
|
162
|
+
Atom.all.should be_empty
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "#all.sorted_by" do
|
168
|
+
|
169
|
+
it "should sort ascending by default" do
|
170
|
+
Post.new(:content => "b").save
|
171
|
+
Post.new(:content => "a").save
|
172
|
+
posts = Post.all.sorted_by(:content)
|
173
|
+
posts[0].content.should == "a"
|
174
|
+
posts[1].content.should == "b"
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should sort desc when specified" do
|
178
|
+
Post.new(:content => "a").save
|
179
|
+
Post.new(:content => "b").save
|
180
|
+
posts = Post.all.sorted_by(:content) { |q| q.descending(true) }
|
181
|
+
posts[0].content.should == "b"
|
182
|
+
posts[1].content.should == "a"
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should sort date attributes lexicographically" do
|
186
|
+
t = Time.new
|
187
|
+
Post.new(:viewed_at => t+1000, :content => "late").save
|
188
|
+
Post.new(:viewed_at => t, :content => "early").save
|
189
|
+
posts = Post.all.sorted_by(:viewed_at)
|
190
|
+
posts[0].content.should == "early"
|
191
|
+
posts[1].content.should == "late"
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "results" do
|
195
|
+
|
196
|
+
it "should be retrievable by exact criteria" do
|
197
|
+
Post.new(:subject => "foo").save
|
198
|
+
Post.new(:subject => "foo").save
|
199
|
+
Post.new(:subject => "bar").save
|
200
|
+
Post.all.sorted_by(:subject) { |q| q.key("foo") }.size.should == 2
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should be retrievable by relative criteria" do
|
204
|
+
Rating.new(:stars => 1).save
|
205
|
+
Rating.new(:stars => 5).save
|
206
|
+
Rating.all.sorted_by(:stars) { |q| q.endkey(3) }.size.should == 1
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should be retrievable by combined criteria" do
|
210
|
+
User.new(:name => "paul", :age => 28).save
|
211
|
+
User.new(:name => "paul", :age => 72).save
|
212
|
+
User.new(:name => "atlas", :age => 99).save
|
213
|
+
User.all.sorted_by(:name, :age) { |q| q.startkey(["paul",0 ]).endkey(["paul", 50]) }.size.should == 1
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should be retrievable by combined criteria where not all docs contain all attributes" do
|
217
|
+
User.new(:name => "paul", :age => 28).save
|
218
|
+
User.new(:name => "paul", :age => 72).save
|
219
|
+
User.new(:name => "atlas").save
|
220
|
+
User.all.sorted_by(:name, :age) { |q| q.startkey(["paul",0 ]).endkey(["paul", 50]) }.size.should == 1
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "defaults" do
|
228
|
+
|
229
|
+
it "should be set on initialisation" do
|
230
|
+
r = Rating.new
|
231
|
+
r.stars.should == 5
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should be saved" do
|
235
|
+
r = Rating.new.save
|
236
|
+
RelaxDB.load(r._id).stars.should == 5
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should be ignored once overwritten" do
|
240
|
+
r = Rating.new
|
241
|
+
r.stars = nil
|
242
|
+
r.save
|
243
|
+
RelaxDB.load(r._id).stars.should be_nil
|
244
|
+
end
|
245
|
+
|
246
|
+
it "may be a simple value" do
|
247
|
+
simple = Class.new(RelaxDB::Document) do
|
248
|
+
property :foo, :default => :bar
|
249
|
+
end
|
250
|
+
simple.new.foo.should == :bar
|
251
|
+
end
|
252
|
+
|
253
|
+
it "may be a proc" do
|
254
|
+
simple = Class.new(RelaxDB::Document) do
|
255
|
+
property :foo, :default => lambda { :bar }
|
256
|
+
end
|
257
|
+
simple.new.foo.should == :bar
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "validator" do
|
263
|
+
|
264
|
+
it "should prevent an object from being saved if it evaluates to false" do
|
265
|
+
r = Class.new(RelaxDB::Document) do
|
266
|
+
property :thumbs_up, :validator => lambda { false }
|
267
|
+
end
|
268
|
+
r.new.save.should be_false
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should pass the property value to the validator" do
|
272
|
+
r = Class.new(RelaxDB::Document) do
|
273
|
+
property :thumbs_up, :validator => lambda { |tu| tu >=0 && tu < 3 }
|
274
|
+
end
|
275
|
+
r.new(:thumbs_up => 2).save.should_not be_false
|
276
|
+
r.new(:thumbs_up => 3).save.should be_false
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should add the validation error message if supplied, on failure" do
|
280
|
+
r = Class.new(RelaxDB::Document) do
|
281
|
+
property :thumbs_up, :validator => lambda { false }, :validation_msg => "Too many thumbs"
|
282
|
+
end
|
283
|
+
x = r.new
|
284
|
+
x.save
|
285
|
+
x.errors[:thumbs_up].should == "Too many thumbs"
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should perform all validations" do
|
289
|
+
r = Class.new(RelaxDB::Document) do
|
290
|
+
property :foo, :validator => lambda { false }, :validation_msg => "oof"
|
291
|
+
property :bar, :validator => lambda { false }, :validation_msg => "rab"
|
292
|
+
end
|
293
|
+
x = r.new
|
294
|
+
x.save
|
295
|
+
x.errors[:foo].should == "oof"
|
296
|
+
x.errors[:bar].should == "rab"
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/spec_models.rb'
|
3
|
+
|
4
|
+
describe RelaxDB::HasManyProxy do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
RelaxDB.configure(:host => "localhost", :port => 5984)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
|
12
|
+
RelaxDB.use_db "relaxdb_spec_db"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "has_many" do
|
16
|
+
|
17
|
+
it "should be considered enumerable" do
|
18
|
+
u = User.new.save
|
19
|
+
u.items.should be_a_kind_of( Enumerable)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should actually be enumerable" do
|
23
|
+
u = User.new.save
|
24
|
+
u.items << Item.new(:name => "a")
|
25
|
+
u.items << Item.new(:name => "b")
|
26
|
+
names = u.items.inject("") { |memo, i| memo << i.name }
|
27
|
+
names.should == "ab"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should preserve the collection across the load / save boundary" do
|
31
|
+
u = User.new.save
|
32
|
+
u.items << Item.new
|
33
|
+
u = RelaxDB.load u._id
|
34
|
+
u.items.size.should == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#<<" do
|
38
|
+
|
39
|
+
it "should link the added item to the parent" do
|
40
|
+
u = User.new
|
41
|
+
u.items << Item.new
|
42
|
+
u.items[0].user.should == u
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return self" do
|
46
|
+
u = User.new.save
|
47
|
+
u.items << Item.new << Item.new
|
48
|
+
u.items[0].user.should == u
|
49
|
+
u.items[1].user.should == u
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not created duplicates when invoked with same object more than once" do
|
53
|
+
u = User.new.save
|
54
|
+
i = Item.new
|
55
|
+
u.items << i << i
|
56
|
+
u.items.size.should == 1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return false when the child fails validation" do
|
60
|
+
d = Dysfunctional.new
|
61
|
+
r = (d.failures << Failure.new)
|
62
|
+
r.should be_false
|
63
|
+
d.failures.should be_empty
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#=" do
|
69
|
+
|
70
|
+
it "should fail" do
|
71
|
+
# This may be implemented in future
|
72
|
+
lambda { User.new.items = [] }.should raise_error
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#delete" do
|
78
|
+
|
79
|
+
it "should nullify the belongs_to relationship" do
|
80
|
+
u = User.new.save
|
81
|
+
i = Item.new
|
82
|
+
u.items << i
|
83
|
+
u.items.delete i
|
84
|
+
i.user.should be_nil
|
85
|
+
RelaxDB.load(i._id).user.should be_nil
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#clear" do
|
91
|
+
|
92
|
+
it "should result in an empty collection" do
|
93
|
+
u = User.new.save
|
94
|
+
u.items << Item.new << Item.new
|
95
|
+
u.items.clear
|
96
|
+
u.items.should be_empty
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should nullify all child relationships" do
|
100
|
+
u = User.new.save
|
101
|
+
i1, i2 = Item.new, Item.new
|
102
|
+
u.items << i1
|
103
|
+
u.items << i2
|
104
|
+
u.items.clear
|
105
|
+
|
106
|
+
i1.user.should be_nil
|
107
|
+
i2.user.should be_nil
|
108
|
+
RelaxDB.load(i1._id).user.should be_nil
|
109
|
+
RelaxDB.load(i2._id).user.should be_nil
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "owner" do
|
115
|
+
|
116
|
+
it "should be able to form multiple relationships with the same class of child" do
|
117
|
+
u1, u2 = User.new.save, User.new.save
|
118
|
+
i = Invite.new(:recipient => u2)
|
119
|
+
u1.invites_sent << Invite.new
|
120
|
+
RelaxDB.load(u1._id).invites_sent[0] == i
|
121
|
+
RelaxDB.load(u2._id).invites_received[0] == i
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#destroy" do
|
125
|
+
|
126
|
+
it "should nullify its child relationships" do
|
127
|
+
u = User.new.save
|
128
|
+
u.items << Item.new << Item.new
|
129
|
+
u.destroy!
|
130
|
+
Item.all.sorted_by(:user_id) { |q| q.key(u._id) }.should be_empty
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/spec_models.rb'
|
3
|
+
|
4
|
+
describe RelaxDB::HasOneProxy do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
RelaxDB.configure(:host => "localhost", :port => 5984)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
|
12
|
+
RelaxDB.use_db "relaxdb_spec_db"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "has_one" do
|
16
|
+
|
17
|
+
it "should return nil when accessed before assignment" do
|
18
|
+
p = Photo.new
|
19
|
+
p.rating.should == nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be establishable via a constructor attribute" do
|
23
|
+
r = Rating.new
|
24
|
+
p = Photo.new :rating => r
|
25
|
+
p.rating.should == r
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be establishable via assignment" do
|
29
|
+
p = Photo.new
|
30
|
+
r = Rating.new
|
31
|
+
p.rating = r
|
32
|
+
p.rating.should == r
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return the same object on repeated invocations" do
|
36
|
+
p = Photo.new.save
|
37
|
+
p.rating = Rating.new
|
38
|
+
p = RelaxDB.load(p._id)
|
39
|
+
p.rating.object_id.should == p.rating.object_id
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be preserved across load / save boundary" do
|
43
|
+
r = Rating.new
|
44
|
+
p = Photo.new(:rating => r).save
|
45
|
+
p = RelaxDB.load p._id
|
46
|
+
p.rating.should == r
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able reference itself via its child" do
|
50
|
+
r = Rating.new
|
51
|
+
p = Photo.new(:rating => r).save
|
52
|
+
p = RelaxDB.load p._id
|
53
|
+
p.rating.photo.should == p
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#=" do
|
57
|
+
|
58
|
+
it "should create a reference from the child to the parent" do
|
59
|
+
p = Photo.new
|
60
|
+
r = Rating.new
|
61
|
+
p.rating = r
|
62
|
+
r.photo.should == p
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should save the assigned object" do
|
66
|
+
p = Photo.new
|
67
|
+
r = Rating.new
|
68
|
+
p.rating = r
|
69
|
+
r.should_not be_unsaved
|
70
|
+
end
|
71
|
+
|
72
|
+
it "will not save the parent" do
|
73
|
+
p = Photo.new
|
74
|
+
r = Rating.new
|
75
|
+
p.rating = r
|
76
|
+
p.should be_unsaved
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should set the target to nil when nil is assigned" do
|
80
|
+
p = Photo.new
|
81
|
+
p.rating = nil
|
82
|
+
p.rating.should be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should nullify any existing relationship in the database" do
|
86
|
+
p = Photo.new
|
87
|
+
r = Rating.new
|
88
|
+
p.rating = r
|
89
|
+
p.rating = nil
|
90
|
+
RelaxDB.load(r._id).photo.should be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should nullify any existing relationship on a known in-memory object" do
|
94
|
+
p = Photo.new
|
95
|
+
r = Rating.new
|
96
|
+
p.rating = r
|
97
|
+
p.rating = nil
|
98
|
+
r.photo.should be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "will not nullify any existing relationship on unknown in-memory objects" do
|
102
|
+
p = Photo.new.save
|
103
|
+
r = Rating.new
|
104
|
+
p.rating = r
|
105
|
+
r_copy = RelaxDB.load(r._id)
|
106
|
+
p.rating = nil
|
107
|
+
r_copy.photo.should_not be_nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it "will not throw an error when the rhs fails validation" do
|
111
|
+
d = Dysfunctional.new.save
|
112
|
+
f = Failure.new
|
113
|
+
d.failure = f
|
114
|
+
d.failure.should == f
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/spec_models.rb'
|
3
|
+
|
4
|
+
describe RelaxDB::Query do
|
5
|
+
|
6
|
+
describe "#view_name" do
|
7
|
+
|
8
|
+
it "should match a single key attribute" do
|
9
|
+
q = RelaxDB::SortedByView.new("", :foo)
|
10
|
+
q.view_name.should == "all_sorted_by_foo"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should match key attributes" do
|
14
|
+
q = RelaxDB::SortedByView.new("", :foo, :bar)
|
15
|
+
q.view_name.should == "all_sorted_by_foo_and_bar"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#view_path" do
|
20
|
+
|
21
|
+
it "should list design document and view name" do
|
22
|
+
q = RelaxDB::Query.new("Zenith", "mount")
|
23
|
+
q.view_path.should == "_view/Zenith/mount"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should contain URL and JSON encoded key when the key has been set" do
|
27
|
+
q = RelaxDB::Query.new("Zenith", "mount")
|
28
|
+
q.key("olympus")
|
29
|
+
q.view_path.should == "_view/Zenith/mount?key=%22olympus%22"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should honour startkey, endkey and count" do
|
33
|
+
q = RelaxDB::Query.new("Zenith", "all_sorted_by_name_and_height")
|
34
|
+
q.startkey(["olympus"]).endkey(["vesuvius", 3600]).count(100)
|
35
|
+
q.view_path.should == "_view/Zenith/all_sorted_by_name_and_height?startkey=%5B%22olympus%22%5D&endkey=%5B%22vesuvius%22%2C3600%5D&count=100"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should specify the key as the empty string if key was set to nil" do
|
39
|
+
q = RelaxDB::Query.new("", "")
|
40
|
+
q.key(nil)
|
41
|
+
q.view_path.should == "_view//?key=%22%22"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|