couchdb 0.1.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.
- data/LICENSE +20 -0
- data/README.rdoc +47 -0
- data/Rakefile +48 -0
- data/lib/couchdb.rb +12 -0
- data/lib/couchdb/collection.rb +121 -0
- data/lib/couchdb/database.rb +57 -0
- data/lib/couchdb/design.rb +57 -0
- data/lib/couchdb/design/view.rb +37 -0
- data/lib/couchdb/document.rb +127 -0
- data/lib/couchdb/row.rb +22 -0
- data/lib/couchdb/server.rb +42 -0
- data/spec/acceptance/database_spec.rb +56 -0
- data/spec/acceptance/document_spec.rb +78 -0
- data/spec/acceptance/server_spec.rb +43 -0
- data/spec/acceptance/views_spec.rb +49 -0
- data/spec/lib/couchdb/collection_spec.rb +121 -0
- data/spec/lib/couchdb/database_spec.rb +138 -0
- data/spec/lib/couchdb/design/view_spec.rb +89 -0
- data/spec/lib/couchdb/design_spec.rb +99 -0
- data/spec/lib/couchdb/document_spec.rb +322 -0
- data/spec/lib/couchdb/row_spec.rb +56 -0
- data/spec/lib/couchdb/server_spec.rb +87 -0
- data/spec/spec_helper.rb +5 -0
- metadata +137 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "lib", "couchdb", "design", "view"))
|
3
|
+
|
4
|
+
describe CouchDB::Design::View do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@database = mock CouchDB::Database
|
8
|
+
@views_proxy = mock CouchDB::Design::ViewsProxy, :<< => nil
|
9
|
+
@design = mock CouchDB::Design, :database => @database, :url => "http://host:1234/test/_design/test_design", :views => @views_proxy
|
10
|
+
|
11
|
+
@view = described_class.new @design, "test_view", "test_map", "test_reduce"
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "initialize" do
|
15
|
+
|
16
|
+
it "should set the design" do
|
17
|
+
@view.design.should == @design
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set the name" do
|
21
|
+
@view.name.should == "test_view"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set the map function" do
|
25
|
+
@view.map.should == "test_map"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should set the reduce function" do
|
29
|
+
@view.reduce.should == "test_reduce"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should add the view to the design" do
|
33
|
+
@views_proxy.should_receive(:<<).with(@view)
|
34
|
+
@view.send :initialize, @design, "test_view", "test_map", "test_reduce"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "to_hash" do
|
40
|
+
|
41
|
+
it "should return a hash with all view data" do
|
42
|
+
@view.to_hash.should == {
|
43
|
+
"test_view" => {
|
44
|
+
"map" => "test_map",
|
45
|
+
"reduce" => "test_reduce"
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "collection" do
|
53
|
+
|
54
|
+
it "should return nil if design is nil" do
|
55
|
+
@view.design = nil
|
56
|
+
@view.collection.should be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return a collection with the database of the design" do
|
60
|
+
collection = @view.collection
|
61
|
+
collection.database.should == @database
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return a collection with the url of the view" do
|
65
|
+
collection = @view.collection
|
66
|
+
collection.url.should == @view.url
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return a collection with the given options" do
|
70
|
+
collection = @view.collection :test => "test value"
|
71
|
+
collection.options.should == { :test => "test value" }
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "url" do
|
77
|
+
|
78
|
+
it "should return nil if design is nil" do
|
79
|
+
@view.design = nil
|
80
|
+
@view.url.should be_nil
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should return the url" do
|
84
|
+
@view.url.should == "http://host:1234/test/_design/test_design/_view/test_view"
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
|
3
|
+
describe CouchDB::Design do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@database = mock CouchDB::Database, :url => "http://host:1234/test"
|
7
|
+
|
8
|
+
@design = described_class.new @database, "test_design"
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "initialize" do
|
12
|
+
|
13
|
+
it "should set the database" do
|
14
|
+
@design.database.should == @database
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should set the id" do
|
18
|
+
@design.id.should == "test_design"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set the attributes" do
|
22
|
+
@design.language.should == "javascript"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "id" do
|
28
|
+
|
29
|
+
it "should return the id without _design prefix" do
|
30
|
+
@design["_id"] = "_design/test_design"
|
31
|
+
@design.id.should == "test_design"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "id=" do
|
37
|
+
|
38
|
+
it "should add the _design prefix to the id" do
|
39
|
+
@design.id = "test_design"
|
40
|
+
@design["_id"].should == "_design/test_design"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "language" do
|
46
|
+
|
47
|
+
it "should return the langauge field" do
|
48
|
+
@design["language"] = "test_language"
|
49
|
+
@design.language.should == "test_language"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "language=" do
|
55
|
+
|
56
|
+
it "should set the langauge field" do
|
57
|
+
@design.language = "test_language"
|
58
|
+
@design["language"].should == "test_language"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "views" do
|
64
|
+
|
65
|
+
before :each do
|
66
|
+
@view_hash = { "test_view" => { "map" => "test_map", "reduce" => "test_reduce" } }
|
67
|
+
@view = mock CouchDB::Design::View, :to_hash => @view_hash
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "<<" do
|
71
|
+
|
72
|
+
it "should add a view" do
|
73
|
+
@design.views << @view
|
74
|
+
@design["views"].should == @view_hash
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "[]" do
|
80
|
+
|
81
|
+
before :each do
|
82
|
+
CouchDB::Design::View.stub(:new).and_return(@view)
|
83
|
+
@design.views << @view
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should initialize a new view" do
|
87
|
+
CouchDB::Design::View.should_receive(:new).with("test_view", "test_map", "test_reduce").and_return(@view)
|
88
|
+
@design.views["test_view"]
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return the new view" do
|
92
|
+
@design.views["test_view"].should == @view
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,322 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
|
3
|
+
describe CouchDB::Document do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
Transport::JSON.stub(:request)
|
7
|
+
@database = mock CouchDB::Database, :url => "http://host:1234/test"
|
8
|
+
@document = described_class.new @database, "_id" => "test_document_1"
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "[]" do
|
12
|
+
|
13
|
+
it "should return the requested property" do
|
14
|
+
@document[:test] = "test value"
|
15
|
+
@document["test"].should == "test value"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "[]=" do
|
21
|
+
|
22
|
+
it "should set the documents content" do
|
23
|
+
@document["test"] = "test value"
|
24
|
+
@document[:test].should == "test value"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "id" do
|
30
|
+
|
31
|
+
it "should return the _id property" do
|
32
|
+
@document["_id"] = "test_document_2"
|
33
|
+
@document.id.should == "test_document_2"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "id=" do
|
39
|
+
|
40
|
+
it "should set the _id property" do
|
41
|
+
@document.id = "test_document_2"
|
42
|
+
@document["_id"].should == "test_document_2"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "rev" do
|
48
|
+
|
49
|
+
it "should return the _rev property" do
|
50
|
+
@document["_rev"] = 1
|
51
|
+
@document.rev.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "rev=" do
|
57
|
+
|
58
|
+
it "should set the _id property" do
|
59
|
+
@document.rev = 1
|
60
|
+
@document["_rev"].should == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "==" do
|
66
|
+
|
67
|
+
it "should be true if the id's of the models are equal" do
|
68
|
+
@document.should == described_class.new(@database, "_id" => "test_document_1")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be false if the id's of the models are not equal" do
|
72
|
+
@document.should_not == described_class.new(@database, "_id" => "invalid")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "new?" do
|
78
|
+
|
79
|
+
it "should be true on new model" do
|
80
|
+
described_class.new(@database).should be_new
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be false on existing model" do
|
84
|
+
@document.rev = "valid"
|
85
|
+
@document.should_not be_new
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "exists?" do
|
91
|
+
|
92
|
+
it "should request the document to check it's existance" do
|
93
|
+
Transport::JSON.should_receive(:request).with(
|
94
|
+
:get,
|
95
|
+
"http://host:1234/test/test_document_1",
|
96
|
+
:expected_status_code => 200
|
97
|
+
)
|
98
|
+
@document.exists?
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return true if document is existing" do
|
102
|
+
@document.exists?.should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should return false if transport returns a 404" do
|
106
|
+
Transport::JSON.stub(:request).and_raise(Transport::UnexpectedStatusCodeError.new(404))
|
107
|
+
@document.exists?.should be_false
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should pass all unexpected status errors that are different from 404" do
|
111
|
+
Transport::JSON.stub(:request).and_raise(Transport::UnexpectedStatusCodeError.new(500))
|
112
|
+
lambda do
|
113
|
+
@document.exists?
|
114
|
+
end.should raise_error(Transport::UnexpectedStatusCodeError)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "load" do
|
120
|
+
|
121
|
+
it "should request the document" do
|
122
|
+
Transport::JSON.should_receive(:request).with(
|
123
|
+
:get,
|
124
|
+
"http://host:1234/test/test_document_1",
|
125
|
+
:expected_status_code => 200
|
126
|
+
)
|
127
|
+
@document.load
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should set the properties with the result" do
|
131
|
+
Transport::JSON.stub(:request).and_return({
|
132
|
+
"_id" => "test_document_2",
|
133
|
+
"_rev" => 1
|
134
|
+
})
|
135
|
+
@document.load
|
136
|
+
@document.id.should == "test_document_2"
|
137
|
+
@document.rev.should == 1
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should raise an NotFoundError if the transport returns a 404 status code" do
|
141
|
+
Transport::JSON.stub(:request).and_raise(Transport::UnexpectedStatusCodeError.new(404))
|
142
|
+
lambda do
|
143
|
+
@document.load
|
144
|
+
end.should raise_error(described_class::NotFoundError)
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "save" do
|
150
|
+
|
151
|
+
context "on a new model" do
|
152
|
+
|
153
|
+
before :each do
|
154
|
+
Transport::JSON.stub(:request).and_return({
|
155
|
+
"id" => "test_document_2",
|
156
|
+
"rev" => 1
|
157
|
+
})
|
158
|
+
@document = described_class.new @database
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should request the creation of the document" do
|
162
|
+
Transport::JSON.should_receive(:request).with(
|
163
|
+
:post,
|
164
|
+
"http://host:1234/test",
|
165
|
+
hash_including(
|
166
|
+
:expected_status_code => 201
|
167
|
+
)
|
168
|
+
).and_return({
|
169
|
+
"id" => "test_document_2",
|
170
|
+
"rev" => 1
|
171
|
+
})
|
172
|
+
@document.save
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should return true if the model has been saved" do
|
176
|
+
@document.save.should be_true
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should set the document id and rev" do
|
180
|
+
@document.save
|
181
|
+
@document.id.should == "test_document_2"
|
182
|
+
@document.rev.should == 1
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should return false on wrong status code" do
|
186
|
+
Transport::JSON.stub(:request).and_raise(Transport::UnexpectedStatusCodeError.new(404))
|
187
|
+
@document.save.should be_false
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
context "on an existing model" do
|
193
|
+
|
194
|
+
before :each do
|
195
|
+
Transport::JSON.stub(:request).and_return({
|
196
|
+
"rev" => 2
|
197
|
+
})
|
198
|
+
@document.rev = 1
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should request the update of the doucment" do
|
202
|
+
Transport::JSON.should_receive(:request).with(
|
203
|
+
:put,
|
204
|
+
"http://host:1234/test/test_document_1",
|
205
|
+
:body => { "_id" => "test_document_1", "_rev" => 1 },
|
206
|
+
:expected_status_code => 201
|
207
|
+
).and_return({
|
208
|
+
"rev" => 2
|
209
|
+
})
|
210
|
+
@document.save
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should return true if the model has been updated" do
|
214
|
+
@document.save.should be_true
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should set the document rev" do
|
218
|
+
@document.save
|
219
|
+
@document.rev.should == 2
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should return false on wrong status code" do
|
223
|
+
Transport::JSON.stub!(:request).and_raise(Transport::UnexpectedStatusCodeError.new(404))
|
224
|
+
@document.save.should be_false
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "destroy" do
|
232
|
+
|
233
|
+
describe "on a new model" do
|
234
|
+
|
235
|
+
before :each do
|
236
|
+
@document = described_class.new @database
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should return false" do
|
240
|
+
@document.destroy.should be_false
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "on an existing model" do
|
246
|
+
|
247
|
+
before :each do
|
248
|
+
@document.rev = 1
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should request the destruction of the document" do
|
252
|
+
Transport::JSON.should_receive(:request).with(
|
253
|
+
:delete,
|
254
|
+
"http://host:1234/test/test_document_1",
|
255
|
+
hash_including(
|
256
|
+
:headers => { "If-Match" => 1 },
|
257
|
+
:expected_status_code => 200
|
258
|
+
)
|
259
|
+
)
|
260
|
+
@document.destroy
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should return true if the model has been destroyed" do
|
264
|
+
@document.destroy.should be_true
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should raise NotFoundError on wrong status code" do
|
268
|
+
Transport::JSON.stub(:request).and_raise(Transport::UnexpectedStatusCodeError.new(404))
|
269
|
+
lambda do
|
270
|
+
@document.destroy
|
271
|
+
end.should raise_error(described_class::NotFoundError)
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should be new afterwards" do
|
275
|
+
@document.destroy
|
276
|
+
@document.should be_new
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "method_missing" do
|
284
|
+
|
285
|
+
it "should pass every call to the inner properties hash" do
|
286
|
+
@document["test"] = "test value"
|
287
|
+
result = nil
|
288
|
+
@document.each{ |key, value| result = [ key, value ] }
|
289
|
+
result.should == [ "test", "test value" ]
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
describe "create" do
|
295
|
+
|
296
|
+
before :each do
|
297
|
+
@document = mock described_class, :save => true
|
298
|
+
described_class.stub(:new).and_return(@document)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should initialize the document" do
|
302
|
+
described_class.should_receive(:new).with(@database).and_return(@document)
|
303
|
+
described_class.create @database
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should save the document" do
|
307
|
+
@document.should_receive(:save).and_return(true)
|
308
|
+
described_class.create @database
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should return the document if save was successful" do
|
312
|
+
described_class.create(@database).should == @document
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should return bil if save failed" do
|
316
|
+
@document.stub(:save).and_return(false)
|
317
|
+
described_class.create(@database).should be_nil
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|