samlown-couchrest 0.37.2 → 1.0.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.
Files changed (78) hide show
  1. data/README.md +10 -4
  2. data/Rakefile +1 -1
  3. data/history.txt +8 -0
  4. data/lib/couchrest.rb +27 -49
  5. data/lib/couchrest/{core/database.rb → database.rb} +6 -11
  6. data/lib/couchrest/{core/design.rb → design.rb} +2 -2
  7. data/lib/couchrest/{core/document.rb → document.rb} +1 -1
  8. data/lib/couchrest/helper/attachments.rb +29 -0
  9. data/lib/couchrest/middlewares/logger.rb +3 -3
  10. data/lib/couchrest/monkeypatches.rb +1 -71
  11. data/lib/couchrest/{core/response.rb → response.rb} +0 -0
  12. data/lib/couchrest/{core/rest_api.rb → rest_api.rb} +9 -6
  13. data/lib/couchrest/{core/server.rb → server.rb} +0 -0
  14. data/spec/couchrest/{core/couchrest_spec.rb → couchrest_spec.rb} +16 -3
  15. data/spec/couchrest/{core/database_spec.rb → database_spec.rb} +2 -2
  16. data/spec/couchrest/{core/design_spec.rb → design_spec.rb} +2 -2
  17. data/spec/couchrest/{core/document_spec.rb → document_spec.rb} +1 -1
  18. data/spec/couchrest/{core/server_spec.rb → server_spec.rb} +2 -2
  19. data/spec/spec.opts +0 -1
  20. data/spec/spec_helper.rb +0 -4
  21. metadata +24 -113
  22. data/couchrest.gemspec +0 -183
  23. data/examples/model/example.rb +0 -144
  24. data/lib/couchrest/core/adapters/restclient.rb +0 -35
  25. data/lib/couchrest/core/http_abstraction.rb +0 -48
  26. data/lib/couchrest/core/view.rb +0 -4
  27. data/lib/couchrest/mixins.rb +0 -4
  28. data/lib/couchrest/mixins/attachments.rb +0 -31
  29. data/lib/couchrest/mixins/attribute_protection.rb +0 -74
  30. data/lib/couchrest/mixins/callbacks.rb +0 -532
  31. data/lib/couchrest/mixins/class_proxy.rb +0 -124
  32. data/lib/couchrest/mixins/collection.rb +0 -260
  33. data/lib/couchrest/mixins/design_doc.rb +0 -103
  34. data/lib/couchrest/mixins/document_queries.rb +0 -80
  35. data/lib/couchrest/mixins/extended_attachments.rb +0 -70
  36. data/lib/couchrest/mixins/extended_document_mixins.rb +0 -9
  37. data/lib/couchrest/mixins/properties.rb +0 -154
  38. data/lib/couchrest/mixins/validation.rb +0 -246
  39. data/lib/couchrest/mixins/views.rb +0 -173
  40. data/lib/couchrest/more/casted_array.rb +0 -25
  41. data/lib/couchrest/more/casted_model.rb +0 -58
  42. data/lib/couchrest/more/extended_document.rb +0 -310
  43. data/lib/couchrest/more/property.rb +0 -50
  44. data/lib/couchrest/more/typecast.rb +0 -175
  45. data/lib/couchrest/support/blank.rb +0 -42
  46. data/lib/couchrest/support/rails.rb +0 -42
  47. data/lib/couchrest/validation/auto_validate.rb +0 -157
  48. data/lib/couchrest/validation/contextual_validators.rb +0 -78
  49. data/lib/couchrest/validation/validation_errors.rb +0 -125
  50. data/lib/couchrest/validation/validators/absent_field_validator.rb +0 -74
  51. data/lib/couchrest/validation/validators/confirmation_validator.rb +0 -107
  52. data/lib/couchrest/validation/validators/format_validator.rb +0 -122
  53. data/lib/couchrest/validation/validators/formats/email.rb +0 -66
  54. data/lib/couchrest/validation/validators/formats/url.rb +0 -43
  55. data/lib/couchrest/validation/validators/generic_validator.rb +0 -120
  56. data/lib/couchrest/validation/validators/length_validator.rb +0 -139
  57. data/lib/couchrest/validation/validators/method_validator.rb +0 -89
  58. data/lib/couchrest/validation/validators/numeric_validator.rb +0 -109
  59. data/lib/couchrest/validation/validators/required_field_validator.rb +0 -114
  60. data/spec/couchrest/more/attribute_protection_spec.rb +0 -150
  61. data/spec/couchrest/more/casted_extended_doc_spec.rb +0 -79
  62. data/spec/couchrest/more/casted_model_spec.rb +0 -406
  63. data/spec/couchrest/more/extended_doc_attachment_spec.rb +0 -135
  64. data/spec/couchrest/more/extended_doc_inherited_spec.rb +0 -40
  65. data/spec/couchrest/more/extended_doc_spec.rb +0 -808
  66. data/spec/couchrest/more/extended_doc_subclass_spec.rb +0 -98
  67. data/spec/couchrest/more/extended_doc_view_spec.rb +0 -462
  68. data/spec/couchrest/more/property_spec.rb +0 -628
  69. data/spec/fixtures/more/article.rb +0 -35
  70. data/spec/fixtures/more/card.rb +0 -22
  71. data/spec/fixtures/more/cat.rb +0 -20
  72. data/spec/fixtures/more/course.rb +0 -22
  73. data/spec/fixtures/more/event.rb +0 -8
  74. data/spec/fixtures/more/invoice.rb +0 -17
  75. data/spec/fixtures/more/person.rb +0 -9
  76. data/spec/fixtures/more/question.rb +0 -6
  77. data/spec/fixtures/more/service.rb +0 -12
  78. data/spec/fixtures/more/user.rb +0 -22
