dm-core 1.0.0.rc2 → 1.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Gemfile +1 -1
  2. data/LICENSE +1 -1
  3. data/README.rdoc +1 -1
  4. data/Rakefile +3 -4
  5. data/VERSION +1 -1
  6. data/dm-core.gemspec +7 -5
  7. data/lib/dm-core.rb +44 -0
  8. data/lib/dm-core/adapters.rb +1 -1
  9. data/lib/dm-core/adapters/abstract_adapter.rb +16 -0
  10. data/lib/dm-core/collection.rb +2 -2
  11. data/lib/dm-core/model.rb +64 -53
  12. data/lib/dm-core/model/property.rb +14 -6
  13. data/lib/dm-core/model/relationship.rb +10 -18
  14. data/lib/dm-core/property.rb +10 -10
  15. data/lib/dm-core/query.rb +8 -18
  16. data/lib/dm-core/resource.rb +3 -11
  17. data/lib/dm-core/resource/state.rb +13 -16
  18. data/lib/dm-core/resource/state/dirty.rb +11 -1
  19. data/lib/dm-core/resource/state/transient.rb +9 -1
  20. data/lib/dm-core/spec/lib/adapter_helpers.rb +5 -0
  21. data/lib/dm-core/spec/shared/adapter_spec.rb +2 -0
  22. data/lib/dm-core/spec/shared/resource_spec.rb +0 -31
  23. data/lib/dm-core/version.rb +1 -1
  24. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +2 -0
  25. data/spec/public/associations/many_to_many_spec.rb +2 -1
  26. data/spec/public/associations/many_to_one_spec.rb +1 -0
  27. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +1 -0
  28. data/spec/public/associations/one_to_many_spec.rb +2 -0
  29. data/spec/public/associations/one_to_one_spec.rb +2 -0
  30. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +1 -0
  31. data/spec/public/collection_spec.rb +2 -0
  32. data/spec/public/finalize_spec.rb +34 -0
  33. data/spec/public/model/hook_spec.rb +1 -0
  34. data/spec/public/model/property_spec.rb +1 -0
  35. data/spec/public/model/relationship_spec.rb +22 -0
  36. data/spec/public/model_spec.rb +138 -3
  37. data/spec/public/property/discriminator_spec.rb +1 -0
  38. data/spec/public/property/object_spec.rb +1 -0
  39. data/spec/public/property_spec.rb +13 -4
  40. data/spec/public/resource_spec.rb +1 -0
  41. data/spec/public/sel_spec.rb +2 -0
  42. data/spec/public/shared/collection_shared_spec.rb +0 -45
  43. data/spec/public/shared/finder_shared_spec.rb +110 -0
  44. data/spec/public/shared/property_shared_spec.rb +1 -1
  45. data/spec/rcov.opts +1 -1
  46. data/spec/semipublic/associations/many_to_many_spec.rb +3 -0
  47. data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
  48. data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
  49. data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
  50. data/spec/semipublic/associations/relationship_spec.rb +6 -0
  51. data/spec/semipublic/query/conditions/comparison_spec.rb +3 -0
  52. data/spec/semipublic/query/conditions/operation_spec.rb +1 -0
  53. data/spec/semipublic/query/path_spec.rb +2 -0
  54. data/spec/semipublic/query_spec.rb +2 -3
  55. data/spec/semipublic/resource/state/clean_spec.rb +2 -1
  56. data/spec/semipublic/resource/state/deleted_spec.rb +2 -1
  57. data/spec/semipublic/resource/state/dirty_spec.rb +42 -20
  58. data/spec/semipublic/resource/state/immutable_spec.rb +7 -1
  59. data/spec/semipublic/resource/state/transient_spec.rb +69 -40
  60. data/spec/semipublic/resource/state_spec.rb +72 -66
  61. data/spec/semipublic/shared/property_shared_spec.rb +1 -0
  62. data/spec/semipublic/shared/resource_shared_spec.rb +1 -0
  63. data/spec/spec_helper.rb +0 -10
  64. data/tasks/spec.rake +3 -0
  65. metadata +9 -7
@@ -8,6 +8,7 @@ describe DataMapper::Model::Property do
8
8
 
9
9
  property :id, Serial
10
10
  end
