juozasg-couchrest 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/LICENSE +176 -0
  2. data/README.rdoc +67 -0
  3. data/Rakefile +86 -0
  4. data/THANKS +15 -0
  5. data/bin/couchapp +58 -0
  6. data/bin/couchdir +20 -0
  7. data/bin/couchview +48 -0
  8. data/examples/model/example.rb +138 -0
  9. data/examples/word_count/markov +38 -0
  10. data/examples/word_count/views/books/chunked-map.js +3 -0
  11. data/examples/word_count/views/books/united-map.js +1 -0
  12. data/examples/word_count/views/markov/chain-map.js +6 -0
  13. data/examples/word_count/views/markov/chain-reduce.js +7 -0
  14. data/examples/word_count/views/word_count/count-map.js +6 -0
  15. data/examples/word_count/views/word_count/count-reduce.js +3 -0
  16. data/examples/word_count/word_count.rb +67 -0
  17. data/examples/word_count/word_count_query.rb +39 -0
  18. data/lib/couchrest/commands/generate.rb +71 -0
  19. data/lib/couchrest/commands/push.rb +103 -0
  20. data/lib/couchrest/core/database.rb +173 -0
  21. data/lib/couchrest/core/design.rb +89 -0
  22. data/lib/couchrest/core/document.rb +60 -0
  23. data/lib/couchrest/core/model.rb +557 -0
  24. data/lib/couchrest/core/server.rb +51 -0
  25. data/lib/couchrest/core/view.rb +4 -0
  26. data/lib/couchrest/helper/file_manager.rb +317 -0
  27. data/lib/couchrest/helper/pager.rb +103 -0
  28. data/lib/couchrest/helper/streamer.rb +44 -0
  29. data/lib/couchrest/helper/templates/bar.txt +11 -0
  30. data/lib/couchrest/helper/templates/example-map.js +8 -0
  31. data/lib/couchrest/helper/templates/example-reduce.js +10 -0
  32. data/lib/couchrest/helper/templates/index.html +26 -0
  33. data/lib/couchrest/monkeypatches.rb +24 -0
  34. data/lib/couchrest.rb +125 -0
  35. data/spec/couchapp_spec.rb +87 -0
  36. data/spec/couchrest/core/couchrest_spec.rb +191 -0
  37. data/spec/couchrest/core/database_spec.rb +478 -0
  38. data/spec/couchrest/core/design_spec.rb +131 -0
  39. data/spec/couchrest/core/document_spec.rb +96 -0
  40. data/spec/couchrest/core/model_spec.rb +660 -0
  41. data/spec/couchrest/helpers/file_manager_spec.rb +203 -0
  42. data/spec/couchrest/helpers/pager_spec.rb +122 -0
  43. data/spec/couchrest/helpers/streamer_spec.rb +23 -0
  44. data/spec/fixtures/attachments/couchdb.png +0 -0
  45. data/spec/fixtures/attachments/test.html +11 -0
  46. data/spec/fixtures/views/lib.js +3 -0
  47. data/spec/fixtures/views/test_view/lib.js +3 -0
  48. data/spec/fixtures/views/test_view/only-map.js +4 -0
  49. data/spec/fixtures/views/test_view/test-map.js +3 -0
  50. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  51. data/spec/spec.opts +6 -0
  52. data/spec/spec_helper.rb +14 -0
  53. data/utils/remap.rb +27 -0
  54. data/utils/subset.rb +30 -0
  55. metadata +154 -0
