dm-core 1.1.0 → 1.2.0.rc1

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 (104) hide show
  1. data/Gemfile +13 -11
  2. data/README.rdoc +1 -1
  3. data/Rakefile +1 -2
  4. data/VERSION +1 -1
  5. data/dm-core.gemspec +30 -176
  6. data/lib/dm-core.rb +32 -67
  7. data/lib/dm-core/adapters/abstract_adapter.rb +1 -2
  8. data/lib/dm-core/associations/many_to_many.rb +11 -5
  9. data/lib/dm-core/associations/many_to_one.rb +17 -2
  10. data/lib/dm-core/associations/one_to_many.rb +16 -0
  11. data/lib/dm-core/backwards.rb +13 -0
  12. data/lib/dm-core/collection.rb +1 -1
  13. data/lib/dm-core/model.rb +99 -41
  14. data/lib/dm-core/model/property.rb +24 -27
  15. data/lib/dm-core/model/relationship.rb +22 -28
  16. data/lib/dm-core/property.rb +37 -50
  17. data/lib/dm-core/property/boolean.rb +6 -10
  18. data/lib/dm-core/property/date.rb +0 -2
  19. data/lib/dm-core/property/date_time.rb +0 -2
  20. data/lib/dm-core/property/decimal.rb +5 -1
  21. data/lib/dm-core/property/discriminator.rb +24 -26
  22. data/lib/dm-core/property/float.rb +5 -1
  23. data/lib/dm-core/property/numeric.rb +6 -9
  24. data/lib/dm-core/property/string.rb +2 -1
  25. data/lib/dm-core/property/time.rb +0 -2
  26. data/lib/dm-core/property/typecast/time.rb +7 -2
  27. data/lib/dm-core/property_set.rb +1 -3
  28. data/lib/dm-core/query.rb +3 -10
  29. data/lib/dm-core/query/conditions/comparison.rb +5 -1
  30. data/lib/dm-core/query/conditions/operation.rb +1 -1
  31. data/lib/dm-core/relationship_set.rb +0 -2
  32. data/lib/dm-core/resource.rb +27 -28
  33. data/lib/dm-core/resource/{state.rb → persistence_state.rb} +2 -2
  34. data/lib/dm-core/resource/{state → persistence_state}/clean.rb +4 -4
  35. data/lib/dm-core/resource/{state → persistence_state}/deleted.rb +2 -2
  36. data/lib/dm-core/resource/{state → persistence_state}/dirty.rb +2 -2
  37. data/lib/dm-core/resource/{state → persistence_state}/immutable.rb +3 -3
  38. data/lib/dm-core/resource/{state → persistence_state}/persisted.rb +3 -3
  39. data/lib/dm-core/resource/{state → persistence_state}/transient.rb +3 -3
  40. data/lib/dm-core/spec/lib/adapter_helpers.rb +2 -5
  41. data/lib/dm-core/spec/setup.rb +3 -2
  42. data/lib/dm-core/spec/shared/public/property_spec.rb +8 -0
  43. data/lib/dm-core/spec/shared/resource_spec.rb +14 -0
  44. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +1 -1
  45. data/lib/dm-core/support/descendant_set.rb +0 -2
  46. data/lib/dm-core/support/ext/array.rb +0 -19
  47. data/lib/dm-core/support/ext/blank.rb +1 -0
  48. data/lib/dm-core/support/hook.rb +0 -3
  49. data/lib/dm-core/support/naming_conventions.rb +6 -0
  50. data/lib/dm-core/support/ordered_set.rb +0 -2
  51. data/lib/dm-core/support/subject_set.rb +0 -2
  52. data/lib/dm-core/version.rb +1 -1
  53. data/spec/public/associations/many_to_many_spec.rb +0 -1
  54. data/spec/public/model/property_spec.rb +55 -9
  55. data/spec/public/model/relationship_spec.rb +24 -2
  56. data/spec/public/model_spec.rb +32 -0
  57. data/spec/public/property/binary_spec.rb +14 -6
  58. data/spec/public/property/boolean_spec.rb +14 -6
  59. data/spec/public/property/class_spec.rb +14 -6
  60. data/spec/public/property/date_spec.rb +14 -6
  61. data/spec/public/property/date_time_spec.rb +14 -6
  62. data/spec/public/property/decimal_spec.rb +10 -2
  63. data/spec/public/property/discriminator_spec.rb +15 -1
  64. data/spec/public/property/float_spec.rb +14 -6
  65. data/spec/public/property/integer_spec.rb +14 -6
  66. data/spec/public/property/object_spec.rb +8 -0
  67. data/spec/public/property/serial_spec.rb +14 -6
  68. data/spec/public/property/string_spec.rb +14 -6
  69. data/spec/public/property/text_spec.rb +14 -6
  70. data/spec/public/property/time_spec.rb +14 -6
  71. data/spec/public/resource_spec.rb +58 -0
  72. data/spec/public/shared/finder_shared_spec.rb +8 -4
  73. data/spec/semipublic/associations/many_to_many_spec.rb +2 -0
  74. data/spec/semipublic/associations/many_to_one_spec.rb +2 -0
  75. data/spec/semipublic/associations/one_to_many_spec.rb +2 -0
  76. data/spec/semipublic/associations/one_to_one_spec.rb +2 -0
  77. data/spec/semipublic/property/binary_spec.rb +5 -5
  78. data/spec/semipublic/property/boolean_spec.rb +5 -5
  79. data/spec/semipublic/property/class_spec.rb +5 -5
  80. data/spec/semipublic/property/date_spec.rb +5 -5
  81. data/spec/semipublic/property/date_time_spec.rb +5 -5
  82. data/spec/semipublic/property/decimal_spec.rb +2 -2
  83. data/spec/semipublic/property/discriminator_spec.rb +5 -5
  84. data/spec/semipublic/property/float_spec.rb +5 -5
  85. data/spec/semipublic/property/integer_spec.rb +5 -5
  86. data/spec/semipublic/property/lookup_spec.rb +3 -3
  87. data/spec/semipublic/property/serial_spec.rb +5 -5
  88. data/spec/semipublic/property/string_spec.rb +5 -5
  89. data/spec/semipublic/property/text_spec.rb +5 -5
  90. data/spec/semipublic/property/time_spec.rb +5 -5
  91. data/spec/semipublic/query/conditions/comparison_spec.rb +44 -4
  92. data/spec/semipublic/query_spec.rb +2 -11
  93. data/spec/semipublic/resource/state/clean_spec.rb +6 -6
  94. data/spec/semipublic/resource/state/deleted_spec.rb +4 -4
  95. data/spec/semipublic/resource/state/dirty_spec.rb +8 -8
  96. data/spec/semipublic/resource/state/immutable_spec.rb +6 -6
  97. data/spec/semipublic/resource/state/transient_spec.rb +5 -5
  98. data/spec/semipublic/resource/state_spec.rb +15 -15
  99. data/spec/semipublic/shared/resource_shared_spec.rb +7 -1
  100. data/spec/semipublic/shared/resource_state_shared_spec.rb +8 -8
  101. data/spec/unit/array_spec.rb +0 -14
  102. data/spec/unit/blank_spec.rb +11 -0
  103. metadata +70 -188
  104. data/lib/dm-core/support/inflector.rb +0 -3
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::DateTime do
4
4
  before :all do