11
+ DataMapper.finalize
11
12
  end
12
13
 
13
14
  describe '#property' do
@@ -468,6 +468,7 @@ describe DataMapper::Associations do
468
468
 
469
469
  Car.belongs_to(@name, :required => false)
470
470
  Engine.has(1, :car)
471
+ DataMapper.finalize
471
472
  end
472
473
 
473
474
  supported_by :all do
@@ -486,6 +487,7 @@ describe DataMapper::Associations do
486
487
  describe 'with a :key option' do
487
488
  before :all do
488
489
  @relationship = Car.belongs_to("#{@name}_with_key".to_sym, @model, :required => false, :key => true)
490
+ DataMapper.finalize
489
491
  end
490
492
 
491
493
  it 'should create a foreign key that is part of the key' do
@@ -501,6 +503,7 @@ describe DataMapper::Associations do
501
503
  before :all do
502
504
  Car.has(1, :engine)
503
505
  Engine.belongs_to(:car)
506
+ DataMapper.finalize
504
507
  end
505
508
 
506
509
  supported_by :all do
@@ -628,6 +631,7 @@ describe DataMapper::Associations do
628
631
  describe 'with a model' do
629
632
  before :all do
630
633
  Engine.belongs_to(:vehicle, Car)
634
+ DataMapper.finalize
631
635
  end
632
636
 
633
637
  it 'should set the relationship target model' do
@@ -638,6 +642,7 @@ describe DataMapper::Associations do
638
642
  describe 'with a :model option' do
639
643
  before :all do
640
644
  Engine.belongs_to(:vehicle, :model => Car)
645
+ DataMapper.finalize
641
646
  end
642
647
 
643
648
  it 'should set the relationship target model' do
@@ -648,6 +653,7 @@ describe DataMapper::Associations do
648
653
  describe 'with a single element as :child_key option' do
649
654
  before :all do
650
655
  Engine.belongs_to(:vehicle, :model => Car, :child_key => :bike_id)
656
+ DataMapper.finalize
651
657
  end
652
658
 
653
659
  it 'should set the relationship child key' do
@@ -658,6 +664,7 @@ describe DataMapper::Associations do
658
664
  describe 'with an array as :child_key option' do
659
665
  before :all do
660
666
  Engine.belongs_to(:vehicle, :model => Car, :child_key => [:bike_id])
667
+ DataMapper.finalize
661
668
  end
662
669
 
663
670
  it 'should set the relationship child key' do
@@ -668,6 +675,7 @@ describe DataMapper::Associations do
668
675
  describe 'with a single element as :parent_key option' do
669
676
  before :all do
670
677
  Engine.belongs_to(:vehicle, :model => Car, :parent_key => :name)
678
+ DataMapper.finalize
671
679
  end
672
680
 
673
681
  it 'should set the relationship parent key' do
@@ -678,6 +686,7 @@ describe DataMapper::Associations do
678
686
  describe 'with an array as :parent_key option' do
679
687
  before :all do
680
688
  Engine.belongs_to(:vehicle, :model => Car, :parent_key => [:name])
689
+ DataMapper.finalize
681
690
  end
682
691
 
683
692
  it 'should set the relationship parent key' do
@@ -696,6 +705,7 @@ describe DataMapper::Associations do
696
705
 
697
706
  Car.has(1, @name)
698
707
  Engine.belongs_to(:car)
708
+ DataMapper.finalize
699
709
  end
700
710
 
701
711
  supported_by :all do
@@ -720,6 +730,7 @@ describe DataMapper::Associations do
720
730
 
721
731
  Car.has(1, @name, :through => DataMapper::Resource)
722
732
  Engine.has(1, :car, :through => DataMapper::Resource)
733
+ DataMapper.finalize
723
734
  end
724
735
 
725
736
  supported_by :all do
@@ -753,6 +764,7 @@ describe DataMapper::Associations do
753
764
 
754
765
  Car.has(1..4, @name)
755
766
  Door.belongs_to(:car, :required => false)
767
+ DataMapper.finalize
756
768
  end
757
769
 
758
770
  supported_by :all do
@@ -777,6 +789,7 @@ describe DataMapper::Associations do
777
789
 
778
790
  Window.has(1, :car, :through => DataMapper::Resource)
