dm-hibernate-adapter 0.1pre-java

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 (34) hide show
  1. data/lib/dm-hibernate-adapter.rb +471 -0
  2. data/lib/dm-hibernate-adapter/dialects.rb +37 -0
  3. data/lib/dm-hibernate-adapter/hibernate.rb +403 -0
  4. data/lib/dm-hibernate-adapter/spec/setup.rb +27 -0
  5. data/lib/dm-hibernate-adapter/transaction.rb +27 -0
  6. data/lib/dm-hibernate-adapter_ext.jar +0 -0
  7. data/lib/jibernate.rb +2 -0
  8. data/spec/abstract_adapter/adapter_shared_spec.rb +514 -0
  9. data/spec/abstract_adapter/dm-hibernate-adapter_spec.rb +25 -0
  10. data/spec/abstract_adapter/rcov.opts +6 -0
  11. data/spec/abstract_adapter/spec.opts +4 -0
  12. data/spec/abstract_adapter/spec_helper.rb +8 -0
  13. data/spec/dm_core/adapter_spec.rb +12 -0
  14. data/spec/dm_core/rcov.opts +6 -0
  15. data/spec/dm_core/spec.opts +5 -0
  16. data/spec/dm_core/spec_helper.rb +42 -0
  17. data/spec/log4j.properties +11 -0
  18. data/spec/transient/dm-hibernate-adapter_spec.rb +57 -0
  19. data/spec/transient/lib/adapter_helpers.rb +107 -0
  20. data/spec/transient/lib/collection_helpers.rb +18 -0
  21. data/spec/transient/lib/counter_adapter.rb +38 -0
  22. data/spec/transient/lib/pending_helpers.rb +46 -0
  23. data/spec/transient/lib/rspec_immediate_feedback_formatter.rb +54 -0
  24. data/spec/transient/rcov.opts +6 -0
  25. data/spec/transient/shared/adapter_shared_spec.rb +408 -0
  26. data/spec/transient/shared/finder_shared_spec.rb +1513 -0
  27. data/spec/transient/shared/model_spec.rb +165 -0
  28. data/spec/transient/shared/property_spec.rb +412 -0
  29. data/spec/transient/shared/resource_shared_spec.rb +1226 -0
  30. data/spec/transient/shared/resource_spec.rb +133 -0
  31. data/spec/transient/shared/sel_shared_spec.rb +112 -0
  32. data/spec/transient/spec.opts +4 -0
  33. data/spec/transient/spec_helper.rb +14 -0
  34. metadata +210 -0