5
- @name = :created_at
6
- @type = DataMapper::Property::DateTime
7
- @primitive = DateTime
8
- @value = DateTime.now
9
- @other_value = DateTime.now+15
5
+ @name = :created_at
6
+ @type = described_class
7
+ @primitive = DateTime
8
+ @value = DateTime.now
9
+ @other_value = DateTime.now + 15
10
10
  @invalid_value = 1
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive) }
21
+ end
14
22
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe DataMapper::Property::Decimal do
4
4
  before :all do
5
5
  @name = :rate
6
- @type = DataMapper::Property::Decimal
6
+ @type = described_class
7
7
  @options = { :precision => 5, :scale => 2 }
8
8
  @primitive = BigDecimal
9
9
  @value = BigDecimal('1.0')
@@ -11,5 +11,13 @@ describe DataMapper::Property::Decimal do
11
11
  @invalid_value = true
12
12
  end
13
13
 
14
- it_should_behave_like "A public Property"
14
+ it_should_behave_like 'A public Property'
15
+
16
+ describe '.options' do
17
+ subject { described_class.options }
18
+
19
+ it { should be_kind_of(Hash) }
20
+
21
+ it { should eql(:primitive => @primitive, :precision => 10, :scale => 0) }
22
+ end
15
23
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe DataMapper::Property::Discriminator do
4
4
  before :all do