@@ -1,40 +0,0 @@
1
- require File.expand_path('../../../spec_helper', __FILE__)
2
-
3
- begin
4
- require 'rubygems' unless ENV['SKIP_RUBYGEMS']
5
- require 'activesupport'
6
- ActiveSupport::JSON.backend = :JSONGem
7
-
8
- class PlainParent
9
- class_inheritable_accessor :foo
10
- self.foo = :bar
11
- end
12
-
13
- class PlainChild < PlainParent
14
- end
15
-
16
- class ExtendedParent < CouchRest::ExtendedDocument
17
- class_inheritable_accessor :foo
18
- self.foo = :bar
19
- end
20
-
21
- class ExtendedChild < ExtendedParent
22
- end
23
-
24
- describe "Using chained inheritance without CouchRest::ExtendedDocument" do
25
- it "should preserve inheritable attributes" do
26
- PlainParent.foo.should == :bar
27
- PlainChild.foo.should == :bar
28
- end
29
- end
30
-
31
- describe "Using chained inheritance with CouchRest::ExtendedDocument" do
32
- it "should preserve inheritable attributes" do
33
- ExtendedParent.foo.should == :bar
34
- ExtendedChild.foo.should == :bar
35
- end
36
- end
37
-
38
- rescue LoadError
39
- puts "This spec requires 'active_support' to be loaded"
40
- end
@@ -1,808 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.expand_path("../../../spec_helper", __FILE__)
4
- require File.join(FIXTURE_PATH, 'more', 'article')
5
- require File.join(FIXTURE_PATH, 'more', 'course')
6
- require File.join(FIXTURE_PATH, 'more', 'card')
7
- require File.join(FIXTURE_PATH, 'more', 'cat')
8
-
9
- describe "ExtendedDocument" do
10
-
11
- class WithDefaultValues < CouchRest::ExtendedDocument
12
- use_database TEST_SERVER.default_database
13
- property :preset, :type => 'Object', :default => {:right => 10, :top_align => false}
14
- property :set_by_proc, :default => Proc.new{Time.now}, :cast_as => 'Time'
15
- property :tags, :type => ['String'], :default => []
16
- property :read_only_with_default, :default => 'generic', :read_only => true
17
- property :default_false, :type => 'Boolean', :default => false
18
- property :name
19
- timestamps!
20
- end
21
-
22
- class WithCallBacks < CouchRest::ExtendedDocument
23
- include ::CouchRest::Validation
24
- use_database TEST_SERVER.default_database
25
- property :name
26
- property :run_before_validate
27
- property :run_after_validate
28
- property :run_before_save
29
- property :run_after_save
30
- property :run_before_create
31
- property :run_after_create
32
- property :run_before_update
33
- property :run_after_update
34
-
35
- before_validate do |object|
36
- object.run_before_validate = true
37
- end
38
- after_validate do |object|
39
- object.run_after_validate = true
40
- end
41
- before_save do |object|
42
- object.run_before_save = true
43
- end
44
- after_save do |object|
45
- object.run_after_save = true
46
- end
47
- before_create do |object|
48
- object.run_before_create = true
49
- end
50
- after_create do |object|
51
- object.run_after_create = true
52
- end
53
- before_update do |object|
54
- object.run_before_update = true
55
- end
56
- after_update do |object|
57
- object.run_after_update = true
58
- end
59
-
60
- property :run_one
61
- property :run_two
62
- property :run_three
63
-
64
- before_save :run_one_method, :run_two_method do |object|
65
- object.run_three = true
66
- end
67
- def run_one_method
68
- self.run_one = true
69
- end
70
- def run_two_method
71
- self.run_two = true
72
- end
73
-
74
- attr_accessor :run_it
75
- property :conditional_one
76
- property :conditional_two
77
-
78
- before_save :conditional_one_method, :conditional_two_method, :if => proc { self.run_it }
79
- def conditional_one_method
80
- self.conditional_one = true
81
- end
82
- def conditional_two_method
83
- self.conditional_two = true
84
- end
85
- end
86
-
87
- class WithTemplateAndUniqueID < CouchRest::ExtendedDocument
88
- use_database TEST_SERVER.default_database
89
- unique_id do |model|
90
- model['important-field']
91
- end
92
- property :preset, :default => 'value'
93
- property :has_no_default
94
- end
95
-
96
- class WithGetterAndSetterMethods < CouchRest::ExtendedDocument
97
- use_database TEST_SERVER.default_database
98
-
99
- property :other_arg
100
- def arg
101
- other_arg
102
- end
103
-
104
- def arg=(value)
105
- self.other_arg = "foo-#{value}"
106
- end
107
- end
108
-
109
- class WithAfterInitializeMethod < CouchRest::ExtendedDocument
110
- use_database TEST_SERVER.default_database
111
-
112
- property :some_value
113
-
114
- def after_initialize
115
- self.some_value ||= "value"
116
- end
117
-
118
- end
119
-
120
-
121
- before(:each) do
122
- @obj = WithDefaultValues.new
123
- end
124
-
125
- describe "instance database connection" do
126
- it "should use the default database" do
127
- @obj.database.name.should == 'couchrest-test'
128
- end
129
-
130
- it "should override the default db" do
131
- @obj.database = TEST_SERVER.database!('couchrest-extendedmodel-test')
132
- @obj.database.name.should == 'couchrest-extendedmodel-test'
133
- @obj.database.delete!
134
- end
135
- end
136
-
137
- describe "a new model" do
138
- it "should be a new document" do
139
- @obj = Basic.new
140
- @obj.rev.should be_nil
141
- @obj.should be_new
142
- @obj.should be_new_document
143
- @obj.should be_new_record
144
- end
145
-
146
- it "should not failed on a nil value in argument" do
147
- @obj = Basic.new(nil)
148
- @obj.should == { 'couchrest-type' => 'Basic' }
149
- end
150
- end
151
-
152
- describe "creating a new document" do
153
- it "should instantialize and save a document" do
154
- article = Article.create(:title => 'my test')
155
- article.title.should == 'my test'
156
- article.should_not be_new
157
- end
158
-
159
- it "should trigger the create callbacks" do
160
- doc = WithCallBacks.create(:name => 'my other test')
161
- doc.run_before_create.should be_true
162
- doc.run_after_create.should be_true
163
- doc.run_before_save.should be_true
164
- doc.run_after_save.should be_true
165
- end
166
- end
167
-
168
- describe "update attributes without saving" do
169
- before(:each) do
170
- a = Article.get "big-bad-danger" rescue nil
171
- a.destroy if a
172
- @art = Article.new(:title => "big bad danger")
173
- @art.save
174
- end
175
- it "should work for attribute= methods" do
176
- @art['title'].should == "big bad danger"
177
- @art.update_attributes_without_saving('date' => Time.now, :title => "super danger")
178
- @art['title'].should == "super danger"
179
- end
180
- it "should silently ignore _id" do
181
- @art.update_attributes_without_saving('_id' => 'foobar')
182
- @art['_id'].should_not == 'foobar'
183
- end
184
- it "should silently ignore _rev" do
185
- @art.update_attributes_without_saving('_rev' => 'foobar')
186
- @art['_rev'].should_not == 'foobar'
187
- end
188
- it "should silently ignore created_at" do
189
- @art.update_attributes_without_saving('created_at' => 'foobar')
190
- @art['created_at'].should_not == 'foobar'
191
- end
192
- it "should silently ignore updated_at" do
193
- @art.update_attributes_without_saving('updated_at' => 'foobar')
194
- @art['updated_at'].should_not == 'foobar'
195
- end
196
- it "should also work using attributes= alias" do
197
- @art.respond_to?(:attributes=).should be_true
198
- @art.attributes = {'date' => Time.now, :title => "something else"}
199
- @art['title'].should == "something else"
200
- end
201
-
202
- it "should flip out if an attribute= method is missing" do
203
- lambda {
204
- @art.update_attributes_without_saving('slug' => "new-slug", :title => "super danger")
205
- }.should raise_error
206
- end
207
-
208
- it "should not change other attributes if there is an error" do
209
- lambda {
210
- @art.update_attributes_without_saving('slug' => "new-slug", :title => "super danger")
211
- }.should raise_error
212
- @art['title'].should == "big bad danger"
213
- end
214
- end
215
-
216
- describe "update attributes" do
217
- before(:each) do
218
- a = Article.get "big-bad-danger" rescue nil
219
- a.destroy if a
220
- @art = Article.new(:title => "big bad danger")
221
- @art.save
222
- end
223
- it "should save" do
224
- @art['title'].should == "big bad danger"
225
- @art.update_attributes('date' => Time.now, :title => "super danger")
226
- loaded = Article.get(@art.id)
227
- loaded['title'].should == "super danger"
228
- end
229
- end
230
-
231
- describe "with default" do
232
- it "should have the default value set at initalization" do
233
- @obj.preset.should == {:right => 10, :top_align => false}
234
- end
235
-
236
- it "should have the default false value explicitly assigned" do
237
- @obj.default_false.should == false
238
- end
239
-
240
- it "should automatically call a proc default at initialization" do
241
- @obj.set_by_proc.should be_an_instance_of(Time)
242
- @obj.set_by_proc.should == @obj.set_by_proc
243
- @obj.set_by_proc.should < Time.now
244
- end
245
-
246
- it "should let you overwrite the default values" do
247
- obj = WithDefaultValues.new(:preset => 'test')
248
- obj.preset = 'test'
249
- end
250
-
251
- it "should work with a default empty array" do
252
- obj = WithDefaultValues.new(:tags => ['spec'])
253
- obj.tags.should == ['spec']
254
- end
255
-
256
- it "should set default value of read-only property" do
257
- obj = WithDefaultValues.new
258
- obj.read_only_with_default.should == 'generic'
259
- end
260
- end
261
-
262
- describe "a doc with template values (CR::Model spec)" do
263
- before(:all) do
264
- WithTemplateAndUniqueID.all.map{|o| o.destroy(true)}
265
- WithTemplateAndUniqueID.database.bulk_delete
266
- @tmpl = WithTemplateAndUniqueID.new
267
- @tmpl2 = WithTemplateAndUniqueID.new(:preset => 'not_value', 'important-field' => '1')
268
- end
269
- it "should have fields set when new" do
270
- @tmpl.preset.should == 'value'
271
- end
272
- it "shouldn't override explicitly set values" do
273
- @tmpl2.preset.should == 'not_value'
274
- end
275
- it "shouldn't override existing documents" do
276
- @tmpl2.save
277
- tmpl2_reloaded = WithTemplateAndUniqueID.get(@tmpl2.id)
278
- @tmpl2.preset.should == 'not_value'
279
- tmpl2_reloaded.preset.should == 'not_value'
280
- end
281
- end
282
-
283
- describe "getting a model" do
284
- before(:all) do
285
- @art = Article.new(:title => 'All About Getting')
286
- @art.save
287
- end
288
- it "should load and instantiate it" do
289
- foundart = Article.get @art.id
290
- foundart.title.should == "All About Getting"
291
- end
292
-
293
- it "should return nil if `get` is used and the document doesn't exist" do
294
- foundart = Article.get 'matt aimonetti'
295
- foundart.should be_nil
296
- end
297
-
298
- it "should raise an error if `get!` is used and the document doesn't exist" do
299
- lambda{foundart = Article.get!('matt aimonetti')}.should raise_error
300
- end
301
- end
302
-
303
- describe "getting a model with a subobjects array" do
304
- before(:all) do
305
- course_doc = {
306
- "title" => "Metaphysics 200",
307
- "questions" => [
308
- {
309
- "q" => "Carve the ___ of reality at the ___.",
310
- "a" => ["beast","joints"]
311
- },{
312
- "q" => "Who layed the smack down on Leibniz's Law?",
313
- "a" => "Willard Van Orman Quine"
314
- }
315
- ]
316
- }
317
- r = Course.database.save_doc course_doc
318
- @course = Course.get r['id']
319
- end
320
- it "should load the course" do
321
- @course.title.should == "Metaphysics 200"
322
- end
323
- it "should instantiate them as such" do
324
- @course["questions"][0].a[0].should == "beast"
325
- end
326
- end
327
-
328
- describe "finding all instances of a model" do
329
- before(:all) do
330
- WithTemplateAndUniqueID.design_doc_fresh = false
331
- WithTemplateAndUniqueID.all.map{|o| o.destroy(true)}
332
- WithTemplateAndUniqueID.database.bulk_delete
333
- WithTemplateAndUniqueID.new('important-field' => '1').save
334
- WithTemplateAndUniqueID.new('important-field' => '2').save
335
- WithTemplateAndUniqueID.new('important-field' => '3').save
336
- WithTemplateAndUniqueID.new('important-field' => '4').save
337
- end
338
- it "should make the design doc" do
339
- WithTemplateAndUniqueID.all
340
- d = WithTemplateAndUniqueID.design_doc
341
- d['views']['all']['map'].should include('WithTemplateAndUniqueID')
342
- end
343
- it "should find all" do
344
- rs = WithTemplateAndUniqueID.all
345
- rs.length.should == 4
346
- end
347
- end
348
-
349
- describe "counting all instances of a model" do
350
- before(:each) do
351
- @db = reset_test_db!
352
- WithTemplateAndUniqueID.design_doc_fresh = false
353
- end
354
-
355
- it ".count should return 0 if there are no docuemtns" do
356
- WithTemplateAndUniqueID.count.should == 0
357
- end
358
-
359
- it ".count should return the number of documents" do
360
- WithTemplateAndUniqueID.new('important-field' => '1').save
361
- WithTemplateAndUniqueID.new('important-field' => '2').save
362
- WithTemplateAndUniqueID.new('important-field' => '3').save
363
-
364
- WithTemplateAndUniqueID.count.should == 3
365
- end
366
- end
367
-
368
- describe "finding the first instance of a model" do
369
- before(:each) do
370
- @db = reset_test_db!
371
- WithTemplateAndUniqueID.design_doc_fresh = false
372
- WithTemplateAndUniqueID.new('important-field' => '1').save
373
- WithTemplateAndUniqueID.new('important-field' => '2').save
374
- WithTemplateAndUniqueID.new('important-field' => '3').save
375
- WithTemplateAndUniqueID.new('important-field' => '4').save
376
- end
377
- it "should make the design doc" do
378
- WithTemplateAndUniqueID.all
379
- d = WithTemplateAndUniqueID.design_doc
380
- d['views']['all']['map'].should include('WithTemplateAndUniqueID')
381
- end
382
- it "should find first" do
383
- rs = WithTemplateAndUniqueID.first
384
- rs['important-field'].should == "1"
385
- end
386
- it "should return nil if no instances are found" do
387
- WithTemplateAndUniqueID.all.each {|obj| obj.destroy }
388
- WithTemplateAndUniqueID.first.should be_nil
389
- end
390
- end
391
-
392
- describe "getting a model with a subobject field" do
393
- before(:all) do
394
- course_doc = {
395
- "title" => "Metaphysics 410",
396
- "professor" => {
397
- "name" => ["Mark", "Hinchliff"]
398
- },
399
- "ends_at" => "2008/12/19 13:00:00 +0800"
400
- }
401
- r = Course.database.save_doc course_doc
402
- @course = Course.get r['id']
403
- end
404
- it "should load the course" do
405
- @course["professor"]["name"][1].should == "Hinchliff"
406
- end
407
- it "should instantiate the professor as a person" do
408
- @course['professor'].last_name.should == "Hinchliff"
409
- end
410
- it "should instantiate the ends_at as a Time" do
411
- @course['ends_at'].should == Time.parse("2008/12/19 13:00:00 +0800")
412
- end
413
- end
414
-
415
- describe "timestamping" do
416
- before(:each) do
417
- oldart = Article.get "saving-this" rescue nil
418
- oldart.destroy if oldart
419
- @art = Article.new(:title => "Saving this")
420
- @art.save
421
- end
422
-
423
- it "should define the updated_at and created_at getters and set the values" do
424
- @obj.save
425
- obj = WithDefaultValues.get(@obj.id)
426
- obj.should be_an_instance_of(WithDefaultValues)
427
- obj.created_at.should be_an_instance_of(Time)
428
- obj.updated_at.should be_an_instance_of(Time)
429
- obj.created_at.to_s.should == @obj.updated_at.to_s
430
- end
431
-
432
- it "should not change created_at on update" do
433
- 2.times do
434
- lambda do
435
- @art.save
436
- end.should_not change(@art, :created_at)
437
- end
438
- end
439
-
440
- it "should set the time on create" do
441
- (Time.now - @art.created_at).should < 2
442
- foundart = Article.get @art.id
443
- foundart.created_at.should == foundart.updated_at
444
- end
445
- it "should set the time on update" do
446
- @art.save
447
- @art.created_at.should < @art.updated_at
448
- end
449
- end
450
-
451
- describe "basic saving and retrieving" do
452
- it "should work fine" do
453
- @obj.name = "should be easily saved and retrieved"
454
- @obj.save
455
- saved_obj = WithDefaultValues.get(@obj.id)
456
- saved_obj.should_not be_nil
457
- end
458
-
459
- it "should parse the Time attributes automatically" do
460
- @obj.name = "should parse the Time attributes automatically"
461
- @obj.set_by_proc.should be_an_instance_of(Time)
462
- @obj.save
463
- @obj.set_by_proc.should be_an_instance_of(Time)
464
- saved_obj = WithDefaultValues.get(@obj.id)
465
- saved_obj.set_by_proc.should be_an_instance_of(Time)
466
- end
467
- end
468
-
469
- describe "saving a model" do
470
- before(:all) do
471
- @sobj = Basic.new
472
- @sobj.save.should == true
473
- end
474
-
475
- it "should save the doc" do
476
- doc = Basic.get(@sobj.id)
477
- doc['_id'].should == @sobj.id
478
- end
479
-
480
- it "should be set for resaving" do
481
- rev = @obj.rev
482
- @sobj['another-key'] = "some value"
483
- @sobj.save
484
- @sobj.rev.should_not == rev
485
- end
486
-
487
- it "should set the id" do
488
- @sobj.id.should be_an_instance_of(String)
489
- end
490
-
491
- it "should set the type" do
492
- @sobj['couchrest-type'].should == 'Basic'
493
- end
494
-
495
- describe "save!" do
496
-
497
- before(:each) do
498
- @sobj = Card.new(:first_name => "Marcos", :last_name => "Tapajós")
499
- end
500
-
501
- it "should return true if save the document" do
502
- @sobj.save!.should == true
503
- end
504
-
505
- it "should raise error if don't save the document" do
506
- @sobj.first_name = nil
507
- lambda { @sobj.save!.should == true }.should raise_error(RuntimeError)
508
- end
509
-
510
- end
511
-
512
-
513
- end
514
-
515
- describe "saving a model with a unique_id configured" do
516
- before(:each) do
517
- @art = Article.new
518
- @old = Article.database.get('this-is-the-title') rescue nil
519
- Article.database.delete_doc(@old) if @old
520
- end
521
-
522
- it "should be a new document" do
523
- @art.should be_new
524
- @art.title.should be_nil
525
- end
526
-
527
- it "should require the title" do
528
- lambda{@art.save}.should raise_error
529
- @art.title = 'This is the title'
530
- @art.save.should == true
531
- end
532
-
533
- it "should not change the slug on update" do
534
- @art.title = 'This is the title'
535
- @art.save.should == true
536
- @art.title = 'new title'
537
- @art.save.should == true
538
- @art.slug.should == 'this-is-the-title'
539
- end
540
-
541
- it "should raise an error when the slug is taken" do
542
- @art.title = 'This is the title'
543
- @art.save.should == true
544
- @art2 = Article.new(:title => 'This is the title!')
545
- lambda{@art2.save}.should raise_error
546
- end
547
-
548
- it "should set the slug" do
549
- @art.title = 'This is the title'
550
- @art.save.should == true
551
- @art.slug.should == 'this-is-the-title'
552
- end
553
-
554
- it "should set the id" do
555
- @art.title = 'This is the title'
556
- @art.save.should == true
557
- @art.id.should == 'this-is-the-title'
558
- end
559
- end
560
-
561
- describe "saving a model with a unique_id lambda" do
562
- before(:each) do
563
- @templated = WithTemplateAndUniqueID.new
564
- @old = WithTemplateAndUniqueID.get('very-important') rescue nil
565
- @old.destroy if @old
566
- end
567
-
568
- it "should require the field" do
569
- lambda{@templated.save}.should raise_error
570
- @templated['important-field'] = 'very-important'
571
- @templated.save.should == true
572
- end
573
-
574
- it "should save with the id" do
575
- @templated['important-field'] = 'very-important'
576
- @templated.save.should == true
577
- t = WithTemplateAndUniqueID.get('very-important')
578
- t.should == @templated
579
- end
580
-
581
- it "should not change the id on update" do
582
- @templated['important-field'] = 'very-important'
583
- @templated.save.should == true
584
- @templated['important-field'] = 'not-important'
585
- @templated.save.should == true
586
- t = WithTemplateAndUniqueID.get('very-important')
587
- t.should == @templated
588
- end
589
-
590
- it "should raise an error when the id is taken" do
591
- @templated['important-field'] = 'very-important'
592
- @templated.save.should == true
593
- lambda{WithTemplateAndUniqueID.new('important-field' => 'very-important').save}.should raise_error
594
- end
595
-
596
- it "should set the id" do
597
- @templated['important-field'] = 'very-important'
598
- @templated.save.should == true
599
- @templated.id.should == 'very-important'
600
- end
601
- end
602
-
603
- describe "destroying an instance" do
604
- before(:each) do
605
- @dobj = Basic.new
606
- @dobj.save.should == true
607
- end
608
- it "should return true" do
609
- result = @dobj.destroy
610
- result.should == true
611
- end
612
- it "should be resavable" do
613
- @dobj.destroy
614
- @dobj.rev.should be_nil
615
- @dobj.id.should be_nil
616
- @dobj.save.should == true
617
- end
618
- it "should make it go away" do
619
- @dobj.destroy
620
- lambda{Basic.get!(@dobj.id)}.should raise_error
621
- end
622
- end
623
-
624
-
625
- describe "callbacks" do
626
-
627
- before(:each) do
628
- @doc = WithCallBacks.new
629
- end
630
-
631
-
632
- describe "validate" do
633
- it "should run before_validate before validating" do
634
- @doc.run_before_validate.should be_nil
635
- @doc.should be_valid
636
- @doc.run_before_validate.should be_true
637
- end
638
- it "should run after_validate after validating" do
639
- @doc.run_after_validate.should be_nil
640
- @doc.should be_valid
641
- @doc.run_after_validate.should be_true
642
- end
643
- end
644
-
645
- describe "save" do
646
- it "should run the after filter after saving" do
647
- @doc.run_after_save.should be_nil
648
- @doc.save.should be_true
649
- @doc.run_after_save.should be_true
650
- end
651
- it "should run the grouped callbacks before saving" do
652
- @doc.run_one.should be_nil
653
- @doc.run_two.should be_nil
654
- @doc.run_three.should be_nil
655
- @doc.save.should be_true
656
- @doc.run_one.should be_true
657
- @doc.run_two.should be_true
658
- @doc.run_three.should be_true
659
- end
660
- it "should not run conditional callbacks" do
661
- @doc.run_it = false
662
- @doc.save.should be_true
663
- @doc.conditional_one.should be_nil
664
- @doc.conditional_two.should be_nil
665
- end
666
- it "should run conditional callbacks" do
667
- @doc.run_it = true
668
- @doc.save.should be_true
669
- @doc.conditional_one.should be_true
670
- @doc.conditional_two.should be_true
671
- end
672
- end
673
- describe "create" do
674
- it "should run the before save filter when creating" do
675
- @doc.run_before_save.should be_nil
676
- @doc.create.should_not be_nil
677
- @doc.run_before_save.should be_true
678
- end
679
- it "should run the before create filter" do
680
- @doc.run_before_create.should be_nil
681
- @doc.create.should_not be_nil
682
- @doc.create
683
- @doc.run_before_create.should be_true
684
- end
685
- it "should run the after create filter" do
686
- @doc.run_after_create.should be_nil
687
- @doc.create.should_not be_nil
688
- @doc.create
689
- @doc.run_after_create.should be_true
690
- end
691
- end
692
- describe "update" do
693
-
694
- before(:each) do
695
- @doc.save
696
- end
697
- it "should run the before update filter when updating an existing document" do
698
- @doc.run_before_update.should be_nil
699
- @doc.update
700
- @doc.run_before_update.should be_true
701
- end
702
- it "should run the after update filter when updating an existing document" do
703
- @doc.run_after_update.should be_nil
704
- @doc.update
705
- @doc.run_after_update.should be_true
706
- end
707
- it "should run the before update filter when saving an existing document" do
708
- @doc.run_before_update.should be_nil
709
- @doc.save
710
- @doc.run_before_update.should be_true
711
- end
712
-
713
- end
714
- end
715
-
716
- describe "getter and setter methods" do
717
- it "should try to call the arg= method before setting :arg in the hash" do
718
- @doc = WithGetterAndSetterMethods.new(:arg => "foo")
719
- @doc['arg'].should be_nil
720
- @doc[:arg].should be_nil
721
- @doc.other_arg.should == "foo-foo"
722
- end
723
- end
724
-
725
- describe "initialization" do
726
- it "should call after_initialize method if available" do
727
- @doc = WithAfterInitializeMethod.new
728
- @doc['some_value'].should eql('value')
729
- end
730
- end
731
-
732
- describe "recursive validation on an extended document" do
733
- before :each do
734
- reset_test_db!
735
- @cat = Cat.new(:name => 'Sockington')
736
- end
737
-
738
- it "should not save if a nested casted model is invalid" do
739
- @cat.favorite_toy = CatToy.new
740
- @cat.should_not be_valid
741
- @cat.save.should be_false
742
- lambda{@cat.save!}.should raise_error
743
- end
744
-
745
- it "should save when nested casted model is valid" do
746
- @cat.favorite_toy = CatToy.new(:name => 'Squeaky')
747
- @cat.should be_valid
748
- @cat.save.should be_true
749
- lambda{@cat.save!}.should_not raise_error
750
- end
751
-
752
- it "should not save when nested collection contains an invalid casted model" do
753
- @cat.toys = [CatToy.new(:name => 'Feather'), CatToy.new]
754
- @cat.should_not be_valid
755
- @cat.save.should be_false
756
- lambda{@cat.save!}.should raise_error
757
- end
758
-
759
- it "should save when nested collection contains valid casted models" do
760
- @cat.toys = [CatToy.new(:name => 'feather'), CatToy.new(:name => 'ball-o-twine')]
761
- @cat.should be_valid
762
- @cat.save.should be_true
763
- lambda{@cat.save!}.should_not raise_error
764
- end
765
-
766
- it "should not fail if the nested casted model doesn't have validation" do
767
- Cat.property :trainer, :cast_as => 'Person'
768
- Cat.validates_presence_of :name
769
- cat = Cat.new(:name => 'Mr Bigglesworth')
770
- cat.trainer = Person.new
771
- cat.trainer.validatable?.should be_false
772
- cat.should be_valid
773
- cat.save.should be_true
774
- end
775
- end
776
-
777
- describe "searching the contents of an extended document" do
778
- before :each do
779
- @db = reset_test_db!
780
-
781
- names = ["Fuzzy", "Whiskers", "Mr Bigglesworth", "Sockington", "Smitty", "Sammy", "Samson", "Simon"]
782
- names.each { |name| Cat.create(:name => name) }
783
-
784
- search_function = { 'defaults' => {'store' => 'no', 'index' => 'analyzed_no_norms'},
785
- 'index' => "function(doc) { ret = new Document(); ret.add(doc['name'], {'field':'name'}); return ret; }" }
786
- @db.save_doc({'_id' => '_design/search', 'fulltext' => {'cats' => search_function}})
787
- end
788
-
789
- it "should be able to paginate through a large set of search results" do
790
- if couchdb_lucene_available?
791
- names = []
792
- Cat.paginated_each(:design_doc => "search", :view_name => "cats",
793
- :q => 'name:S*', :search => true, :include_docs => true, :per_page => 3) do |cat|
794
- cat.should_not be_nil
795
- names << cat.name
796
- end
797
-
798
- names.size.should == 5
799
- names.should include('Sockington')
800
- names.should include('Smitty')
801
- names.should include('Sammy')
802
- names.should include('Samson')
803
- names.should include('Simon')
804
- end
805
- end
806
- end
807
-
808
- end