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.
Files changed (37) hide show
  1. data/.gitignore +2 -1
  2. data/Aqua.gemspec +14 -11
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/lib/aqua.rb +5 -7
  6. data/lib/aqua/object/config.rb +2 -3
  7. data/lib/aqua/object/initializers.rb +309 -0
  8. data/lib/aqua/object/pack.rb +56 -132
  9. data/lib/aqua/object/query.rb +30 -2
  10. data/lib/aqua/object/stub.rb +60 -95
  11. data/lib/aqua/object/tank.rb +1 -0
  12. data/lib/aqua/object/translator.rb +313 -0
  13. data/lib/aqua/object/unpack.rb +26 -227
  14. data/lib/aqua/store/couch_db/couch_db.rb +1 -0
  15. data/lib/aqua/store/couch_db/database.rb +1 -1
  16. data/lib/aqua/store/couch_db/design_document.rb +126 -2
  17. data/lib/aqua/store/couch_db/result_set.rb +36 -0
  18. data/lib/aqua/store/couch_db/storage_methods.rb +182 -17
  19. data/lib/aqua/store/storage.rb +4 -48
  20. data/lib/aqua/support/mash.rb +2 -3
  21. data/lib/aqua/support/set.rb +4 -16
  22. data/spec/object/object_fixtures/array_udder.rb +1 -1
  23. data/spec/object/object_fixtures/persistent.rb +0 -2
  24. data/spec/object/pack_spec.rb +137 -517
  25. data/spec/object/query_spec.rb +36 -6
  26. data/spec/object/stub_spec.rb +10 -9
  27. data/spec/object/translator_packing_spec.rb +402 -0
  28. data/spec/object/translator_unpacking_spec.rb +262 -0
  29. data/spec/object/unpack_spec.rb +162 -320
  30. data/spec/spec_helper.rb +18 -0
  31. data/spec/store/couchdb/design_document_spec.rb +148 -7
  32. data/spec/store/couchdb/result_set_spec.rb +95 -0
  33. data/spec/store/couchdb/storage_methods_spec.rb +150 -10
  34. metadata +13 -9
  35. data/lib/aqua/support/initializers.rb +0 -216
  36. data/spec/object/object_fixtures/grounded.rb +0 -13
  37. 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
@@ -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
- @time = Time.now
13
- @date = Date.parse('12/23/1969')
14
- @log = Log.new( :message => "Hello World! This is a log entry", :created_at => Time.now )
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 from storage' do
27
-
28
- it 'should raise in error if the id doesn\'t exist in the data store' do
29
- user = User.new(:id => 'gerbil_farts')
30
- user.id.should == 'gerbil_farts'
31
- lambda{ user.reload! }.should raise_error
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
- it 'should raise an error if the id is nil' do
35
- lambda{ User.new.reload! }.should raise_error
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 instance variables' do
95
- it 'should reinstantiate all the instance variables' do
96
- user = User.load(@user.id)
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 unpack Bignums' do
138
- @user.grab_bag = 12345678901234567890
139
- @user.grab_bag.class.should == Bignum
140
- @user.commit!
141
- user = User.load(@user.id)
142
- user.grab_bag.should == 12345678901234567890
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 unpack Floats' do
146
- @user.grab_bag = 1.681
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 unpack Rationals' do
153
- @user.grab_bag = Rational( 1, 17 )
154
- @user.commit!
155
- user = User.load(@user.id)
156
- user.grab_bag.should == Rational( 1, 17 )
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
- it 'should unpack a deeply nested Array' do
172
- @user.grab_bag = ['1','1','1', ['2','2', ['3']]]
173
- @user.commit!
174
- user = User.load(@user.id)
175
- user.grab_bag.should == @user.grab_bag
176
- end
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
- describe 'hash' do
188
- it 'should unpack a basic hash' do
189
- @user.grab_bag = {'1' => '2'}
190
- @user.commit!
191
- user = User.load(@user.id)
192
- user.grab_bag.should == @user.grab_bag
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
- describe 'hash keys' do
196
- it 'should unpack as symbol and strings' do
197
- @user.grab_bag = {'first' => '1', :second => '2'}
198
- @user.commit!
199
- user = User.load(@user.id)
200
- user.grab_bag.keys.should include('first', :second)
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 unpack a numeric object' do
204
- @user.grab_bag = {1 => 'first', 2 => 'second'}
205
- @user.commit!
206
- user = User.load(@user.id)
207
- user.grab_bag.keys.should include( 1, 2 )
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
- it 'should unpack a more complex object' do
211
- struct = OpenStruct.new( :gerbil => true )
212
- @user.grab_bag = { struct => 'first' }
213
- @user.commit!
214
- user = User.load(@user.id)
215
- user.grab_bag.keys.should include( struct )
216
- end
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
- it 'should unpack non-string values' do
220
- @user.grab_bag = {'1' => 2}
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 unpack a Struct' do
256
- @struct = OpenStruct.new(
257
- :gerbil => true,
258
- :cat => 'yup, that too!',
259
- :disaster => ['pow', 'blame', 'chase', 'spew'],
260
- :nipples => 'yes'
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
- @user.grab_bag = @struct
264
- @user.commit!
265
- user = User.load(@user.id)
157
+ before(:each) do
158
+ @arrayd = ArrayD.new([1,2])
159
+ @arrayd.bucket = 34
160
+ @arrayd.commit!
266
161
 
267
- user.grab_bag.should == @user.grab_bag
268
- end
269
-
270
- it 'should unpack a Range' do
271
- @user.grab_bag = 1..3
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 unpack a Set' do
278
- set = Set.new([1,2,3])
279
- @user.grab_bag = set
280
- @user.commit!
281
- user = User.load(@user.id)
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
- describe 'embedded IO:' do
286
- describe 'File' do
287
- before(:each) do
288
- @file = File.new(File.dirname(__FILE__) + '/../store/couchdb/fixtures_and_data/image_attach.png')
289
- @user.grab_bag = @file
290
- @user.commit!
291
- user = User.load(@user.id)
292
- @grab_bag = user.grab_bag
293
- end
294
-
295
- it 'should unpack Files as FileStubs' do
296
- @grab_bag.class.should == Aqua::FileStub
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
- after(:all) do
322
- User.configure_aqua( :embed => {:stub => :username } )
323
- end
324
-
325
- before(:each) do
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