couchrest_model_thought 1.0.0.beta8

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 (70) hide show
  1. data/Gemfile +9 -0
  2. data/LICENSE +176 -0
  3. data/README.md +320 -0
  4. data/Rakefile +69 -0
  5. data/THANKS.md +19 -0
  6. data/examples/model/example.rb +144 -0
  7. data/lib/couchrest/model/associations.rb +207 -0
  8. data/lib/couchrest/model/attribute_protection.rb +74 -0
  9. data/lib/couchrest/model/attributes.rb +91 -0
  10. data/lib/couchrest/model/base.rb +111 -0
  11. data/lib/couchrest/model/callbacks.rb +27 -0
  12. data/lib/couchrest/model/casted_array.rb +39 -0
  13. data/lib/couchrest/model/casted_model.rb +68 -0
  14. data/lib/couchrest/model/class_proxy.rb +122 -0
  15. data/lib/couchrest/model/collection.rb +260 -0
  16. data/lib/couchrest/model/design_doc.rb +126 -0
  17. data/lib/couchrest/model/document_queries.rb +82 -0
  18. data/lib/couchrest/model/errors.rb +23 -0
  19. data/lib/couchrest/model/extended_attachments.rb +73 -0
  20. data/lib/couchrest/model/persistence.rb +141 -0
  21. data/lib/couchrest/model/properties.rb +144 -0
  22. data/lib/couchrest/model/property.rb +96 -0
  23. data/lib/couchrest/model/support/couchrest.rb +19 -0
  24. data/lib/couchrest/model/support/hash.rb +9 -0
  25. data/lib/couchrest/model/typecast.rb +170 -0
  26. data/lib/couchrest/model/validations/casted_model.rb +14 -0
  27. data/lib/couchrest/model/validations/locale/en.yml +5 -0
  28. data/lib/couchrest/model/validations/uniqueness.rb +42 -0
  29. data/lib/couchrest/model/validations.rb +68 -0
  30. data/lib/couchrest/model/version.rb +5 -0
  31. data/lib/couchrest/model/views.rb +160 -0
  32. data/lib/couchrest/model.rb +5 -0
  33. data/lib/couchrest_model.rb +53 -0
  34. data/spec/couchrest/assocations_spec.rb +213 -0
  35. data/spec/couchrest/attachment_spec.rb +148 -0
  36. data/spec/couchrest/attribute_protection_spec.rb +153 -0
  37. data/spec/couchrest/base_spec.rb +463 -0
  38. data/spec/couchrest/casted_model_spec.rb +424 -0
  39. data/spec/couchrest/casted_spec.rb +75 -0
  40. data/spec/couchrest/class_proxy_spec.rb +132 -0
  41. data/spec/couchrest/inherited_spec.rb +40 -0
  42. data/spec/couchrest/persistence_spec.rb +409 -0
  43. data/spec/couchrest/property_spec.rb +804 -0
  44. data/spec/couchrest/subclass_spec.rb +99 -0
  45. data/spec/couchrest/validations.rb +85 -0
  46. data/spec/couchrest/view_spec.rb +463 -0
  47. data/spec/fixtures/attachments/README +3 -0
  48. data/spec/fixtures/attachments/couchdb.png +0 -0
  49. data/spec/fixtures/attachments/test.html +11 -0
  50. data/spec/fixtures/base.rb +139 -0
  51. data/spec/fixtures/more/article.rb +35 -0
  52. data/spec/fixtures/more/card.rb +17 -0
  53. data/spec/fixtures/more/cat.rb +19 -0
  54. data/spec/fixtures/more/course.rb +25 -0
  55. data/spec/fixtures/more/event.rb +8 -0
  56. data/spec/fixtures/more/invoice.rb +14 -0
  57. data/spec/fixtures/more/person.rb +9 -0
  58. data/spec/fixtures/more/question.rb +7 -0
  59. data/spec/fixtures/more/service.rb +10 -0
  60. data/spec/fixtures/more/user.rb +22 -0
  61. data/spec/fixtures/views/lib.js +3 -0
  62. data/spec/fixtures/views/test_view/lib.js +3 -0
  63. data/spec/fixtures/views/test_view/only-map.js +4 -0
  64. data/spec/fixtures/views/test_view/test-map.js +3 -0
  65. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  66. data/spec/spec.opts +5 -0
  67. data/spec/spec_helper.rb +48 -0
  68. data/utils/remap.rb +27 -0
  69. data/utils/subset.rb +30 -0
  70. metadata +215 -0
