couchrest 0.12.4 → 0.23
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/README.md +33 -8
- data/Rakefile +11 -2
- data/examples/model/example.rb +19 -13
- data/lib/couchrest.rb +70 -11
- data/lib/couchrest/core/database.rb +121 -62
- data/lib/couchrest/core/design.rb +7 -17
- data/lib/couchrest/core/document.rb +42 -30
- data/lib/couchrest/core/response.rb +16 -0
- data/lib/couchrest/core/server.rb +47 -10
- data/lib/couchrest/helper/upgrade.rb +51 -0
- data/lib/couchrest/mixins.rb +4 -0
- data/lib/couchrest/mixins/attachments.rb +31 -0
- data/lib/couchrest/mixins/callbacks.rb +483 -0
- data/lib/couchrest/mixins/class_proxy.rb +108 -0
- data/lib/couchrest/mixins/design_doc.rb +90 -0
- data/lib/couchrest/mixins/document_queries.rb +44 -0
- data/lib/couchrest/mixins/extended_attachments.rb +68 -0
- data/lib/couchrest/mixins/extended_document_mixins.rb +7 -0
- data/lib/couchrest/mixins/properties.rb +129 -0
- data/lib/couchrest/mixins/validation.rb +242 -0
- data/lib/couchrest/mixins/views.rb +169 -0
- data/lib/couchrest/monkeypatches.rb +81 -6
- data/lib/couchrest/more/casted_model.rb +28 -0
- data/lib/couchrest/more/extended_document.rb +215 -0
- data/lib/couchrest/more/property.rb +40 -0
- data/lib/couchrest/support/blank.rb +42 -0
- data/lib/couchrest/support/class.rb +176 -0
- data/lib/couchrest/validation/auto_validate.rb +163 -0
- data/lib/couchrest/validation/contextual_validators.rb +78 -0
- data/lib/couchrest/validation/validation_errors.rb +118 -0
- data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
- data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
- data/lib/couchrest/validation/validators/format_validator.rb +117 -0
- data/lib/couchrest/validation/validators/formats/email.rb +66 -0
- data/lib/couchrest/validation/validators/formats/url.rb +43 -0
- data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
- data/lib/couchrest/validation/validators/length_validator.rb +134 -0
- data/lib/couchrest/validation/validators/method_validator.rb +89 -0
- data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
- data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
- data/spec/couchrest/core/database_spec.rb +189 -124
- data/spec/couchrest/core/design_spec.rb +13 -6
- data/spec/couchrest/core/document_spec.rb +231 -177
- data/spec/couchrest/core/server_spec.rb +35 -0
- data/spec/couchrest/helpers/pager_spec.rb +1 -1
- data/spec/couchrest/more/casted_extended_doc_spec.rb +40 -0
- data/spec/couchrest/more/casted_model_spec.rb +98 -0
- data/spec/couchrest/more/extended_doc_attachment_spec.rb +130 -0
- data/spec/couchrest/more/extended_doc_spec.rb +509 -0
- data/spec/couchrest/more/extended_doc_subclass_spec.rb +98 -0
- data/spec/couchrest/more/extended_doc_view_spec.rb +355 -0
- data/spec/couchrest/more/property_spec.rb +136 -0
- data/spec/fixtures/more/article.rb +34 -0
- data/spec/fixtures/more/card.rb +20 -0
- data/spec/fixtures/more/course.rb +14 -0
- data/spec/fixtures/more/event.rb +6 -0
- data/spec/fixtures/more/invoice.rb +17 -0
- data/spec/fixtures/more/person.rb +8 -0
- data/spec/fixtures/more/question.rb +6 -0
- data/spec/fixtures/more/service.rb +12 -0
- data/spec/spec_helper.rb +13 -7
- metadata +58 -4
- data/lib/couchrest/core/model.rb +0 -613
- data/spec/couchrest/core/model_spec.rb +0 -855
@@ -14,7 +14,7 @@ describe CouchRest::Design do
|
|
14
14
|
describe "with an unsaved view" do
|
15
15
|
before(:each) do
|
16
16
|
@des = CouchRest::Design.new
|
17
|
-
|
17
|
+
@des.view_by :name
|
18
18
|
end
|
19
19
|
it "should accept a name" do
|
20
20
|
@des.name = "mytest"
|
@@ -31,7 +31,7 @@ describe CouchRest::Design do
|
|
31
31
|
describe "saving" do
|
32
32
|
before(:each) do
|
33
33
|
@des = CouchRest::Design.new
|
34
|
-
|
34
|
+
@des.view_by :name
|
35
35
|
@des.database = reset_test_db!
|
36
36
|
end
|
37
37
|
it "should fail without a name" do
|
@@ -49,7 +49,7 @@ describe CouchRest::Design do
|
|
49
49
|
@db.bulk_save([{"name" => "x"},{"name" => "y"}])
|
50
50
|
@des = CouchRest::Design.new
|
51
51
|
@des.database = @db
|
52
|
-
|
52
|
+
@des.view_by :name
|
53
53
|
end
|
54
54
|
it "should by queryable when it's saved" do
|
55
55
|
@des.name = "mydesign"
|
@@ -57,12 +57,19 @@ describe CouchRest::Design do
|
|
57
57
|
res = @des.view :by_name
|
58
58
|
res["rows"][0]["key"].should == "x"
|
59
59
|
end
|
60
|
+
it "should be queryable on specified database" do
|
61
|
+
@des.name = "mydesign"
|
62
|
+
@des.save
|
63
|
+
@des.database = nil
|
64
|
+
res = @des.view_on @db, :by_name
|
65
|
+
res["rows"][0]["key"].should == "x"
|
66
|
+
end
|
60
67
|
end
|
61
68
|
|
62
69
|
describe "from a saved document" do
|
63
70
|
before(:each) do
|
64
71
|
@db = reset_test_db!
|
65
|
-
@db.
|
72
|
+
@db.save_doc({
|
66
73
|
"_id" => "_design/test",
|
67
74
|
"views" => {
|
68
75
|
"by_name" => {
|
@@ -92,7 +99,7 @@ describe CouchRest::Design do
|
|
92
99
|
@db = reset_test_db!
|
93
100
|
@des = CouchRest::Design.new
|
94
101
|
@des.name = "test"
|
95
|
-
|
102
|
+
@des.view_by :name, :descending => true
|
96
103
|
@des.database = @db
|
97
104
|
@des.save
|
98
105
|
@db.bulk_save([{"name" => "a"},{"name" => "z"}])
|
@@ -116,7 +123,7 @@ describe CouchRest::Design do
|
|
116
123
|
@db = reset_test_db!
|
117
124
|
@des = CouchRest::Design.new
|
118
125
|
@des.name = "test"
|
119
|
-
|
126
|
+
@des.view_by :name, :age
|
120
127
|
@des.database = @db
|
121
128
|
@des.save
|
122
129
|
@db.bulk_save([{"name" => "a", "age" => 2},
|
@@ -1,213 +1,267 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
|
3
|
-
|
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
|
24
|
-
|
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
|
-
@
|
44
|
-
@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
|
57
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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"
|
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
|
+
|
92
70
|
end
|
93
|
-
end
|
94
71
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
lambda{@doc.destroy}.should raise_error(ArgumentError)
|
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
|
110
86
|
end
|
111
|
-
end
|
112
87
|
|
88
|
+
describe "bulk saving" do
|
89
|
+
before :all do
|
90
|
+
@db = reset_test_db!
|
91
|
+
end
|
113
92
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
"
|
119
|
-
|
120
|
-
|
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
|
121
101
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
129
125
|
end
|
130
|
-
end
|
131
126
|
|
132
|
-
describe "
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
138
143
|
end
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
+
|
145
|
+
|
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']
|
144
153
|
end
|
145
|
-
it "should
|
146
|
-
|
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
|
147
161
|
end
|
148
162
|
end
|
149
|
-
|
163
|
+
|
164
|
+
describe "copying a document" do
|
150
165
|
before :each do
|
151
|
-
@db
|
166
|
+
@db = reset_test_db!
|
167
|
+
@resp = @db.save_doc({'key' => 'value'})
|
168
|
+
@docid = 'new-location'
|
169
|
+
@doc = @db.get(@resp['id'])
|
152
170
|
end
|
153
|
-
|
154
|
-
|
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
|
155
180
|
end
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
167
200
|
end
|
168
201
|
end
|
169
202
|
end
|
170
203
|
|
171
|
-
describe "
|
172
|
-
before
|
204
|
+
describe "dealing with attachments" do
|
205
|
+
before do
|
173
206
|
@db = reset_test_db!
|
174
|
-
@
|
175
|
-
|
176
|
-
@doc = @db.get(
|
207
|
+
@attach = "<html><head><title>My Doc</title></head><body><p>Has words.</p></body></html>"
|
208
|
+
response = @db.save_doc({'key' => 'value'})
|
209
|
+
@doc = @db.get(response['id'])
|
177
210
|
end
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
211
|
+
|
212
|
+
def append_attachment(name='test.html', attach=@attach)
|
213
|
+
@doc['_attachments'] ||= {}
|
214
|
+
@doc['_attachments'][name] = {
|
215
|
+
'type' => 'text/html',
|
216
|
+
'data' => attach
|
217
|
+
}
|
218
|
+
@doc.save
|
219
|
+
@rev = @doc['_rev']
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "PUTing an attachment directly to the doc" do
|
223
|
+
before do
|
224
|
+
@doc.put_attachment('test.html', @attach)
|
184
225
|
end
|
185
|
-
|
186
|
-
|
187
|
-
|
226
|
+
|
227
|
+
it "is there" do
|
228
|
+
@db.fetch_attachment(@doc, 'test.html').should == @attach
|
229
|
+
end
|
230
|
+
|
231
|
+
it "updates the revision" do
|
232
|
+
@doc['_rev'].should_not == @rev
|
233
|
+
end
|
234
|
+
|
235
|
+
it "updates attachments" do
|
236
|
+
@attach2 = "<html><head><title>My Doc</title></head><body><p>Is Different.</p></body></html>"
|
237
|
+
@doc.put_attachment('test.html', @attach2)
|
238
|
+
@db.fetch_attachment(@doc, 'test.html').should == @attach2
|
188
239
|
end
|
189
240
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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)
|
204
|
-
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)
|
241
|
+
|
242
|
+
describe "fetching an attachment from a doc directly" do
|
243
|
+
before do
|
244
|
+
append_attachment
|
245
|
+
end
|
246
|
+
|
247
|
+
it "pulls the attachment" do
|
248
|
+
@doc.fetch_attachment('test.html').should == @attach
|
211
249
|
end
|
212
250
|
end
|
213
|
-
|
251
|
+
|
252
|
+
describe "deleting an attachment from a doc directly" do
|
253
|
+
before do
|
254
|
+
append_attachment
|
255
|
+
@doc.delete_attachment('test.html')
|
256
|
+
end
|
257
|
+
|
258
|
+
it "removes it" do
|
259
|
+
lambda { @db.fetch_attachment(@doc, 'test.html').should }.should raise_error(RestClient::ResourceNotFound)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "updates the revision" do
|
263
|
+
@doc['_rev'].should_not == @rev
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|