paulcarey-relaxdb 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,13 +3,8 @@ require File.dirname(__FILE__) + '/spec_models.rb'
3
3
 
4
4
  describe RelaxDB::Document do
5
5
 
6
- before(:all) do
7
- RelaxDB.configure(:host => "localhost", :port => 5984)
8
- end
9
-
10
6
  before(:each) do
11
- RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
12
- RelaxDB.use_db "relaxdb_spec_db"
7
+ setup_test_db
13
8
  end
14
9
 
15
10
  describe ".new" do
@@ -131,43 +126,7 @@ describe RelaxDB::Document do
131
126
  end
132
127
 
133
128
  end
134
-
135
- describe "#save_all" do
136
-
137
- before(:each) do
138
- # Create the underlying views
139
- User.new(:items => [], :invites_received => [], :invites_sent => [])
140
- end
141
-
142
- # it should issue a single POST
143
- it "should issue no PUT requests" do
144
- RelaxDB.db.put_count = 0
145
- RelaxDB.db.get_count = 0
146
-
147
- i1, i2 = Item.new(:name => "i1"), Item.new(:name => "i2")
148
- u = User.new(:items => [i1, i2])
149
- u.save_all!
150
129
 
151
- RelaxDB.db.put_count.should == 0
152
- RelaxDB.db.get_count.should == 3
153
- end
154
-
155
- end
156
-
157
- describe "#all_children" do
158
-
159
- it "should return an array containing all children" do
160
- r = Rating.new
161
- p = Photo.new(:rating => r)
162
- t = Tag.new
163
- t1, t2 = Tagging.new(:photo => p, :tag => t), Tagging.new(:photo => p, :tag => t)
164
- p.taggings = [t1, t2]
165
- p.all_children.size.should == 3
166
- [r, t1, t2].each { |c| p.all_children.should include(c) }
167
- end
168
-
169
- end
170
-
171
130
  describe "user defined property reader" do
172
131
 
173
132
  it "should not effect normal operation" do
@@ -226,6 +185,7 @@ describe RelaxDB::Document do
226
185
 
227
186
  it "should prevent the object from being resaved" do
228
187
  p = Atom.new.save.destroy!
188
+ # Exepcted failure - see http://issues.apache.org/jira/browse/COUCHDB-292
229
189
  lambda { p.save! }.should raise_error
230
190
  end
231
191
 
@@ -282,11 +242,14 @@ describe RelaxDB::Document do
282
242
 
283
243
  describe ".all.size" do
284
244
 
285
- it "should return the total number of docs" do
245
+ it "should return the total number of docs in a single query" do
286
246
  docs = []
287
247
  100.times { docs << Atom.new }
288
248
  RelaxDB.bulk_save(*docs)
249
+
250
+ RelaxDB.db.get_count = 0
289
251
  Atom.all.size.should == 100
252
+ RelaxDB.db.get_count.should == 1
290
253
  end
291
254
 
292
255
  it "should return 0 when no docs exist" do
@@ -295,12 +258,12 @@ describe RelaxDB::Document do
295
258
 
296
259
  end
297
260
 
298
- describe ".all.sorted_by" do
299
-
261
+ describe "by_" do
262
+
300
263
  it "should sort ascending by default" do
301
264
  Post.new(:content => "b").save
302
265
  Post.new(:content => "a").save
303
- posts = Post.all.sorted_by(:content)
266
+ posts = Post.by_content
304
267
  posts[0].content.should == "a"
305
268
  posts[1].content.should == "b"
306
269
  end
@@ -308,7 +271,7 @@ describe RelaxDB::Document do
308
271
  it "should sort desc when specified" do
309
272
  Post.new(:content => "a").save
310
273
  Post.new(:content => "b").save
311
- posts = Post.all.sorted_by(:content) { |q| q.descending(true) }
274
+ posts = Post.by_content :descending => true
312
275
  posts[0].content.should == "b"
313
276
  posts[1].content.should == "a"
314
277
  end
@@ -317,7 +280,7 @@ describe RelaxDB::Document do
317
280
  t = Time.new
318
281
  Post.new(:viewed_at => t+1000, :content => "late").save