5
5
  module ::Blog
6
- class Article
6
+ class Content
7
7
  include DataMapper::Resource
8
8
 
9
9
  property :id, Serial
@@ -11,16 +11,26 @@ describe DataMapper::Property::Discriminator do
11
11
  property :type, Discriminator
12
12
  end
13
13
 
14
+ class Article < Content; end
14
15
  class Announcement < Article; end
15
16
  class Release < Announcement; end
16
17
  end
17
18
  DataMapper.finalize
18
19
 
20
+ @content_model = Blog::Content
19
21
  @article_model = Blog::Article
20
22
  @announcement_model = Blog::Announcement
21
23
  @release_model = Blog::Release
22
24
  end
23
25
 
26
+ describe '.options' do
27
+ subject { described_class.options }
28
+
29
+ it { should be_kind_of(Hash) }
30
+
31
+ it { should include(:primitive => Class, :required => true) }
32
+ end
33
+
24
34
  it 'should typecast to a Model' do
25
35
  @article_model.properties[:type].typecast('Blog::Release').should equal(@release_model)
26
36
  end
@@ -84,6 +94,10 @@ describe DataMapper::Property::Discriminator do
84
94
  end
85
95
 
86
96
  describe 'Model#default_scope' do
97
+ it 'should have no default scope for the top level model' do
98
+ @content_model.default_scope[:type].should be_nil
99
+ end
100
+
87
101
  it 'should set the default scope for the grandparent model' do
88
102
  @article_model.default_scope[:type].to_a.should =~ [ @article_model, @announcement_model, @release_model ]
89
103
  end
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Float do
4
4
  before :all do
5
- @name = :rating
6
- @type = DataMapper::Property::Float
7
- @primitive = Float
8
- @value = 0.1
9
- @other_value = 0.2
5
+ @name = :rating
6
+ @type = described_class
7
+ @primitive = Float
8
+ @value = 0.1
9
+ @other_value = 0.2
10
10
  @invalid_value = '1'
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive, :precision => 10, :scale => nil) }
21
+ end
14
22
  end
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Integer do
4
4
  before :all do
5
- @name = :age
6
- @type = DataMapper::Property::Integer
7
- @primitive = Integer
8
- @value = 1
9
- @other_value = 2
5
+ @name = :age
6
+ @type = described_class
7
+ @primitive = Integer
8
+ @value = 1
9
+ @other_value = 2
10
10
  @invalid_value = '1'
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive) }
21
+ end
14
22
  end
@@ -19,6 +19,14 @@ describe DataMapper::Property, 'Object type' do
19
19
 
20
20
  subject { @property }
21
21
 
22
+ describe '.options' do
23
+ subject { described_class.options }
24
+
25
+ it { should be_kind_of(Hash) }
26
+
27
+ it { should be_empty }
28
+ end
29
+
22
30
  it { should respond_to(:typecast) }
23
31
 
