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.
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +3 -4
- data/VERSION +1 -1
- data/dm-core.gemspec +7 -5
- data/lib/dm-core.rb +44 -0
- data/lib/dm-core/adapters.rb +1 -1
- data/lib/dm-core/adapters/abstract_adapter.rb +16 -0
- data/lib/dm-core/collection.rb +2 -2
- data/lib/dm-core/model.rb +64 -53
- data/lib/dm-core/model/property.rb +14 -6
- data/lib/dm-core/model/relationship.rb +10 -18
- data/lib/dm-core/property.rb +10 -10
- data/lib/dm-core/query.rb +8 -18
- data/lib/dm-core/resource.rb +3 -11
- data/lib/dm-core/resource/state.rb +13 -16
- data/lib/dm-core/resource/state/dirty.rb +11 -1
- data/lib/dm-core/resource/state/transient.rb +9 -1
- data/lib/dm-core/spec/lib/adapter_helpers.rb +5 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +2 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +0 -31
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +2 -0
- data/spec/public/associations/many_to_many_spec.rb +2 -1
- data/spec/public/associations/many_to_one_spec.rb +1 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/associations/one_to_many_spec.rb +2 -0
- data/spec/public/associations/one_to_one_spec.rb +2 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +1 -0
- data/spec/public/collection_spec.rb +2 -0
- data/spec/public/finalize_spec.rb +34 -0
- data/spec/public/model/hook_spec.rb +1 -0
- data/spec/public/model/property_spec.rb +1 -0
- data/spec/public/model/relationship_spec.rb +22 -0
- data/spec/public/model_spec.rb +138 -3
- data/spec/public/property/discriminator_spec.rb +1 -0
- data/spec/public/property/object_spec.rb +1 -0
- data/spec/public/property_spec.rb +13 -4
- data/spec/public/resource_spec.rb +1 -0
- data/spec/public/sel_spec.rb +2 -0
- data/spec/public/shared/collection_shared_spec.rb +0 -45
- data/spec/public/shared/finder_shared_spec.rb +110 -0
- data/spec/public/shared/property_shared_spec.rb +1 -1
- data/spec/rcov.opts +1 -1
- data/spec/semipublic/associations/many_to_many_spec.rb +3 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
- data/spec/semipublic/associations/relationship_spec.rb +6 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +3 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1 -0
- data/spec/semipublic/query/path_spec.rb +2 -0
- data/spec/semipublic/query_spec.rb +2 -3
- data/spec/semipublic/resource/state/clean_spec.rb +2 -1
- data/spec/semipublic/resource/state/deleted_spec.rb +2 -1
- data/spec/semipublic/resource/state/dirty_spec.rb +42 -20
- data/spec/semipublic/resource/state/immutable_spec.rb +7 -1
- data/spec/semipublic/resource/state/transient_spec.rb +69 -40
- data/spec/semipublic/resource/state_spec.rb +72 -66
- data/spec/semipublic/shared/property_shared_spec.rb +1 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -10
- data/tasks/spec.rake +3 -0
- metadata +9 -7
@@ -21,6 +21,10 @@ share_examples_for 'Finder Interface' do
|
|
21
21
|
pending if @skip
|
22
22
|
end
|
23
23
|
|
24
|
+
it 'should be Enumerable' do
|
25
|
+
@articles.should be_kind_of(Enumerable)
|
26
|
+
end
|
27
|
+
|
24
28
|
[ :[], :slice ].each do |method|
|
25
29
|
it { @articles.should respond_to(method) }
|
26
30
|
|
@@ -880,6 +884,71 @@ share_examples_for 'Finder Interface' do
|
|
880
884
|
end
|
881
885
|
end
|
882
886
|
|
887
|
+
it { @articles.should respond_to(:each) }
|
888
|
+
|
889
|
+
describe '#each' do
|
890
|
+
subject { @articles.each(&block) }
|
891
|
+
|
892
|
+
let(:yields) { [] }
|
893
|
+
let(:block) { lambda { |resource| yields << resource } }
|
894
|
+
|
895
|
+
before do
|
896
|
+
@copy = @articles.kind_of?(Class) ? @articles : @articles.dup
|
897
|
+
@copy.to_a
|
898
|
+
end
|
899
|
+
|
900
|
+
it { should equal(@articles) }
|
901
|
+
|
902
|
+
it { method(:subject).should change { yields.dup }.from([]).to(@copy.to_a) }
|
903
|
+
end
|
904
|
+
|
905
|
+
it { @articles.should respond_to(:fetch) }
|
906
|
+
|
907
|
+
describe '#fetch' do
|
908
|
+
subject { @articles.fetch(*args, &block) }
|
909
|
+
|
910
|
+
let(:block) { nil }
|
911
|
+
|
912
|
+
context 'with a valid index and no default' do
|
913
|
+
let(:args) { [ 0 ] }
|
914
|
+
|
915
|
+
before do
|
916
|
+
@copy = @articles.kind_of?(Class) ? @articles : @articles.dup
|
917
|
+
@copy.to_a
|
918
|
+
end
|
919
|
+
|
920
|
+
should_not_be_a_kicker
|
921
|
+
|
922
|
+
it { should be_kind_of(DataMapper::Resource) }
|
923
|
+
|
924
|
+
it { should == @copy.entries.fetch(*args) }
|
925
|
+
end
|
926
|
+
|
927
|
+
context 'with an invalid index and no default' do
|
928
|
+
let(:args) { [ 42 ] }
|
929
|
+
|
930
|
+
it { method(:subject).should raise_error(IndexError) }
|
931
|
+
end
|
932
|
+
|
933
|
+
context 'with an invalid index and a default' do
|
934
|
+
let(:default) { mock('Default') }
|
935
|
+
let(:args) { [ 42, default ] }
|
936
|
+
|
937
|
+
it { should equal(default) }
|
938
|
+
end
|
939
|
+
|
940
|
+
context 'with an invalid index and a block default' do
|
941
|
+
let(:yields) { [] }
|
942
|
+
let(:default) { mock('Default') }
|
943
|
+
let(:block) { lambda { |index| yields << index; default } }
|
944
|
+
let(:args) { [ 42 ] }
|
945
|
+
|
946
|
+
it { should equal(default) }
|
947
|
+
|
948
|
+
it { method(:subject).should change { yields.dup }.from([]).to([ 42 ]) }
|
949
|
+
end
|
950
|
+
end
|
951
|
+
|
883
952
|
it { @articles.should respond_to(:first) }
|
884
953
|
|
885
954
|
describe '#first' do
|
@@ -1200,6 +1269,16 @@ share_examples_for 'Finder Interface' do
|
|
1200
1269
|
it 'should should be the last Resource in the Collection matching the query' do
|
1201
1270
|
@resource.should == @article
|
1202
1271
|
end
|
1272
|
+
|
1273
|
+
it 'should not update the original query order' do
|
1274
|
+
collection = @articles.all(:order => [ :title ])
|
1275
|
+
original_order = collection.query.order[0].dup
|
1276
|
+
last = collection.last(:content => 'Sample')
|
1277
|
+
|
1278
|
+
last.should == @resource
|
1279
|
+
|
1280
|
+
collection.query.order[0].should == original_order
|
1281
|
+
end
|
1203
1282
|
end
|
1204
1283
|
|
1205
1284
|
describe 'with a limit specified' do
|
@@ -1269,6 +1348,37 @@ share_examples_for 'Finder Interface' do
|
|
1269
1348
|
end
|
1270
1349
|
end
|
1271
1350
|
|
1351
|
+
it { @articles.should respond_to(:values_at) }
|
1352
|
+
|
1353
|
+
describe '#values_at' do
|
1354
|
+
subject { @articles.values_at(*args) }
|
1355
|
+
|
1356
|
+
before :all do
|
1357
|
+
@copy = @articles.kind_of?(Class) ? @articles : @articles.dup
|
1358
|
+
@copy.to_a
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
context 'with positive offset' do
|
1362
|
+
let(:args) { [ 0 ] }
|
1363
|
+
|
1364
|
+
should_not_be_a_kicker
|
1365
|
+
|
1366
|
+
it { should be_kind_of(Array) }
|
1367
|
+
|
1368
|
+
it { should == @copy.entries.values_at(*args) }
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
describe 'with negative offset' do
|
1372
|
+
let(:args) { [ -1 ] }
|
1373
|
+
|
1374
|
+
should_not_be_a_kicker
|
1375
|
+
|
1376
|
+
it { should be_kind_of(Array) }
|
1377
|
+
|
1378
|
+
it { should == @copy.entries.values_at(*args) }
|
1379
|
+
end
|
1380
|
+
end
|
1381
|
+
|
1272
1382
|
it 'should respond to a belongs_to relationship method with #method_missing' do
|
1273
1383
|
pending_if 'Model#method_missing should delegate to relationships', @articles.kind_of?(Class) do
|
1274
1384
|
@articles.should respond_to(:original)
|
@@ -108,7 +108,7 @@ share_examples_for 'A public Property' do
|
|
108
108
|
[true, false].each do |value|
|
109
109
|
describe "when created with :#{method} => #{value}" do
|
110
110
|
before :all do
|
111
|
-
opt = method.to_s.
|
111
|
+
opt = method.to_s.chomp('?').to_sym
|
112
112
|
@property = @type.new(@model, @name, opt => value)
|
113
113
|
end
|
114
114
|
|
data/spec/rcov.opts
CHANGED
@@ -50,6 +50,7 @@ describe 'Many to Many Associations' do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
|
53
54
|
@article_model = Blog::Article
|
54
55
|
@author_model = Blog::Author
|
55
56
|
|
@@ -61,6 +62,8 @@ describe 'Many to Many Associations' do
|
|
61
62
|
@subject_without_default = @article_model.has(n, :without_default, 'Author', :through => :without_default_join, :via => :author)
|
62
63
|
@subject_with_default = @article_model.has(n, :with_default, 'Author', :through => :with_default_join, :via => :author, :default => @default_value)
|
63
64
|
@subject_with_default_callable = @article_model.has(n, :with_default_callable, 'Author', :through => :with_default_callable_join, :via => :author, :default => lambda { |resource, relationship| @default_value_callable })
|
65
|
+
|
66
|
+
DataMapper.finalize
|
64
67
|
end
|
65
68
|
|
66
69
|
supported_by :all do
|
@@ -32,6 +32,8 @@ describe 'One to Many Associations' do
|
|
32
32
|
@subject_without_default = @article_model.has(n, :without_default, @author_model, :child_key => [ :without_default_id ])
|
33
33
|
@subject_with_default = @article_model.has(n, :with_default, @author_model, :child_key => [ :with_default_id ], :default => @default_value)
|
34
34
|
@subject_with_default_callable = @article_model.has(n, :with_default_callable, @author_model, :child_key => [ :with_default_callable_id ], :default => lambda { |resource, relationship| @default_value_callable })
|
35
|
+
|
36
|
+
DataMapper.finalize
|
35
37
|
end
|
36
38
|
|
37
39
|
supported_by :all do
|
@@ -30,6 +30,8 @@ describe 'One to One Associations' do
|
|
30
30
|
@subject_without_default = @article_model.has(1, :without_default, @author_model, :child_key => [ :without_default_id ])
|
31
31
|
@subject_with_default = @article_model.has(1, :with_default, @author_model, :child_key => [ :with_default_id ], :default => @default_value)
|
32
32
|
@subject_with_default_callable = @article_model.has(1, :with_default_callable, @author_model, :child_key => [ :with_default_callable_id ], :default => lambda { |resource, relationship| @default_value_callable })
|
33
|
+
|
34
|
+
DataMapper.finalize
|
33
35
|
end
|
34
36
|
|
35
37
|
supported_by :all do
|
@@ -38,6 +38,7 @@ describe DataMapper::Associations::Relationship do
|
|
38
38
|
# TODO: move this to spec/public/model/relationship_spec.rb
|
39
39
|
@article_relationship.child_repository_name.should == :default
|
40
40
|
@article_relationship.parent_repository_name.should be_nil
|
41
|
+
DataMapper.finalize
|
41
42
|
end
|
42
43
|
|
43
44
|
it 'should return the inverted relationships' do
|
@@ -58,6 +59,7 @@ describe DataMapper::Associations::Relationship do
|
|
58
59
|
# TODO: move this to spec/public/model/relationship_spec.rb
|
59
60
|
@article_relationship.child_repository_name.should == :default
|
60
61
|
@article_relationship.parent_repository_name.should be_nil
|
62
|
+
DataMapper.finalize
|
61
63
|
end
|
62
64
|
|
63
65
|
it 'should return the inverted relationships' do
|
@@ -78,6 +80,7 @@ describe DataMapper::Associations::Relationship do
|
|
78
80
|
# TODO: move this to spec/public/model/relationship_spec.rb
|
79
81
|
@article_relationship.child_repository_name.should == :default
|
80
82
|
@article_relationship.parent_repository_name.should == :default
|
83
|
+
DataMapper.finalize
|
81
84
|
end
|
82
85
|
|
83
86
|
it 'should return the inverted relationships' do
|
@@ -98,6 +101,7 @@ describe DataMapper::Associations::Relationship do
|
|
98
101
|
|
99
102
|
# after Relationship#inverse to ensure no match
|
100
103
|
@expected = @comment_model.belongs_to(:article)
|
104
|
+
DataMapper.finalize
|
101
105
|
end
|
102
106
|
|
103
107
|
it 'should return a Relationship' do
|
@@ -129,6 +133,7 @@ describe DataMapper::Associations::Relationship do
|
|
129
133
|
|
130
134
|
# after Relationship#inverse to ensure no match
|
131
135
|
@expected = @article_model.has(n, :comments)
|
136
|
+
DataMapper.finalize
|
132
137
|
end
|
133
138
|
|
134
139
|
it 'should return a Relationship' do
|
@@ -156,6 +161,7 @@ describe DataMapper::Associations::Relationship do
|
|
156
161
|
describe '#valid?' do
|
157
162
|
before :all do
|
158
163
|
@relationship = @article_model.has(n, :comments)
|
164
|
+
DataMapper.finalize
|
159
165
|
end
|
160
166
|
|
161
167
|
supported_by :all do
|
@@ -14,6 +14,8 @@ shared_examples_for 'DataMapper::Query::Conditions::AbstractComparison' do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
DataMapper.finalize
|
18
|
+
|
17
19
|
@model = Blog::Article
|
18
20
|
end
|
19
21
|
|
@@ -270,6 +272,7 @@ describe DataMapper::Query::Conditions::Comparison do
|
|
270
272
|
property :title, String, :required => true
|
271
273
|
end
|
272
274
|
end
|
275
|
+
DataMapper.finalize
|
273
276
|
|
274
277
|
@model = Blog::Article
|
275
278
|
end
|
@@ -24,6 +24,7 @@ describe DataMapper::Query::Path do
|
|
24
24
|
@relationship = Author.relationships[:articles]
|
25
25
|
@relationships = [ @relationship ]
|
26
26
|
@property = Article.properties[:title]
|
27
|
+
DataMapper.finalize
|
27
28
|
end
|
28
29
|
|
29
30
|
it { DataMapper::Query::Path.should respond_to(:new) }
|
@@ -103,6 +104,7 @@ describe DataMapper::Query::Path do
|
|
103
104
|
@property = Article.properties[:title]
|
104
105
|
|
105
106
|
@path = DataMapper::Query::Path.new(@relationships)
|
107
|
+
DataMapper.finalize
|
106
108
|
end
|
107
109
|
|
108
110
|
it { @path.should respond_to(:==) }
|
@@ -1306,9 +1306,8 @@ describe DataMapper::Query do
|
|
1306
1306
|
property :id, Serial
|
1307
1307
|
end
|
1308
1308
|
|
1309
|
-
#
|
1310
|
-
|
1311
|
-
Other.send(:assert_valid)
|
1309
|
+
# finalize the models
|
1310
|
+
DataMapper.finalize
|
1312
1311
|
|
1313
1312
|
@repository = DataMapper::Repository.new(:default)
|
1314
1313
|
@model = User
|
@@ -13,6 +13,7 @@ describe DataMapper::Resource::State::Clean do
|
|
13
13
|
belongs_to :parent, self, :required => false
|
14
14
|
has n, :children, self, :inverse => :parent
|
15
15
|
end
|
16
|
+
DataMapper.finalize
|
16
17
|
|
17
18
|
@model = Author
|
18
19
|
end
|
@@ -25,7 +26,7 @@ describe DataMapper::Resource::State::Clean do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
after do
|
28
|
-
@
|
29
|
+
@model.destroy!
|
29
30
|
end
|
30
31
|
|
31
32
|
[ :commit, :rollback ].each do |method|
|
@@ -14,6 +14,7 @@ describe DataMapper::Resource::State::Deleted do
|
|
14
14
|
has n, :children, self, :inverse => :parent
|
15
15
|
end
|
16
16
|
|
17
|
+
DataMapper.finalize
|
17
18
|
@model = Author
|
18
19
|
end
|
19
20
|
|
@@ -24,7 +25,7 @@ describe DataMapper::Resource::State::Deleted do
|
|
24
25
|
end
|
25
26
|
|
26
27
|
after do
|
27
|
-
@
|
28
|
+
@model.destroy!
|
28
29
|
end
|
29
30
|
|
30
31
|
describe '#commit' do
|
@@ -14,11 +14,15 @@ describe DataMapper::Resource::State::Dirty do
|
|
14
14
|
has n, :children, self, :inverse => :parent
|
15
15
|
end
|
16
16
|
|
17
|
+
DataMapper.finalize
|
18
|
+
|
17
19
|
@model = Author
|
18
20
|
end
|
19
21
|
|
20
22
|
before do
|
21
|
-
@
|
23
|
+
@parent = @model.create(:name => 'Jane Doe')
|
24
|
+
|
25
|
+
@resource = @model.create(:id => 2, :name => 'Dan Kubb', :parent => @parent)
|
22
26
|
@resource.attributes = { :name => 'John Doe' }
|
23
27
|
|
24
28
|
@state = @resource.persisted_state
|
@@ -26,35 +30,53 @@ describe DataMapper::Resource::State::Dirty do
|
|
26
30
|
end
|
27
31
|
|
28
32
|
after do
|
29
|
-
@
|
30
|
-
end
|
31
|
-
|
32
|
-
after do
|
33
|
-
@model.all.destroy!
|
33
|
+
@model.destroy!
|
34
34
|
end
|
35
35
|
|
36
36
|
describe '#commit' do
|
37
37
|
subject { @state.commit }
|
38
38
|
|
39
39
|
supported_by :all do
|
40
|
-
|
41
|
-
|
42
|
-
end
|
40
|
+
context 'with valid attributes' do
|
41
|
+
let(:state) { @state }
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
before do
|
44
|
+
@new_id = @resource.id = @resource.id.succ
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return a Clean state' do
|
48
|
+
should eql(DataMapper::Resource::State::Clean.new(@resource))
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should set the child key if the parent key changes' do
|
52
|
+
original_id = @parent.id
|
53
|
+
@parent.update(:id => 42).should be(true)
|
54
|
+
method(:subject).should change(@resource, :parent_id).from(original_id.to_s).to('42')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should update the resource' do
|
58
|
+
subject
|
59
|
+
@model.get!(*@resource.key).should == @resource
|
60
|
+
end
|
47
61
|
|
48
|
-
|
49
|
-
|
50
|
-
|
62
|
+
it 'should update the resource to the identity map if the key changed' do
|
63
|
+
identity_map = @resource.repository.identity_map(@model)
|
64
|
+
identity_map.should == { @resource.key => @resource }
|
65
|
+
subject
|
66
|
+
identity_map.should == { [ @new_id ] => @resource }
|
67
|
+
end
|
51
68
|
end
|
52
69
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
70
|
+
context 'with invalid attributes' do
|
71
|
+
before do
|
72
|
+
@resource.coding = 'yes'
|
73
|
+
end
|
74
|
+
|
75
|
+
it { should equal(@state) }
|
76
|
+
|
77
|
+
it 'should update the resource to the identity map if the key changed' do
|
78
|
+
method(:subject).should_not change { @resource.repository.identity_map(@model).dup }
|
79
|
+
end
|
58
80
|
end
|
59
81
|
end
|
60
82
|
end
|
@@ -13,11 +13,13 @@ describe DataMapper::Resource::State::Immutable do
|
|
13
13
|
belongs_to :parent, self, :required => false
|
14
14
|
end
|
15
15
|
|
16
|
+
DataMapper.finalize
|
17
|
+
|
16
18
|
@model = Author
|
17
19
|
end
|
18
20
|
|
19
21
|
before do
|
20
|
-
@parent
|
22
|
+
@parent = @model.create(:name => 'John Doe')
|
21
23
|
|
22
24
|
@resource = @model.create(:name => 'Dan Kubb', :parent => @parent)
|
23
25
|
@resource = @model.first(@model.key.zip(@resource.key).to_hash.merge(:fields => [ :name, :parent_id ]))
|
@@ -26,6 +28,10 @@ describe DataMapper::Resource::State::Immutable do
|
|
26
28
|
@state.should be_kind_of(DataMapper::Resource::State::Immutable)
|
27
29
|
end
|
28
30
|
|
31
|
+
after do
|
32
|
+
@model.destroy!
|
33
|
+
end
|
34
|
+
|
29
35
|
describe '#commit' do
|
30
36
|
subject { @state.commit }
|
31
37
|
|