779
791
  Car.has(1..4, :windows, :through => DataMapper::Resource)
792
+ DataMapper.finalize
780
793
  end
781
794
 
782
795
  supported_by :all do
@@ -806,6 +819,7 @@ describe DataMapper::Associations do
806
819
  describe 'when the 3rd argument is a Model' do
807
820
  before :all do
808
821
  Car.has(1, :engine, Engine)
822
+ DataMapper.finalize
809
823
  end
810
824
 
811
825
  it 'should set the relationship target model' do
@@ -816,6 +830,7 @@ describe DataMapper::Associations do
816
830
  describe 'when the 3rd argument is a String' do
817
831
  before :all do
818
832
  Car.has(1, :engine, 'Engine')
833
+ DataMapper.finalize
819
834
  end
820
835
 
821
836
  it 'should set the relationship target model' do
@@ -836,6 +851,7 @@ describe DataMapper::Associations do
836
851
  describe 'when a relationship has an inverse' do
837
852
  before :all do
838
853
  @engine_relationship = Car.has(1, :engine, :inverse => Engine.belongs_to(:sports_car, Car))
854
+ DataMapper.finalize
839
855
  end
840
856
 
841
857
  supported_by :all do
@@ -848,6 +864,7 @@ describe DataMapper::Associations do
848
864
  describe 'when a relationship does not have an inverse' do
849
865
  before :all do
850
866
  @engine_relationship = Car.has(1, :engine)
867
+ DataMapper.finalize
851
868
  end
852
869
 
853
870
  supported_by :all do
@@ -865,6 +882,7 @@ describe DataMapper::Associations do
865
882
  class ::ElectricCar < Car; end
866
883
 
867
884
  Car.has(1, :engine, :inverse => Engine.belongs_to(:sports_car, Car))
885
+ DataMapper.finalize
868
886
  end
869
887
 
870
888
  supported_by :all do
@@ -889,6 +907,7 @@ describe DataMapper::Associations do
889
907
  class ::ElectricCar < Car; end
890
908
 
891
909
  Car.has(1, :engine)
910
+ DataMapper.finalize
892
911
  end
893
912
 
894
913
  supported_by :all do
@@ -915,6 +934,7 @@ describe DataMapper::Associations do
915
934
  class ::ElectricCar < Car; end
916
935
 
917
936
  ElectricCar.has(1, :engine, :inverse => Engine.belongs_to(:sports_car, Car))
937
+ DataMapper.finalize
918
938
  end
919
939
 
920
940
  supported_by :all do
@@ -939,6 +959,7 @@ describe DataMapper::Associations do
939
959
  class ::ElectricCar < Car; end
940
960
 
941
961
  ElectricCar.has(1, :engine)
962
+ DataMapper.finalize
942
963
  end
943
964
 
944
965
  supported_by :all do
@@ -978,6 +999,7 @@ describe DataMapper::Associations do
978
999
  belongs_to :owner, Employee, :required => false
979
1000
  has n, :employees
980
1001
  end
1002
+ DataMapper.finalize
981
1003
  end
982
1004
 
983
1005
  supported_by :all do
@@ -18,6 +18,7 @@ describe DataMapper::Model do
18
18
  has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
19
19
  end
20
20
  end
21
+ DataMapper.finalize
21
22
 
22
23
  @article_model = Blog::Article
23
24
  end
@@ -121,9 +122,9 @@ describe DataMapper::Model do
121
122
  class Article
122
123
  include DataMapper::Resource
123
124
 
124
- property :id, Serial
125
- property :title, String
126
- property :content, Text
125
+ property :id, Serial
126
+ property :title, String, :required => true, :default => 'Default Title'
127
+ property :content, Text
127
128
  property :subtitle, String
128
129
 
129
130
  belongs_to :original, self, :required => false
@@ -141,6 +142,7 @@ describe DataMapper::Model do
141
142
  has n, :articles, :through => Resource
142
143
  end
143
144
  end
145
+ DataMapper.finalize
144
146
 
145
147
  @article_model = Blog::Article
146
148
  @publication_model = Blog::Publication
@@ -160,6 +162,139 @@ describe DataMapper::Model do
160
162
  @other = @articles.create(:title => 'Other Article', :content => 'Other')
161
163
  end