24
32
  describe '#typecast' do
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Serial do
4
4
  before :all do
5
- @name = :id
6
- @type = DataMapper::Property::Serial
7
- @primitive = Integer
8
- @value = 1
9
- @other_value = 2
5
+ @name = :id
6
+ @type = described_class
7
+ @primitive = Integer
8
+ @value = 1
9
+ @other_value = 2
10
10
  @invalid_value = 'foo'
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive, :min => 1, :serial => true) }
21
+ end
14
22
  end
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::String do
4
4
  before :all do
5
- @name = :name
6
- @type = DataMapper::Property::String
7
- @primitive = String
8
- @value = 'value'
9
- @other_value = 'return value'
5
+ @name = :name
6
+ @type = described_class
7
+ @primitive = String
8
+ @value = 'value'
9
+ @other_value = 'return value'
10
10
  @invalid_value = 1
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive, :length => 50) }
21
+ end
14
22
  end
@@ -2,15 +2,23 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Text do
4
4
  before :all do
5
- @name = :title
6
- @type = DataMapper::Property::Text
7
- @primitive = String
8
- @value = 'value'
9
- @other_value = 'return value'
5
+ @name = :title
6
+ @type = described_class
7
+ @primitive = String
8
+ @value = 'value'
9
+ @other_value = 'return value'
10
10
  @invalid_value = 1
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive, :length => 65535, :lazy => true) }
21
+ end
14
22
 
15
23
  describe 'migration with an index' do
16
24
  supported_by :all do
@@ -2,13 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Time do
4
4
  before :all do
5
- @name = :deleted_at
6
- @type = DataMapper::Property::Time
7
- @primitive = Time
8
- @value = Time.now
9
- @other_value = Time.now+15
5
+ @name = :deleted_at
6
+ @type = described_class
7
+ @primitive = Time
8
+ @value = Time.now
9
+ @other_value = Time.now + 15
10
10
  @invalid_value = 1
11
11
  end
12
12
 
13
- it_should_behave_like "A public Property"
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:primitive => @primitive) }
21
+ end
14
22
  end
@@ -222,5 +222,63 @@ describe DataMapper::Resource do
222
222
  end
223
223
  end
224
224
  end
225
+
226
+ describe '#attribute_get' do
227
+ subject { object.attribute_get(name) }
228
+
229
+ let(:object) { @user }
230
+
231
+ context 'with a known property' do
232
+ let(:name) { :name }
233
+
234
+ it 'returns the attribute value' do
235
+ should == 'dbussink'
236
+ end
237
+ end
238
+
239
+ context 'with an unknown property' do
240
+ let(:name) { :unknown }
241
+
242
+ it 'returns nil' do
243
+ should be_nil
244
+ end
245
+ end
246
+ end
247
+
248
+ describe '#attribute_set' do
249
+ subject { object.attribute_set(name, value) }
250
+
251
+ let(:object) { @user.dup }
252
+
253
+ context 'with a known property' do
254
+ let(:name) { :name }
255
+ let(:value) { 'dkubb' }
256
+
257
+ it 'sets the attribute' do
258
+ expect { subject }.to change { object.name }.
259
+ from('dbussink').
260
+ to('dkubb')
261
+ end
262
+
263
+ it 'makes the object dirty' do
264
+ expect { subject }.to change { object.dirty? }.
265
+ from(false).
266
+ to(true)
267
+ end
268
+ end
269
+
270
+ context 'with an unknown property' do
271
+ let(:name) { :unknown }
272
+ let(:value) { mock('Unknown Value') }
273
+
274
+ it 'does not set the attribute' do
275
+ expect { subject }.to_not change { object.attributes.dup }
276
+ end
277
+
278
+ it 'does not make the object dirty' do
279
+ expect { subject }.to_not change { object.dirty? }
280
+ end
281
+ end
282
+ end
225
283
  end
226
284
  end
