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.
Files changed (60) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/Aqua.gemspec +121 -0
  4. data/LICENCE_COUCHREST +176 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +105 -0
  7. data/Rakefile +83 -0
  8. data/VERSION +1 -0
  9. data/lib/aqua.rb +101 -0
  10. data/lib/aqua/object/config.rb +43 -0
  11. data/lib/aqua/object/extensions/ar_convert.rb +0 -0
  12. data/lib/aqua/object/extensions/ar_style.rb +0 -0
  13. data/lib/aqua/object/extensions/property.rb +0 -0
  14. data/lib/aqua/object/extensions/validation.rb +0 -0
  15. data/lib/aqua/object/pack.rb +306 -0
  16. data/lib/aqua/object/query.rb +18 -0
  17. data/lib/aqua/object/stub.rb +122 -0
  18. data/lib/aqua/object/tank.rb +54 -0
  19. data/lib/aqua/object/unpack.rb +253 -0
  20. data/lib/aqua/store/couch_db/attachments.rb +183 -0
  21. data/lib/aqua/store/couch_db/couch_db.rb +151 -0
  22. data/lib/aqua/store/couch_db/database.rb +186 -0
  23. data/lib/aqua/store/couch_db/design_document.rb +57 -0
  24. data/lib/aqua/store/couch_db/http_client/adapter/rest_client.rb +53 -0
  25. data/lib/aqua/store/couch_db/http_client/rest_api.rb +62 -0
  26. data/lib/aqua/store/couch_db/server.rb +103 -0
  27. data/lib/aqua/store/couch_db/storage_methods.rb +405 -0
  28. data/lib/aqua/store/storage.rb +59 -0
  29. data/lib/aqua/support/initializers.rb +216 -0
  30. data/lib/aqua/support/mash.rb +144 -0
  31. data/lib/aqua/support/set.rb +23 -0
  32. data/lib/aqua/support/string_extensions.rb +121 -0
  33. data/spec/aqua_spec.rb +19 -0
  34. data/spec/object/config_spec.rb +58 -0
  35. data/spec/object/object_fixtures/array_udder.rb +5 -0
  36. data/spec/object/object_fixtures/canned_hash.rb +5 -0
  37. data/spec/object/object_fixtures/gerbilmiester.rb +18 -0
  38. data/spec/object/object_fixtures/grounded.rb +13 -0
  39. data/spec/object/object_fixtures/log.rb +19 -0
  40. data/spec/object/object_fixtures/persistent.rb +12 -0
  41. data/spec/object/object_fixtures/sugar.rb +4 -0
  42. data/spec/object/object_fixtures/user.rb +38 -0
  43. data/spec/object/pack_spec.rb +607 -0
  44. data/spec/object/query_spec.rb +27 -0
  45. data/spec/object/stub_spec.rb +51 -0
  46. data/spec/object/tank_spec.rb +61 -0
  47. data/spec/object/unpack_spec.rb +361 -0
  48. data/spec/spec.opts +3 -0
  49. data/spec/spec_helper.rb +16 -0
  50. data/spec/store/couchdb/attachments_spec.rb +164 -0
  51. data/spec/store/couchdb/couch_db_spec.rb +104 -0
  52. data/spec/store/couchdb/database_spec.rb +161 -0
  53. data/spec/store/couchdb/design_document_spec.rb +43 -0
  54. data/spec/store/couchdb/fixtures_and_data/document_fixture.rb +3 -0
  55. data/spec/store/couchdb/fixtures_and_data/image_attach.png +0 -0
  56. data/spec/store/couchdb/server_spec.rb +96 -0
  57. data/spec/store/couchdb/storage_methods_spec.rb +408 -0
  58. data/utils/code_statistics.rb +134 -0
  59. data/utils/console +11 -0
  60. metadata +136 -0
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require_fixtures
3
+
4
+ describe Aqua::Query do
5
+ before(:each) do
6
+ User::Storage.database.delete_all
7
+ @time = Time.now
8
+ @date = Date.parse('12/23/1969')
9
+ @log = Log.new( :message => "Hello World! This is a log entry", :created_at => Time.now )
10
+ @user = User.new(
11
+ :username => 'kane',
12
+ :name => ['Kane', 'Baccigalupi'],
13
+ :dob => @date,
14
+ :created_at => @time,
15
+ :log => @log,
16
+ :password => 'my secret!'
17
+ )
18
+ @user.commit!
19
+ end
20
+
21
+ describe 'query_index' do
22
+ it 'should be a class method' do
23
+ User.should respond_to(:query_index)
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,51 @@
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
+
7
+ describe Aqua::Stub do
8
+ before(:each) do
9
+ @params = {
10
+ :id => 'my_great_id',
11
+ :class => 'Gerbilmiester',
12
+ :methods => {
13
+ :gerbil => true,
14
+ :bacon => 'chunky'
15
+ }
16
+ }
17
+ @stub = Aqua::Stub.new( @params )
18
+ end
19
+
20
+ describe 'initialization' do
21
+ it 'should initialize delegate with a TempStub' do
22
+ delegate = @stub.instance_eval( "__getobj__" )
23
+ delegate.class.should == Aqua::TempStub
24
+ end
25
+
26
+ it 'should initialize the delegate_id' do
27
+ @stub.instance_eval('delegate_id').should == 'my_great_id'
28
+ end
29
+
30
+ it 'should initialize the delegate_class' do
31
+ @stub.instance_eval('delegate_class').should == 'Gerbilmiester'
32
+ end
33
+ end
34
+
35
+ describe 'delegation' do
36
+ it 'should return correct values for initialized methods' do
37
+ @stub.gerbil.should == true
38
+ @stub.bacon.should == 'chunky'
39
+ end
40
+
41
+ it 'should try to retrieve an object if an unspecified method is called' do
42
+ Gerbilmiester.should_receive(:load).and_return( Gerbilmiester.new )
43
+ @stub.herd
44
+ end
45
+
46
+ it 'should return correct values for new delegate' do
47
+ Gerbilmiester.should_receive(:load).and_return( Gerbilmiester.new )
48
+ @stub.herd.should == 'Yah, yah, little gerbil'
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require_fixtures
3
+
4
+ describe Aqua::Tank do
5
+ it 'should add the class method :aquatic to all objects' do
6
+ Object.should respond_to( :aquatic )
7
+ User.should respond_to(:aquatic)
8
+ end
9
+
10
+ it 'should add an instance method :aquatic? that identifies whether an object is aquatic' do
11
+ Object.new.should respond_to( :aquatic? )
12
+ Object.new.should_not be_aquatic
13
+ User.new.should be_aquatic
14
+ end
15
+
16
+ it 'should add class method :aquatic? that identifies whether a class is aquatic' do
17
+ Object.should respond_to( :aquatic? )
18
+ Object.should_not be_aquatic
19
+ User.should be_aquatic
20
+ end
21
+
22
+ it 'should add the class method :super_aquatic to all objects'
23
+
24
+ describe 'declaring a class as aquatic' do
25
+ it 'should add pack methods to the class and its instances' do
26
+ Log.should respond_to(:hide_attributes)
27
+ Log.new.should respond_to(:commit)
28
+ end
29
+
30
+ it 'should add unpack methods to the class and its instances' do
31
+ Log.should respond_to( :load )
32
+ Log.new.should respond_to( :reload )
33
+ end
34
+
35
+ it 'should add configuration methods to the class' do
36
+ Log.should respond_to(:configure_aqua)
37
+ end
38
+
39
+ it 'should add query methods to the class and its instances'
40
+ end
41
+
42
+ describe 'including Aqua::Pack on the class' do
43
+ it 'should add pack methods to the class and its instances' do
44
+ Persistent.should respond_to(:hide_attributes)
45
+ Persistent.new.should respond_to(:commit)
46
+ end
47
+
48
+ it 'should add unpack methods to the class and its instances' do
49
+ Persistent.should respond_to( :load )
50
+ Persistent.new.should respond_to( :reload )
51
+ end
52
+
53
+ it 'should add configuration methods to the class' do
54
+ Persistent.should respond_to( :configure_aqua )
55
+ end
56
+
57
+ it 'should add query methods to the class and its instances'
58
+ end
59
+
60
+ end
61
+
@@ -0,0 +1,361 @@
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
+
7
+ require File.dirname(__FILE__) + "/../../lib/aqua/support/set"
8
+
9
+ describe Aqua::Unpack do
10
+ before(:each) do
11
+ 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
+ )
23
+ @user.commit!
24
+ end
25
+
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
33
+
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
45
+ 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
93
+
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
135
+ end
136
+
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
143
+ end
144
+
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
150
+ end
151
+
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
169
+ end
170
+
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
186
+
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
194
+
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)
201
+ 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 )
208
+ end
209
+
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
217
+ end
218
+
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
253
+ end
254
+
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
+ )
262
+
263
+ @user.grab_bag = @struct
264
+ @user.commit!
265
+ user = User.load(@user.id)
266
+
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)
275
+ end
276
+
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
283
+ end
284
+
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] } )
319
+ end
320
+
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
360
+ end
361
+