319
282
  Post.new(:viewed_at => t, :content => "early").save
320
- posts = Post.all.sorted_by(:viewed_at)
283
+ posts = Post.by_viewed_at
321
284
  posts[0].content.should == "early"
322
285
  posts[1].content.should == "late"
323
286
  end
@@ -327,48 +290,47 @@ describe RelaxDB::Document do
327
290
  100.times { |i| docs << Primitives.new(:num => i) }
328
291
  RelaxDB.bulk_save(*docs)
329
292
  # Create the view
330
- Primitives.all.sorted_by(:num)
331
- res = RelaxDB.view("Primitives", "all_sorted_by_num") { |q| q.reduce(true) }
332
- count = RelaxDB.reduce_result(res)
293
+ Primitives.by_num
294
+ count = RelaxDB.view "Primitives_by_num", :reduce => true
333
295
  count.should == 100
334
296
  end
335
297
 
336
298
  describe "results" do
337
299
 
338
300
  it "should be an empty array when no docs match" do
339
- Post.all.sorted_by(:subject).should == []
301
+ Post.by_subject.should == []
340
302
  end
341
303
 
342
304
  it "should be retrievable by exact criteria" do
343
305
  Post.new(:subject => "foo").save
344
306
  Post.new(:subject => "foo").save
345
307
  Post.new(:subject => "bar").save
346
- Post.all.sorted_by(:subject) { |q| q.key("foo") }.size.should == 2
308
+ Post.by_subject(:key => "foo").size.should == 2
347
309
  end
348
310
 
349
311
  it "should be retrievable by relative criteria" do
350
312
  Rating.new(:stars => 1).save
351
313
  Rating.new(:stars => 5).save
352
- Rating.all.sorted_by(:stars) { |q| q.endkey(3) }.size.should == 1
314
+ Rating.by_stars(:endkey => 3).size.should == 1
353
315
  end
354
316
 
355
317
  it "should be retrievable by combined criteria" do
356
318
  User.new(:name => "paul", :age => 28).save
357
319
  User.new(:name => "paul", :age => 72).save
358
320
  User.new(:name => "atlas", :age => 99).save
359
- User.all.sorted_by(:name, :age) { |q| q.startkey(["paul",0 ]).endkey(["paul", 50]) }.size.should == 1
321
+ User.by_name_and_age(:startkey => ["paul",0 ], :endkey => ["paul", 50]).size.should == 1
360
322
  end
361
323
 
362
324
  it "should be retrievable by combined criteria where not all docs contain all attributes" do
363
325
  User.new(:name => "paul", :age => 28).save
364
326
  User.new(:name => "paul", :age => 72).save
365
327
  User.new(:name => "atlas").save
366
- User.all.sorted_by(:name, :age) { |q| q.startkey(["paul",0 ]).endkey(["paul", 50]) }.size.should == 1
328
+ User.by_name_and_age(:startkey => ["paul",0 ], :endkey => ["paul", 50]).size.should == 1
367
329
  end
368
330
 
369
331
  it "should be retrievable by a multi key post" do
370
332
  5.times { |i| Primitives.new(:num => i).save }
371
- ps = Primitives.all.sorted_by(:num) { |q| q.keys([0, 4]) }
333
+ ps = Primitives.by_num :keys => [0, 4]
372
334
  ps.map { |p| p.num }.should == [0, 4]
373
335
  end
374
336
 
@@ -4,12 +4,7 @@ require File.dirname(__FILE__) + '/spec_models.rb'
4
4
  describe RelaxDB::HasManyProxy do
5
5
 
6
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"
7
+ setup_test_db
13
8
  end
14
9
 
15
10
  describe "has_many" do
@@ -90,22 +85,22 @@ describe RelaxDB::HasManyProxy do
90
85
  it "should preserve given relationships across save/load boundary" do
91
86
  i1, i2 = Item.new(:name => "i1"), Item.new(:name => "i2")
92
87
  u = User.new(:items => [i1, i2])
93
- u.save_all!
88
+ RelaxDB.bulk_save u, *u.items
94
89
  u = RelaxDB.load u._id