162
164
 
165
+ describe '#new' do
166
+ subject { model.new(*args) }
167
+
168
+ let(:model) { @article_model }
169
+
170
+ context 'with no arguments' do
171
+ let(:args) { [] }
172
+
173
+ it { should be_instance_of(model) }
174
+
175
+ its(:attributes) { should == { :title => 'Default Title' } }
176
+ end
177
+
178
+ context 'with an empty Hash' do
179
+ let(:args) { [ {} ] }
180
+
181
+ it { should be_instance_of(model) }
182
+
183
+ its(:attributes) { should == { :title => 'Default Title' } }
184
+ end
185
+
186
+ context 'with a non-empty Hash' do
187
+ let(:attributes) { { :title => 'A Title' } }
188
+ let(:args) { [ attributes ] }
189
+
190
+ it { should be_instance_of(model) }
191
+
192
+ its(:attributes) { should == attributes }
193
+ end
194
+
195
+ context 'with nil' do
196
+ let(:args) { [ nil ] }
197
+
198
+ it { should be_instance_of(model) }
199
+
200
+ its(:attributes) { should == { :title => 'Default Title' } }
201
+ end
202
+ end
203
+
204
+ [ :create, :create! ].each do |method|
205
+ describe "##{method}" do
206
+ subject { model.send(method, *args) }
207
+
208
+ let(:model) { @article_model }
209
+
210
+ context 'with no arguments' do
211
+ let(:args) { [] }
212
+
213
+ it { should be_instance_of(model) }
214
+
215
+ it { should be_saved }
216
+ end
217
+
218
+ context 'with an empty Hash' do
219
+ let(:args) { [ {} ] }
220
+
221
+ it { should be_instance_of(model) }
222
+
223
+ it { should be_saved }
224
+ end
225
+
226
+ context 'with a non-empty Hash' do
227
+ let(:attributes) { { :title => 'A Title' } }
228
+ let(:args) { [ attributes ] }
229
+
230
+ it { should be_instance_of(model) }
231
+
232
+ it { should be_saved }
233
+
234
+ its(:title) { should == attributes[:title] }
235
+ end
236
+
237
+ context 'with nil' do
238
+ let(:args) { [ nil ] }
239
+
240
+ it { should be_instance_of(model) }
241
+
242
+ it { should be_saved }
243
+ end
244
+ end
245
+ end
246
+
247
+ [ :destroy, :destroy! ].each do |method|
248
+ describe "##{method}" do
249
+ subject { model.send(method) }
250
+
251
+ let(:model) { @article_model }
252
+
253
+ it 'should remove all resources' do
254
+ method(:subject).should change { model.any? }.from(true).to(false)
255
+ end
256
+ end
257
+ end
258
+
259
+ [ :update, :update! ].each do |method|
260
+ describe "##{method}" do
261
+ subject { model.send(method, *args) }
262
+
263
+ let(:model) { @article_model }
264
+
265
+ context 'with attributes' do
266
+ let(:attributes) { { :title => 'Updated Title' } }
267
+ let(:args) { [ attributes ] }
268
+
269
+ it { should be(true) }
270
+
271
+ it 'should persist the changes' do
272
+ subject
273
+ model.all(:fields => [ :title ]).map { |resource| resource.title }.uniq.should == [ attributes[:title] ]
274
+ end
275
+ end
276
+
277
+ context 'with attributes where one is a parent association' do
278
+ let(:attributes) { { :original => @other } }
279
+ let(:args) { [ attributes ] }
280
+
281
+ it { should be(true) }
282
+
283
+ it 'should persist the changes' do
284
+ subject
285
+ model.all(:fields => [ :original_id ]).map { |resource| resource.original }.uniq.should == [ attributes[:original] ]
286
+ end
287
+ end
288
+
289
+ context 'with attributes where a required property is nil' do
290
+ let(:attributes) { { :title => nil } }
291
+ let(:args) { [ attributes ] }
292
+
293
+ it { should be(false) }
294
+ end
295
+ end
296
+ end
297
+
163
298
  it_should_behave_like 'Finder Interface'
164
299
 
165
300
  it 'DataMapper::Model should respond to raise_on_save_failure' do