@@ -0,0 +1,409 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../../spec_helper', __FILE__)
3
+ require File.join(FIXTURE_PATH, 'base')
4
+ require File.join(FIXTURE_PATH, 'more', 'cat')
5
+ require File.join(FIXTURE_PATH, 'more', 'article')
6
+ require File.join(FIXTURE_PATH, 'more', 'course')
7
+ require File.join(FIXTURE_PATH, 'more', 'card')
8
+
9
+ describe "Model Persistence" do
10
+
11
+ before(:each) do
12
+ @obj = WithDefaultValues.new
13
+ end
14
+
15
+ describe "creating a new document from database" do
16
+
17
+ it "should instantialize" do
18
+ doc = Article.create_from_database({'_id' => 'testitem1', '_rev' => 123, 'couchrest-type' => 'Article', 'name' => 'my test'})
19
+ doc.class.should eql(Article)
20
+ end
21
+
22
+ it "should instantialize of same class if no couchrest-type included from DB" do
23
+ doc = Article.create_from_database({'_id' => 'testitem1', '_rev' => 123, 'name' => 'my test'})
24
+ doc.class.should eql(Article)
25
+ end
26
+
27
+ it "should instantialize document of different type" do
28
+ doc = Article.create_from_database({'_id' => 'testitem2', '_rev' => 123, 'couchrest-type' => 'WithTemplateAndUniqueID', 'name' => 'my test'})
29
+ doc.class.should eql(WithTemplateAndUniqueID)
30
+ end
31
+
32
+ end
33
+
34
+ describe "basic saving and retrieving" do
35
+ it "should work fine" do
36
+ @obj.name = "should be easily saved and retrieved"
37
+ @obj.save
38
+ saved_obj = WithDefaultValues.get(@obj.id)
39
+ saved_obj.should_not be_nil
40
+ end
41
+
42
+ it "should parse the Time attributes automatically" do
43
+ @obj.name = "should parse the Time attributes automatically"
44
+ @obj.set_by_proc.should be_an_instance_of(Time)
45
+ @obj.save
46
+ @obj.set_by_proc.should be_an_instance_of(Time)
47
+ saved_obj = WithDefaultValues.get(@obj.id)
48
+ saved_obj.set_by_proc.should be_an_instance_of(Time)
49
+ end
50
+ end
51
+
52
+ describe "creating a model" do
53
+
54
+ before(:each) do
55
+ @sobj = Basic.new
56
+ end
57
+
58
+ it "should accept true or false on save for validation" do
59
+ @sobj.should_receive(:valid?)
60
+ @sobj.save(true)
61
+ end
62
+
63
+ it "should accept hash with validation option" do
64
+ @sobj.should_receive(:valid?)
65
+ @sobj.save(:validate => true)
66
+ end
67
+
68
+ it "should not call validation when option is false" do
69
+ @sobj.should_not_receive(:valid?)
70
+ @sobj.save(false)
71
+ end
72
+
73
+ it "should not call validation when option :validate is false" do
74
+ @sobj.should_not_receive(:valid?)
75
+ @sobj.save(:validate => false)
76
+ end
77
+
78
+ it "should instantialize and save a document" do
79
+ article = Article.create(:title => 'my test')
80
+ article.title.should == 'my test'
81
+ article.should_not be_new
82
+ end
83
+
84
+ it "should trigger the create callbacks" do
85
+ doc = WithCallBacks.create(:name => 'my other test')
86
+ doc.run_before_create.should be_true
87
+ doc.run_after_create.should be_true
88
+ doc.run_before_save.should be_true
89
+ doc.run_after_save.should be_true
90
+ end
91
+
92
+ end
93
+
94
+ describe "saving a model" do
95
+ before(:all) do
96
+ @sobj = Basic.new
97
+ @sobj.save.should be_true
98
+ end
99
+
100
+ it "should save the doc" do
101
+ doc = Basic.get(@sobj.id)
102
+ doc['_id'].should == @sobj.id
103
+ end
104
+
105
+ it "should be set for resaving" do
106
+ rev = @obj.rev
107
+ @sobj['another-key'] = "some value"
108
+ @sobj.save
109
+ @sobj.rev.should_not == rev
110
+ end
111
+
112
+ it "should set the id" do
113
+ @sobj.id.should be_an_instance_of(String)
114
+ end
115
+
116
+ it "should set the type" do
117
+ @sobj['couchrest-type'].should == 'Basic'
118
+ end
119
+
120
+ it "should accept true or false on save for validation" do
121
+ @sobj.should_receive(:valid?)
122
+ @sobj.save(true)
123
+ end
124
+
125
+ it "should accept hash with validation option" do
126
+ @sobj.should_receive(:valid?)
127
+ @sobj.save(:validate => true)
128
+ end
129
+
130
+ it "should not call validation when option is false" do
131
+ @sobj.should_not_receive(:valid?)
132
+ @sobj.save(false)
133
+ end
134
+
135
+ it "should not call validation when option :validate is false" do
136
+ @sobj.should_not_receive(:valid?)
137
+ @sobj.save(:validate => false)
138
+ end
139
+
140
+ describe "save!" do
141
+
142
+ before(:each) do
143
+ @sobj = Card.new(:first_name => "Marcos", :last_name => "Tapajós")
144
+ end
145
+
146
+ it "should return true if save the document" do
147
+ @sobj.save!.should be_true
148
+ end
149
+
150
+ it "should raise error if don't save the document" do
151
+ @sobj.first_name = nil
152
+ lambda { @sobj.save! }.should raise_error(CouchRest::Model::Errors::Validations)
153
+ end
154
+
155
+ end
156
+ end
157
+
158
+ describe "saving a model with a unique_id configured" do
159
+ before(:each) do
160
+ @art = Article.new
161
+ @old = Article.database.get('this-is-the-title') rescue nil
162
+ Article.database.delete_doc(@old) if @old
163
+ end
164
+
165
+ it "should be a new document" do
166
+ @art.should be_new
167
+ @art.title.should be_nil
168
+ end
169
+
170
+ it "should require the title" do
171
+ lambda{@art.save}.should raise_error
172
+ @art.title = 'This is the title'
173
+ @art.save.should be_true
174
+ end
175
+
176
+ it "should not change the slug on update" do
177
+ @art.title = 'This is the title'
178
+ @art.save.should be_true
179
+ @art.title = 'new title'
180
+ @art.save.should be_true
181
+ @art.slug.should == 'this-is-the-title'
182
+ end
183
+
184
+ it "should raise an error when the slug is taken" do
185
+ @art.title = 'This is the title'
186
+ @art.save.should be_true
187
+ @art2 = Article.new(:title => 'This is the title!')
188
+ lambda{@art2.save}.should raise_error
189
+ end
190
+
191
+ it "should set the slug" do
192
+ @art.title = 'This is the title'
193
+ @art.save.should be_true
194
+ @art.slug.should == 'this-is-the-title'
195
+ end
196
+
197
+ it "should set the id" do
198
+ @art.title = 'This is the title'
199
+ @art.save.should be_true
200
+ @art.id.should == 'this-is-the-title'
201
+ end
202
+ end
203
+
204
+ describe "saving a model with a unique_id lambda" do
205
+ before(:each) do
206
+ @templated = WithTemplateAndUniqueID.new
207
+ @old = WithTemplateAndUniqueID.get('very-important') rescue nil
208
+ @old.destroy if @old
209
+ end
210
+
211
+ it "should require the field" do
212
+ lambda{@templated.save}.should raise_error
213
+ @templated['important-field'] = 'very-important'
214
+ @templated.save.should be_true
215
+ end
216
+
217
+ it "should save with the id" do
218
+ @templated['important-field'] = 'very-important'
219
+ @templated.save.should be_true
220
+ t = WithTemplateAndUniqueID.get('very-important')
221
+ t.should == @templated
222
+ end
223
+
224
+ it "should not change the id on update" do
225
+ @templated['important-field'] = 'very-important'
226
+ @templated.save.should be_true
227
+ @templated['important-field'] = 'not-important'
228
+ @templated.save.should be_true
229
+ t = WithTemplateAndUniqueID.get('very-important')
230
+ t.should == @templated
231
+ end
232
+
233
+ it "should raise an error when the id is taken" do
234
+ @templated['important-field'] = 'very-important'
235
+ @templated.save.should be_true
236
+ lambda{WithTemplateAndUniqueID.new('important-field' => 'very-important').save}.should raise_error
237
+ end
238
+
239
+ it "should set the id" do
240
+ @templated['important-field'] = 'very-important'
241
+ @templated.save.should be_true
242
+ @templated.id.should == 'very-important'
243
+ end
244
+ end
245
+
246
+ describe "destroying an instance" do
247
+ before(:each) do
248
+ @dobj = Basic.new
249
+ @dobj.save.should be_true
250
+ end
251
+ it "should return true" do
252
+ result = @dobj.destroy
253
+ result.should be_true
254
+ end
255
+ it "should be resavable" do
256
+ @dobj.destroy
257
+ @dobj.rev.should be_nil
258
+ @dobj.id.should be_nil
259
+ @dobj.save.should be_true
260
+ end
261
+ it "should make it go away" do
262
+ @dobj.destroy
263
+ lambda{Basic.get!(@dobj.id)}.should raise_error
264
+ end
265
+ end
266
+
267
+
268
+ describe "getting a model" do
269
+ before(:all) do
270
+ @art = Article.new(:title => 'All About Getting')
271
+ @art.save
272
+ end
273
+ it "should load and instantiate it" do
274
+ foundart = Article.get @art.id
275
+ foundart.title.should == "All About Getting"
276
+ end
277
+ it "should load and instantiate with find" do
278
+ foundart = Article.find @art.id
279
+ foundart.title.should == "All About Getting"
280
+ end
281
+ it "should return nil if `get` is used and the document doesn't exist" do
282
+ foundart = Article.get 'matt aimonetti'
283
+ foundart.should be_nil
284
+ end
285
+ it "should raise an error if `get!` is used and the document doesn't exist" do
286
+ lambda{foundart = Article.get!('matt aimonetti')}.should raise_error
287
+ end
288
+ it "should raise an error if `find!` is used and the document doesn't exist" do
289
+ lambda{foundart = Article.find!('matt aimonetti')}.should raise_error
290
+ end
291
+ end
292
+
293
+ describe "getting a model with a subobjects array" do
294
+ before(:all) do
295
+ course_doc = {
296
+ "title" => "Metaphysics 200",
297
+ "questions" => [
298
+ {
299
+ "q" => "Carve the ___ of reality at the ___.",
300
+ "a" => ["beast","joints"]
301
+ },{
302
+ "q" => "Who layed the smack down on Leibniz's Law?",
303
+ "a" => "Willard Van Orman Quine"
304
+ }
305
+ ]
306
+ }
307
+ r = Course.database.save_doc course_doc
308
+ @course = Course.get r['id']
309
+ end
310
+ it "should load the course" do
311
+ @course.title.should == "Metaphysics 200"
312
+ end
313
+ it "should instantiate them as such" do
314
+ @course["questions"][0].a[0].should == "beast"
315
+ end
316
+ end
317
+
318
+ describe "callbacks" do
319
+
320
+ before(:each) do
321
+ @doc = WithCallBacks.new
322
+ end
323
+
324
+ describe "validation" do
325
+ it "should run before_validation before validating" do
326
+ @doc.run_before_validate.should be_nil
327
+ @doc.should be_valid
328
+ @doc.run_before_validate.should be_true
329
+ end
330
+ it "should run after_validation after validating" do
331
+ @doc.run_after_validate.should be_nil
332
+ @doc.should be_valid
333
+ @doc.run_after_validate.should be_true
334
+ end
335
+ end
336
+
337
+ describe "save" do
338
+ it "should run the after filter after saving" do
339
+ @doc.run_after_save.should be_nil
340
+ @doc.save.should be_true
341
+ @doc.run_after_save.should be_true
342
+ end
343
+ it "should run the grouped callbacks before saving" do
344
+ @doc.run_one.should be_nil
345
+ @doc.run_two.should be_nil
346
+ @doc.run_three.should be_nil
347
+ @doc.save.should be_true
348
+ @doc.run_one.should be_true
349
+ @doc.run_two.should be_true
350
+ @doc.run_three.should be_true
351
+ end
352
+ it "should not run conditional callbacks" do
353
+ @doc.run_it = false
354
+ @doc.save.should be_true
355
+ @doc.conditional_one.should be_nil
356
+ @doc.conditional_two.should be_nil
357
+ end
358
+ it "should run conditional callbacks" do
359
+ @doc.run_it = true
360
+ @doc.save.should be_true
361
+ @doc.conditional_one.should be_true
362
+ @doc.conditional_two.should be_true
363
+ end
364
+ end
365
+ describe "create" do
366
+ it "should run the before save filter when creating" do
367
+ @doc.run_before_save.should be_nil
368
+ @doc.create.should_not be_nil
369
+ @doc.run_before_save.should be_true
370
+ end
371
+ it "should run the before create filter" do
372
+ @doc.run_before_create.should be_nil
373
+ @doc.create.should_not be_nil
374
+ @doc.create
375
+ @doc.run_before_create.should be_true
376
+ end
377
+ it "should run the after create filter" do
378
+ @doc.run_after_create.should be_nil
379
+ @doc.create.should_not be_nil
380
+ @doc.create
381
+ @doc.run_after_create.should be_true
382
+ end
383
+ end
384
+ describe "update" do
385
+
386
+ before(:each) do
387
+ @doc.save
388
+ end
389
+ it "should run the before update filter when updating an existing document" do
390
+ @doc.run_before_update.should be_nil
391
+ @doc.update
392
+ @doc.run_before_update.should be_true
393
+ end
394
+ it "should run the after update filter when updating an existing document" do
395
+ @doc.run_after_update.should be_nil
396
+ @doc.update
397
+ @doc.run_after_update.should be_true
398
+ end
399
+ it "should run the before update filter when saving an existing document" do
400
+ @doc.run_before_update.should be_nil
401
+ @doc.save
402
+ @doc.run_before_update.should be_true
403
+ end
404
+
405
+ end
406
+ end
407
+
408
+
409
+ end