95
90
  u.items.map { |i| i.name }.sort.join.should == "i1i2"
96
91
  end
97
92
 
98
93
  it "should invoke the derived properties writer" do
99
- P = Class.new(RelaxDB::Document) do
94
+ class HmsdParent < RelaxDB::Document
100
95
  property :foo, :derived => [:zongs, lambda {|f, o| o.zongs.first.z / 2 }]
101
- has_many :zongs, :class => "Zong"
96
+ has_many :zongs, :class => "HmsdChild"
102
97
  end
103
- Zong = Class.new(RelaxDB::Document) do
98
+ class HmsdChild < RelaxDB::Document
104
99
  property :z
105
- belongs_to :p
100
+ belongs_to :hmsd_parent
106
101
  end
107
- oz = Zong.new(:z => 10)
108
- op = P.new(:zongs => [oz])
102
+ oz = HmsdChild.new(:z => 10)
103
+ op = HmsdParent.new(:zongs => [oz])
109
104
  op.foo.should == 5
110
105
  end
111
106
 
@@ -161,10 +156,12 @@ describe RelaxDB::HasManyProxy do
161
156
  describe "#destroy" do
162
157
 
163
158
  it "should nullify its child relationships" do
159
+ Item.view_by :user_id
160
+
164
161
  u = User.new.save
165
162
  u.items << Item.new << Item.new
166
163
  u.destroy!
167
- Item.all.sorted_by(:user_id) { |q| q.key(u._id) }.should be_empty
164
+ Item.by_user_id(:key => u._id).should be_empty
168
165
  end
169
166
 
170
167
  end
data/spec/has_one_spec.rb CHANGED
@@ -3,13 +3,8 @@ require File.dirname(__FILE__) + '/spec_models.rb'
3
3
 
4
4
  describe RelaxDB::HasOneProxy do
5
5
 
6
- before(:all) do
7
- RelaxDB.configure(:host => "localhost", :port => 5984)
8
- end
9
-
10
6
  before(:each) do
11
- RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
12
- RelaxDB.use_db "relaxdb_spec_db"
7
+ setup_test_db
13
8
  end
14
9
 
15
10
  describe "has_one" do
data/spec/query_spec.rb CHANGED
@@ -2,67 +2,71 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
  require File.dirname(__FILE__) + '/spec_models.rb'
3
3
 
4
4
  describe RelaxDB::Query do
5
+
6
+ before(:all) do
7
+ RelaxDB.configure :host => "localhost", :port => 5984, :design_doc => ""
8
+ end
5
9
 
6
10
  describe "#view_name" do
7
11
 
8
12
  it "should match a single key attribute" do
9
- q = RelaxDB::SortedByView.new("", :foo)
10
- q.view_name.should == "all_sorted_by_foo"
13
+ q = RelaxDB::ViewCreator.by_att_list ["bar"], :foo
14
+ q.view_name.should == "bar_by_foo"
11
15
  end
12
16
 
13
17
  it "should match key attributes" do
14
- q = RelaxDB::SortedByView.new("", :foo, :bar)
15
- q.view_name.should == "all_sorted_by_foo_and_bar"
18
+ q = RelaxDB::ViewCreator.by_att_list ["bar"], :foo, :bar
19
+ q.view_name.should == "bar_by_foo_and_bar"
16
20
  end
17
21
  end
18
22
 
19
23
  describe "#view_path" do
20
24
 
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"
25
+ it "should list design document and view name and default reduce to false" do
26
+ q = RelaxDB::Query.new("mount")
27
+ q.view_path.should == "_design//_view/mount?reduce=false"
24
28
  end
25
29
 
26
30
  it "should contain URL and JSON encoded key when the key has been set" do
27
- q = RelaxDB::Query.new("", "")
31
+ q = RelaxDB::Query.new("")
28
32
  q.key("olympus")
29
- q.view_path.should == "_view//?key=%22olympus%22"
33
+ q.view_path.should == "_design//_view/?key=%22olympus%22&reduce=false"
30
34
  end
31
35
 
32
36
  it "should honour startkey, endkey and limit" do
