aqua 0.1.6 → 0.2.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/.gitignore +2 -1
- data/Aqua.gemspec +14 -11
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/aqua.rb +5 -7
- data/lib/aqua/object/config.rb +2 -3
- data/lib/aqua/object/initializers.rb +309 -0
- data/lib/aqua/object/pack.rb +56 -132
- data/lib/aqua/object/query.rb +30 -2
- data/lib/aqua/object/stub.rb +60 -95
- data/lib/aqua/object/tank.rb +1 -0
- data/lib/aqua/object/translator.rb +313 -0
- data/lib/aqua/object/unpack.rb +26 -227
- data/lib/aqua/store/couch_db/couch_db.rb +1 -0
- data/lib/aqua/store/couch_db/database.rb +1 -1
- data/lib/aqua/store/couch_db/design_document.rb +126 -2
- data/lib/aqua/store/couch_db/result_set.rb +36 -0
- data/lib/aqua/store/couch_db/storage_methods.rb +182 -17
- data/lib/aqua/store/storage.rb +4 -48
- data/lib/aqua/support/mash.rb +2 -3
- data/lib/aqua/support/set.rb +4 -16
- data/spec/object/object_fixtures/array_udder.rb +1 -1
- data/spec/object/object_fixtures/persistent.rb +0 -2
- data/spec/object/pack_spec.rb +137 -517
- data/spec/object/query_spec.rb +36 -6
- data/spec/object/stub_spec.rb +10 -9
- data/spec/object/translator_packing_spec.rb +402 -0
- data/spec/object/translator_unpacking_spec.rb +262 -0
- data/spec/object/unpack_spec.rb +162 -320
- data/spec/spec_helper.rb +18 -0
- data/spec/store/couchdb/design_document_spec.rb +148 -7
- data/spec/store/couchdb/result_set_spec.rb +95 -0
- data/spec/store/couchdb/storage_methods_spec.rb +150 -10
- metadata +13 -9
- data/lib/aqua/support/initializers.rb +0 -216
- data/spec/object/object_fixtures/grounded.rb +0 -13
- data/spec/object/object_fixtures/sugar.rb +0 -4
@@ -0,0 +1,262 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require_fixtures
|
3
|
+
|
4
|
+
Aqua.set_storage_engine('CouchDB') # to initialize CouchDB
|
5
|
+
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
6
|
+
Translator = Aqua::Translator unless defined?( Translator )
|
7
|
+
Translator = Aqua::Translator unless defined?( Translator )
|
8
|
+
|
9
|
+
describe Translator, 'unpacking' do
|
10
|
+
before(:each) do
|
11
|
+
build_user_ivars
|
12
|
+
Translator.instance_eval "@classes = {}"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'finding a documents class' do
|
16
|
+
it 'should return a class' do
|
17
|
+
Translator.get_class( 'User' ).should == User
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should cache the mapping of class name to class' do
|
21
|
+
Translator.classes.should == {}
|
22
|
+
Translator.get_class( 'User' )
|
23
|
+
Translator.classes.should == {'User' => User}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'class methods should unpack' do
|
28
|
+
def round_trip( obj, debug=false )
|
29
|
+
@pack = Translator.pack_object(obj).pack
|
30
|
+
if debug
|
31
|
+
puts obj.inspect
|
32
|
+
puts @pack.inspect
|
33
|
+
end
|
34
|
+
@result = Translator.unpack_object(@pack)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'string' do
|
38
|
+
round_trip( 'string' ).should == 'string'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'true' do
|
42
|
+
round_trip( true ).should == true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'false' do
|
46
|
+
round_trip( false ).should == false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'nil' do
|
50
|
+
round_trip( nil ).should == nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'Symbols' do
|
54
|
+
round_trip( :symbol ).should == :symbol
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'times' do
|
58
|
+
time = Time.now
|
59
|
+
round_trip( time ).to_s.should == time.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'dates' do
|
63
|
+
date = Date.today
|
64
|
+
round_trip( date ).should == date
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'Fixnums' do
|
68
|
+
round_trip( 3 ).should == 3
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'Bignums' do
|
72
|
+
round_trip( 12345678901234567890 ).should == 12345678901234567890
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'Floats' do
|
76
|
+
round_trip( 1.68 ).should == 1.68
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'Rationals' do
|
80
|
+
round_trip( Rational( 1,17 ) ).should == Rational( 1,17 )
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'Ranges' do
|
84
|
+
round_trip( (1..3) ).should == (1..3)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'arrays of string' do
|
88
|
+
array = ['one', 'two', 'three']
|
89
|
+
round_trip( array ).should == array
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'mixed arrays' do
|
93
|
+
array = [1, 2, 3.4]
|
94
|
+
round_trip( array ).should == array
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'array derivatives' do
|
98
|
+
array_udder = ArrayUdder.new([1,2,3])
|
99
|
+
array_udder.udder
|
100
|
+
array_udder.instance_variables.should_not be_empty
|
101
|
+
unpacked = round_trip( array_udder )
|
102
|
+
unpacked.class.should == ArrayUdder
|
103
|
+
unpacked.should == array_udder # array values match
|
104
|
+
unpacked.instance_variables.should_not be_empty
|
105
|
+
unpacked.instance_variable_get('@udder').should == array_udder.instance_variable_get('@udder')
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'simple hashes' do
|
109
|
+
hash = {'one' => 'two'}
|
110
|
+
round_trip( hash ).should == hash
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'mixed hashes with string keys' do
|
114
|
+
hash = {'one' => 1}
|
115
|
+
round_trip( hash ).should == hash
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'hashes with object keys' do
|
119
|
+
hash = { 1 => 'one' }
|
120
|
+
round_trip( hash ).should == hash
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'hash derivatives' do
|
124
|
+
canned_hash = CannedHash.new( :one => 'one', 1 => 'one' )
|
125
|
+
canned_hash.yum
|
126
|
+
canned_hash.instance_variables.should_not be_empty
|
127
|
+
unpacked = round_trip( canned_hash )
|
128
|
+
unpacked.class.should == CannedHash
|
129
|
+
unpacked.should == canned_hash
|
130
|
+
unpacked.instance_variables.should_not be_empty
|
131
|
+
unpacked.instance_variable_get('@yum').should == canned_hash.instance_variable_get('@yum')
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'open structs' do
|
135
|
+
struct = OpenStruct.new(:cots => 3, :beds => 'none')
|
136
|
+
round_trip( struct ).should == struct
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'unpacking aquatic objects' do
|
141
|
+
before(:each) do
|
142
|
+
@pack = Translator.pack_object( @user ).pack
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'embedable objects' do
|
146
|
+
log = Translator.unpack_object( @pack['ivars']['@log'] )
|
147
|
+
log.class.should == Log
|
148
|
+
log.instance_variables.each do |ivar_name|
|
149
|
+
log.instance_variable_get(ivar_name).to_s.should ==
|
150
|
+
@log.instance_variable_get(ivar_name).to_s
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'external objects' do
|
155
|
+
before(:each) do
|
156
|
+
@sub_pack = @pack['ivars']['@other_user']
|
157
|
+
@sub_pack['init']['id'] = 'other_user_id'
|
158
|
+
@returned_user = Translator.unpack_object( @sub_pack )
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should reconstitute as an Aqua::Stub object' do
|
162
|
+
@returned_user.class.should == Aqua::Stub
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should respond to stubbed methods' do
|
166
|
+
@returned_user.methods.should include( 'username' )
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should request the delegate object when a non-stubbed method is requested' do
|
170
|
+
User.should_receive(:load).with( 'other_user_id' ).and_return( @other_user )
|
171
|
+
@returned_user.name
|
172
|
+
@returned_user.delegate.should == @other_user
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe 'unpacking file-like things' do
|
178
|
+
# Files have to be stored within an aquatic object, since they are handled as attachments
|
179
|
+
# Since attachments require the base object information in order to be retrieved,
|
180
|
+
# instance information (the base object) has to be passed in with the opts
|
181
|
+
|
182
|
+
class Attachment
|
183
|
+
aquatic
|
184
|
+
attr_accessor :file, :tempfile, :id
|
185
|
+
end
|
186
|
+
|
187
|
+
before(:each) do
|
188
|
+
@file = File.new(File.dirname(__FILE__) + '/../store/couchdb/fixtures_and_data/image_attach.png')
|
189
|
+
|
190
|
+
@tempfile = Tempfile.new('temp.txt')
|
191
|
+
@tempfile.write('I am a tempfile!')
|
192
|
+
@tempfile.rewind
|
193
|
+
|
194
|
+
@attachment = Attachment.new
|
195
|
+
@attachment.id = 'my_base_object_id'
|
196
|
+
@attachment.file = @file
|
197
|
+
@attachment.tempfile = @tempfile
|
198
|
+
|
199
|
+
@pack = Translator.pack_object( @attachment ).pack
|
200
|
+
@opts = Translator::Opts.new
|
201
|
+
@opts.base_object = @attachment
|
202
|
+
@opts.base_id = @attachment.id
|
203
|
+
end
|
204
|
+
|
205
|
+
describe 'files' do
|
206
|
+
before(:each) do
|
207
|
+
@stub = Translator.unpack_object( @pack['ivars']['@file'], @opts )
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should be reconstituted as Aqua::FileStub objects' do
|
211
|
+
@stub.class.should == Aqua::FileStub
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should have stubbed methods' do
|
215
|
+
@stub.methods.should include( 'content_type', 'content_length' )
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should have a information about the base object' do
|
219
|
+
@stub.base_id.should == @attachment.id
|
220
|
+
@stub.base_class.should == Attachment
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should get retrieved when other file methods are called' do
|
224
|
+
Attachment::Storage.should_receive(:attachment).with( 'my_base_object_id', 'image_attach.png' ).and_return( @file )
|
225
|
+
@stub.read
|
226
|
+
@stub.delegate.should == @file
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe "tempfiles" do
|
231
|
+
before(:each) do
|
232
|
+
@stub = Translator.unpack_object( @pack['ivars']['@tempfile'], @opts )
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should be reconstituted as Aqua::FileStub objects' do
|
236
|
+
@stub.class.should == Aqua::FileStub
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should have stubbed methods' do
|
240
|
+
@stub.methods.should include( 'content_type', 'content_length' )
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should have a information about the base object' do
|
244
|
+
@stub.base_id.should == @attachment.id
|
245
|
+
@stub.base_class.should == Attachment
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should get retrieved when other file methods are called' do
|
249
|
+
Attachment::Storage.should_receive(:attachment).with( 'my_base_object_id', 'temp.txt' ).and_return( @tempfile )
|
250
|
+
@stub.read
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe 'reloading' do
|
256
|
+
it 'should be tested separately' do
|
257
|
+
pending( 'regression tests are in unpack_spec')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
end
|
data/spec/object/unpack_spec.rb
CHANGED
@@ -4,358 +4,200 @@ require_fixtures
|
|
4
4
|
Aqua.set_storage_engine('CouchDB') # to initialize CouchDB
|
5
5
|
CouchDB = Aqua::Store::CouchDB unless defined?( CouchDB )
|
6
6
|
|
7
|
-
require File.dirname(__FILE__) + "/../../lib/aqua/support/set"
|
8
|
-
|
9
7
|
describe Aqua::Unpack do
|
10
8
|
before(:each) do
|
11
9
|
User::Storage.database.delete_all
|
12
|
-
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@user = User.new(
|
16
|
-
:username => 'kane',
|
17
|
-
:name => ['Kane', 'Baccigalupi'],
|
18
|
-
:dob => @date,
|
19
|
-
:created_at => @time,
|
20
|
-
:log => @log,
|
21
|
-
:password => 'my secret!'
|
22
|
-
)
|
10
|
+
build_user_ivars
|
11
|
+
@file = File.new( File.dirname(__FILE__) + '/../store/couchdb/fixtures_and_data/image_attach.png' )
|
12
|
+
@user.grab_bag = @file
|
23
13
|
@user.commit!
|
24
|
-
end
|
14
|
+
end
|
25
15
|
|
26
|
-
describe 'loading
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
16
|
+
describe 'loading' do
|
17
|
+
describe 'retreiving the storage document from the database' do
|
18
|
+
it 'should work if the document exists' do
|
19
|
+
document = User._get_store( @user.id )
|
20
|
+
document.class.should == User::Storage
|
21
|
+
end
|
33
22
|
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
describe 'unpacking to a new object' do
|
41
|
-
describe 'init' do
|
42
|
-
it 'should initialize an Aquatic object' do
|
43
|
-
user = User.load( @user.id )
|
44
|
-
user.class.should == User
|
23
|
+
it 'should raise an error if the document does not exist' do
|
24
|
+
lambda{ User._get_store( 'not_no_here' ) }.should raise_error
|
45
25
|
end
|
46
|
-
|
47
|
-
describe 'Array derivatives' do
|
48
|
-
before(:each) do
|
49
|
-
class Arrayed < Array
|
50
|
-
aquatic
|
51
|
-
attr_accessor :my_accessor
|
52
|
-
end
|
53
|
-
arrayish = Arrayed['a', 'b', 'c', 'd']
|
54
|
-
arrayish.my_accessor = 'Newt'
|
55
|
-
arrayish.commit!
|
56
|
-
@id = arrayish.id
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'should create an aquatic Array derivative' do
|
60
|
-
arrayish_2 = Arrayed.load( @id )
|
61
|
-
arrayish_2.class.should == Arrayed
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should load init values into an aquatic Array derivative' do
|
65
|
-
arrayish_2 = Arrayed.load( @id )
|
66
|
-
arrayish_2.first.should == 'a'
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe 'Hash derivatives' do
|
71
|
-
before(:each) do
|
72
|
-
class Hashed < Hash
|
73
|
-
aquatic
|
74
|
-
attr_accessor :my_accessor
|
75
|
-
end
|
76
|
-
hashish = Hashed.new
|
77
|
-
hashish['1'] = '2'
|
78
|
-
hashish.my_accessor = 'Newt'
|
79
|
-
hashish.commit!
|
80
|
-
@id = hashish.id
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'should create an aquatic Hash derivative' do
|
84
|
-
Hashed.load( @id ).class.should == Hashed
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should load init values into an aquatic Hash derivative' do
|
88
|
-
hashish = Hashed.load( @id )
|
89
|
-
hashish['1'].should == '2'
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
26
|
+
end
|
93
27
|
|
94
|
-
describe 'unpacking the
|
95
|
-
|
96
|
-
|
97
|
-
['@created_at', '@dob', '@log', '@name', '@username'].each do |ivar|
|
98
|
-
user.instance_variables.should include( ivar )
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'should unpack Dates' do
|
103
|
-
user = User.load(@user.id)
|
104
|
-
user.dob.should == @user.dob
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'should unpack Times' do
|
108
|
-
user = User.load(@user.id)
|
109
|
-
user.created_at.to_s.should == @user.created_at.to_s
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'should unpack Strings' do
|
113
|
-
user = User.load(@user.id)
|
114
|
-
user.username.should == @user.username
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'should unpack true and false' do
|
118
|
-
# true
|
119
|
-
@user.grab_bag = true
|
120
|
-
@user.commit!
|
121
|
-
user = User.load(@user.id)
|
122
|
-
user.grab_bag.should == true
|
123
|
-
# false
|
124
|
-
@user.grab_bag = false
|
125
|
-
@user.commit!
|
126
|
-
user = User.load(@user.id)
|
127
|
-
user.grab_bag.should == false
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'should unpack Fixnums' do
|
131
|
-
@user.grab_bag = 3
|
132
|
-
@user.commit!
|
133
|
-
user = User.load(@user.id)
|
134
|
-
user.grab_bag.should == 3
|
28
|
+
describe 'unpacking the document' do
|
29
|
+
before(:each) do
|
30
|
+
@new_user = User.load( @user.id )
|
135
31
|
end
|
136
32
|
|
137
|
-
it 'should
|
138
|
-
@
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
33
|
+
it 'should add the base_id to the translator' do
|
34
|
+
@new_user._translator.base_id.should == @user.id
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should initiate the right kind of object' do
|
38
|
+
@new_user.class.should == User
|
143
39
|
end
|
144
40
|
|
145
|
-
it 'should
|
146
|
-
@
|
147
|
-
@user.commit!
|
148
|
-
user = User.load(@user.id)
|
149
|
-
user.grab_bag.should == 1.681
|
41
|
+
it 'should have the right id' do
|
42
|
+
@new_user.id.should == @user.id
|
150
43
|
end
|
151
44
|
|
152
|
-
it 'should
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'should unpack an Array' do
|
160
|
-
user = User.load(@user.id)
|
161
|
-
user.name.should == @user.name
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'should unpace an Array with non-string objects' do
|
165
|
-
@user.grab_bag = ['1', 2]
|
166
|
-
@user.commit!
|
167
|
-
user = User.load(@user.id)
|
168
|
-
user.grab_bag.should == @user.grab_bag
|
45
|
+
it 'should have a revision' do
|
46
|
+
doc = User::Storage.get( @user.id )
|
47
|
+
doc.rev.should_not be_nil
|
48
|
+
doc.rev.should_not be_empty
|
49
|
+
@new_user._rev.should == doc.rev
|
169
50
|
end
|
170
51
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
it 'should unpack an Array derivative' do
|
179
|
-
array_udder = ArrayUdder['1','2','3']
|
180
|
-
array_udder.udder
|
181
|
-
@user.grab_bag = array_udder
|
182
|
-
@user.commit!
|
183
|
-
user = User.load( @user.id )
|
184
|
-
user.grab_bag.should == @user.grab_bag
|
185
|
-
end
|
52
|
+
describe 'instance variables' do
|
53
|
+
it 'should reinstantiate the simple types' do
|
54
|
+
@new_user.created_at.class.should == Time
|
55
|
+
@new_user.created_at.to_s.should == @time.to_s
|
56
|
+
@new_user.dob.should == @date
|
57
|
+
@new_user.name.should == ['Kane', 'Baccigalupi']
|
58
|
+
end
|
186
59
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
60
|
+
it 'should reinstantiate embedded aquatic objects' do
|
61
|
+
# todo: should add a method to log so that it isn't doing equality by object_id
|
62
|
+
@new_user.log.class.should == Log
|
63
|
+
@new_user.log.created_at.to_s.should == @log.created_at.to_s
|
64
|
+
@new_user.log.message.should == @log.message
|
65
|
+
end
|
194
66
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
67
|
+
it 'should have nil for hidden variables' do
|
68
|
+
@new_user.password.should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'that are external aquatic' do
|
72
|
+
before(:each) do
|
73
|
+
@external = @new_user.other_user
|
201
74
|
end
|
202
|
-
|
203
|
-
it 'should
|
204
|
-
@
|
205
|
-
|
206
|
-
|
207
|
-
|
75
|
+
|
76
|
+
it 'should be of class Aqua::Stub' do
|
77
|
+
@external.class.should == Aqua::Stub
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should respond to stubbed methods' do
|
81
|
+
@external.methods.should include( 'username' )
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should retrieve external object when non-stubbed method is called' do
|
85
|
+
User.should_receive(:load).with( @other_user.id ).and_return( @other_user )
|
86
|
+
@external.name
|
87
|
+
@external.delegate.should == @other_user
|
208
88
|
end
|
89
|
+
|
90
|
+
it 'should delegate non-stubbed methods to the external object' do
|
91
|
+
@external.name.should == ['What', 'Ever']
|
92
|
+
end
|
93
|
+
end
|
209
94
|
|
210
|
-
|
211
|
-
|
212
|
-
@
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
95
|
+
describe 'that are attachments' do
|
96
|
+
before(:each) do
|
97
|
+
@attachment = @new_user.grab_bag
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should be of class Aqua::FileStub' do
|
101
|
+
@attachment.class.should == Aqua::FileStub
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should have basic data about the file' do
|
105
|
+
@attachment.methods.should include( 'content_type', 'content_length' )
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should retrieve the attachment as a delegate when non-stubbed methods are called' do
|
109
|
+
User::Storage.should_receive(:attachment).with( @new_user.id, 'image_attach.png' ).and_return( @file )
|
110
|
+
@attachment.read
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should delegate to the loaded attachment' do
|
114
|
+
@attachment.read.should == @file.read
|
115
|
+
end
|
217
116
|
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'reloading' do
|
122
|
+
describe 'with no-initialization' do
|
123
|
+
before(:each) do
|
124
|
+
# dup the @user and change everything! but don't save
|
125
|
+
@changed_user = @user.dup
|
126
|
+
@changed_user.username = 'not kane'
|
127
|
+
@changed_user.name = []
|
128
|
+
@changed_user.dob = Date.parse('1/1/2001')
|
129
|
+
@changed_user.created_at = Time.parse('1/1/2001')
|
130
|
+
@changed_user.log = Log.new(:message => 'some other message')
|
131
|
+
@changed_user.other_user = @user
|
132
|
+
end
|
218
133
|
|
219
|
-
|
220
|
-
|
221
|
-
@user.commit!
|
222
|
-
user = User.load(@user.id)
|
223
|
-
user.grab_bag.should == @user.grab_bag
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'should unpack deep nesting' do
|
227
|
-
@user.grab_bag = {'1' => {'2' => {'3' => 4}}}
|
228
|
-
@user.commit!
|
229
|
-
user = User.load(@user.id)
|
230
|
-
user.grab_bag.should == @user.grab_bag
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'should unpack a Hash derivative' do
|
234
|
-
@struct = OpenStruct.new(
|
235
|
-
:gerbil => true,
|
236
|
-
:cat => 'yup, that too!',
|
237
|
-
:disaster => ['pow', 'blame', 'chase', 'spew'],
|
238
|
-
:nipples => 'yes'
|
239
|
-
)
|
240
|
-
|
241
|
-
@hash_derivative = CannedHash.new(
|
242
|
-
:ingredients => ['Corned Beef', 'Potatoes', 'Tin Can'],
|
243
|
-
:healthometer => false,
|
244
|
-
:random_struct => @struct
|
245
|
-
)
|
246
|
-
|
247
|
-
@user.grab_bag = @hash_derivative
|
248
|
-
@user.commit!
|
249
|
-
|
250
|
-
user = User.load(@user.id)
|
251
|
-
user.grab_bag.should == @user.grab_bag
|
252
|
-
end
|
134
|
+
it 'should not raise an error' do
|
135
|
+
lambda{ @changed_user.reload }.should_not raise_error
|
253
136
|
end
|
254
137
|
|
255
|
-
it 'should
|
256
|
-
@
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
138
|
+
it 'should reset to saved instance variables' do
|
139
|
+
@changed_user.reload
|
140
|
+
@changed_user.username.should == @user.username
|
141
|
+
@changed_user.name.should == @user.name
|
142
|
+
@changed_user.dob.should == @user.dob
|
143
|
+
@changed_user.created_at.to_s.should == @user.created_at.to_s
|
144
|
+
@changed_user.log.created_at.to_s.should == @user.log.created_at.to_s
|
145
|
+
@changed_user.log.message.should == @user.log.message
|
146
|
+
# since this is a stub, not the same object, lets test how it works
|
147
|
+
@changed_user.other_user.name.should == @user.other_user.name
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'with initialization and #replace methods' do
|
152
|
+
class ArrayD < Array
|
153
|
+
aquatic
|
154
|
+
attr_accessor :bucket
|
155
|
+
end
|
262
156
|
|
263
|
-
|
264
|
-
@
|
265
|
-
|
157
|
+
before(:each) do
|
158
|
+
@arrayd = ArrayD.new([1,2])
|
159
|
+
@arrayd.bucket = 34
|
160
|
+
@arrayd.commit!
|
266
161
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
@
|
272
|
-
@user.commit!
|
273
|
-
user = User.load(@user.id)
|
274
|
-
user.grab_bag.should == (1..3)
|
162
|
+
# change the instance, but don't commit
|
163
|
+
@arrayd[0] = 'one'
|
164
|
+
@arrayd[1] = 'two'
|
165
|
+
@arrayd << 'and more'
|
166
|
+
@arrayd.bucket = @arrayd.join(' ... ')
|
275
167
|
end
|
168
|
+
|
169
|
+
it 'should not raise an error' do
|
170
|
+
lambda{ @arrayd.reload }.should_not raise_error
|
171
|
+
end
|
276
172
|
|
277
|
-
it 'should
|
278
|
-
|
279
|
-
@
|
280
|
-
@
|
281
|
-
|
282
|
-
user.grab_bag.should == set
|
173
|
+
it 'should reset to saved initialization' do
|
174
|
+
@arrayd.reload
|
175
|
+
@arrayd[0].should == 1
|
176
|
+
@arrayd[1].should == 2
|
177
|
+
@arrayd[2].should == nil
|
283
178
|
end
|
284
179
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
end
|
298
|
-
|
299
|
-
it 'stub should have methods for content_type and content_length' do
|
300
|
-
@grab_bag.methods.should include('content_type', 'content_length')
|
301
|
-
end
|
302
|
-
|
303
|
-
it 'should retrieve the attachment' do
|
304
|
-
data = @grab_bag.read
|
305
|
-
data.should_not be_nil
|
306
|
-
data.should == @file.read
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
it 'should unpack an aquatic object' do
|
312
|
-
@user.commit!
|
313
|
-
@user.log.should == @log
|
314
|
-
end
|
315
|
-
|
316
|
-
describe 'externally saved aquatic objects' do
|
317
|
-
before(:all) do
|
318
|
-
User.configure_aqua( :embed => {:stub => [:username, :name] } )
|
180
|
+
it 'should reset to saved instance variables' do
|
181
|
+
@reloaded = @arrayd.reload
|
182
|
+
@reloaded.should == @arrayd
|
183
|
+
@arrayd.bucket.should == 34
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'with initialization and no #replace methods' do
|
188
|
+
it 'should raise an exception' do
|
189
|
+
class Event < Range
|
190
|
+
aquatic
|
191
|
+
attr_accessor :name
|
319
192
|
end
|
193
|
+
event = Event.new( Time.parse('11/19/2009'), Time.parse('11/21/2009') )
|
194
|
+
event.name = 'RubyConf 09',
|
195
|
+
event.commit!
|
320
196
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
@time2 = Time.now - 3600
|
327
|
-
@graeme = User.new(:username => 'graeme', :name => ['Graeme', 'Nelson'], :created_at => @time2 )
|
328
|
-
@user = User.new(
|
329
|
-
:username => 'kane',
|
330
|
-
:name => ['Kane', 'Baccigalupi'],
|
331
|
-
:dob => @date,
|
332
|
-
:created_at => @time,
|
333
|
-
:log => @log,
|
334
|
-
:password => 'my secret!',
|
335
|
-
:other_user => @graeme
|
336
|
-
)
|
337
|
-
@user.commit!
|
338
|
-
end
|
339
|
-
|
340
|
-
it 'should load a Stub' do
|
341
|
-
user = User.load(@user.id)
|
342
|
-
user.other_user.class.should == Aqua::Stub
|
343
|
-
end
|
344
|
-
|
345
|
-
it 'should retrieve cached methods' do
|
346
|
-
user = User.load(@user.id)
|
347
|
-
User.should_not_receive(:load)
|
348
|
-
user.other_user.username.should == 'graeme'
|
349
|
-
user.other_user.name.should == ['Graeme', 'Nelson']
|
350
|
-
end
|
351
|
-
|
352
|
-
it 'should retrieve the stubbed object when an additional method is required' do
|
353
|
-
user = User.load(@user.id)
|
354
|
-
user.other_user.created_at.to_s.should == @time2.to_s
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
end
|
359
|
-
end
|
197
|
+
lambda {event.reload}.should raise_error( NotImplementedError )
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
360
202
|
end
|
361
203
|
|