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.
- data/Gemfile +13 -11
- data/README.rdoc +1 -1
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/dm-core.gemspec +30 -176
- data/lib/dm-core.rb +32 -67
- data/lib/dm-core/adapters/abstract_adapter.rb +1 -2
- data/lib/dm-core/associations/many_to_many.rb +11 -5
- data/lib/dm-core/associations/many_to_one.rb +17 -2
- data/lib/dm-core/associations/one_to_many.rb +16 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1 -1
- data/lib/dm-core/model.rb +99 -41
- data/lib/dm-core/model/property.rb +24 -27
- data/lib/dm-core/model/relationship.rb +22 -28
- data/lib/dm-core/property.rb +37 -50
- data/lib/dm-core/property/boolean.rb +6 -10
- data/lib/dm-core/property/date.rb +0 -2
- data/lib/dm-core/property/date_time.rb +0 -2
- data/lib/dm-core/property/decimal.rb +5 -1
- data/lib/dm-core/property/discriminator.rb +24 -26
- data/lib/dm-core/property/float.rb +5 -1
- data/lib/dm-core/property/numeric.rb +6 -9
- data/lib/dm-core/property/string.rb +2 -1
- data/lib/dm-core/property/time.rb +0 -2
- data/lib/dm-core/property/typecast/time.rb +7 -2
- data/lib/dm-core/property_set.rb +1 -3
- data/lib/dm-core/query.rb +3 -10
- data/lib/dm-core/query/conditions/comparison.rb +5 -1
- data/lib/dm-core/query/conditions/operation.rb +1 -1
- data/lib/dm-core/relationship_set.rb +0 -2
- data/lib/dm-core/resource.rb +27 -28
- data/lib/dm-core/resource/{state.rb → persistence_state.rb} +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/clean.rb +4 -4
- data/lib/dm-core/resource/{state → persistence_state}/deleted.rb +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/dirty.rb +2 -2
- data/lib/dm-core/resource/{state → persistence_state}/immutable.rb +3 -3
- data/lib/dm-core/resource/{state → persistence_state}/persisted.rb +3 -3
- data/lib/dm-core/resource/{state → persistence_state}/transient.rb +3 -3
- data/lib/dm-core/spec/lib/adapter_helpers.rb +2 -5
- data/lib/dm-core/spec/setup.rb +3 -2
- data/lib/dm-core/spec/shared/public/property_spec.rb +8 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +14 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +1 -1
- data/lib/dm-core/support/descendant_set.rb +0 -2
- data/lib/dm-core/support/ext/array.rb +0 -19
- data/lib/dm-core/support/ext/blank.rb +1 -0
- data/lib/dm-core/support/hook.rb +0 -3
- data/lib/dm-core/support/naming_conventions.rb +6 -0
- data/lib/dm-core/support/ordered_set.rb +0 -2
- data/lib/dm-core/support/subject_set.rb +0 -2
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/associations/many_to_many_spec.rb +0 -1
- data/spec/public/model/property_spec.rb +55 -9
- data/spec/public/model/relationship_spec.rb +24 -2
- data/spec/public/model_spec.rb +32 -0
- data/spec/public/property/binary_spec.rb +14 -6
- data/spec/public/property/boolean_spec.rb +14 -6
- data/spec/public/property/class_spec.rb +14 -6
- data/spec/public/property/date_spec.rb +14 -6
- data/spec/public/property/date_time_spec.rb +14 -6
- data/spec/public/property/decimal_spec.rb +10 -2
- data/spec/public/property/discriminator_spec.rb +15 -1
- data/spec/public/property/float_spec.rb +14 -6
- data/spec/public/property/integer_spec.rb +14 -6
- data/spec/public/property/object_spec.rb +8 -0
- data/spec/public/property/serial_spec.rb +14 -6
- data/spec/public/property/string_spec.rb +14 -6
- data/spec/public/property/text_spec.rb +14 -6
- data/spec/public/property/time_spec.rb +14 -6
- data/spec/public/resource_spec.rb +58 -0
- data/spec/public/shared/finder_shared_spec.rb +8 -4
- data/spec/semipublic/associations/many_to_many_spec.rb +2 -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/property/binary_spec.rb +5 -5
- data/spec/semipublic/property/boolean_spec.rb +5 -5
- data/spec/semipublic/property/class_spec.rb +5 -5
- data/spec/semipublic/property/date_spec.rb +5 -5
- data/spec/semipublic/property/date_time_spec.rb +5 -5
- data/spec/semipublic/property/decimal_spec.rb +2 -2
- data/spec/semipublic/property/discriminator_spec.rb +5 -5
- data/spec/semipublic/property/float_spec.rb +5 -5
- data/spec/semipublic/property/integer_spec.rb +5 -5
- data/spec/semipublic/property/lookup_spec.rb +3 -3
- data/spec/semipublic/property/serial_spec.rb +5 -5
- data/spec/semipublic/property/string_spec.rb +5 -5
- data/spec/semipublic/property/text_spec.rb +5 -5
- data/spec/semipublic/property/time_spec.rb +5 -5
- data/spec/semipublic/query/conditions/comparison_spec.rb +44 -4
- data/spec/semipublic/query_spec.rb +2 -11
- data/spec/semipublic/resource/state/clean_spec.rb +6 -6
- data/spec/semipublic/resource/state/deleted_spec.rb +4 -4
- data/spec/semipublic/resource/state/dirty_spec.rb +8 -8
- data/spec/semipublic/resource/state/immutable_spec.rb +6 -6
- data/spec/semipublic/resource/state/transient_spec.rb +5 -5
- data/spec/semipublic/resource/state_spec.rb +15 -15
- data/spec/semipublic/shared/resource_shared_spec.rb +7 -1
- data/spec/semipublic/shared/resource_state_shared_spec.rb +8 -8
- data/spec/unit/array_spec.rb +0 -14
- data/spec/unit/blank_spec.rb +11 -0
- metadata +70 -188
- data/lib/dm-core/support/inflector.rb +0 -3
@@ -24,13 +24,10 @@ module DataMapper
|
|
24
24
|
@adapter = DataMapper::Spec.adapter(kind)
|
25
25
|
@repository = DataMapper.repository(@adapter.name)
|
26
26
|
|
27
|
+
@repository.scope { DataMapper.finalize }
|
28
|
+
|
27
29
|
# create all tables and constraints before each spec
|
28
30
|
if @repository.respond_to?(:auto_migrate!)
|
29
|
-
# If we are going to auto-migrate, we must also finalize
|
30
|
-
@repository.scope do
|
31
|
-
DataMapper.finalize
|
32
|
-
end
|
33
|
-
|
34
31
|
@repository.auto_migrate!
|
35
32
|
end
|
36
33
|
end
|
data/lib/dm-core/spec/setup.rb
CHANGED
@@ -42,11 +42,12 @@ module DataMapper
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def require_spec_adapter
|
45
|
-
|
45
|
+
desired_adapter = ENV['ADAPTER']
|
46
|
+
if desired_adapter.nil? || desired_adapter == 'in_memory'
|
46
47
|
ENV['ADAPTER_SUPPORTS'] = 'all'
|
47
48
|
Adapters.use(Adapters::InMemoryAdapter)
|
48
49
|
else
|
49
|
-
require "dm-#{
|
50
|
+
require "dm-#{desired_adapter}-adapter/spec/setup"
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
@@ -22,6 +22,14 @@ share_examples_for 'A public Property' do
|
|
22
22
|
@type.accept_options :foo, :bar
|
23
23
|
end
|
24
24
|
|
25
|
+
before :all do
|
26
|
+
@original = @type.accepted_options.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
after :all do
|
30
|
+
@type.accepted_options.replace(@original - [ :foo, :bar ])
|
31
|
+
end
|
32
|
+
|
25
33
|
describe "predefined options" do
|
26
34
|
before :all do
|
27
35
|
class ::ChildSubType < @subtype
|
@@ -101,6 +101,13 @@ share_examples_for 'A public Resource' do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
with_alternate_adapter do
|
104
|
+
before :all do
|
105
|
+
if @user_model.respond_to?(:auto_migrate!)
|
106
|
+
# force the user model to be available in the alternate repository
|
107
|
+
@user_model.auto_migrate!(@adapter.name)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
104
111
|
describe 'when comparing to a resource with a different repository, but the same properties' do
|
105
112
|
before :all do
|
106
113
|
rescue_if @skip do
|
@@ -489,6 +496,13 @@ share_examples_for 'A public Resource' do
|
|
489
496
|
end
|
490
497
|
|
491
498
|
with_alternate_adapter do
|
499
|
+
before :all do
|
500
|
+
if @user_model.respond_to?(:auto_migrate!)
|
501
|
+
# force the user model to be available in the alternate repository
|
502
|
+
@user_model.auto_migrate!(@adapter.name)
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
492
506
|
describe 'when comparing to a resource with a different repository, but the same properties' do
|
493
507
|
before :all do
|
494
508
|
rescue_if @skip do
|
@@ -1,24 +1,5 @@
|
|
1
1
|
module DataMapper; module Ext
|
2
2
|
module Array
|
3
|
-
# Transforms an Array of key/value pairs into a Hash.
|
4
|
-
#
|
5
|
-
# This is a better idiom than using Hash[*array.flatten] in Ruby 1.8.6
|
6
|
-
# because it is not possible to limit the flattening to a single
|
7
|
-
# level.
|
8
|
-
#
|
9
|
-
# @param [Array] array
|
10
|
-
# The array of key/value pairs to transform.
|
11
|
-
#
|
12
|
-
# @return [Hash]
|
13
|
-
# A Hash where each entry in the Array is turned into a key/value.
|
14
|
-
#
|
15
|
-
# @api semipublic
|
16
|
-
def self.to_hash(array)
|
17
|
-
h = {}
|
18
|
-
array.each { |k,v| h[k] = v }
|
19
|
-
h
|
20
|
-
end
|
21
|
-
|
22
3
|
# Transforms an Array of key/value pairs into a {Mash}.
|
23
4
|
#
|
24
5
|
# This is a better idiom than using Mash[*array.flatten] in Ruby 1.8.6
|
data/lib/dm-core/support/hook.rb
CHANGED
@@ -38,6 +38,12 @@ module DataMapper
|
|
38
38
|
end
|
39
39
|
end # module UnderscoredAndPluralizedWithoutModule
|
40
40
|
|
41
|
+
module UnderscoredAndPluralizedWithoutLeadingModule
|
42
|
+
def self.call(name)
|
43
|
+
UnderscoredAndPluralized.call(name.to_s.gsub(/^[^:]*::/,''))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
41
47
|
module Underscored
|
42
48
|
def self.call(name)
|
43
49
|
DataMapper::Inflector.underscore(name)
|
data/lib/dm-core/version.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
shared_examples_for "a correct property declaration" do
|
4
|
+
it 'should define a name accessor' do
|
5
|
+
@model.should_not be_method_defined(@property_name)
|
6
|
+
subject
|
7
|
+
@model.should be_method_defined(@property_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should define a name= mutator' do
|
11
|
+
@model.should_not be_method_defined(:"#{@property_name}=")
|
12
|
+
subject
|
13
|
+
@model.should be_method_defined(:"#{@property_name}=")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
describe DataMapper::Model::Property do
|
4
18
|
before do
|
5
19
|
Object.send(:remove_const, :ModelPropertySpecs) if defined?(ModelPropertySpecs)
|
@@ -12,19 +26,45 @@ describe DataMapper::Model::Property do
|
|
12
26
|
end
|
13
27
|
|
14
28
|
describe '#property' do
|
29
|
+
context "using default repository" do
|
30
|
+
before do
|
31
|
+
Object.send(:remove_const, :UserDefault) if defined?(::UserDefault)
|
32
|
+
|
33
|
+
class ::UserDefault
|
34
|
+
include DataMapper::Resource
|
35
|
+
property :id, Serial
|
36
|
+
end
|
37
|
+
|
38
|
+
@model = ::UserDefault
|
39
|
+
@property_name = :name
|
40
|
+
end
|
15
41
|
|
16
|
-
|
42
|
+
subject do
|
43
|
+
::UserDefault.property(:name, String)
|
44
|
+
end
|
17
45
|
|
18
|
-
|
19
|
-
ModelPropertySpecs.should_not be_method_defined(:name)
|
20
|
-
subject
|
21
|
-
ModelPropertySpecs.should be_method_defined(:name)
|
46
|
+
it_should_behave_like "a correct property declaration"
|
22
47
|
end
|
23
48
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
49
|
+
context "using alternate repository" do
|
50
|
+
before do
|
51
|
+
Object.send(:remove_const, :UserAlternate) if defined?(::UserAlternate)
|
52
|
+
|
53
|
+
class ::UserAlternate
|
54
|
+
include DataMapper::Resource
|
55
|
+
property :id, Serial
|
56
|
+
repository(:alternate) { property :age, Integer }
|
57
|
+
end
|
58
|
+
|
59
|
+
@model = UserAlternate
|
60
|
+
@property_name = :alt_name
|
61
|
+
end
|
62
|
+
|
63
|
+
subject do
|
64
|
+
::UserAlternate.property(:alt_name, String)
|
65
|
+
end
|
66
|
+
|
67
|
+
it_should_behave_like "a correct property declaration"
|
28
68
|
end
|
29
69
|
|
30
70
|
it 'should raise an exception if the method exists' do
|
@@ -33,6 +73,12 @@ describe DataMapper::Model::Property do
|
|
33
73
|
}.should raise_error(ArgumentError, '+name+ was :key, which cannot be used as a property name since it collides with an existing method or a query option')
|
34
74
|
end
|
35
75
|
|
76
|
+
it 'should raise an exception if the property is boolean and method with question mark already exists' do
|
77
|
+
lambda {
|
78
|
+
ModelPropertySpecs.property(:destroyed, DataMapper::Property::Boolean)
|
79
|
+
}.should raise_error(ArgumentError, '+name+ was :destroyed, which cannot be used as a property name since it collides with an existing method or a query option')
|
80
|
+
end
|
81
|
+
|
36
82
|
it 'should raise an exception if the name is the same as one of the query options' do
|
37
83
|
lambda {
|
38
84
|
ModelPropertySpecs.property(:order, String)
|
@@ -282,7 +282,8 @@ share_examples_for 'it creates a many accessor' do
|
|
282
282
|
|
283
283
|
# set the model scope to only return the first record
|
284
284
|
@model.default_scope.update(
|
285
|
-
|
285
|
+
Hash[ @model.key(@repository.name).zip(@expected.key) ]
|
286
|
+
)
|
286
287
|
|
287
288
|
@return = @car.model.get(*@car.key).__send__(@name)
|
288
289
|
end
|
@@ -433,7 +434,7 @@ describe DataMapper::Associations do
|
|
433
434
|
class ::Car
|
434
435
|
include DataMapper::Resource
|
435
436
|
|
436
|
-
property :id,
|
437
|
+
property :id, Serial
|
437
438
|
property :name, String
|
438
439
|
end
|
439
440
|
|
@@ -497,6 +498,27 @@ describe DataMapper::Associations do
|
|
497
498
|
end
|
498
499
|
end
|
499
500
|
end
|
501
|
+
|
502
|
+
describe 'with a :unique option' do
|
503
|
+
let(:unique) { [ :one, :two, :three ] }
|
504
|
+
|
505
|
+
before :all do
|
506
|
+
@relationship = Car.belongs_to("#{@name}_with_unique".to_sym, @model, :unique => unique)
|
507
|
+
DataMapper.finalize
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'should create a foreign key that is unique' do
|
511
|
+
@relationship.child_key.each do |property|
|
512
|
+
property.should be_unique
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
it 'should create a foreign key that has a unique index' do
|
517
|
+
@relationship.child_key.each do |property|
|
518
|
+
property.unique_index.should equal(unique)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
500
522
|
end
|
501
523
|
|
502
524
|
# TODO: refactor these specs into above structure once they pass
|
data/spec/public/model_spec.rb
CHANGED
@@ -36,6 +36,13 @@ describe DataMapper::Model do
|
|
36
36
|
|
37
37
|
describe '#copy' do
|
38
38
|
with_alternate_adapter do
|
39
|
+
before :all do
|
40
|
+
if @article_model.respond_to?(:auto_migrate!)
|
41
|
+
# force the article model to be available in the alternate repository
|
42
|
+
@article_model.auto_migrate!(@adapter.name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
39
46
|
describe 'between identical models' do
|
40
47
|
before :all do
|
41
48
|
@return = @resources = @article_model.copy(@repository.name, @adapter.name)
|
@@ -422,5 +429,30 @@ describe DataMapper::Model do
|
|
422
429
|
end
|
423
430
|
end
|
424
431
|
end
|
432
|
+
|
433
|
+
it 'A model should respond to allowed_writer_methods' do
|
434
|
+
@article_model.should respond_to(:allowed_writer_methods)
|
435
|
+
end
|
436
|
+
|
437
|
+
describe '#allowed_writer_methods' do
|
438
|
+
subject { @article_model.allowed_writer_methods }
|
439
|
+
|
440
|
+
let(:expected_writer_methods) do
|
441
|
+
%w[ original= revisions= previous= publications= article_publications=
|
442
|
+
id= title= content= subtitle= original_id= persisted_state= ].to_set
|
443
|
+
end
|
444
|
+
|
445
|
+
it { should be_kind_of(Set) }
|
446
|
+
|
447
|
+
it { should be_all { |method| method.kind_of?(String) } }
|
448
|
+
|
449
|
+
it { should be_frozen }
|
450
|
+
|
451
|
+
it 'is idempotent' do
|
452
|
+
should equal(instance_eval(&self.class.subject))
|
453
|
+
end
|
454
|
+
|
455
|
+
it { should eql(expected_writer_methods) }
|
456
|
+
end
|
425
457
|
end
|
426
458
|
end
|
@@ -2,13 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DataMapper::Property::Binary do
|
4
4
|
before :all do
|
5
|
-
@name
|
6
|
-
@type
|
7
|
-
@primitive
|
8
|
-
@value
|
9
|
-
@other_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
|
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,13 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DataMapper::Property::Boolean do
|
4
4
|
before :all do
|
5
|
-
@name
|
6
|
-
@type
|
7
|
-
@primitive
|
8
|
-
@value
|
9
|
-
@other_value
|
5
|
+
@name = :active
|
6
|
+
@type = described_class
|
7
|
+
@primitive = TrueClass
|
8
|
+
@value = true
|
9
|
+
@other_value = false
|
10
10
|
@invalid_value = 1
|
11
11
|
end
|
12
12
|
|
13
|
-
it_should_behave_like
|
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
|
@@ -8,13 +8,21 @@ describe DataMapper::Property::Class do
|
|
8
8
|
class ::Foo; end
|
9
9
|
class ::Bar; end
|
10
10
|
|
11
|
-
@name
|
12
|
-
@type
|
13
|
-
@primitive
|
14
|
-
@value
|
15
|
-
@other_value
|
11
|
+
@name = :type
|
12
|
+
@type = described_class
|
13
|
+
@primitive = Class
|
14
|
+
@value = Foo
|
15
|
+
@other_value = Bar
|
16
16
|
@invalid_value = 1
|
17
17
|
end
|
18
18
|
|
19
|
-
it_should_behave_like
|
19
|
+
it_should_behave_like 'A public Property'
|
20
|
+
|
21
|
+
describe '.options' do
|
22
|
+
subject { described_class.options }
|
23
|
+
|
24
|
+
it { should be_kind_of(Hash) }
|
25
|
+
|
26
|
+
it { should eql(:primitive => @primitive) }
|
27
|
+
end
|
20
28
|
end
|
@@ -2,13 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DataMapper::Property::Date do
|
4
4
|
before :all do
|
5
|
-
@name
|
6
|
-
@type
|
7
|
-
@primitive
|
8
|
-
@value
|
9
|
-
@other_value
|
5
|
+
@name = :created_on
|
6
|
+
@type = described_class
|
7
|
+
@primitive = Date
|
8
|
+
@value = Date.today
|
9
|
+
@other_value = Date.today + 1
|
10
10
|
@invalid_value = 1
|
11
11
|
end
|
12
12
|
|
13
|
-
it_should_behave_like
|
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
|