33
- q = RelaxDB::Query.new("", "")
37
+ q = RelaxDB::Query.new("")
34
38
  q.startkey(["olympus"]).endkey(["vesuvius", 3600]).limit(100)
35
- q.view_path.should == "_view//?startkey=%5B%22olympus%22%5D&endkey=%5B%22vesuvius%22%2C3600%5D&limit=100"
39
+ q.view_path.should == "_design//_view/?startkey=%5B%22olympus%22%5D&endkey=%5B%22vesuvius%22%2C3600%5D&limit=100&reduce=false"
36
40
  end
37
41
 
38
42
  it "should specify a null key if key was set to nil" do
39
- q = RelaxDB::Query.new("", "")
43
+ q = RelaxDB::Query.new("")
40
44
  q.key(nil)
41
- q.view_path.should == "_view//?key=null"
45
+ q.view_path.should == "_design//_view/?key=null&reduce=false"
42
46
  end
43
47
 
44
48
  it "should specify a null startkey if startkey was set to nil" do
45
- q = RelaxDB::Query.new("", "")
49
+ q = RelaxDB::Query.new("")
46
50
  q.startkey(nil)
47
- q.view_path.should == "_view//?startkey=null"
51
+ q.view_path.should == "_design//_view/?startkey=null&reduce=false"
48
52
  end
49
53
 
50
54
  it "should specify a null endkey if endkey was set to nil" do
51
- q = RelaxDB::Query.new("", "")
55
+ q = RelaxDB::Query.new("")
52
56
  q.endkey(nil)
53
- q.view_path.should == "_view//?endkey=null"
57
+ q.view_path.should == "_design//_view/?endkey=null&reduce=false"
54
58
  end
55
59
 
56
60
  it "should not JSON encode the startkey_docid" do
57
- q = RelaxDB::Query.new("", "")
61
+ q = RelaxDB::Query.new("")
58
62
  q.startkey_docid("foo")
59
- q.view_path.should == "_view//?startkey_docid=foo"
63
+ q.view_path.should == "_design//_view/?startkey_docid=foo&reduce=false"
60
64
  end
61
65
 
62
66
  it "should not JSON encode the endkey_docid" do
63
- q = RelaxDB::Query.new("", "")
67
+ q = RelaxDB::Query.new("")
64
68
  q.endkey_docid("foo")
65
- q.view_path.should == "_view//?endkey_docid=foo"
69
+ q.view_path.should == "_design//_view/?endkey_docid=foo&reduce=false"
66
70
  end
67
71
 
68
72
  end
@@ -70,7 +74,7 @@ describe RelaxDB::Query do
70
74
  describe "#keys" do
71
75
 
72
76
  it "should return a JSON encoded hash" do
73
- q = RelaxDB::Query.new("", "")
77
+ q = RelaxDB::Query.new("")
74
78
  q.keys(["a", "b"])
75
79
  q.keys.should == '{"keys":["a","b"]}'
76
80
  end
@@ -4,12 +4,7 @@ require File.dirname(__FILE__) + '/spec_models.rb'
4
4
  describe RelaxDB::ReferencesManyProxy do
5
5
 
6
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"
7
+ setup_test_db
13
8
  end
14
9
 
15
10
  describe "references_many" do
data/spec/relaxdb_spec.rb CHANGED
@@ -3,19 +3,14 @@ require File.dirname(__FILE__) + '/spec_models.rb'
3
3
 
4
4
  describe RelaxDB do
5
5
 
6
- before(:all) do
7
- RelaxDB.configure(:host => "localhost", :port => 5984)
8
- end
9
-
10
6
  before(:each) do
11
- RelaxDB.delete_db "relaxdb_spec_db" rescue "ok"
12
- RelaxDB.use_db "relaxdb_spec_db"
7
+ setup_test_db
13
8
  end
14
9
 
15
10
  describe ".create_object" do
16
11
 
17
12
  it "should return an instance of a known object if passed a hash with a class key" do
18
- data = { "class" => "Item" }
13
+ data = { "relaxdb_class" => "Item" }
19
14
  obj = RelaxDB.create_object(data)
