jchris-couchrest 0.12.6 → 0.16

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 (59) hide show
  1. data/README.md +33 -8
  2. data/Rakefile +1 -1
  3. data/examples/model/example.rb +19 -13
  4. data/lib/couchrest.rb +27 -2
  5. data/lib/couchrest/core/database.rb +113 -41
  6. data/lib/couchrest/core/document.rb +48 -27
  7. data/lib/couchrest/core/response.rb +15 -0
  8. data/lib/couchrest/core/server.rb +47 -10
  9. data/lib/couchrest/mixins.rb +4 -0
  10. data/lib/couchrest/mixins/attachments.rb +31 -0
  11. data/lib/couchrest/mixins/callbacks.rb +442 -0
  12. data/lib/couchrest/mixins/design_doc.rb +63 -0
  13. data/lib/couchrest/mixins/document_queries.rb +48 -0
  14. data/lib/couchrest/mixins/extended_attachments.rb +68 -0
  15. data/lib/couchrest/mixins/extended_document_mixins.rb +6 -0
  16. data/lib/couchrest/mixins/properties.rb +120 -0
  17. data/lib/couchrest/mixins/validation.rb +234 -0
  18. data/lib/couchrest/mixins/views.rb +168 -0
  19. data/lib/couchrest/monkeypatches.rb +75 -0
  20. data/lib/couchrest/more/casted_model.rb +28 -0
  21. data/lib/couchrest/more/extended_document.rb +215 -0
  22. data/lib/couchrest/more/property.rb +40 -0
  23. data/lib/couchrest/support/blank.rb +42 -0
  24. data/lib/couchrest/support/class.rb +175 -0
  25. data/lib/couchrest/validation/auto_validate.rb +163 -0
  26. data/lib/couchrest/validation/contextual_validators.rb +78 -0
  27. data/lib/couchrest/validation/validation_errors.rb +118 -0
  28. data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
  29. data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
  30. data/lib/couchrest/validation/validators/format_validator.rb +117 -0
  31. data/lib/couchrest/validation/validators/formats/email.rb +66 -0
  32. data/lib/couchrest/validation/validators/formats/url.rb +43 -0
  33. data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
  34. data/lib/couchrest/validation/validators/length_validator.rb +134 -0
  35. data/lib/couchrest/validation/validators/method_validator.rb +89 -0
  36. data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
  37. data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
  38. data/spec/couchrest/core/database_spec.rb +183 -67
  39. data/spec/couchrest/core/design_spec.rb +1 -1
  40. data/spec/couchrest/core/document_spec.rb +271 -173
  41. data/spec/couchrest/core/server_spec.rb +35 -0
  42. data/spec/couchrest/helpers/pager_spec.rb +1 -1
  43. data/spec/couchrest/more/casted_model_spec.rb +97 -0
  44. data/spec/couchrest/more/extended_doc_attachment_spec.rb +129 -0
  45. data/spec/couchrest/more/extended_doc_spec.rb +509 -0
  46. data/spec/couchrest/more/extended_doc_view_spec.rb +204 -0
  47. data/spec/couchrest/more/property_spec.rb +129 -0
  48. data/spec/fixtures/more/article.rb +34 -0
  49. data/spec/fixtures/more/card.rb +20 -0
  50. data/spec/fixtures/more/course.rb +14 -0
  51. data/spec/fixtures/more/event.rb +6 -0
  52. data/spec/fixtures/more/invoice.rb +17 -0
  53. data/spec/fixtures/more/person.rb +8 -0
  54. data/spec/fixtures/more/question.rb +6 -0
  55. data/spec/fixtures/more/service.rb +12 -0
  56. data/spec/spec_helper.rb +13 -7
  57. metadata +76 -3
  58. data/lib/couchrest/core/model.rb +0 -613
  59. data/spec/couchrest/core/model_spec.rb +0 -855
@@ -62,7 +62,7 @@ describe CouchRest::Design do
62
62
  describe "from a saved document" do
63
63
  before(:each) do
64
64
  @db = reset_test_db!