@@ -14,6 +14,7 @@ describe DataMapper::Property::Discriminator do
14
14
  class Announcement < Article; end
15
15
  class Release < Announcement; end
16
16
  end
17
+ DataMapper.finalize
17
18
 
18
19
  @article_model = Blog::Article
19
20
  @announcement_model = Blog::Announcement
@@ -12,6 +12,7 @@ describe DataMapper::Property, 'Object type' do
12
12
  end
13
13
  end
14
14
 
15
+ DataMapper.finalize
15
16
  @model = Blog::Article
16
17
  @property = @model.properties[:meta]
17
18
  end
@@ -25,6 +25,7 @@ describe DataMapper::Property do
25
25
  property :format, String, :default => 'jpeg'
26
26
  property :taken_at, Time, :default => proc { Time.now }
27
27
  end
28
+ DataMapper.finalize
28
29
  end
29
30
 
30
31
  supported_by :all do
@@ -93,8 +94,8 @@ describe DataMapper::Property do
93
94
  Track.properties[:album].index.should eql(:artist_album)
94
95
  end
95
96
 
96
- it 'returns nil when property has no index' do
97
- Track.properties[:musicbrainz_hash].index.should be_nil
97
+ it 'returns false when property has no index' do
98
+ Track.properties[:musicbrainz_hash].index.should be(false)
98
99
  end
99
100
  end
100
101
 
@@ -308,8 +309,16 @@ describe DataMapper::Property do
308
309
  Track.properties[:musicbrainz_hash].unique_index.should be(true)
309
310
  end
310
311
 
311
- it 'returns nil when property has no unique index' do
312
- Image.properties[:title].unique_index.should be_nil
312
+ it 'returns false when property has no unique index' do
313
+ Track.properties[:title].unique_index.should be(false)
314
+ end
315
+
316
+ it 'returns true when property is unique' do
317
+ Image.properties[:title].unique_index.should be(true)
318
+ end
319
+
320
+ it 'returns :key when property is a key' do
321
+ Track.properties[:id].unique_index.should == :key
313
322
  end
314
323
  end
315
324
 
@@ -59,6 +59,7 @@ describe DataMapper::Resource do
59
59
 
60
60
  property :name, String, :key => true, :default => 'a default value'
61
61
  end
62
+ DataMapper.finalize
62
63
 
63
64
  @user_model = Blog::User
64
65
  @author_model = Blog::Author
@@ -26,6 +26,8 @@ describe 'SEL', 'with STI subclasses' do
26
26
  class Comment < Message; end
27
27
  end
28
28
 
29
+ DataMapper.finalize
30
+
29
31
  @author_model = Blog::Author
30
32
  @message_model = Blog::Message
31
33
  @article_model = Blog::Article
@@ -481,51 +481,6 @@ share_examples_for 'A public Collection' do
481
481
  end
482
482
  end
483
483
 
484
- # TODO: move this to enumerable_shared_spec.rb
485
- it { should respond_to(:each) }
486
-
487
- describe '#each' do
488
- before :all do
489
- rescue_if @skip do
490
- @resources = @articles.dup.entries
491
- @resources.should_not be_empty
492
-
493
- @yield = []
494
- @collections = []
495
-
496
- @return = @articles.each do |resource|
497
- @yield << resource
498
- @collections << [ resource, resource.collection.object_id ]
499
- end
500
- end
501
- end
502
-
503
- it 'should return a Collection' do
504
- @return.should be_kind_of(DataMapper::Collection)
505
- end
506
-
507
- it 'should return self' do
508
- @return.should equal(@articles)
509
- end
510
-
511
- it 'should yield to each entry' do
512
- @yield.should == @articles
513
- end
514
-
515
- it 'should yield Resources' do
516
- @yield.each { |resource| resource.should be_kind_of(DataMapper::Resource) }
517
- end
518
-
519
- it 'should relate the Resource collection to the Collection within the block only' do
520
- pending_if 'Fix SEL for m:m', @many_to_many do
521
- @collections.each do |resource, object_id|
522
- resource.collection.should_not equal(@articles) # collection outside block
523
- object_id.should == @articles.object_id # collection inside block
524
- end
525
- end
526
- end
527
- end
528
-
529
484
  it { should respond_to(:insert) }
530
485
 
531
486
  describe '#insert' do