20
15
  obj.should be_instance_of(Item)
21
16
  end
@@ -86,9 +81,9 @@ describe RelaxDB do
86
81
  lambda { RelaxDB.bulk_save!(c.new) }.should raise_error(RelaxDB::ValidationFailure)
87
82
  end
88
83
 
89
- it "should raise an exception if a document update conflict occurs on save" do
84
+ it "will not raise an exception if a document update conflict occurs on save" do
90
85
  Atom.new(:_id => "a1").save!
91
- lambda { RelaxDB.bulk_save! Atom.new(:_id => "a1") }.should raise_error(RelaxDB::UpdateConflict)
86
+ RelaxDB.bulk_save! Atom.new(:_id => "a1")
92
87
  end
93
88
 
94
89
  end
@@ -96,13 +91,14 @@ describe RelaxDB do
96
91
  describe ".replicate_db" do
97
92
 
98
93
  it "should replicate the named database" do
99
- orig = "relaxdb_spec_db"
100
- replica = "relaxdb_spec_db_replica"
101
- RelaxDB.delete_db replica rescue "ok"
102
- Atom.new.save # implicitly saved to orig
94
+ orig = "relaxdb_spec"
95
+ replica = "relaxdb_spec_replicate_test"
96
+ RelaxDB.delete_db replica rescue :ok
97
+ class ReplicaTest < RelaxDB::Document; end
98
+ ReplicaTest.new.save # implicitly saved to orig
103
99
  RelaxDB.replicate_db orig, replica
104
100
  RelaxDB.use_db replica
105
- Atom.all.size.should == 1
101
+ ReplicaTest.all.size.should == 1
106
102
  end
107
103
 
108
104
  end
@@ -172,31 +168,49 @@ describe RelaxDB do
172
168
  }
173
169
  >
174
170
 
175
- it "should request a view and return a hash" do
176
- RelaxDB::DesignDocument.get("viewtest").add_view("simple", "map", map_func).save
177
- data = RelaxDB.view("viewtest", "simple")
178
- data.should be_instance_of(Hash)
171
+ it "should request a view and return an array" do
172
+ RelaxDB::DesignDocument.get(RelaxDB.dd).add_view("simple", "map", map_func).save
173
+ data = RelaxDB.view("simple")
174
+ data.should be_instance_of(Array)
179
175
  end
180
176
 
181
- it "may accept a block" do
182
- RelaxDB::DesignDocument.get("viewtest").add_view("simple", "map", map_func).save
177
+ it "may accept query params" do
178
+ RelaxDB::DesignDocument.get(RelaxDB.dd).add_view("simple", "map", map_func).save
183
179
  RelaxDB.db.put("x", {}.to_json)
184
180
  RelaxDB.db.put("y", {}.to_json)
185
- data = RelaxDB.view("viewtest", "simple") { |q| q.key("x") }
186
- data["rows"].size.should == 1
181
+ res = RelaxDB.view "simple", :key => "x"
182
+ res.first._id.should == "x"
187
183
  end
188
184
 
189
185
  it "should be queryable with a multi key post" do
186
+ Primitives.view_by :num
187
+
190
188
  5.times { |i| Primitives.new(:num => i).save }
191
- # Create the view
192
- Primitives.all.sorted_by(:num)
193
- resp = RelaxDB.view("Primitives", "all_sorted_by_num") do |q|
194
- q.keys([0, 4])
195
- q.reduce(false).group(true) # group invocation should hopefully be temporary
196
- end
197
- RelaxDB.instantiate(resp).map{ |p| p.num }.should == [0, 4]
189
+ Primitives.by_num
190
+ result = RelaxDB.view "Primitives_by_num", :keys => [0, 4], :reduce => false
191
+ result.map{ |p| p.num }.should == [0, 4]
198
192
  end
199
193
 