@@ -343,7 +343,8 @@ share_examples_for 'Finder Interface' do
343
343
  describe 'with a collection' do
344
344
  before :all do
345
345
  @collection = @article_model.all(
346
- DataMapper::Ext::Array.to_hash(@article_model.key.zip(@original.key)))
346
+ Hash[ @article_model.key.zip(@original.key) ]
347
+ )
347
348
 
348
349
  @return = @articles.all(:original => @collection)
349
350
  end
@@ -481,7 +482,8 @@ share_examples_for 'Finder Interface' do
481
482
  describe 'with a collection' do
482
483
  before :all do
483
484
  @collection = @article_model.all(
484
- DataMapper::Ext::Array.to_hash(@article_model.key.zip(@new.key)))
485
+ Hash[ @article_model.key.zip(@new.key) ]
486
+ )
485
487
 
486
488
  @return = @articles.all(:previous => @collection)
487
489
  end
@@ -618,7 +620,8 @@ share_examples_for 'Finder Interface' do
618
620
  describe 'with a collection' do
619
621
  before :all do
620
622
  @collection = @article_model.all(
621
- DataMapper::Ext::Array.to_hash(@article_model.key.zip(@new.key)))
623
+ Hash[ @article_model.key.zip(@new.key) ]
624
+ )
622
625
 
623
626
  @return = @articles.all(:revisions => @collection)
624
627
  end
@@ -759,7 +762,8 @@ share_examples_for 'Finder Interface' do
759
762
  describe 'with a collection' do
760
763
  before :all do
761
764
  @collection = @publication_model.all(
762
- DataMapper::Ext::Array.to_hash(@publication_model.key.zip(@publication.key)))
765
+ Hash[ @publication_model.key.zip(@publication.key) ]
766
+ )
763
767
 
764
768
  @return = @articles.all(:publications => @collection)
765
769
  end
@@ -54,6 +54,8 @@ describe 'Many to Many Associations' do
54
54
  @article_model = Blog::Article
55
55
  @author_model = Blog::Author
56
56
 
57
+ DataMapper.finalize
58
+
57
59
  n = @article_model.n
58
60
 
59
61
  @default_value = [ @author_model.new(:name => 'Dan Kubb') ]
@@ -23,6 +23,8 @@ describe 'Many to One Associations' do
23
23
  @user_model = User
24
24
  @comment_model = Comment
25
25
 
26
+ DataMapper.finalize
27
+
26
28
  @default_value = @user_model.new(:name => 'dkubb', :age => 34, :description => 'Test')
27
29
  @default_value_callable = @user_model.new(:name => 'jdoe', :age => 21, :description => 'Test')
28
30
 
@@ -24,6 +24,8 @@ describe 'One to Many Associations' do
24
24
  @article_model = Blog::Article
25
25
  @author_model = Blog::Author
26
26
 
27
+ DataMapper.finalize
28
+
27
29
  n = @article_model.n
28
30
 
29
31
  @default_value = [ @author_model.new(:name => 'Dan Kubb') ]
@@ -24,6 +24,8 @@ describe 'One to One Associations' do
24
24
  @article_model = Blog::Article
25
25
  @author_model = Blog::Author
26
26
 
27
+ DataMapper.finalize
28
+
27
29
  @default_value = @author_model.new(:name => 'Dan Kubb')
28
30
  @default_value_callable = @author_model.new(:name => 'John Doe')
29
31
 
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe DataMapper::Property::Binary do
4
4
  before :all do
5
- @name = :title
6
- @type = DataMapper::Property::Binary
7
- @value = 'value'
8
- @other_value = 'return value'
5
+ @name = :title
6
+ @type = described_class
7
+ @value = 'value'
8
+ @other_value = 'return value'
9
9
  @invalid_value = 1
10
10
  end
11
11
 
12
- it_should_behave_like "A semipublic Property"
12
+ it_should_behave_like 'A semipublic Property'
13
13
  end