@@ -0,0 +1,660 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ class Basic < CouchRest::Model
4
+ end
5
+
6
+ class BasicWithValidation < CouchRest::Model
7
+
8
+ before :save, :validate
9
+ key_accessor :name
10
+
11
+ def validate
12
+ throw(:halt, false) unless name
13
+ end
14
+ end
15
+
16
+ class WithTemplate < CouchRest::Model
17
+ unique_id do |model|
18
+ model['important-field']
19
+ end
20
+ set_default({
21
+ :preset => 'value',
22
+ 'more-template' => [1,2,3]
23
+ })
24
+ key_accessor :preset
25
+ end
26
+
27
+ class Question < CouchRest::Model
28
+ key_accessor :q, :a
29
+ couchrest_type = 'Question'
30
+ end
31
+
32
+ class Person < CouchRest::Model
33
+ key_accessor :name
34
+ def last_name
35
+ name.last
36
+ end
37
+ end
38
+
39
+ class Course < CouchRest::Model
40
+ key_accessor :title
41
+ cast :questions, :as => ['Question']
42
+ cast :professor, :as => 'Person'
43
+ view_by :title
44
+ view_by :dept, :ducktype => true
45
+ end
46
+
47
+ class Article < CouchRest::Model
48
+ use_database CouchRest.database!('http://localhost:5984/couchrest-model-test')
49
+ unique_id :slug
50
+
51
+ view_by :date, :descending => true
52
+ view_by :user_id, :date
53
+
54
+ view_by :tags,
55
+ :map =>
56
+ "function(doc) {
57
+ if (doc['couchrest-type'] == 'Article' && doc.tags) {
58
+ doc.tags.forEach(function(tag){
59
+ emit(tag, 1);
60
+ });
61
+ }
62
+ }",
63
+ :reduce =>
64
+ "function(keys, values, rereduce) {
65
+ return sum(values);
66
+ }"
67
+
68
+ key_writer :date
69
+ key_reader :slug, :created_at, :updated_at
70
+ key_accessor :title, :tags
71
+
72
+ timestamps!
73
+
74
+ before(:create, :generate_slug_from_title)
75
+ def generate_slug_from_title
76
+ self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'')
77
+ end
78
+ end
79
+
80
+ describe CouchRest::Model do
81
+ before(:all) do
82
+ @cr = CouchRest.new(COUCHHOST)
83
+ @db = @cr.database(TESTDB)
84
+ @db.delete! rescue nil
85
+ @db = @cr.create_db(TESTDB) rescue nil
86
+ @adb = @cr.database('couchrest-model-test')
87
+ @adb.delete! rescue nil
88
+ CouchRest.database!('http://localhost:5984/couchrest-model-test')
89
+ CouchRest::Model.default_database = CouchRest.database!('http://localhost:5984/couchrest-test')
90
+ end
91
+
92
+ it "should use the default database" do
93
+ Basic.database.info['db_name'].should == 'couchrest-test'
94
+ end
95
+
96
+ it "should override the default db" do
97
+ Article.database.info['db_name'].should == 'couchrest-model-test'
98
+ end
99
+
100
+ describe "a new model" do
101
+ it "should be a new_record" do
102
+ @obj = Basic.new
103
+ @obj.rev.should be_nil
104
+ @obj.should be_a_new_record
105
+ end
106
+ end
107
+
108
+ describe "a model with key_accessors" do
109
+ it "should allow reading keys" do
110
+ @art = Article.new
111
+ @art['title'] = 'My Article Title'
112
+ @art.title.should == 'My Article Title'
113
+ end
114
+ it "should allow setting keys" do
115
+ @art = Article.new
116
+ @art.title = 'My Article Title'
117
+ @art['title'].should == 'My Article Title'
118
+ end
119
+ end
120
+
121
+ describe "a model with key_writers" do
122
+ it "should allow setting keys" do
123
+ @art = Article.new
124
+ t = Time.now
125
+ @art.date = t
126
+ @art['date'].should == t
127
+ end
128
+ it "should not allow reading keys" do
129
+ @art = Article.new
130
+ t = Time.now
131
+ @art.date = t
132
+ lambda{@art.date}.should raise_error
133
+ end
134
+ end
135
+
136
+ describe "a model with key_readers" do
137
+ it "should allow reading keys" do
138
+ @art = Article.new
139
+ @art['slug'] = 'my-slug'
140
+ @art.slug.should == 'my-slug'
141
+ end
142
+ it "should not allow setting keys" do
143
+ @art = Article.new
144
+ lambda{@art.slug = 'My Article Title'}.should raise_error
145
+ end
146
+ end
147
+
148
+ describe "update attributes without saving" do
149
+ before(:each) do
150
+ a = Article.get "big-bad-danger" rescue nil
151
+ a.destroy if a
152
+ @art = Article.new(:title => "big bad danger")
153
+ @art.save
154
+ end
155
+ it "should work for attribute= methods" do
156
+ @art['title'].should == "big bad danger"
157
+ @art.update_attributes('date' => Time.now, :title => "super danger")
158
+ @art['title'].should == "super danger"
159
+ end
160
+
161
+ it "should flip out if an attribute= method is missing" do
162
+ lambda {
163
+ @art.update_attributes('slug' => "new-slug", :title => "super danger")
164
+ }.should raise_error
165
+ end
166
+
167
+ it "should not change other attributes if there is an error" do
168
+ lambda {
169
+ @art.update_attributes('slug' => "new-slug", :title => "super danger")
170
+ }.should raise_error
171
+ @art['title'].should == "big bad danger"
172
+ end
173
+
174
+ end
175
+
176
+ describe "update attributes" do
177
+ before(:each) do
178
+ a = Article.get "big-bad-danger" rescue nil
179
+ a.destroy if a
180
+ @art = Article.new(:title => "big bad danger")
181
+ @art.save
182
+ end
183
+ it "should save" do
184
+ @art['title'].should == "big bad danger"
185
+ @art.update_attributes('date' => Time.now, :title => "super danger")
186
+ loaded = Article.get @art.id
187
+ loaded['title'].should == "super danger"
188
+ end
189
+ end
190
+
191
+ describe "a model with template values" do
192
+ before(:all) do
193
+ @tmpl = WithTemplate.new
194
+ end
195
+ it "should have fields set when new" do
196
+ @tmpl.preset.should == 'value'
197
+ end
198
+ end
199
+
200
+ describe "getting a model" do
201
+ before(:all) do
202
+ @art = Article.new(:title => 'All About Getting')
203
+ @art.save
204
+ end
205
+ it "should load and instantiate it" do
206
+ foundart = Article.get @art.id
207
+ foundart.title.should == "All About Getting"
208
+ end
209
+ end
210
+
211
+ describe "getting a model with a subobjects array" do
212
+ before(:all) do
213
+ course_doc = {
214
+ "title" => "Metaphysics 200",
215
+ "questions" => [
216
+ {
217
+ "q" => "Carve the ___ of reality at the ___.",
218
+ "a" => ["beast","joints"]
219
+ },{
220
+ "q" => "Who layed the smack down on Leibniz's Law?",
221
+ "a" => "Willard Van Orman Quine"
222
+ }
223
+ ]
224
+ }
225
+ r = Course.database.save course_doc
226
+ @course = Course.get r['id']
227
+ end
228
+ it "should load the course" do
229
+ @course.title.should == "Metaphysics 200"
230
+ end
231
+ it "should instantiate them as such" do
232
+ @course["questions"][0].a[0].should == "beast"
233
+ end
234
+ end
235
+
236
+ describe "finding all instances of a model" do
237
+ before(:all) do
238
+ WithTemplate.new('important-field' => '1').save
239
+ WithTemplate.new('important-field' => '2').save
240
+ WithTemplate.new('important-field' => '3').save
241
+ WithTemplate.new('important-field' => '4').save
242
+ end
243
+ it "should make the design doc" do
244
+ WithTemplate.all
245
+ d = WithTemplate.design_doc
246
+ d['views']['all']['map'].should include('WithTemplate')
247
+ end
248
+ it "should find all" do
249
+ rs = WithTemplate.all
250
+ rs.length.should == 4
251
+ end
252
+ end
253
+
254
+ describe "finding the first instance of a model" do
255
+ before(:all) do
256
+ WithTemplate.new('important-field' => '1').save
257
+ WithTemplate.new('important-field' => '2').save
258
+ WithTemplate.new('important-field' => '3').save
259
+ WithTemplate.new('important-field' => '4').save
260
+ end
261
+ it "should make the design doc" do
262
+ WithTemplate.all
263
+ d = WithTemplate.design_doc
264
+ d['views']['all']['map'].should include('WithTemplate')
265
+ end
266
+ it "should find first" do
267
+ rs = WithTemplate.first
268
+ rs['important-field'].should == "1"
269
+ end
270
+ it "should return nil if no instances are found" do
271
+ WithTemplate.all.each {|obj| obj.destroy }
272
+ WithTemplate.first.should be_nil
273
+ end
274
+ end
275
+
276
+ describe "getting a model with a subobject field" do
277
+ before(:all) do
278
+ course_doc = {
279
+ "title" => "Metaphysics 410",
280
+ "professor" => {
281
+ "name" => ["Mark", "Hinchliff"]
282
+ }
283
+ }
284
+ r = Course.database.save course_doc
285
+ @course = Course.get r['id']
286
+ end
287
+ it "should load the course" do
288
+ @course["professor"]["name"][1].should == "Hinchliff"
289
+ end
290
+ it "should instantiate the professor as a person" do
291
+ @course['professor'].last_name.should == "Hinchliff"
292
+ end
293
+ end
294
+
295
+ describe "saving a model" do
296
+ before(:all) do
297
+ @obj = Basic.new
298
+ @obj.save.should == true
299
+ end
300
+
301
+ it "should save the doc" do
302
+ doc = @obj.database.get @obj.id
303
+ doc['_id'].should == @obj.id
304
+ end
305
+
306
+ it "should be set for resaving" do
307
+ rev = @obj.rev
308
+ @obj['another-key'] = "some value"
309
+ @obj.save
310
+ @obj.rev.should_not == rev
311
+ end
312
+
313
+ it "should set the id" do
314
+ @obj.id.should be_an_instance_of(String)
315
+ end
316
+
317
+ it "should set the type" do
318
+ @obj['couchrest-type'].should == 'Basic'
319
+ end
320
+ end
321
+
322
+ describe "saving a model with validation hooks added as extlib" do
323
+ before(:all) do
324
+ @obj = BasicWithValidation.new
325
+ end
326
+
327
+ it "save should return false is the model doesn't save as expected" do
328
+ @obj.save.should be_false
329
+ end
330
+
331
+ it "save! should raise and exception if the model doesn't save" do
332
+ lambda{ @obj.save!}.should raise_error("#{@obj.inspect} failed to save")
333
+ end
334
+
335
+ end
336
+
337
+ describe "saving a model with a unique_id configured" do
338
+ before(:each) do
339
+ @art = Article.new
340
+ @old = Article.database.get('this-is-the-title') rescue nil
341
+ Article.database.delete(@old) if @old
342
+ end
343
+
344
+ it "should be a new document" do
345
+ @art.should be_a_new_document
346
+ @art.title.should be_nil
347
+ end
348
+
349
+ it "should require the title" do
350
+ lambda{@art.save}.should raise_error
351
+ @art.title = 'This is the title'
352
+ @art.save.should == true
353
+ end
354
+
355
+ it "should not change the slug on update" do
356
+ @art.title = 'This is the title'
357
+ @art.save.should == true
358
+ @art.title = 'new title'
359
+ @art.save.should == true
360
+ @art.slug.should == 'this-is-the-title'
361
+ end
362
+
363
+ it "should raise an error when the slug is taken" do
364
+ @art.title = 'This is the title'
365
+ @art.save.should == true
366
+ @art2 = Article.new(:title => 'This is the title!')
367
+ lambda{@art2.save}.should raise_error
368
+ end
369
+
370
+ it "should set the slug" do
371
+ @art.title = 'This is the title'
372
+ @art.save.should == true
373
+ @art.slug.should == 'this-is-the-title'
374
+ end
375
+
376
+ it "should set the id" do
377
+ @art.title = 'This is the title'
378
+ @art.save.should == true
379
+ @art.id.should == 'this-is-the-title'
380
+ end
381
+ end
382
+
383
+ describe "saving a model with a unique_id lambda" do
384
+ before(:each) do
385
+ @templated = WithTemplate.new
386
+ @old = WithTemplate.get('very-important') rescue nil
387
+ @old.destroy if @old
388
+ end
389
+
390
+ it "should require the field" do
391
+ lambda{@templated.save}.should raise_error
392
+ @templated['important-field'] = 'very-important'
393
+ @templated.save.should == true
394
+ end
395
+
396
+ it "should save with the id" do
397
+ @templated['important-field'] = 'very-important'
398
+ @templated.save.should == true
399
+ t = WithTemplate.get('very-important')
400
+ t.should == @templated
401
+ end
402
+
403
+ it "should not change the id on update" do
404
+ @templated['important-field'] = 'very-important'
405
+ @templated.save.should == true
406
+ @templated['important-field'] = 'not-important'
407
+ @templated.save.should == true
408
+ t = WithTemplate.get('very-important')
409
+ t.should == @templated
410
+ end
411
+
412
+ it "should raise an error when the id is taken" do
413
+ @templated['important-field'] = 'very-important'
414
+ @templated.save.should == true
415
+ lambda{WithTemplate.new('important-field' => 'very-important').save}.should raise_error
416
+ end
417
+
418
+ it "should set the id" do
419
+ @templated['important-field'] = 'very-important'
420
+ @templated.save.should == true
421
+ @templated.id.should == 'very-important'
422
+ end
423
+ end
424
+
425
+ describe "a model with timestamps" do
426
+ before(:each) do
427
+ oldart = Article.get "saving-this" rescue nil
428
+ oldart.destroy if oldart
429
+ @art = Article.new(:title => "Saving this")
430
+ @art.save
431
+ end
432
+ it "should set the time on create" do
433
+ (Time.now - @art.created_at).should < 2
434
+ foundart = Article.get @art.id
435
+ foundart.created_at.should == foundart.updated_at
436
+ end
437
+ it "should set the time on update" do
438
+ @art.save
439
+ @art.created_at.should < @art.updated_at
440
+ end
441
+ end
442
+
443
+ describe "a model with simple views and a default param" do
444
+ before(:all) do
445
+ written_at = Time.now - 24 * 3600 * 7
446
+ @titles = ["this and that", "also interesting", "more fun", "some junk"]
447
+ @titles.each do |title|
448
+ a = Article.new(:title => title)
449
+ a.date = written_at
450
+ a.save
451
+ written_at += 24 * 3600
452
+ end
453
+ end
454
+
455
+ it "should have a design doc" do
456
+ Article.design_doc["views"]["by_date"].should_not be_nil
457
+ end
458
+
459
+ it "should save the design doc" do
460
+ Article.by_date #rescue nil
461
+ doc = Article.database.get Article.design_doc.id
462
+ doc['views']['by_date'].should_not be_nil
463
+ end
464
+
465
+ it "should return the matching raw view result" do
466
+ view = Article.by_date :raw => true
467
+ view['rows'].length.should == 4
468
+ end
469
+
470
+ it "should not include non-Articles" do
471
+ Article.database.save({"date" => 1})
472
+ view = Article.by_date :raw => true
473
+ view['rows'].length.should == 4
474
+ end
475
+
476
+ it "should return the matching objects (with default argument :descending => true)" do
477
+ articles = Article.by_date
478
+ articles.collect{|a|a.title}.should == @titles.reverse
479
+ end
480
+
481
+ it "should allow you to override default args" do
482
+ articles = Article.by_date :descending => false
483
+ articles.collect{|a|a.title}.should == @titles
484
+ end
485
+ end
486
+
487
+ describe "another model with a simple view" do
488
+ before(:all) do
489
+ Course.database.delete! rescue nil
490
+ @db = @cr.create_db(TESTDB) rescue nil
491
+ %w{aaa bbb ddd eee}.each do |title|
492
+ Course.new(:title => title).save
493
+ end
494
+ end
495
+ it "should make the design doc upon first query" do
496
+ Course.by_title
497
+ doc = Course.design_doc
498
+ doc['views']['all']['map'].should include('Course')
499
+ end
500
+ it "should can query via view" do
501
+ # register methods with method-missing, for local dispatch. method
502
+ # missing lookup table, no heuristics.
503
+ view = Course.view :by_title
504
+ designed = Course.by_title
505
+ view.should == designed
506
+ end
507
+ it "should get them" do
508
+ rs = Course.by_title
509
+ rs.length.should == 4
510
+ end
511
+ it "should yield" do
512
+ courses = []
513
+ rs = Course.by_title # remove me
514
+ Course.view(:by_title) do |course|
515
+ courses << course
516
+ end
517
+ courses[0]["doc"]["title"].should =='aaa'
518
+ end
519
+ end
520
+
521
+
522
+ describe "a ducktype view" do
523
+ before(:all) do
524
+ @id = @db.save({:dept => true})['id']
525
+ end
526
+ it "should setup" do
527
+ duck = Course.get(@id) # from a different db
528
+ duck["dept"].should == true
529
+ end
530
+ it "should make the design doc" do
531
+ @as = Course.by_dept
532
+ @doc = Course.design_doc
533
+ @doc["views"]["by_dept"]["map"].should_not include("couchrest")
534
+ end
535
+ it "should not look for class" do |variable|
536
+ @as = Course.by_dept
537
+ @as[0]['_id'].should == @id
538
+ end
539
+ end
540
+
541
+ describe "a model with a compound key view" do
542
+ before(:all) do
543
+ written_at = Time.now - 24 * 3600 * 7
544
+ @titles = ["uniq one", "even more interesting", "less fun", "not junk"]
545
+ @user_ids = ["quentin", "aaron"]
546
+ @titles.each_with_index do |title,i|
547
+ u = i % 2
548
+ a = Article.new(:title => title, :user_id => @user_ids[u])
549
+ a.date = written_at
550
+ a.save
551
+ written_at += 24 * 3600
552
+ end
553
+ end
554
+ it "should create the design doc" do
555
+ Article.by_user_id_and_date rescue nil
556
+ doc = Article.design_doc
557
+ doc['views']['by_date'].should_not be_nil
558
+ end
559
+ it "should sort correctly" do
560
+ articles = Article.by_user_id_and_date
561
+ articles.collect{|a|a['user_id']}.should == ['aaron', 'aaron', 'quentin',
562
+ 'quentin']
563
+ articles[1].title.should == 'not junk'
564
+ end
565
+ it "should be queryable with couchrest options" do
566
+ articles = Article.by_user_id_and_date :count => 1, :startkey => 'quentin'
567
+ articles.length.should == 1
568
+ articles[0].title.should == "even more interesting"
569
+ end
570
+ end
571
+
572
+ describe "with a custom view" do
573
+ before(:all) do
574
+ @titles = ["very uniq one", "even less interesting", "some fun",
575
+ "really junk", "crazy bob"]
576
+ @tags = ["cool", "lame"]
577
+ @titles.each_with_index do |title,i|
578
+ u = i % 2
579
+ a = Article.new(:title => title, :tags => [@tags[u]])
580
+ a.save
581
+ end
582
+ end
583
+ it "should be available raw" do
584
+ view = Article.by_tags :raw => true
585
+ view['rows'].length.should == 5
586
+ end
587
+
588
+ it "should be default to :reduce => false" do
589
+ ars = Article.by_tags
590
+ ars.first.tags.first.should == 'cool'
591
+ end
592
+
593
+ it "should be raw when reduce is true" do
594
+ view = Article.by_tags :reduce => true, :group => true
595
+ view['rows'].find{|r|r['key'] == 'cool'}['value'].should == 3
596
+ end
597
+ end
598
+
599
+ # TODO: moved to Design, delete
600
+ describe "adding a view" do
601
+ before(:each) do
602
+ Article.by_date
603
+ @design_docs = Article.database.documents :startkey => "_design/",
604
+ :endkey => "_design/\u9999"
605
+ end
606
+ it "should not create a design doc on view definition" do
607
+ Article.view_by :created_at
608
+ newdocs = Article.database.documents :startkey => "_design/",
609
+ :endkey => "_design/\u9999"
610
+ newdocs["rows"].length.should == @design_docs["rows"].length
611
+ end
612
+ it "should create a new design document on view access" do
613
+ Article.view_by :updated_at
614
+ Article.by_updated_at
615
+ newdocs = Article.database.documents :startkey => "_design/",
616
+ :endkey => "_design/\u9999"
617
+ # puts @design_docs.inspect
618
+ # puts newdocs.inspect
619
+ newdocs["rows"].length.should == @design_docs["rows"].length + 1
620
+ end
621
+ end
622
+
623
+ describe "with a lot of designs left around" do
624
+ before(:each) do
625
+ Article.by_date
626
+ Article.view_by :field
627
+ Article.by_field
628
+ end
629
+ it "should clean them up" do
630
+ Article.view_by :stream
631
+ Article.by_stream
632
+ ddocs = Article.all_design_doc_versions
633
+ ddocs["rows"].length.should > 1
634
+ Article.cleanup_design_docs!
635
+ ddocs = Article.all_design_doc_versions
636
+ ddocs["rows"].length.should == 1
637
+ end
638
+ end
639
+
640
+ describe "destroying an instance" do
641
+ before(:each) do
642
+ @obj = Basic.new
643
+ @obj.save.should == true
644
+ end
645
+ it "should return true" do
646
+ result = @obj.destroy
647
+ result.should == true
648
+ end
649
+ it "should be resavable" do
650
+ @obj.destroy
651
+ @obj.rev.should be_nil
652
+ @obj.id.should be_nil
653
+ @obj.save.should == true
654
+ end
655
+ it "should make it go away" do
656
+ @obj.destroy
657
+ lambda{Basic.get(@obj.id)}.should raise_error
658
+ end
659
+ end
660
+ end