194
+ it "should return nil for a reduce view with no results" do
195
+ Primitives.view_by :num
196
+ RelaxDB.view("Primitives_by_num", :reduce => true).should be_nil
197
+ end
198
+
199
+ it "should return a single value for a reduce view with a single result" do
200
+ Primitives.view_by :num
201
+ Primitives.new(:num => :x).save!
202
+ RelaxDB.view("Primitives_by_num", :reduce => true).should == 1
203
+ end
204
+
205
+ it "should return an array for a reduce view with multiple results" do
206
+ Primitives.view_by :num
207
+ 2.times { |i| Primitives.new(:num => i).save! }
208
+ res = RelaxDB.view("Primitives_by_num", :reduce => true, :group => true)
209
+ res.should be_an_instance_of(Array)
210
+ res.size.should == 2
211
+ end
212
+
213
+
200
214
  end
201
215
 
202
216
  describe ".merge" do
@@ -220,6 +234,51 @@ describe RelaxDB do
220
234
 
221
235
  end
222
236
 
237
+ describe "create_views disabled" do
238
+
239
+ before(:each) do
240
+ create_test_db
241
+ RelaxDB.enable_view_creation false
242
+
243
+ class CvdBar < RelaxDB::Document
244
+ view_by :foo
245
+ has_one :foo1
246
+ has_many :foon
247
+ references_many :foor
248
+ end
249
+ end
250
+
251
+ it "should not create any views" do
252
+ dd = RelaxDB::DesignDocument.get "spec_doc"
253
+ dd.data["views"].should be_nil
254
+ end
255
+
256
+ end
257
+
258
+ describe "create_views enabled" do
259
+
260
+ before(:each) do
261
+ create_test_db
262
+
263
+ class CveBar < RelaxDB::Document
264
+ view_by :foo
265
+ has_one :foo1
266
+ has_many :foon
267
+ references_many :foor
268
+ end
269
+ end
270
+
271
+ it "should create all views" do
272
+ dd = RelaxDB::DesignDocument.get "spec_doc"
273
+ dd.data["views"]["CveBar_all"].should be
274
+ dd.data["views"]["CveBar_by_foo"].should be
275
+ dd.data["views"]["CveBar_foo1"].should be
276
+ dd.data["views"]["CveBar_foon"].should be
277
+ dd.data["views"]["CveBar_foor"].should be
278
+ end
279
+
280
+ end
281
+
223
282
  # if caching is added
224
283
  # it "should offer an example where behaviour is different with caching enabled and caching disabled"
225
284
 
data/spec/spec_helper.rb CHANGED
@@ -8,3 +8,37 @@ end
8
8
 
9
9
  $:.unshift(File.dirname(__FILE__) + '/../lib')
10
10
  require 'relaxdb'
11
+
12
+ def setup_test_db
13
+ # RelaxDB.configure :host => "localhost", :port => 5984, :design_doc => "spec_doc", :logger => Logger.new(STDOUT)
14
+ RelaxDB.configure :host => "localhost", :port => 5984, :design_doc => "spec_doc"
15
+
16
+ RelaxDB.delete_db "relaxdb_spec" rescue "ok"
17
+ RelaxDB.use_db "relaxdb_spec"
18
+ begin
19
+ RelaxDB.replicate_db "relaxdb_spec_base", "relaxdb_spec"
20
+ RelaxDB.enable_view_creation
21
+ rescue => e
22
+ puts "\n===== Run rake create_base_db before the first spec run ====="
23
+ puts
24
+ exit!
25
+ end
26
+ end
27
+
28
+ def create_test_db params = {}
29
+ defaults = {:host => "localhost", :port => 5984, :design_doc => "spec_doc"}
30
+ RelaxDB.configure defaults.merge(params)
31
+
32
+ RelaxDB.delete_db "relaxdb_spec" rescue "ok"
33
+ RelaxDB.use_db "relaxdb_spec"
34
+ RelaxDB.enable_view_creation
35
+ end
36
+
37
+ def create_base_db
38
+ RelaxDB.configure :host => "localhost", :port => 5984, :design_doc => "spec_doc"
39
+ RelaxDB.delete_db "relaxdb_spec_base" rescue "ok"
40
+ RelaxDB.use_db "relaxdb_spec_base"
41
+ RelaxDB.enable_view_creation
42
+ require File.dirname(__FILE__) + '/spec_models.rb'
43
+ puts "Created relaxdb_spec_base"
44
+ end