@@ -0,0 +1,165 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ share_examples_for 'An Adapter with model_spec support' do
4
+ # TODO: move these specs into shared specs for #copy
5
+ describe DataMapper::Model do
6
+ before :all do
7
+
8
+ raise '+@adapter+ should be defined in before block' unless instance_variable_get('@adapter')
9
+
10
+ # module ::Blog
11
+
12
+ class Article
13
+ include DataMapper::Resource
14
+
15
+ property :id, Serial
16
+ property :title, String, :required => true
17
+ property :content, Text, :writer => :private, :default => lambda { |resource, property| resource.title }
18
+ property :subtitle, String
19
+ property :author, String, :required => true
20
+
21
+ belongs_to :original, self, :required => false
22
+ has n, :revisions, self, :child_key => [ :original_id ]
23
+ has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
24
+ end
25
+ # end
26
+
27
+ @article_model = Article
28
+ end
29
+
30
+ # supported_by :all do
31
+ before :all do
32
+ @author = 'Dan Kubb'
33
+
34
+ @original = @article_model.create(:title => 'Original Article', :author => @author)
35
+ @article = @article_model.create(:title => 'Sample Article', :original => @original, :author => @author)
36
+ @other = @article_model.create(:title => 'Other Article', :author => @author)
37
+ end
38
+
39
+ it { @article_model.should respond_to(:copy) }
40
+
41
+ describe '#copy' do
42
+ # with_alternate_adapter do
43
+ describe 'between identical models' do
44
+ before :all do
45
+ @return = @resources = @article_model.copy(@repository.name, @alternate_adapter.name)
46
+ end
47
+
48
+ it 'should return a Collection' do
49
+ @return.should be_a_kind_of(DataMapper::Collection)
50
+ end
51
+
52
+ it 'should return Resources' do
53
+ @return.each { |resource| resource.should be_a_kind_of(DataMapper::Resource) }
54
+ end
55
+
56
+ it 'should have each Resource set to the expected Repository' do
57
+ @resources.each { |resource| resource.repository.name.should == @alternate_adapter.name }
58
+ end
59
+
60
+ it 'should create the Resources in the expected Repository' do
61
+ @article_model.all(:repository => DataMapper.repository(@alternate_adapter.name)).should == @resources
62
+ end
63
+ end
64
+
65
+ describe 'between different models' do
66
+ before :all do
67
+ @other.destroy
68
+ @article.destroy
69
+ @original.destroy
70
+
71
+ # make sure the default repository is empty
72
+ @article_model.all(:repository => @repository).should be_empty
73
+
74
+ # add an extra property to the alternate model
75
+ DataMapper.repository(@alternate_adapter.name) do
76
+ @article_model.property :status, String, :default => 'new'
77
+ end
78
+
79
+ if @article_model.respond_to?(:auto_migrate!)
80
+ @article_model.auto_migrate!(@alternate_adapter.name)
81
+ end
82
+
83
+ # add new resources to the alternate repository
84
+ DataMapper.repository(@alternate_adapter.name) do
85
+ @heff1 = @article_model.create(:title => 'Alternate Repository', :author => @author)
86
+ end
87
+
88
+ # copy from the alternate to the default repository
89
+ @return = @resources = @article_model.copy(@alternate_adapter.name, :default)
90
+ end
91
+
92
+ it 'should return a Collection' do
93
+ @return.should be_a_kind_of(DataMapper::Collection)
94
+ end
95
+
96
+ it 'should return Resources' do
97
+ @return.each { |resource| resource.should be_a_kind_of(DataMapper::Resource) }
98
+ end
99
+
100
+ it 'should have each Resource set to the expected Repository' do
101
+ @resources.each { |resource| resource.repository.name.should == :default }
102
+ end
103
+
104
+ it 'should create the Resources in the expected Repository' do
105
+ @article_model.all.should == @resources
106
+ end
107
+ end
108
+ # end
109
+ end
110
+ end
111
+ # end
112
+
113
+ describe DataMapper::Model do
114
+ extend DataMapper::Spec::CollectionHelpers::GroupMethods
115
+
116
+ self.loaded = false
117
+
118
+ before :all do
119
+ module ::Blog
120
+ class Article
121
+ include DataMapper::Resource
122
+
123
+ property :id, Serial
124
+ property :title, String
125
+ property :content, Text
126
+ property :subtitle, String
127
+
128
+ belongs_to :original, self, :required => false
129
+ has n, :revisions, self, :child_key => [ :original_id ]
130
+ has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
131
+ has n, :publications, :through => Resource
132
+ end
133
+
134
+ class Publication
135
+ include DataMapper::Resource
136
+
137
+ property :id, Serial
138
+ property :name, String
139
+
140
+ has n, :articles, :through => Resource
141
+ end
142
+ end
143
+
144
+ @article_model = Blog::Article
145
+ @publication_model = Blog::Publication
146
+ end
147
+
148
+ # supported_by :all do
149
+ # model cannot be a kicker
150
+ def should_not_be_a_kicker; end
151
+
152
+ def model?; true end
153
+
154
+ before :all do
155
+ @articles = @article_model
156
+
157
+ @original = @articles.create(:title => 'Original Article')
158
+ @article = @articles.create(:title => 'Sample Article', :content => 'Sample', :original => @original)
159
+ @other = @articles.create(:title => 'Other Article', :content => 'Other')
160
+ end
161
+
162
+ it_should_behave_like 'Finder Interface'
163
+ # end
164
+ end
165
+ end
@@ -0,0 +1,412 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
3
+
4
+ share_examples_for 'An Adapter with property_spec support' do
5
+ # instance methods
6
+ describe DataMapper::Property do
7
+
8
+ # define the model prior to supported_by
9
+ before :all do
10
+ class ::Track
11
+ include DataMapper::Resource
12
+
13
+ property :id, Serial
14
+ property :artist, String, :lazy => false, :index => :artist_album
15
+ property :title, String, :field => 'name', :index => true
16
+ property :album, String, :index => :artist_album
17
+ property :musicbrainz_hash, String, :unique => true, :unique_index => true
18
+ end
19
+
20
+ class ::Image
21
+ include DataMapper::Resource
22
+
23
+ property :md5hash, String, :key => true, :length => 32
24
+ property :title, String, :required => true, :unique => true
25
+ property :description, Text, :length => 1..1024, :lazy => [ :detail ]
26
+ property :format, String, :default => 'jpeg'
27
+ property :taken_at, Time, :default => proc { Time.now }
28
+ end
29
+
30
+ # TODO
31
+ # <added>
32
+ ::Track.auto_migrate!
33
+ ::Image.auto_migrate!
34
+ # </added>
35
+ end
36
+
37
+ # supported_by :all do
38
+ describe '#field' do
39
+ it 'returns @field value if it is present' do
40
+ Track.properties[:title].field.should eql('name')
41
+ end
42
+
43
+ it 'returns field for specific repository when it is present'
44
+
45
+ it 'sets field value using field naming convention on first reference'
46
+ end
47
+
48
+ describe '#custom?' do
49
+ it 'is true for custom type fields (not provided by dm_core)'
50
+
51
+ it 'is false for core type fields (provided by dm_core)'
52
+ end
53
+
54
+ describe '#default_for' do
55
+ it 'returns default value for non-callables' do
56
+ Image.properties[:format].default_for(Image.new).should == 'jpeg'
57
+ end
58
+
59
+ it 'returns result of a call for callable values' do
60
+ Image.properties[:taken_at].default_for(Image.new).year.should == Time.now.year
61
+ end
62
+ end
63
+
64
+ describe '#eql?' do
65
+ it 'is true for properties with the same model and name' do
66
+ Track.properties[:title].should eql(Track.properties[:title])
67
+ end
68
+
69
+
70
+ it 'is false for properties of different models' do
71
+ Track.properties[:title].should_not eql(Image.properties[:title])
72
+ end
73
+
74
+ it 'is false for properties with different names' do
75
+ Track.properties[:title].should_not eql(Track.properties[:id])
76
+ end
77
+ end
78
+
79
+ describe '#get' do
80
+ before :all do
81
+ @image = Image.create(:md5hash => '5268f0f3f452844c79843e820f998869',
82
+ :title => 'Rome at the sunset',
83
+ :description => 'Just wow')
84
+
85
+ @image.should be_saved
86
+
87
+ @image = Image.first(:fields => [ :md5hash, :title ], :md5hash => @image.md5hash)
88
+ end
89
+
90
+ it 'triggers loading for lazy loaded properties' do
91
+ Image.properties[:description].get(@image)
92
+ Image.properties[:description].loaded?(@image).should be(true)
93
+ end
94
+
95
+ it 'assigns loaded value to @ivar' do
96
+ Image.properties[:description].get(@image)
97
+ @image.instance_variable_get(:@description).should == 'Just wow'
98
+ end
99
+
100
+ it 'sets default value for new records with nil value' do
101
+ Image.properties[:format].get(@image).should == 'jpeg'
102
+ end
103
+
104
+ it 'returns property value' do
105
+ Image.properties[:description].get(@image).should == 'Just wow'
106
+ end
107
+ end
108
+
109
+ describe '#get!' do
110
+ before :all do
111
+ @image = Image.new
112
+
113
+ # now some dark Ruby magic
114
+ @image.instance_variable_set(:@description, 'Is set by magic')
115
+ end
116
+
117
+ it 'gets instance variable value from the resource directly' do
118
+ # if you know a better way to test direct instance variable access,
119
+ # go ahead and make changes to this example
120
+ Image.properties[:description].get!(@image).should == 'Is set by magic'
121
+ end
122
+ end
123
+
124
+ describe '#index' do
125
+ it 'returns true when property has an index' do
126
+ Track.properties[:title].index.should be_true
127
+ end
128
+
129
+ it 'returns index name when property has a named index' do
130
+ Track.properties[:album].index.should eql(:artist_album)
131
+ end
132
+
133
+ it 'returns nil when property has no index' do
134
+ Track.properties[:musicbrainz_hash].index.should be_nil
135
+ end
136
+ end
137
+
138
+ describe '#initialize' do
139
+ describe 'when tracking strategy is explicitly given' do
140
+ it 'uses tracking strategy from options'
141
+ end
142
+
143
+ describe 'when custom type has tracking stragegy' do
144
+ it 'uses tracking strategy from type'
145
+ end
146
+ end
147
+
148
+ describe '#inspect' do
149
+ before :all do
150
+ @str = Track.properties[:title].inspect
151
+ end
152
+
153
+ it 'features model name' do
154
+ @str.should =~ /@model=Track/
155
+ end
156
+
157
+ it 'features property name' do
158
+ @str.should =~ /@name=:title/
159
+ end
160
+ end
161
+
162
+ describe '#key?' do
163
+ describe 'returns true when property is a ' do
164
+ it 'serial key' do
165
+ Track.properties[:id].key?.should be_true
166
+ end
167
+ it 'natural key' do
168
+ Image.properties[:md5hash].key?.should be_true
169
+ end
170
+ end
171
+
172
+ it 'returns true when property is a part of composite key'
173
+
174
+ it 'returns false when property does not relate to a key' do
175
+ Track.properties[:title].key?.should be_false
176
+ end
177
+ end
178
+
179
+ describe '#lazy?' do
180
+ it 'returns true when property is lazy loaded' do
181
+ Image.properties[:description].lazy?.should be_true
182
+ end
183
+
184
+ it 'returns false when property is not lazy loaded' do
185
+ Track.properties[:artist].lazy?.should be_false
186
+ end
187
+ end
188
+
189
+ describe '#length' do
190
+ it 'returns upper bound for Range values' do
191
+ Image.properties[:description].length.should eql(1024)
192
+ end
193
+
194
+ it 'returns value as is for integer values' do
195
+ Image.properties[:md5hash].length.should eql(32)
196
+ end
197
+ end
198
+
199
+ describe '#min' do
200
+ describe 'when :min and :max options not provided to constructor' do
201
+ before do
202
+ @property = Image.property(:integer_with_nil_min, Integer)
203
+ end
204
+
205
+ it 'should be nil' do
206
+ @property.min.should be_nil
207
+ end
208
+ end
209
+
210
+ describe 'when :min option not provided to constructor, but :max is provided' do
211
+ before do
212
+ @property = Image.property(:integer_with_default_min, Integer, :max => 1)
213
+ end
214
+
215
+ it 'should be the default value' do
216
+ @property.min.should == 0
217
+ end
218
+ end
219
+
220
+ describe 'when :min and :max options provided to constructor' do
221
+ before do
222
+ @min = 1
223
+ @property = Image.property(:integer_with_explicit_min, Integer, :min => @min, :max => 2)
224
+ end
225
+
226
+ it 'should be the expected value' do
227
+ @property.min.should == @min
228
+ end
229
+ end
230
+ end
231
+
232
+ describe '#max' do
233
+ describe 'when :min and :max options not provided to constructor' do
234
+ before do
235
+ @property = Image.property(:integer_with_nil_max, Integer)
236
+ end
237
+
238
+ it 'should be nil' do
239
+ @property.max.should be_nil
240
+ end
241
+ end
242
+
243
+ describe 'when :max option not provided to constructor, but :min is provided' do
244
+ before do
245
+ @property = Image.property(:integer_with_default_max, Integer, :min => 1)
246
+ end
247
+
248
+ it 'should be the default value' do
249
+ @property.max.should == 2**31-1
250
+ end
251
+ end
252
+
253
+ describe 'when :min and :max options provided to constructor' do
254
+ before do
255
+ @max = 2
256
+ @property = Image.property(:integer_with_explicit_max, Integer, :min => 1, :max => @max)
257
+ end
258
+
259
+ it 'should be the expected value' do
260
+ @property.max.should == @max
261
+ end
262
+ end
263
+ end
264
+
265
+ describe '#allow_nil?' do
266
+ it 'returns true when property can accept nil as its value' do
267
+ Track.properties[:artist].allow_nil?.should be_true
268
+ end
269
+
270
+ it 'returns false when property nil value is prohibited for this property' do
271
+ Image.properties[:title].allow_nil?.should be_false
272
+ end
273
+ end
274
+
275
+ describe '#serial?' do
276
+ it 'returns true when property is serial (auto incrementing)' do
277
+ Track.properties[:id].serial?.should be_true
278
+ end
279
+
280
+ it 'returns false when property is NOT serial (auto incrementing)' do
281
+ Image.properties[:md5hash].serial?.should be_false
282
+ end
283
+ end
284
+
285
+ # What's going on here:
286
+ #
287
+ # we first set original value and make an assertion on it
288
+ # then we try to set it again, which clears original value
289
+ # (since original value is set, property is no longer dirty)
290
+ describe '#set_original_value' do
291
+ before :all do
292
+ @image = Image.create(
293
+ :md5hash => '5268f0f3f452844c79843e820f998869',
294
+ :title => 'Rome at the sunset',
295
+ :description => 'Just wow'
296
+ )
297
+
298
+ @property = Image.properties[:title]
299
+ end
300
+
301
+ describe 'when value changes' do
302
+ before :all do
303
+ @property.set_original_value(@image, 'New title')
304
+ end
305
+
306
+ it 'sets original value of the property' do
307
+ @image.original_attributes[@property].should == 'Rome at the sunset'
308
+ end
309
+ end
310
+
311
+ describe 'when value stays the same' do
312
+ before :all do
313
+ @property.set_original_value(@image, 'Rome at the sunset')
314
+ end
315
+
316
+ it 'only sets original value when it has changed' do
317
+ @property.set_original_value(@image, 'Rome at the sunset')
318
+ @image.original_attributes.should_not have_key(@property)
319
+ end
320
+ end
321
+ end
322
+
323
+ describe '#set' do
324
+ before :all do
325
+ # keep in mind we must run these examples with a
326
+ # saved model instance
327
+ @image = Image.create(
328
+ :md5hash => '5268f0f3f452844c79843e820f998869',
329
+ :title => 'Rome at the sunset',
330
+ :description => 'Just wow'
331
+ )
332
+
333
+ @property = Image.properties[:title]
334
+ end
335
+
336
+ it 'triggers lazy loading for given resource'
337
+
338
+ it 'type casts given value' do
339
+ @property.set(@image, Addressable::URI.parse('http://test.example/'))
340
+ # get a string that has been typecasted using #to_str
341
+ @image.title.should == 'http://test.example/'
342
+ end
343
+
344
+ it 'stores original value' do
345
+ @property.set(@image, 'Updated value')
346
+ @image.original_attributes[@property].should == 'Rome at the sunset'
347
+ end
348
+
349
+ it 'sets new property value' do
350
+ @property.set(@image, 'Updated value')
351
+ @image.title.should == 'Updated value'
352
+ end
353
+ end
354
+
355
+ describe '#set!' do
356
+ before :all do
357
+ @image = Image.new(:md5hash => '5268f0f3f452844c79843e820f998869',
358
+ :title => 'Rome at the sunset',
359
+ :description => 'Just wow')
360
+
361
+ @property = Image.properties[:title]
362
+ end
363
+
364
+ it 'directly sets instance variable on given resource' do
365
+ @property.set!(@image, 'Set with dark Ruby magic')
366
+ @image.title.should == 'Set with dark Ruby magic'
367
+ end
368
+ end
369
+
370
+ describe '#unique?' do
371
+ it 'is true for fields that explicitly given uniq index' do
372
+ Track.properties[:musicbrainz_hash].unique?.should be_true
373
+ end
374
+
375
+ it 'is true for serial fields' do
376
+ pending do
377
+ Track.properties[:title].unique?.should be_true
378
+ end
379
+ end
380
+
381
+ it 'is true for keys' do
382
+ Image.properties[:md5hash].unique?.should be_true
383
+ end
384
+ end
385
+
386
+ describe '#unique_index' do
387
+ it 'returns true when property has unique index' do
388
+ Track.properties[:musicbrainz_hash].unique_index.should be_true
389
+ end
390
+
391
+ it 'returns nil when property has no unique index' do
392
+ Image.properties[:title].unique_index.should be_nil
393
+ end
394
+ end
395
+
396
+ describe "exception on bad property names" do
397
+ it "is raised for 'model'" do
398
+ lambda {
399
+ Track.property :model, String
400
+ }.should raise_error(ArgumentError)
401
+ end
402
+
403
+ it "is raised for 'repository_name'" do
404
+ lambda {
405
+ Track.property :repository_name, String
406
+ }.should raise_error(ArgumentError)
407
+ end
408
+ end
409
+ # end
410
+ end # DataMapper::Property
411
+
412
+ end