65
- @db.save({
65
+ @db.save_doc({
66
66
  "_id" => "_design/test",
67
67
  "views" => {
68
68
  "by_name" => {
@@ -1,213 +1,311 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
- describe CouchRest::Document, "[]=" do
4
- before(:each) do
5
- @doc = CouchRest::Document.new
6
- end
7
- it "should work" do
8
- @doc["enamel"].should == nil
9
- @doc["enamel"] = "Strong"
10
- @doc["enamel"].should == "Strong"
11
- end
12
- it "[]= should convert to string" do
13
- @doc["enamel"].should == nil
14
- @doc[:enamel] = "Strong"
15
- @doc["enamel"].should == "Strong"
16
- end
17
- it "should read as a string" do
18
- @doc[:enamel] = "Strong"
19
- @doc[:enamel].should == "Strong"
20
- end
21
- end
3
+ class Video < CouchRest::Document; end
22
4
 
23
- describe CouchRest::Document, "new" do
24
- before(:each) do
25
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
26
- end
27
- it "should create itself from a Hash" do
28
- @doc["key"].should == [1,2,3]
29
- @doc["more"].should == "values"
30
- end
31
- it "should not have rev and id" do
32
- @doc.rev.should be_nil
33
- @doc.id.should be_nil
34
- end
35
- it "should freak out when saving without a database" do
36
- lambda{@doc.save}.should raise_error(ArgumentError)
37
- end
38
- end
39
-
40
- # move to database spec
41
- describe CouchRest::Document, "saving using a database" do
5
+ describe CouchRest::Document do
6
+
42
7
  before(:all) do
43
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
44
- @db = reset_test_db!
45
- @resp = @db.save(@doc)
46
- end
47
- it "should apply the database" do
48
- @doc.database.should == @db
49
- end
50
- it "should get id and rev" do
51
- @doc.id.should == @resp["id"]
52
- @doc.rev.should == @resp["rev"]
8
+ @couch = CouchRest.new
9
+ @db = @couch.database!(TESTDB)
53
10
  end
54
- end
55
11
 
56
- describe CouchRest::Document, "bulk saving" do
57
- before :all do
58
- @db = reset_test_db!
12
+ describe "[]=" do
13
+ before(:each) do
14
+ @doc = CouchRest::Document.new
15
+ end
16
+ it "should work" do
17
+ @doc["enamel"].should == nil
18
+ @doc["enamel"] = "Strong"
19
+ @doc["enamel"].should == "Strong"
20
+ end
21
+ it "[]= should convert to string" do
22
+ @doc["enamel"].should == nil
23
+ @doc[:enamel] = "Strong"
24
+ @doc["enamel"].should == "Strong"
25
+ end
26
+ it "should read as a string" do
27
+ @doc[:enamel] = "Strong"
28
+ @doc[:enamel].should == "Strong"
29
+ end
59
30
  end
60
31
 
61
- it "should use the document bulk save cache" do
62
- doc = CouchRest::Document.new({"_id" => "bulkdoc", "val" => 3})
63
- doc.database = @db
64
- doc.save(true)
65
- lambda { doc.database.get(doc["_id"]) }.should raise_error(RestClient::ResourceNotFound)
66
- doc.database.bulk_save
67
- doc.database.get(doc["_id"])["val"].should == doc["val"]
32
+ describe "default database" do
33
+ before(:each) do
34
+ Video.use_database nil
35
+ end
36
+ it "should be set using use_database on the model" do
37
+ Video.new.database.should be_nil
38
+ Video.use_database @db
39
+ Video.new.database.should == @db
40
+ Video.use_database nil
41
+ end
42
+
43
+ it "should be overwritten by instance" do
44
+ db = @couch.database('test')
45
+ article = Video.new
46
+ article.database.should be_nil
47
+ article.database = db
48
+ article.database.should_not be_nil
49
+ article.database.should == db
50
+ end
68
51
  end
69
- end
70
52
 
71
- describe "getting from a database" do
72
- before(:all) do
73
- @db = reset_test_db!
74
- @resp = @db.save({
75
- "key" => "value"
76
- })
77
- @doc = @db.get @resp['id']
78
- end
79
- it "should return a document" do
80
- @doc.should be_an_instance_of(CouchRest::Document)
81
- end
82
- it "should have a database" do
83
- @doc.database.should == @db
53
+ describe "new" do
54
+ before(:each) do
55
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
56
+ end
57
+ it "should create itself from a Hash" do
58
+ @doc["key"].should == [1,2,3]
59
+ @doc["more"].should == "values"
60
+ end
61
+ it "should not have rev and id" do
62
+ @doc.rev.should be_nil
63
+ @doc.id.should be_nil
64
+ end
65
+
66
+ it "should freak out when saving without a database" do
67
+ lambda{@doc.save}.should raise_error(ArgumentError)
68
+ end
69
+
84
70
  end
85
- it "should be saveable and resavable" do
86
- @doc["more"] = "keys"
87
- @doc.save
88
- @db.get(@resp['id'])["more"].should == "keys"
89
- @doc["more"] = "these keys"
90
- @doc.save
91
- @db.get(@resp['id'])["more"].should == "these keys"
71
+
72
+ # move to database spec
73
+ describe "saving using a database" do
74
+ before(:all) do
75
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
76
+ @db = reset_test_db!
77
+ @resp = @db.save_doc(@doc)
78
+ end
79
+ it "should apply the database" do
80
+ @doc.database.should == @db
81
+ end
82
+ it "should get id and rev" do
83
+ @doc.id.should == @resp["id"]
84
+ @doc.rev.should == @resp["rev"]
85
+ end
92
86
  end
93
- end
94
87
 
95
- describe "destroying a document from a db" do
96
- before(:all) do
97
- @db = reset_test_db!
98
- @resp = @db.save({
99
- "key" => "value"
100
- })
101
- @doc = @db.get @resp['id']
88
+ describe "bulk saving" do
89
+ before :all do
90
+ @db = reset_test_db!
91
+ end
92
+
93
+ it "should use the document bulk save cache" do
94
+ doc = CouchRest::Document.new({"_id" => "bulkdoc", "val" => 3})
95
+ doc.database = @db
96
+ doc.save(true)
97
+ lambda { doc.database.get(doc["_id"]) }.should raise_error(RestClient::ResourceNotFound)
98
+ doc.database.bulk_save
99
+ doc.database.get(doc["_id"])["val"].should == doc["val"]
100
+ end
102
101
  end
103
- it "should make it disappear" do
104
- @doc.destroy
105
- lambda{@db.get @resp['id']}.should raise_error
102
+
103
+ describe "getting from a database" do
104
+ before(:all) do
105
+ @db = reset_test_db!
106
+ @resp = @db.save_doc({
107
+ "key" => "value"
108
+ })
109
+ @doc = @db.get @resp['id']
110
+ end
111
+ it "should return a document" do
112
+ @doc.should be_an_instance_of(CouchRest::Document)
113
+ end
114
+ it "should have a database" do
115
+ @doc.database.should == @db
116
+ end
117
+ it "should be saveable and resavable" do
118
+ @doc["more"] = "keys"
119
+ @doc.save
120
+ @db.get(@resp['id'])["more"].should == "keys"
121
+ @doc["more"] = "these keys"
122
+ @doc.save
123
+ @db.get(@resp['id'])["more"].should == "these keys"
124
+ end
106
125
  end
107
- it "should error when there's no db" do
108
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
109
- lambda{@doc.destroy}.should raise_error(ArgumentError)
126
+
127
+ describe "destroying a document from a db" do
128
+ before(:all) do
129
+ @db = reset_test_db!
130
+ @resp = @db.save_doc({
131
+ "key" => "value"
132
+ })
133
+ @doc = @db.get @resp['id']
134
+ end
135
+ it "should make it disappear" do
136
+ @doc.destroy
137
+ lambda{@db.get @resp['id']}.should raise_error
138
+ end
139
+ it "should error when there's no db" do
140
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
141
+ lambda{@doc.destroy}.should raise_error(ArgumentError)
142
+ end
110
143
  end
111
- end
112
144
 
113
145
 
114
- describe "destroying a document from a db using bulk save" do
115
- before(:all) do
116
- @db = reset_test_db!
117
- @resp = @db.save({
118
- "key" => "value"
119
- })
120
- @doc = @db.get @resp['id']
121
- end
122
- it "should defer actual deletion" do
123
- @doc.destroy(true)
124
- @doc['_id'].should == nil
125
- @doc['_rev'].should == nil
126
- lambda{@db.get @resp['id']}.should_not raise_error
127
- @db.bulk_save
128
- lambda{@db.get @resp['id']}.should raise_error
146
+ describe "destroying a document from a db using bulk save" do
147
+ before(:all) do
148
+ @db = reset_test_db!
149
+ @resp = @db.save_doc({
150
+ "key" => "value"
151
+ })
152
+ @doc = @db.get @resp['id']
153
+ end
154
+ it "should defer actual deletion" do
155
+ @doc.destroy(true)
156
+ @doc['_id'].should == nil
157
+ @doc['_rev'].should == nil
158
+ lambda{@db.get @resp['id']}.should_not raise_error
159
+ @db.bulk_save
160
+ lambda{@db.get @resp['id']}.should raise_error
161
+ end
129
162
  end
130
- end
131
163
 
132
- describe "copying a document" do
133
- before :each do
134
- @db = reset_test_db!
135
- @resp = @db.save({'key' => 'value'})
136
- @docid = 'new-location'
137
- @doc = @db.get(@resp['id'])
138
- end
139
- describe "to a new location" do
140
- it "should work" do
141
- @doc.copy @docid
142
- newdoc = @db.get(@docid)
143
- newdoc['key'].should == 'value'
164
+ describe "copying a document" do
165
+ before :each do
166
+ @db = reset_test_db!
167
+ @resp = @db.save_doc({'key' => 'value'})
168
+ @docid = 'new-location'
169
+ @doc = @db.get(@resp['id'])
170
+ end
171
+ describe "to a new location" do
172
+ it "should work" do
173
+ @doc.copy @docid
174
+ newdoc = @db.get(@docid)
175
+ newdoc['key'].should == 'value'
176
+ end
177
+ it "should fail without a database" do
178
+ lambda{CouchRest::Document.new({"not"=>"a real doc"}).copy}.should raise_error(ArgumentError)
179
+ end
144
180
  end
145
- it "should fail without a database" do
146
- lambda{CouchRest::Document.new({"not"=>"a real doc"}).copy}.should raise_error(ArgumentError)
181
+ describe "to an existing location" do
182
+ before :each do
183
+ @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
184
+ end
185
+ it "should fail without a rev" do
186
+ lambda{@doc.copy @docid}.should raise_error(RestClient::RequestFailed)
187
+ end
188
+ it "should succeed with a rev" do
189
+ @to_be_overwritten = @db.get(@docid)
190
+ @doc.copy "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
191
+ newdoc = @db.get(@docid)
192
+ newdoc['key'].should == 'value'
193
+ end
194
+ it "should succeed given the doc to overwrite" do
195
+ @to_be_overwritten = @db.get(@docid)
196
+ @doc.copy @to_be_overwritten
197
+ newdoc = @db.get(@docid)
198
+ newdoc['key'].should == 'value'
199
+ end
147
200
  end
148
201
  end
149
- describe "to an existing location" do
202
+
203
+ describe "MOVE existing document" do
150
204
  before :each do
151
- @db.save({'_id' => @docid, 'will-exist' => 'here'})
152
- end
153
- it "should fail without a rev" do
154
- lambda{@doc.copy @docid}.should raise_error(RestClient::RequestFailed)
205
+ @db = reset_test_db!
206
+ @resp = @db.save_doc({'key' => 'value'})
207
+ @docid = 'new-location'
208
+ @doc = @db.get(@resp['id'])
155
209
  end
156
- it "should succeed with a rev" do
157
- @to_be_overwritten = @db.get(@docid)
158
- @doc.copy "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
159
- newdoc = @db.get(@docid)
160
- newdoc['key'].should == 'value'
210
+ describe "to a new location" do
211
+ it "should work" do
212
+ @doc.move @docid
213
+ newdoc = @db.get(@docid)
214
+ newdoc['key'].should == 'value'
215
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
216
+ end
217
+ it "should fail without a database" do
218
+ lambda{CouchRest::Document.new({"not"=>"a real doc"}).move}.should raise_error(ArgumentError)
219
+ lambda{CouchRest::Document.new({"_id"=>"not a real doc"}).move}.should raise_error(ArgumentError)
220
+ end
161
221
  end
162
- it "should succeed given the doc to overwrite" do
163
- @to_be_overwritten = @db.get(@docid)
164
- @doc.copy @to_be_overwritten
165
- newdoc = @db.get(@docid)
166
- newdoc['key'].should == 'value'
222
+ describe "to an existing location" do
223
+ before :each do
224
+ @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
225
+ end
226
+ it "should fail without a rev" do
227
+ lambda{@doc.move @docid}.should raise_error(RestClient::RequestFailed)
228
+ lambda{@db.get(@resp['id'])}.should_not raise_error
229
+ end
230
+ it "should succeed with a rev" do
231
+ @to_be_overwritten = @db.get(@docid)
232
+ @doc.move "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
233
+ newdoc = @db.get(@docid)
234
+ newdoc['key'].should == 'value'
235
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
236
+ end
237
+ it "should succeed given the doc to overwrite" do
238
+ @to_be_overwritten = @db.get(@docid)
239
+ @doc.move @to_be_overwritten
240
+ newdoc = @db.get(@docid)
241
+ newdoc['key'].should == 'value'
242
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
243
+ end
167
244
  end
168
245
  end
169
246
  end
170
247
 
171
- describe "MOVE existing document" do
172
- before :each do
248
+ describe "dealing with attachments" do
249
+ before do
173
250
  @db = reset_test_db!
174
- @resp = @db.save({'key' => 'value'})
175
- @docid = 'new-location'
176
- @doc = @db.get(@resp['id'])
251
+ @attach = "<html><head><title>My Doc</title></head><body><p>Has words.</p></body></html>"
252
+ response = @db.save_doc({'key' => 'value'})
253
+ @doc = @db.get(response['id'])
177
254
  end
178
- describe "to a new location" do
179
- it "should work" do
180
- @doc.move @docid
181
- newdoc = @db.get(@docid)
182
- newdoc['key'].should == 'value'
183
- lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
255
+
256
+ def append_attachment(name='test.html', attach=@attach)
257
+ @doc['_attachments'] ||= {}
258
+ @doc['_attachments'][name] = {
259
+ 'type' => 'text/html',
260
+ 'data' => attach
261
+ }
262
+ @doc.save
263
+ @rev = @doc['_rev']
264
+ end
265
+
266
+ describe "PUTing an attachment directly to the doc" do
267
+ before do
268
+ @doc.put_attachment('test.html', @attach)
269
+ end
270
+
271
+ it "is there" do
272
+ @db.fetch_attachment(@doc, 'test.html').should == @attach
273
+ end
274
+
275
+ it "updates the revision" do
276
+ @doc['_rev'].should_not == @rev
184
277
  end
185
- it "should fail without a database" do
186
- lambda{CouchRest::Document.new({"not"=>"a real doc"}).move}.should raise_error(ArgumentError)
187
- lambda{CouchRest::Document.new({"_id"=>"not a real doc"}).move}.should raise_error(ArgumentError)
278
+
279
+ it "updates attachments" do
280
+ @attach2 = "<html><head><title>My Doc</title></head><body><p>Is Different.</p></body></html>"
281
+ @doc.put_attachment('test.html', @attach2)
282
+ @db.fetch_attachment(@doc, 'test.html').should == @attach2
188
283
  end
189
284
  end
190
- describe "to an existing location" do
191
- before :each do
192
- @db.save({'_id' => @docid, 'will-exist' => 'here'})
285
+
286
+ describe "fetching an attachment from a doc directly" do
287
+ before do
288
+ append_attachment
289
+ end
290
+
291
+ it "pulls the attachment" do
292
+ @doc.fetch_attachment('test.html').should == @attach
193
293
  end
194
- it "should fail without a rev" do
195
- lambda{@doc.move @docid}.should raise_error(RestClient::RequestFailed)
196
- lambda{@db.get(@resp['id'])}.should_not raise_error
294
+ end
295
+
296
+ describe "deleting an attachment from a doc directly" do
297
+ before do
298
+ append_attachment
299
+ @doc.delete_attachment('test.html')
197
300
  end
198
- it "should succeed with a rev" do
199
- @to_be_overwritten = @db.get(@docid)
200
- @doc.move "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
201
- newdoc = @db.get(@docid)
202
- newdoc['key'].should == 'value'
203
- lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
301
+
302
+ it "removes it" do
303
+ lambda { @db.fetch_attachment(@doc, 'test.html').should }.should raise_error(RestClient::ResourceNotFound)
204
304
  end
205
- it "should succeed given the doc to overwrite" do
206
- @to_be_overwritten = @db.get(@docid)
207
- @doc.move @to_be_overwritten
208
- newdoc = @db.get(@docid)
209
- newdoc['key'].should == 'value'
210
- lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
305
+
306
+ it "updates the revision" do
307
+ @doc['_rev'].should_not == @rev
211
308
  end
212
309
  end
213
- end
310
+
311
+ end