aqua 0.1.6
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/.document +5 -0
- data/.gitignore +7 -0
- data/Aqua.gemspec +121 -0
- data/LICENCE_COUCHREST +176 -0
- data/LICENSE +20 -0
- data/README.rdoc +105 -0
- data/Rakefile +83 -0
- data/VERSION +1 -0
- data/lib/aqua.rb +101 -0
- data/lib/aqua/object/config.rb +43 -0
- data/lib/aqua/object/extensions/ar_convert.rb +0 -0
- data/lib/aqua/object/extensions/ar_style.rb +0 -0
- data/lib/aqua/object/extensions/property.rb +0 -0
- data/lib/aqua/object/extensions/validation.rb +0 -0
- data/lib/aqua/object/pack.rb +306 -0
- data/lib/aqua/object/query.rb +18 -0
- data/lib/aqua/object/stub.rb +122 -0
- data/lib/aqua/object/tank.rb +54 -0
- data/lib/aqua/object/unpack.rb +253 -0
- data/lib/aqua/store/couch_db/attachments.rb +183 -0
- data/lib/aqua/store/couch_db/couch_db.rb +151 -0
- data/lib/aqua/store/couch_db/database.rb +186 -0
- data/lib/aqua/store/couch_db/design_document.rb +57 -0
- data/lib/aqua/store/couch_db/http_client/adapter/rest_client.rb +53 -0
- data/lib/aqua/store/couch_db/http_client/rest_api.rb +62 -0
- data/lib/aqua/store/couch_db/server.rb +103 -0
- data/lib/aqua/store/couch_db/storage_methods.rb +405 -0
- data/lib/aqua/store/storage.rb +59 -0
- data/lib/aqua/support/initializers.rb +216 -0
- data/lib/aqua/support/mash.rb +144 -0
- data/lib/aqua/support/set.rb +23 -0
- data/lib/aqua/support/string_extensions.rb +121 -0
- data/spec/aqua_spec.rb +19 -0
- data/spec/object/config_spec.rb +58 -0
- data/spec/object/object_fixtures/array_udder.rb +5 -0
- data/spec/object/object_fixtures/canned_hash.rb +5 -0
- data/spec/object/object_fixtures/gerbilmiester.rb +18 -0
- data/spec/object/object_fixtures/grounded.rb +13 -0
- data/spec/object/object_fixtures/log.rb +19 -0
- data/spec/object/object_fixtures/persistent.rb +12 -0
- data/spec/object/object_fixtures/sugar.rb +4 -0
- data/spec/object/object_fixtures/user.rb +38 -0
- data/spec/object/pack_spec.rb +607 -0
- data/spec/object/query_spec.rb +27 -0
- data/spec/object/stub_spec.rb +51 -0
- data/spec/object/tank_spec.rb +61 -0
- data/spec/object/unpack_spec.rb +361 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/store/couchdb/attachments_spec.rb +164 -0
- data/spec/store/couchdb/couch_db_spec.rb +104 -0
- data/spec/store/couchdb/database_spec.rb +161 -0
- data/spec/store/couchdb/design_document_spec.rb +43 -0
- data/spec/store/couchdb/fixtures_and_data/document_fixture.rb +3 -0
- data/spec/store/couchdb/fixtures_and_data/image_attach.png +0 -0
- data/spec/store/couchdb/server_spec.rb +96 -0
- data/spec/store/couchdb/storage_methods_spec.rb +408 -0
- data/utils/code_statistics.rb +134 -0
- data/utils/console +11 -0
- metadata +136 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
Aqua.set_storage_engine('CouchDB') # to initialize the Aqua::Store namespace
|
4
|
+
|
5
|
+
# Conveniences for typing with tests ...
|
6
|
+
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
7
|
+
Database = CouchDB::Database unless defined?( Database )
|
8
|
+
Server = CouchDB::Server unless defined?( Server )
|
9
|
+
Design = CouchDB::DesignDocument unless defined?( Design )
|
10
|
+
|
11
|
+
describe CouchDB::DesignDocument do
|
12
|
+
before(:each) do
|
13
|
+
Aqua::Storage.database.delete_all
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'new and create' do
|
17
|
+
before(:each) do
|
18
|
+
@name = 'User'
|
19
|
+
@design = Design.new(:name => @name)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should require a name to build the uri' do
|
23
|
+
design = Design.new
|
24
|
+
lambda{ design.uri }.should raise_error
|
25
|
+
lambda{ @design.uri }.should_not raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should build the correct uri' do
|
29
|
+
@design.uri.should == 'http://127.0.0.1:5984/aqua/_design/User'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should save' do
|
33
|
+
lambda{ @design.save! }.should_not raise_error
|
34
|
+
lambda{ CouchDB.get( @design.uri ) }.should_not raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'views' do
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
Binary file
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
Aqua.set_storage_engine('CouchDB') # to initialize the Aqua::Store namespace
|
4
|
+
Server = Aqua::Store::CouchDB::Server unless defined?( Server )
|
5
|
+
|
6
|
+
describe 'Aqua::Store::CouchDB::Server' do
|
7
|
+
before(:each) do
|
8
|
+
@server = Server.new
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:all) do
|
12
|
+
Server.new.delete_all
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'initialization' do
|
16
|
+
it 'should have a default uri "http://127.0.0.1:5984"' do
|
17
|
+
@server.uri.should == 'http://127.0.0.1:5984'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should have a settable uri' do
|
21
|
+
server = Server.new(:server => 'http://newhost.com:5984')
|
22
|
+
server.uri.should == 'http://newhost.com:5984'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have a database prefix for namespacing the collection of persistance databases' do
|
26
|
+
@server.namespace.should == 'aqua'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have a settable namespace' do
|
30
|
+
server = Server.new(:namespace => 'not_aqua')
|
31
|
+
server.namespace.should == 'not_aqua'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should escape alpha-numeric, plus hyphen and underscore, characters from the namespace' do
|
35
|
+
server = Server.new(:namespace => '¬_!kosher*%')
|
36
|
+
server.namespace.should == 'not_kosher'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should escape :: in the namespace and substitute with __' do
|
40
|
+
server = Server.new(:namespace => 'not::kosher')
|
41
|
+
server.namespace.should == 'not__kosher'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'general couchdb managment features' do
|
46
|
+
it 'should retain a set of uuids to prevent collision' do
|
47
|
+
token = @server.next_uuid( 2 )
|
48
|
+
@server.next_uuid.should_not == token
|
49
|
+
Aqua::Store::CouchDB.should_receive(:get).and_return({'uuids' => []}) # because we have run out of uuids on the last request
|
50
|
+
@server.next_uuid
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should get couchdb info' do
|
54
|
+
info = @server.info #{"couchdb"=>"Welcome", "version"=>"0.9.0"}
|
55
|
+
info.class.should == Hash
|
56
|
+
info['couchdb'].should == 'Welcome'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should restart the couchdb server' do
|
60
|
+
Aqua::Store::CouchDB.should_receive(:post).with("#{@server.uri}/_restart" )
|
61
|
+
@server.restart!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'managing databases' do
|
66
|
+
before(:all) do
|
67
|
+
Server.new.delete_all # this is kind of circular testing here ...
|
68
|
+
Server.new.databases.size.should == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should have a convenience method for creating databases' do
|
72
|
+
@server.database!('first')
|
73
|
+
Aqua::Store::CouchDB::Database.new('first').should be_exists
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should show all_databases related to this server as an array' do
|
77
|
+
@server.database!('second')
|
78
|
+
dbs = @server.databases
|
79
|
+
dbs.class.should == Array
|
80
|
+
dbs.size.should == 2
|
81
|
+
dbs.first.class.should == Aqua::Store::CouchDB::Database
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should show default database in the list of databases' do
|
85
|
+
Aqua::Store::CouchDB::Database.create!
|
86
|
+
@server.databases.size.should == 3
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should delete_all! databases for the namespace' do
|
90
|
+
@server.databases.size.should == 3
|
91
|
+
@server.delete_all!
|
92
|
+
@server.databases.size.should == 0
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,408 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
Aqua.set_storage_engine('CouchDB') # to initialize the Aqua::Store namespace
|
4
|
+
require File.dirname(__FILE__) + '/fixtures_and_data/document_fixture' # Document ... a Mash with the collection of methods
|
5
|
+
|
6
|
+
# Conveniences for typing with tests ...
|
7
|
+
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
8
|
+
Database = CouchDB::Database unless defined?( Database )
|
9
|
+
Server = CouchDB::Server unless defined?( Server)
|
10
|
+
Attachments = CouchDB::Attachments unless defined?( Attachments )
|
11
|
+
|
12
|
+
describe 'CouchDB::StorageMethods' do
|
13
|
+
before(:each) do
|
14
|
+
@params = {
|
15
|
+
:id => 'my_slug/thaz-right',
|
16
|
+
:rev => "shouldn't change yo!",
|
17
|
+
:more => "my big stuff"
|
18
|
+
}
|
19
|
+
@doc = Document.new( @params )
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'initialization' do
|
23
|
+
it 'should initialize with a hash of values accessible by symbol or string' do
|
24
|
+
@doc[:more].should == 'my big stuff'
|
25
|
+
@doc['more'].should == 'my big stuff'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should set the id with the initialization hash' do
|
29
|
+
@doc.id.should == 'my_slug/thaz-right'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should escape the id' do
|
33
|
+
@doc[:_id].should == 'my_slug%2Fthaz-right'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not set the rev and it should discard those keys' do
|
37
|
+
@doc.rev.should == nil
|
38
|
+
@doc[:rev].should == nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'core attributes' do
|
43
|
+
|
44
|
+
describe 'revisions' do
|
45
|
+
before(:each) do
|
46
|
+
@doc.delete if @doc.exists?
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should be an empty array for a new record' do
|
50
|
+
@doc.revisions.should == []
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should have one value after the document is saved' do
|
54
|
+
@doc.save!
|
55
|
+
@doc.revisions.size.should == 1
|
56
|
+
@doc.revisions.first.should == @doc[:_rev]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should continue adding revisions with each save' do
|
60
|
+
@doc.save!
|
61
|
+
@doc['new_attr'] = 'my new attribute, yup!'
|
62
|
+
@doc.save!
|
63
|
+
@doc.revisions.size.should == 2
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'rev should not be publicly settable' do
|
68
|
+
lambda{ @doc.rev = 'my_rev' }.should raise_error
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'changing the id, post save' do
|
72
|
+
before(:each) do
|
73
|
+
@doc.database.delete_all
|
74
|
+
@doc.save!
|
75
|
+
@doc.id = 'something/new_and_fresh'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should change the id' do
|
79
|
+
@doc.id.should == 'something/new_and_fresh'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should change the _id' do
|
83
|
+
@doc[:_id].should == 'something%2Fnew_and_fresh'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should successfully save' do
|
87
|
+
lambda{ @doc.save! }.should_not raise_error
|
88
|
+
@doc.retrieve['id'].should == 'something/new_and_fresh'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should delete earlier versions on save' do
|
92
|
+
@doc.save!
|
93
|
+
lambda{ CouchDB.get( "#{@doc.database.uri}/aqua/my_slug%2Fthaz-right") }.should raise_error
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'database' do
|
100
|
+
before(:each) do
|
101
|
+
@doc.delete
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should have a database per class' do
|
105
|
+
Document.database.should_not be_nil
|
106
|
+
Document.database.uri.should == 'http://127.0.0.1:5984/aqua'
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should not be nil' do
|
110
|
+
@doc.database.should_not be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should have the default database uri by default' do
|
114
|
+
@doc.database.uri.should == 'http://127.0.0.1:5984/aqua'
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should be settable' do
|
118
|
+
@doc.database = Database.create('my_class')
|
119
|
+
@doc.database.uri.should == 'http://127.0.0.1:5984/aqua_my_class'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should depend on database strategies set for storage\'s parent class' do
|
123
|
+
pending( 'Have to create some CouchDB database strategies. Also have to make parent classes configurable.')
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'uri' do
|
128
|
+
before(:each) do
|
129
|
+
@doc.delete if @doc.exists?
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should have use the default database uri by default with the document id' do
|
133
|
+
@doc.uri.should == 'http://127.0.0.1:5984/aqua/my_slug%2Fthaz-right'
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should reflect the non-default database name' do
|
137
|
+
@doc.database = Database.create('my_class')
|
138
|
+
@doc.uri.should == 'http://127.0.0.1:5984/aqua_my_class/my_slug%2Fthaz-right'
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should use a server generated uuid for the id if an id is not provided' do
|
142
|
+
params = @params.dup
|
143
|
+
params.delete(:id)
|
144
|
+
doc = Document.new( params )
|
145
|
+
doc.uri.should match(/\A#{doc.database.uri}\/[a-f0-9]*\z/)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
describe 'save/create' do
|
151
|
+
before(:each) do
|
152
|
+
@doc.delete if @doc.exists?
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'saving should create a document in the database' do
|
156
|
+
@doc.save
|
157
|
+
lambda{ Aqua::Store::CouchDB.get( @doc.uri ) }.should_not raise_error
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'save should return itself if it worked' do
|
161
|
+
return_value = @doc.save
|
162
|
+
return_value.class.should == Document
|
163
|
+
return_value.id.should == @doc.id
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'saving should return false if it did not work' do
|
167
|
+
@doc.save
|
168
|
+
@doc[:_rev] = nil # should cause a conflict error HTTP 409 in couchdb
|
169
|
+
lambda{ @doc.save }.should_not raise_error
|
170
|
+
@doc.save.should == false
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'saving should update the "id" and "rev"' do
|
174
|
+
doc_id = @doc.id
|
175
|
+
doc_rev = @doc.rev
|
176
|
+
@doc.save
|
177
|
+
@doc[:_id].should_not == doc_id
|
178
|
+
@doc.rev.should_not == doc_rev
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'save! should raise an error on failure when creating' do
|
182
|
+
@doc.save
|
183
|
+
@doc[:_rev] = nil # should cause a conflict error HTTP 409 in couchdb
|
184
|
+
lambda{ @doc.save! }.should raise_error
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'create should return itself when successful' do
|
188
|
+
doc = Document.create(@params)
|
189
|
+
doc.class.should == Document
|
190
|
+
doc.rev.should_not be_nil
|
191
|
+
end
|
192
|
+
|
193
|
+
it '#new? should be true for unsaved documents' do
|
194
|
+
@doc.should be_new
|
195
|
+
end
|
196
|
+
|
197
|
+
it '#new? should be false after a document has been saved' do
|
198
|
+
@doc.save!
|
199
|
+
@doc.should_not be_new
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'should #exists? if it has been saved to CouchDB' do
|
203
|
+
@doc.save!
|
204
|
+
@doc.should be_exists
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should not #exists? if the document is new' do
|
208
|
+
@doc.should_not be_exists
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should reload' do
|
212
|
+
@doc.save!
|
213
|
+
@doc[:noodle] = 'spaghetti'
|
214
|
+
@doc.reload
|
215
|
+
@doc[:noodle].should be_nil
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe 'deleting' do
|
220
|
+
before(:each) do
|
221
|
+
@doc.delete if @doc.exists?
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'should #delete a record' do
|
225
|
+
@doc.save!
|
226
|
+
@doc.delete
|
227
|
+
@doc.should_not be_exists
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should return true on successful #delete' do
|
231
|
+
@doc.save!
|
232
|
+
@doc.delete.should == true
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should return false when it fails' do
|
236
|
+
@doc.save!
|
237
|
+
CouchDB.should_receive(:delete).and_raise( CouchDB::Conflict )
|
238
|
+
@doc.delete.should == false
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should raise an error on failure when #delete! is used' do
|
242
|
+
@doc.save!
|
243
|
+
CouchDB.should_receive(:delete).and_raise( CouchDB::Conflict )
|
244
|
+
lambda { @doc.delete! }.should raise_error
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe 'updating' do
|
249
|
+
before(:each) do
|
250
|
+
@doc.delete if @doc.exists?
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'saving after a change should change the revision number' do
|
254
|
+
@doc.save
|
255
|
+
rev = @doc.rev
|
256
|
+
_id = @doc[:_id]
|
257
|
+
id = @doc[:id]
|
258
|
+
@doc['more'] = 'less ... really'
|
259
|
+
@doc['newness'] = 'overrated'
|
260
|
+
@doc.save
|
261
|
+
@doc.id.should == id
|
262
|
+
@doc[:_id].should == _id
|
263
|
+
@doc.rev.should_not == rev
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'saving after a change should retain changed data' do
|
267
|
+
@doc.save
|
268
|
+
@doc['more'] = 'less ... really'
|
269
|
+
@doc['newness'] = 'overrated'
|
270
|
+
@doc.save
|
271
|
+
|
272
|
+
@doc['more'].should == 'less ... really'
|
273
|
+
@doc['newness'].should == 'overrated'
|
274
|
+
@doc.retrieve['more'].should == 'less ... really'
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'attachments' do
|
279
|
+
before(:each) do
|
280
|
+
@file = File.new( File.dirname( __FILE__ ) + '/fixtures_and_data/image_attach.png' )
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'should have an accessor for storing attachments' do
|
284
|
+
@doc.attachments.should == Attachments.new( @doc )
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should add attachments' do
|
288
|
+
@doc.attachments.add(:my_file, @file)
|
289
|
+
@doc.attachments[:my_file].should == @file
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'should pack attachments' do
|
293
|
+
@doc.attachments.add(:my_file, @file)
|
294
|
+
@doc.attachments.add("dup.png", @file)
|
295
|
+
pack = @doc.attachments.pack
|
296
|
+
pack.keys.should include('my_file', 'dup.png')
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should pack attachments to key _attachments on save' do
|
300
|
+
@doc.delete! if @doc.exists?
|
301
|
+
@doc.attachments.add(:my_file, @file)
|
302
|
+
@doc.attachments.add("dup.png", @file)
|
303
|
+
pack = @doc.attachments.pack
|
304
|
+
@doc.save!
|
305
|
+
@doc[:_attachments].should == pack
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should pack attachments before save' do
|
309
|
+
@doc.delete! if @doc.exists?
|
310
|
+
|
311
|
+
@doc.attachments.add(:my_file, @file)
|
312
|
+
@doc.attachments.add("dup.png", @file)
|
313
|
+
pack = @doc.attachments.pack
|
314
|
+
|
315
|
+
@doc.attachments.should_receive( :pack ).and_return( pack )
|
316
|
+
@doc.commit
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'should pack attachments before save' do
|
320
|
+
@doc.delete! if @doc.exists?
|
321
|
+
|
322
|
+
@doc.attachments.add(:my_file, @file)
|
323
|
+
@doc.attachments.add("dup.png", @file)
|
324
|
+
pack = @doc.attachments.pack
|
325
|
+
|
326
|
+
@doc.attachments.should_receive( :pack ).and_return( pack )
|
327
|
+
@doc.commit
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should be correctly formed in database' do
|
331
|
+
@doc.delete! if @doc.exists?
|
332
|
+
|
333
|
+
@doc.attachments.add(:my_file, @file)
|
334
|
+
@doc.attachments.add("dup.png", @file)
|
335
|
+
@doc.commit
|
336
|
+
@doc.reload
|
337
|
+
|
338
|
+
@doc[:_attachments]['dup.png']['content_type'].should == 'image/png'
|
339
|
+
@doc[:_attachments]['dup.png']['stub'].should == true
|
340
|
+
(@doc[:_attachments]['my_file']['length'] > 0).should == true
|
341
|
+
@doc[:_attachments]['my_file']['content_type'].should == 'image/png'
|
342
|
+
@doc[:_attachments]['my_file']['stub'].should == true
|
343
|
+
(@doc[:_attachments]['my_file']['length'] > 0).should == true
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'should be retrievable by a url' do
|
347
|
+
@doc.delete! if @doc.exists?
|
348
|
+
|
349
|
+
@doc.attachments.add(:my_file, @file)
|
350
|
+
@doc.attachments.add("dup.png", @file)
|
351
|
+
@doc.commit
|
352
|
+
|
353
|
+
url = @doc.attachments.uri_for('dup.png')
|
354
|
+
lambda{ CouchDB.get( url, true ) }.should_not raise_error
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'should save and retrieve the data correctly' do
|
358
|
+
@doc.delete! if @doc.exists?
|
359
|
+
|
360
|
+
@doc.attachments.add(:my_file, @file)
|
361
|
+
@doc.attachments.add("dup.png", @file)
|
362
|
+
@doc.commit
|
363
|
+
|
364
|
+
data = @file.read
|
365
|
+
data.should_not be_nil
|
366
|
+
data.should_not be_empty
|
367
|
+
|
368
|
+
file = @doc.attachments.get!( :my_file )
|
369
|
+
file.read.should == data
|
370
|
+
end
|
371
|
+
|
372
|
+
it 'should save and stream the data correctly' do
|
373
|
+
@doc.delete! if @doc.exists?
|
374
|
+
|
375
|
+
@doc.attachments.add(:my_file, @file)
|
376
|
+
@doc.attachments.add("dup.png", @file)
|
377
|
+
@doc.commit
|
378
|
+
|
379
|
+
data = @file.read
|
380
|
+
data.should_not be_nil
|
381
|
+
data.should_not be_empty
|
382
|
+
|
383
|
+
streamed = @doc.attachments.get!( :my_file, true )
|
384
|
+
streamed.should == data
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'should have a class accessor for attachments' do
|
388
|
+
@doc.delete! if @doc.exists?
|
389
|
+
|
390
|
+
@doc.attachments.add(:my_file, @file)
|
391
|
+
@doc.attachments.add("dup.png", @file)
|
392
|
+
@doc.commit
|
393
|
+
|
394
|
+
data = @file.read
|
395
|
+
data.should_not be_nil
|
396
|
+
data.should_not be_empty
|
397
|
+
|
398
|
+
attachment = Document.attachment( @doc.id, 'my_file' )
|
399
|
+
attachment.read.should == data
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
describe 'indexing/views' do
|
405
|
+
it 'should '
|
406
|
+
end
|
407
|
+
|
408
|
+
end
|