couch_crumbs 0.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/History.txt +4 -0
- data/Manifest.txt +29 -0
- data/README.rdoc +131 -0
- data/Rakefile +37 -0
- data/lib/core_ext/array.rb +9 -0
- data/lib/couch_crumbs/database.rb +68 -0
- data/lib/couch_crumbs/design.rb +129 -0
- data/lib/couch_crumbs/document.rb +471 -0
- data/lib/couch_crumbs/json/all.json +5 -0
- data/lib/couch_crumbs/json/children.json +5 -0
- data/lib/couch_crumbs/json/design.json +5 -0
- data/lib/couch_crumbs/json/simple.json +5 -0
- data/lib/couch_crumbs/query.rb +95 -0
- data/lib/couch_crumbs/server.rb +45 -0
- data/lib/couch_crumbs/view.rb +73 -0
- data/lib/couch_crumbs.rb +45 -0
- data/script/console +11 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/core_ext/array_spec.rb +21 -0
- data/spec/couch_crumbs/database_spec.rb +69 -0
- data/spec/couch_crumbs/design_spec.rb +103 -0
- data/spec/couch_crumbs/document_spec.rb +473 -0
- data/spec/couch_crumbs/server_spec.rb +63 -0
- data/spec/couch_crumbs/view_spec.rb +41 -0
- data/spec/couch_crumbs_spec.rb +18 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +20 -0
- data/tasks/rspec.rake +21 -0
- metadata +105 -0
@@ -0,0 +1,473 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
module CouchCrumbs
|
4
|
+
|
5
|
+
describe Document do
|
6
|
+
|
7
|
+
describe "(class)" do
|
8
|
+
|
9
|
+
describe "#database" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@database = Person.database
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return the active class-level database (or a default)" do
|
16
|
+
@database.name.should eql(CouchCrumbs::default_database.name)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#use_database" do
|
22
|
+
|
23
|
+
before do
|
24
|
+
@address = Database.new(:name => "alternate_database")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow class specific databases" do
|
28
|
+
Person.database.name.should eql(CouchCrumbs::default_database.name)
|
29
|
+
|
30
|
+
Person.use_database(@address.name)
|
31
|
+
|
32
|
+
Person.database.name.should eql(@address.name)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should allow class specific databases" do
|
36
|
+
Address.new.database.name.should eql(@address.name)
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
Person.use_database(CouchCrumbs::default_database.name)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#property" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
@person = Person.create!(:name => "Sleepy")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should add a named property" do
|
52
|
+
Person.properties.should include(:name)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should add a named property accessor" do
|
56
|
+
@person.name.should eql("Sleepy")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should persist named properties" do
|
60
|
+
Person.get!(@person.id).name.should eql("Sleepy")
|
61
|
+
end
|
62
|
+
|
63
|
+
after do
|
64
|
+
@person.destroy!
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#timestamps!" do
|
70
|
+
|
71
|
+
it "should add created_at and updated_at properties" do
|
72
|
+
[:created_at, :updated_at].each do |property|
|
73
|
+
Person.properties.should include(property)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#design_doc" do
|
80
|
+
|
81
|
+
it "should return the design doc for the given class" do
|
82
|
+
Person.design_doc.should be_kind_of(Design)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "views" do
|
88
|
+
|
89
|
+
it "should return an array of all views defined for this class" do
|
90
|
+
Person.views.should be_kind_of(Array)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#doc_view" do
|
96
|
+
|
97
|
+
before do
|
98
|
+
@steve = Person.create!(:name => "Steve")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should create an appropriate view" do
|
102
|
+
Person.by_name.collect{ |p| p.rev }.should include(@steve.rev)
|
103
|
+
end
|
104
|
+
|
105
|
+
after do
|
106
|
+
@steve.destroy!
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#custom_view" do
|
112
|
+
|
113
|
+
before do
|
114
|
+
@steve = Person.create!(:name => "Steve", :title => "CEO")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should create an appropriate advanced docs view" do
|
118
|
+
Person.title.collect{ |p| p.title }.should include(@steve.title)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should create an appropriate advanced values view" do
|
122
|
+
Person.count.should be_kind_of(Integer)
|
123
|
+
end
|
124
|
+
|
125
|
+
after do
|
126
|
+
@steve.destroy!
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#create!" do
|
132
|
+
|
133
|
+
it "should create a new document" do
|
134
|
+
@person = Person.create!
|
135
|
+
|
136
|
+
@person.id.should_not be_empty
|
137
|
+
@person.rev.should_not be_empty
|
138
|
+
@person.should be_kind_of(Person)
|
139
|
+
@person.created_at.strftime("%Y-%m-%d %H:%M").should eql(Time.now.strftime("%Y-%m-%d %H:%M"))
|
140
|
+
end
|
141
|
+
|
142
|
+
after do
|
143
|
+
@person.destroy!
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#parent_document" do
|
149
|
+
|
150
|
+
before do
|
151
|
+
@person = Person.create!
|
152
|
+
|
153
|
+
@address = Address.create!
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should add a parent_id property" do
|
157
|
+
Address.properties.should include(:person_parent_id)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should add a parent accessor" do
|
161
|
+
@address.should respond_to(:person)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should add a parent= accessor" do
|
165
|
+
@address.should respond_to(:person=)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should raise an error if parent has not been saved" do
|
169
|
+
lambda do
|
170
|
+
@address.person = Person.new
|
171
|
+
end.should raise_error
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should set the parent document" do
|
175
|
+
@address.person = @person
|
176
|
+
|
177
|
+
@address.save!
|
178
|
+
|
179
|
+
@address.person.id.should eql(@person.id)
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "#child_document" do
|
185
|
+
|
186
|
+
before do
|
187
|
+
@person = Person.new
|
188
|
+
|
189
|
+
@address = Address.new
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should add a model_name_id property to parent class" do
|
193
|
+
Person.properties.should include(:address_child_id)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should add a child accessor" do
|
197
|
+
@person.should respond_to(:address)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should add a child= accessor" do
|
201
|
+
@person.should respond_to(:address=)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should set the child document" do
|
205
|
+
@person.save!
|
206
|
+
@address.save!
|
207
|
+
|
208
|
+
@person.address = @address
|
209
|
+
|
210
|
+
@person.address.id.should eql(@address.id)
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "#child_documents" do
|
216
|
+
|
217
|
+
before do
|
218
|
+
@person = Person.create!(:name => "Steve")
|
219
|
+
@project = Project.create!(:name => "Website Review")
|
220
|
+
3.times do
|
221
|
+
Project.create!(:name => rand(1_000_000).to_s)
|
222
|
+
end
|
223
|
+
|
224
|
+
@project.person = @person
|
225
|
+
|
226
|
+
@project.save!
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should add an accessor for children" do
|
230
|
+
@person.should respond_to(:projects)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should add a child" do
|
234
|
+
@person.projects.collect{ |p| p.rev }.should eql([@project.rev])
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should add a #add_child method" do
|
238
|
+
@person.should respond_to(:add_project)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should add an accessor for the parent" do
|
242
|
+
@project.should respond_to(:person)
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should add an accessor to set the parent" do
|
246
|
+
@project.should respond_to(:person=)
|
247
|
+
end
|
248
|
+
|
249
|
+
after(:each) do
|
250
|
+
@person.destroy!
|
251
|
+
@project.destroy!
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "(instance)" do
|
259
|
+
|
260
|
+
describe "#initialize" do
|
261
|
+
|
262
|
+
before do
|
263
|
+
@person = Person.new
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should have an id" do
|
267
|
+
@person.id.should match(/[a-z0-9]{32}/i)
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should have a type" do
|
271
|
+
@person.crumb_type.should eql("person")
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
describe "#save!" do
|
277
|
+
|
278
|
+
before do
|
279
|
+
@person = Person.new
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should save a document to a database" do
|
283
|
+
@person.save!.should be_true
|
284
|
+
@person.updated_at.strftime("%Y-%m-%d %H:%M").should eql(Time.now.strftime("%Y-%m-%d %H:%M"))
|
285
|
+
end
|
286
|
+
|
287
|
+
after do
|
288
|
+
@person.destroy!
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "#update_attributes!" do
|
294
|
+
|
295
|
+
before do
|
296
|
+
@person = Person.create!(:name => "one")
|
297
|
+
|
298
|
+
@person.update_attributes!(:name => "two")
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should update the named properties" do
|
302
|
+
Person.get!(@person.id).name.should eql("two")
|
303
|
+
end
|
304
|
+
|
305
|
+
after do
|
306
|
+
@person.destroy!
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
describe "#new_document?" do
|
312
|
+
|
313
|
+
before do
|
314
|
+
@person = Person.new
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should return true prior to a document being saved" do
|
318
|
+
@person.new_document?.should be_true
|
319
|
+
end
|
320
|
+
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "#destroy!" do
|
324
|
+
|
325
|
+
before do
|
326
|
+
@person = Person.create!
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should destroy document" do
|
330
|
+
@person.destroy!.should be_true
|
331
|
+
@person.frozen?.should be_true
|
332
|
+
|
333
|
+
lambda do
|
334
|
+
Person.get!(@person.id)
|
335
|
+
end.should raise_error(RestClient::ResourceNotFound)
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "(callbacks)" do
|
343
|
+
|
344
|
+
before(:each) do
|
345
|
+
@steve = Person.new
|
346
|
+
|
347
|
+
# Remove the #freeze method to allow specs to run.
|
348
|
+
@steve.stub!(:freeze)
|
349
|
+
end
|
350
|
+
|
351
|
+
describe "#after_initialize" do
|
352
|
+
|
353
|
+
it "should be called" do
|
354
|
+
@steve.callbacks.should include(:after_initialize)
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "#before_create" do
|
360
|
+
|
361
|
+
before do
|
362
|
+
@bill = Person.create!
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should be called" do
|
366
|
+
@bill.callbacks.should include(:before_create)
|
367
|
+
end
|
368
|
+
|
369
|
+
after do
|
370
|
+
@bill.destroy!
|
371
|
+
end
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
describe "#after_create" do
|
376
|
+
|
377
|
+
before do
|
378
|
+
@bill = Person.create!
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should be called" do
|
382
|
+
@bill.callbacks.should include(:after_create)
|
383
|
+
end
|
384
|
+
|
385
|
+
after do
|
386
|
+
@bill.destroy!
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
describe "#before_save" do
|
392
|
+
|
393
|
+
before do
|
394
|
+
@steve.save!
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should be called" do
|
398
|
+
@steve.callbacks.should include(:before_save)
|
399
|
+
end
|
400
|
+
|
401
|
+
after do
|
402
|
+
@steve.destroy!
|
403
|
+
end
|
404
|
+
|
405
|
+
end
|
406
|
+
|
407
|
+
describe "#after_save" do
|
408
|
+
|
409
|
+
before do
|
410
|
+
@steve.save!
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should be called" do
|
414
|
+
@steve.callbacks.should include(:after_save)
|
415
|
+
end
|
416
|
+
|
417
|
+
after do
|
418
|
+
@steve.destroy!
|
419
|
+
end
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
describe "#before_destroy" do
|
424
|
+
|
425
|
+
before do
|
426
|
+
@steve.destroy!
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should be called" do
|
430
|
+
@steve.callbacks.should include(:before_destroy)
|
431
|
+
end
|
432
|
+
|
433
|
+
end
|
434
|
+
|
435
|
+
describe "#after_destroy" do
|
436
|
+
|
437
|
+
before do
|
438
|
+
@steve.destroy!
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should be called" do
|
442
|
+
@steve.callbacks.should include(:after_destroy)
|
443
|
+
end
|
444
|
+
|
445
|
+
end
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
describe "(default views)" do
|
450
|
+
|
451
|
+
describe "#all" do
|
452
|
+
|
453
|
+
before do
|
454
|
+
Person.all.destroy!
|
455
|
+
|
456
|
+
@person = Person.create!
|
457
|
+
end
|
458
|
+
|
459
|
+
it "should return all documents of a certain type" do
|
460
|
+
Person.all.collect{ |p| p.id }.should eql([@person.id])
|
461
|
+
end
|
462
|
+
|
463
|
+
after do
|
464
|
+
@person.destroy!
|
465
|
+
end
|
466
|
+
|
467
|
+
end
|
468
|
+
|
469
|
+
end
|
470
|
+
|
471
|
+
end
|
472
|
+
|
473
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
module CouchCrumbs
|
4
|
+
|
5
|
+
describe Server do
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
|
9
|
+
it "should return a server connection" do
|
10
|
+
Server.new.should be_kind_of(Server)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should support an optional :uri argument" do
|
14
|
+
Server.new(:uri => Server::DEFAULT_URI).should be_kind_of(Server)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#status" do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@server = Server.new
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have the current status" do
|
26
|
+
@server.status.should_not be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#databases" do
|
32
|
+
|
33
|
+
before do
|
34
|
+
@server = Server.new
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return an array of databases" do
|
38
|
+
@server.databases.each do |database|
|
39
|
+
database.should be_kind_of(Database)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#uuids" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
@server = Server.new
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return a single UUID" do
|
52
|
+
@server.uuids.should match(/[a-z0-9]{32}/i)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return multiple UUIDs" do
|
56
|
+
@server.uuids(10).size.should eql(10)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
module CouchCrumbs
|
4
|
+
|
5
|
+
describe View do
|
6
|
+
|
7
|
+
describe "#simple_json" do
|
8
|
+
|
9
|
+
it "should return a simple JSON view" do
|
10
|
+
View.simple_json(Person.crumb_type, :name).should be_kind_of(String)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#advanced_json" do
|
16
|
+
|
17
|
+
before do
|
18
|
+
@view = View.advanced_json(File.join("lib", "couch_crumbs", "json", "all.json"), :crumb_type => Person.crumb_type)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return advanced raw JSON" do
|
22
|
+
@view.should be_kind_of(String)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#has_reduce?" do
|
28
|
+
|
29
|
+
before do
|
30
|
+
@view = Person.design_doc.views(:name => "count")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return true if the view has a reduce function" do
|
34
|
+
@view.has_reduce?.should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe CouchCrumbs do
|
4
|
+
|
5
|
+
describe "#connect" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
CouchCrumbs.connect.should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should attempt to connect to a default server and database" do
|
12
|
+
CouchCrumbs.default_server.should be_kind_of(CouchCrumbs::Server)
|
13
|
+
CouchCrumbs.default_database.should be_kind_of(CouchCrumbs::Database)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
require "ruby-debug"
|
5
|
+
|
6
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
7
|
+
|
8
|
+
require "couch_crumbs.rb"
|
9
|
+
|
10
|
+
# Connect to the local/remote CouchDB server
|
11
|
+
CouchCrumbs::connect
|
12
|
+
|
13
|
+
# Bring in the fixtures
|
14
|
+
fixture_path = File.join(File.dirname(__FILE__), "fixtures")
|
15
|
+
|
16
|
+
$:.unshift(fixture_path)
|
17
|
+
|
18
|
+
Dir["#{ fixture_path }/*.rb"].each do |path|
|
19
|
+
require path
|
20
|
+
end
|
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#begin
|
2
|
+
# require 'spec'
|
3
|
+
#rescue LoadError
|
4
|
+
# require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
+
# require 'spec'
|
6
|
+
#end
|
7
|
+
#begin
|
8
|
+
# require 'spec/rake/spectask'
|
9
|
+
#rescue LoadError
|
10
|
+
# puts <<-EOS
|
11
|
+
#To use rspec for testing you must install rspec gem:
|
12
|
+
# gem install rspec
|
13
|
+
#EOS
|
14
|
+
# exit(0)
|
15
|
+
#end
|
16
|
+
#
|
17
|
+
#desc "Run the specs under spec/models"
|
18
|
+
#Spec::Rake::SpecTask.new do |t|
|
19
|
+
# t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
# t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
#end
|