dm-core 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +27 -0
- data/LICENSE +20 -0
- data/{README.txt → README.rdoc} +14 -3
- data/Rakefile +23 -22
- data/VERSION +1 -0
- data/dm-core.gemspec +201 -10
- data/lib/dm-core.rb +32 -23
- data/lib/dm-core/adapters.rb +0 -1
- data/lib/dm-core/adapters/data_objects_adapter.rb +230 -151
- data/lib/dm-core/adapters/mysql_adapter.rb +7 -8
- data/lib/dm-core/adapters/oracle_adapter.rb +39 -59
- data/lib/dm-core/adapters/postgres_adapter.rb +0 -1
- data/lib/dm-core/adapters/sqlite3_adapter.rb +5 -0
- data/lib/dm-core/adapters/sqlserver_adapter.rb +114 -0
- data/lib/dm-core/adapters/yaml_adapter.rb +0 -5
- data/lib/dm-core/associations/many_to_many.rb +118 -56
- data/lib/dm-core/associations/many_to_one.rb +48 -21
- data/lib/dm-core/associations/one_to_many.rb +8 -30
- data/lib/dm-core/associations/one_to_one.rb +1 -5
- data/lib/dm-core/associations/relationship.rb +89 -97
- data/lib/dm-core/collection.rb +299 -184
- data/lib/dm-core/core_ext/enumerable.rb +28 -0
- data/lib/dm-core/core_ext/kernel.rb +0 -2
- data/lib/dm-core/migrations.rb +314 -170
- data/lib/dm-core/model.rb +97 -66
- data/lib/dm-core/model/descendant_set.rb +1 -1
- data/lib/dm-core/model/hook.rb +0 -3
- data/lib/dm-core/model/property.rb +7 -10
- data/lib/dm-core/model/relationship.rb +79 -26
- data/lib/dm-core/model/scope.rb +3 -4
- data/lib/dm-core/property.rb +152 -90
- data/lib/dm-core/property_set.rb +18 -37
- data/lib/dm-core/query.rb +452 -153
- data/lib/dm-core/query/conditions/comparison.rb +266 -173
- data/lib/dm-core/query/conditions/operation.rb +499 -57
- data/lib/dm-core/query/direction.rb +0 -3
- data/lib/dm-core/query/operator.rb +0 -4
- data/lib/dm-core/query/path.rb +10 -12
- data/lib/dm-core/query/sort.rb +4 -10
- data/lib/dm-core/repository.rb +10 -6
- data/lib/dm-core/resource.rb +343 -148
- data/lib/dm-core/spec/adapter_shared_spec.rb +17 -1
- data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +277 -17
- data/lib/dm-core/support/chainable.rb +0 -2
- data/lib/dm-core/support/equalizer.rb +27 -3
- data/lib/dm-core/transaction.rb +75 -75
- data/lib/dm-core/type.rb +19 -5
- data/lib/dm-core/types/discriminator.rb +4 -4
- data/lib/dm-core/types/object.rb +2 -7
- data/lib/dm-core/types/paranoid_boolean.rb +8 -2
- data/lib/dm-core/types/paranoid_datetime.rb +8 -2
- data/lib/dm-core/version.rb +1 -1
- data/script/performance.rb +7 -7
- data/script/profile.rb +6 -6
- data/spec/lib/collection_helpers.rb +2 -2
- data/spec/lib/pending_helpers.rb +22 -3
- data/spec/lib/rspec_immediate_feedback_formatter.rb +1 -0
- data/spec/public/associations/many_to_many_spec.rb +6 -4
- data/spec/public/associations/many_to_one_spec.rb +10 -1
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +39 -0
- data/spec/public/associations/one_to_many_spec.rb +4 -3
- data/spec/public/associations/one_to_one_spec.rb +19 -1
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +45 -0
- data/spec/public/collection_spec.rb +4 -3
- data/spec/public/migrations_spec.rb +144 -0
- data/spec/public/model/relationship_spec.rb +115 -55
- data/spec/public/model_spec.rb +13 -13
- data/spec/public/property/object_spec.rb +106 -0
- data/spec/public/property_spec.rb +18 -14
- data/spec/public/resource_spec.rb +10 -1
- data/spec/public/sel_spec.rb +16 -49
- data/spec/public/setup_spec.rb +1 -1
- data/spec/public/shared/association_collection_shared_spec.rb +6 -14
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +214 -217
- data/spec/public/shared/finder_shared_spec.rb +259 -365
- data/spec/public/shared/resource_shared_spec.rb +524 -248
- data/spec/public/transaction_spec.rb +27 -3
- data/spec/public/types/discriminator_spec.rb +1 -1
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +17 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +3 -20
- data/spec/semipublic/associations_spec.rb +2 -2
- data/spec/semipublic/collection_spec.rb +0 -32
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property_spec.rb +3 -3
- data/spec/semipublic/query/conditions/comparison_spec.rb +1719 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1292 -0
- data/spec/semipublic/query_spec.rb +1285 -144
- data/spec/semipublic/resource_spec.rb +0 -24
- data/spec/semipublic/shared/resource_shared_spec.rb +103 -38
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +15 -6
- data/tasks/ci.rake +1 -0
- data/tasks/metrics.rake +37 -0
- data/tasks/spec.rake +41 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +99 -29
- data/CONTRIBUTING +0 -51
- data/FAQ +0 -93
- data/History.txt +0 -27
- data/MIT-LICENSE +0 -22
- data/Manifest.txt +0 -121
- data/QUICKLINKS +0 -11
- data/SPECS +0 -35
- data/TODO +0 -1
- data/spec/semipublic/query/conditions_spec.rb +0 -528
- data/tasks/ci.rb +0 -24
- data/tasks/dm.rb +0 -58
- data/tasks/doc.rb +0 -17
- data/tasks/gemspec.rb +0 -23
- data/tasks/hoe.rb +0 -45
- data/tasks/install.rb +0 -18
@@ -12,7 +12,10 @@ describe 'One to One Associations' do
|
|
12
12
|
property :description, Text
|
13
13
|
property :admin, Boolean, :accessor => :private
|
14
14
|
|
15
|
-
belongs_to :
|
15
|
+
belongs_to :parent, self, :required => false
|
16
|
+
has n, :children, self, :inverse => :parent
|
17
|
+
|
18
|
+
belongs_to :referrer, self, :required => false
|
16
19
|
belongs_to :comment
|
17
20
|
|
18
21
|
# TODO: remove this after Relationship#inverse can dynamically
|
@@ -50,6 +53,12 @@ describe 'One to One Associations' do
|
|
50
53
|
end
|
51
54
|
end
|
52
55
|
|
56
|
+
class ::Default
|
57
|
+
include DataMapper::Resource
|
58
|
+
|
59
|
+
property :name, String, :key => true, :default => 'a default value'
|
60
|
+
end
|
61
|
+
|
53
62
|
@user_model = Blog::User
|
54
63
|
@author_model = Blog::Author
|
55
64
|
@comment_model = Blog::Comment
|
@@ -93,6 +102,9 @@ describe 'One to One Through Associations' do
|
|
93
102
|
property :description, Text
|
94
103
|
property :admin, Boolean, :accessor => :private
|
95
104
|
|
105
|
+
belongs_to :parent, self, :required => false
|
106
|
+
has n, :children, self, :inverse => :parent
|
107
|
+
|
96
108
|
has 1, :referral_from, Referral, :child_key => [ :referree_name ]
|
97
109
|
has 1, :referral_to, Referral, :child_key => [ :referrer_name ]
|
98
110
|
|
@@ -131,6 +143,12 @@ describe 'One to One Through Associations' do
|
|
131
143
|
end
|
132
144
|
end
|
133
145
|
|
146
|
+
class ::Default
|
147
|
+
include DataMapper::Resource
|
148
|
+
|
149
|
+
property :name, String, :key => true, :default => 'a default value'
|
150
|
+
end
|
151
|
+
|
134
152
|
@referral_model = Blog::Referral
|
135
153
|
@user_model = Blog::User
|
136
154
|
@author_model = Blog::Author
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
|
2
|
+
|
3
|
+
# TODO: combine this into one_to_one_spec.rb
|
4
|
+
|
5
|
+
describe 'One to One Associations when foreign key is part of a composite key and contains a boolean, with an integer and a boolean making up the composite key' do
|
6
|
+
before :all do
|
7
|
+
class ::ParentModel
|
8
|
+
include DataMapper::Resource
|
9
|
+
|
10
|
+
property :integer_key, Integer, :key => true
|
11
|
+
property :boolean_key, Boolean, :key => true
|
12
|
+
|
13
|
+
has 1, :child_model, :child_key => [ :integer_key, :boolean_key ]
|
14
|
+
end
|
15
|
+
|
16
|
+
class ::ChildModel
|
17
|
+
include DataMapper::Resource
|
18
|
+
|
19
|
+
property :integer_key, Integer, :key => true
|
20
|
+
property :other_integer_key, Integer, :key => true
|
21
|
+
property :boolean_key, Boolean, :key => true
|
22
|
+
|
23
|
+
belongs_to :parent_model, :child_key => [ :integer_key, :boolean_key ]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
supported_by :all do
|
28
|
+
before :all do
|
29
|
+
@parent = ParentModel.create(:integer_key => 1, :boolean_key => false)
|
30
|
+
@child = ChildModel.create(:integer_key => 1, :other_integer_key => 1, :boolean_key => false)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be able to access the child' do
|
34
|
+
@parent.child_model.should == @child
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should be able to access the parent' do
|
38
|
+
@child.parent_model.should == @parent
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be able to access the parent_key' do
|
42
|
+
@child.parent_model.key.should_not be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -13,12 +13,12 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
|
13
13
|
include DataMapper::Resource
|
14
14
|
|
15
15
|
property :id, Serial
|
16
|
-
property :title, String, :
|
16
|
+
property :title, String, :required => true
|
17
17
|
property :content, Text
|
18
18
|
property :subtitle, String
|
19
|
-
property :author, String, :
|
19
|
+
property :author, String, :required => true
|
20
20
|
|
21
|
-
belongs_to :original, self, :
|
21
|
+
belongs_to :original, self, :required => false
|
22
22
|
has n, :revisions, self, :child_key => [ :original_id ]
|
23
23
|
has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
|
24
24
|
has n, :publications, :through => Resource
|
@@ -60,6 +60,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
|
60
60
|
it_should_behave_like 'A public Collection'
|
61
61
|
it_should_behave_like 'A Collection supporting Strategic Eager Loading'
|
62
62
|
it_should_behave_like 'Finder Interface'
|
63
|
+
it_should_behave_like 'Collection Finder Interface'
|
63
64
|
end
|
64
65
|
end
|
65
66
|
end
|
@@ -243,6 +243,38 @@ describe DataMapper::Migrations do
|
|
243
243
|
end
|
244
244
|
end
|
245
245
|
end
|
246
|
+
|
247
|
+
describe 'String property' do
|
248
|
+
before :all do
|
249
|
+
@model.property(:id, DataMapper::Types::Serial)
|
250
|
+
end
|
251
|
+
|
252
|
+
[
|
253
|
+
[ 1, 'VARCHAR(1)' ],
|
254
|
+
[ 50, 'VARCHAR(50)' ],
|
255
|
+
[ 255, 'VARCHAR(255)' ],
|
256
|
+
[ nil, 'VARCHAR(50)' ],
|
257
|
+
].each do |length, statement|
|
258
|
+
options = {}
|
259
|
+
options[:length] = length if length
|
260
|
+
|
261
|
+
describe "with a length of #{length}" do
|
262
|
+
before :all do
|
263
|
+
@property = @model.property(:title, String, options)
|
264
|
+
|
265
|
+
@response = capture_log(DataObjects::Mysql) { @model.auto_migrate! }
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should return true' do
|
269
|
+
@response.should be_true
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should create a #{statement} column" do
|
273
|
+
@output.last.should =~ %r{\ACREATE TABLE `blog_articles` \(`id` INT\(10\) UNSIGNED NOT NULL AUTO_INCREMENT, `title` #{Regexp.escape(statement)}, PRIMARY KEY\(`id`\)\) ENGINE = InnoDB CHARACTER SET [a-z\d]+ COLLATE (?:[a-z\d](?:_?[a-z\d]+)*)\z}
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
246
278
|
end
|
247
279
|
end
|
248
280
|
|
@@ -354,6 +386,118 @@ describe DataMapper::Migrations do
|
|
354
386
|
end
|
355
387
|
end
|
356
388
|
end
|
389
|
+
|
390
|
+
describe 'String property' do
|
391
|
+
before :all do
|
392
|
+
@model.property(:id, DataMapper::Types::Serial)
|
393
|
+
end
|
394
|
+
|
395
|
+
[
|
396
|
+
[ 1, 'VARCHAR(1)' ],
|
397
|
+
[ 50, 'VARCHAR(50)' ],
|
398
|
+
[ 255, 'VARCHAR(255)' ],
|
399
|
+
[ nil, 'VARCHAR(50)' ],
|
400
|
+
].each do |length, statement|
|
401
|
+
options = {}
|
402
|
+
options[:length] = length if length
|
403
|
+
|
404
|
+
describe "with a length of #{length}" do
|
405
|
+
before :all do
|
406
|
+
@property = @model.property(:title, String, options)
|
407
|
+
|
408
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_migrate! }
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'should return true' do
|
412
|
+
@response.should be_true
|
413
|
+
end
|
414
|
+
|
415
|
+
it "should create a #{statement} column" do
|
416
|
+
@output[-2].should == "CREATE TABLE \"blog_articles\" (\"id\" SERIAL NOT NULL, \"title\" #{statement}, PRIMARY KEY(\"id\"))"
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
supported_by :sqlserver do
|
425
|
+
before :all do
|
426
|
+
module ::Blog
|
427
|
+
class Article
|
428
|
+
include DataMapper::Resource
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
@model = ::Blog::Article
|
433
|
+
end
|
434
|
+
|
435
|
+
describe '#auto_migrate' do
|
436
|
+
describe 'Integer property' do
|
437
|
+
[
|
438
|
+
[ 0, 1, 'TINYINT' ],
|
439
|
+
[ 0, 255, 'TINYINT' ],
|
440
|
+
[ 0, 256, 'SMALLINT' ],
|
441
|
+
[ 0, 32767, 'SMALLINT' ],
|
442
|
+
[ 0, 32768, 'INT' ],
|
443
|
+
[ 0, 2147483647, 'INT' ],
|
444
|
+
[ 0, 2147483648, 'BIGINT' ],
|
445
|
+
[ 0, 9223372036854775807, 'BIGINT' ],
|
446
|
+
|
447
|
+
[ -1, 1, 'SMALLINT' ],
|
448
|
+
[ -1, 255, 'SMALLINT' ],
|
449
|
+
[ -1, 256, 'SMALLINT' ],
|
450
|
+
[ -1, 32767, 'SMALLINT' ],
|
451
|
+
[ -1, 32768, 'INT' ],
|
452
|
+
[ -1, 2147483647, 'INT' ],
|
453
|
+
[ -1, 2147483648, 'BIGINT' ],
|
454
|
+
[ -1, 9223372036854775807, 'BIGINT' ],
|
455
|
+
|
456
|
+
[ -1, 0, 'SMALLINT' ],
|
457
|
+
[ -32768, 0, 'SMALLINT' ],
|
458
|
+
[ -32769, 0, 'INT' ],
|
459
|
+
[ -2147483648, 0, 'INT' ],
|
460
|
+
[ -2147483649, 0, 'BIGINT' ],
|
461
|
+
[ -9223372036854775808, 0, 'BIGINT' ],
|
462
|
+
|
463
|
+
[ nil, 2147483647, 'INT' ],
|
464
|
+
[ 0, nil, 'INT' ],
|
465
|
+
[ nil, nil, 'INTEGER' ],
|
466
|
+
].each do |min, max, statement|
|
467
|
+
options = { :key => true }
|
468
|
+
options[:min] = min if min
|
469
|
+
options[:max] = max if max
|
470
|
+
|
471
|
+
describe "with a min of #{min} and a max of #{max}" do
|
472
|
+
before :all do
|
473
|
+
@property = @model.property(:id, Integer, options)
|
474
|
+
|
475
|
+
@response = capture_log(DataObjects::Sqlserver) { @model.auto_migrate! }
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'should return true' do
|
479
|
+
@response.should be_true
|
480
|
+
end
|
481
|
+
|
482
|
+
it "should create a #{statement} column" do
|
483
|
+
@output.last.should == "CREATE TABLE \"blog_articles\" (\"id\" #{statement} NOT NULL, PRIMARY KEY(\"id\"))"
|
484
|
+
end
|
485
|
+
|
486
|
+
options.only(:min, :max).each do |key, value|
|
487
|
+
it "should allow the #{key} value #{value} to be stored" do
|
488
|
+
lambda {
|
489
|
+
resource = @model.create(@property => value)
|
490
|
+
@model.first(@property => value).should eql(resource)
|
491
|
+
}.should_not raise_error
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
describe 'String property' do
|
499
|
+
it 'needs specs'
|
500
|
+
end
|
357
501
|
end
|
358
502
|
end
|
359
503
|
end
|
@@ -5,7 +5,7 @@ share_examples_for 'it creates a one accessor' do
|
|
5
5
|
describe 'when there is no associated resource' do
|
6
6
|
describe 'without a query' do
|
7
7
|
before :all do
|
8
|
-
@return = @car.
|
8
|
+
@return = @car.__send__(@name)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'should return nil' do
|
@@ -15,7 +15,7 @@ share_examples_for 'it creates a one accessor' do
|
|
15
15
|
|
16
16
|
describe 'with a query' do
|
17
17
|
before :all do
|
18
|
-
@return = @car.
|
18
|
+
@return = @car.__send__(@name, :id => 99)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'should return nil' do
|
@@ -27,12 +27,12 @@ share_examples_for 'it creates a one accessor' do
|
|
27
27
|
describe 'when there is an associated resource' do
|
28
28
|
before :all do
|
29
29
|
@expected = @model.new
|
30
|
-
@car.
|
30
|
+
@car.__send__("#{@name}=", @expected)
|
31
31
|
end
|
32
32
|
|
33
33
|
describe 'without a query' do
|
34
34
|
before :all do
|
35
|
-
@return = @car.
|
35
|
+
@return = @car.__send__(@name)
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'should return a Resource' do
|
@@ -50,7 +50,7 @@ share_examples_for 'it creates a one accessor' do
|
|
50
50
|
|
51
51
|
@expected.id.should_not be_nil
|
52
52
|
|
53
|
-
@return = @car.
|
53
|
+
@return = @car.__send__(@name, :id => @expected.id)
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should return a Resource' do
|
@@ -66,13 +66,13 @@ share_examples_for 'it creates a one accessor' do
|
|
66
66
|
describe 'when the target model is scoped' do
|
67
67
|
before :all do
|
68
68
|
@resource = @model.new
|
69
|
-
@car.
|
69
|
+
@car.__send__("#{@name}=", @resource)
|
70
70
|
@car.save
|
71
71
|
|
72
72
|
# set the model scope to not match the expected resource
|
73
73
|
@model.default_scope.update(:id.not => @resource.id)
|
74
74
|
|
75
|
-
@return = @car.model.get(*@car.key).
|
75
|
+
@return = @car.model.get(*@car.key).__send__(@name)
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'should return nil' do
|
@@ -88,7 +88,7 @@ share_examples_for 'it creates a one mutator' do
|
|
88
88
|
before :all do
|
89
89
|
@expected = @model.new
|
90
90
|
|
91
|
-
@return = @car.
|
91
|
+
@return = @car.__send__("#{@name}=", @expected)
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'should return the expected Resource' do
|
@@ -96,7 +96,7 @@ share_examples_for 'it creates a one mutator' do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should set the Resource' do
|
99
|
-
@car.
|
99
|
+
@car.__send__(@name).should equal(@expected)
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'should relate associated Resource' do
|
@@ -104,14 +104,14 @@ share_examples_for 'it creates a one mutator' do
|
|
104
104
|
many_to_one = relationship.kind_of?(DataMapper::Associations::ManyToOne::Relationship)
|
105
105
|
one_to_one_through = relationship.kind_of?(DataMapper::Associations::OneToOne::Relationship) && relationship.respond_to?(:through)
|
106
106
|
|
107
|
-
pending_if
|
107
|
+
pending_if many_to_one || one_to_one_through do
|
108
108
|
@expected.car.should == @car
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'should persist the Resource' do
|
113
113
|
@car.save.should be_true
|
114
|
-
@car.model.get(*@car.key).
|
114
|
+
@car.model.get(*@car.key).__send__(@name).should == @expected
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'should persist the associated Resource' do
|
@@ -123,12 +123,12 @@ share_examples_for 'it creates a one mutator' do
|
|
123
123
|
|
124
124
|
describe 'when setting a Hash' do
|
125
125
|
before :all do
|
126
|
-
@car.
|
126
|
+
@car.__send__("#{@name}=", @model.new)
|
127
127
|
|
128
128
|
attributes = { :id => 10 }
|
129
129
|
@expected = @model.new(attributes)
|
130
130
|
|
131
|
-
@return = @car.
|
131
|
+
@return = @car.__send__("#{@name}=", attributes)
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'should return the expected Resource' do
|
@@ -136,7 +136,7 @@ share_examples_for 'it creates a one mutator' do
|
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should set the Resource' do
|
139
|
-
@car.
|
139
|
+
@car.__send__(@name).should equal(@return)
|
140
140
|
end
|
141
141
|
|
142
142
|
it 'should relate associated Resource' do
|
@@ -144,14 +144,14 @@ share_examples_for 'it creates a one mutator' do
|
|
144
144
|
many_to_one = relationship.kind_of?(DataMapper::Associations::ManyToOne::Relationship)
|
145
145
|
one_to_one_through = relationship.kind_of?(DataMapper::Associations::OneToOne::Relationship) && relationship.respond_to?(:through)
|
146
146
|
|
147
|
-
pending_if
|
147
|
+
pending_if many_to_one || one_to_one_through do
|
148
148
|
@return.car.should == @car
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
152
|
it 'should persist the Resource' do
|
153
153
|
@car.save.should be_true
|
154
|
-
@car.model.get(*@car.key).
|
154
|
+
@car.model.get(*@car.key).__send__(@name).should == @return
|
155
155
|
end
|
156
156
|
|
157
157
|
it 'should persist the associated Resource' do
|
@@ -163,9 +163,9 @@ share_examples_for 'it creates a one mutator' do
|
|
163
163
|
|
164
164
|
describe 'when setting nil' do
|
165
165
|
before :all do
|
166
|
-
@car.
|
166
|
+
@car.__send__("#{@name}=", @model.new)
|
167
167
|
|
168
|
-
@return = @car.
|
168
|
+
@return = @car.__send__("#{@name}=", nil)
|
169
169
|
end
|
170
170
|
|
171
171
|
it 'should return nil' do
|
@@ -173,21 +173,21 @@ share_examples_for 'it creates a one mutator' do
|
|
173
173
|
end
|
174
174
|
|
175
175
|
it 'should set nil' do
|
176
|
-
@car.
|
176
|
+
@car.__send__(@name).should be_nil
|
177
177
|
end
|
178
178
|
|
179
179
|
it 'should persist as nil' do
|
180
180
|
@car.save.should be_true
|
181
|
-
@car.model.get(*@car.key).
|
181
|
+
@car.model.get(*@car.key).__send__(@name).should be_nil
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
185
|
describe 'when changing the Resource' do
|
186
186
|
before :all do
|
187
|
-
@car.
|
187
|
+
@car.__send__("#{@name}=", @model.new)
|
188
188
|
@expected = @model.new
|
189
189
|
|
190
|
-
@return = @car.
|
190
|
+
@return = @car.__send__("#{@name}=", @expected)
|
191
191
|
end
|
192
192
|
|
193
193
|
it 'should return the expected Resource' do
|
@@ -195,7 +195,7 @@ share_examples_for 'it creates a one mutator' do
|
|
195
195
|
end
|
196
196
|
|
197
197
|
it 'should set the Resource' do
|
198
|
-
@car.
|
198
|
+
@car.__send__(@name).should equal(@expected)
|
199
199
|
end
|
200
200
|
|
201
201
|
it 'should relate associated Resource' do
|
@@ -210,7 +210,7 @@ share_examples_for 'it creates a one mutator' do
|
|
210
210
|
|
211
211
|
it 'should persist the Resource' do
|
212
212
|
@car.save.should be_true
|
213
|
-
@car.model.get(*@car.key).
|
213
|
+
@car.model.get(*@car.key).__send__(@name).should == @expected
|
214
214
|
end
|
215
215
|
|
216
216
|
it 'should persist the associated Resource' do
|
@@ -227,7 +227,7 @@ share_examples_for 'it creates a many accessor' do
|
|
227
227
|
describe 'when there is no child resource and the source is saved' do
|
228
228
|
before :all do
|
229
229
|
@car.save.should be_true
|
230
|
-
@return = @car.
|
230
|
+
@return = @car.__send__(@name)
|
231
231
|
end
|
232
232
|
|
233
233
|
it 'should return a Collection' do
|
@@ -241,7 +241,7 @@ share_examples_for 'it creates a many accessor' do
|
|
241
241
|
|
242
242
|
describe 'when there is no child resource and the source is not saved' do
|
243
243
|
before :all do
|
244
|
-
@return = @car.
|
244
|
+
@return = @car.__send__(@name)
|
245
245
|
end
|
246
246
|
|
247
247
|
it 'should return a Collection' do
|
@@ -258,9 +258,9 @@ share_examples_for 'it creates a many accessor' do
|
|
258
258
|
@return = nil
|
259
259
|
|
260
260
|
@expected = @model.new
|
261
|
-
@car.
|
261
|
+
@car.__send__("#{@name}=", [ @expected ])
|
262
262
|
|
263
|
-
@return = @car.
|
263
|
+
@return = @car.__send__(@name)
|
264
264
|
end
|
265
265
|
|
266
266
|
it 'should return a Collection' do
|
@@ -274,15 +274,15 @@ share_examples_for 'it creates a many accessor' do
|
|
274
274
|
|
275
275
|
describe 'when the target model is scoped' do
|
276
276
|
before :all do
|
277
|
-
2.times { @car.
|
277
|
+
2.times { @car.__send__(@name).new }
|
278
278
|
@car.save
|
279
279
|
|
280
|
-
@expected = @car.
|
280
|
+
@expected = @car.__send__(@name).first
|
281
281
|
|
282
282
|
# set the model scope to only return the first record
|
283
283
|
@model.default_scope.update(@model.key(@repository.name).zip(@expected.key).to_hash)
|
284
284
|
|
285
|
-
@return = @car.model.get(*@car.key).
|
285
|
+
@return = @car.model.get(*@car.key).__send__(@name)
|
286
286
|
end
|
287
287
|
|
288
288
|
it 'should return a Collection' do
|
@@ -302,7 +302,7 @@ share_examples_for 'it creates a many mutator' do
|
|
302
302
|
before :all do
|
303
303
|
@expected = [ @model.new ]
|
304
304
|
|
305
|
-
@return = @car.
|
305
|
+
@return = @car.__send__("#{@name}=", @expected)
|
306
306
|
end
|
307
307
|
|
308
308
|
it 'should return the expected Collection' do
|
@@ -310,19 +310,19 @@ share_examples_for 'it creates a many mutator' do
|
|
310
310
|
end
|
311
311
|
|
312
312
|
it 'should set the Collection' do
|
313
|
-
@car.
|
314
|
-
@car.
|
313
|
+
@car.__send__(@name).should == @expected
|
314
|
+
@car.__send__(@name).zip(@expected) { |value, expected| value.should equal(expected) }
|
315
315
|
end
|
316
316
|
|
317
317
|
it 'should relate the associated Collection' do
|
318
|
-
pending_if
|
318
|
+
pending_if Car.relationships[@name].kind_of?(DataMapper::Associations::ManyToMany::Relationship) do
|
319
319
|
@expected.each { |resource| resource.car.should == @car }
|
320
320
|
end
|
321
321
|
end
|
322
322
|
|
323
323
|
it 'should persist the Collection' do
|
324
324
|
@car.save.should be_true
|
325
|
-
@car.model.get(*@car.key).
|
325
|
+
@car.model.get(*@car.key).__send__(@name).should == @expected
|
326
326
|
end
|
327
327
|
|
328
328
|
it 'should persist the associated Resource' do
|
@@ -338,7 +338,7 @@ share_examples_for 'it creates a many mutator' do
|
|
338
338
|
@hashes = [ attributes ]
|
339
339
|
@expected = [ @model.new(attributes) ]
|
340
340
|
|
341
|
-
@return = @car.
|
341
|
+
@return = @car.__send__("#{@name}=", @hashes)
|
342
342
|
end
|
343
343
|
|
344
344
|
it 'should return the expected Collection' do
|
@@ -346,18 +346,18 @@ share_examples_for 'it creates a many mutator' do
|
|
346
346
|
end
|
347
347
|
|
348
348
|
it 'should set the Collection' do
|
349
|
-
@car.
|
349
|
+
@car.__send__(@name).should == @return
|
350
350
|
end
|
351
351
|
|
352
352
|
it 'should relate the associated Collection' do
|
353
|
-
pending_if
|
353
|
+
pending_if Car.relationships[@name].kind_of?(DataMapper::Associations::ManyToMany::Relationship) do
|
354
354
|
@return.each { |resource| resource.car.should == @car }
|
355
355
|
end
|
356
356
|
end
|
357
357
|
|
358
358
|
it 'should persist the Collection' do
|
359
359
|
@car.save.should be_true
|
360
|
-
@car.model.get(*@car.key).
|
360
|
+
@car.model.get(*@car.key).__send__(@name).should == @return
|
361
361
|
end
|
362
362
|
|
363
363
|
it 'should persist the associated Resource' do
|
@@ -369,9 +369,9 @@ share_examples_for 'it creates a many mutator' do
|
|
369
369
|
|
370
370
|
describe 'when setting an empty collection' do
|
371
371
|
before :all do
|
372
|
-
@car.
|
372
|
+
@car.__send__("#{@name}=", [ @model.new ])
|
373
373
|
|
374
|
-
@return = @car.
|
374
|
+
@return = @car.__send__("#{@name}=", [])
|
375
375
|
end
|
376
376
|
|
377
377
|
it 'should return a Collection' do
|
@@ -379,22 +379,22 @@ share_examples_for 'it creates a many mutator' do
|
|
379
379
|
end
|
380
380
|
|
381
381
|
it 'should set an empty Collection' do
|
382
|
-
@car.
|
382
|
+
@car.__send__(@name).should be_empty
|
383
383
|
end
|
384
384
|
|
385
385
|
it 'should persist as an empty Collection' do
|
386
386
|
@car.save.should be_true
|
387
|
-
@car.model.get(*@car.key).
|
387
|
+
@car.model.get(*@car.key).__send__(@name).should be_empty
|
388
388
|
end
|
389
389
|
end
|
390
390
|
|
391
391
|
describe 'when changing an associated collection' do
|
392
392
|
before :all do
|
393
|
-
@car.
|
393
|
+
@car.__send__("#{@name}=", [ @model.new ])
|
394
394
|
|
395
395
|
@expected = [ @model.new ]
|
396
396
|
|
397
|
-
@return = @car.
|
397
|
+
@return = @car.__send__("#{@name}=", @expected)
|
398
398
|
end
|
399
399
|
|
400
400
|
it 'should return the expected Resource' do
|
@@ -402,19 +402,19 @@ share_examples_for 'it creates a many mutator' do
|
|
402
402
|
end
|
403
403
|
|
404
404
|
it 'should set the Resource' do
|
405
|
-
@car.
|
406
|
-
@car.
|
405
|
+
@car.__send__(@name).should == @expected
|
406
|
+
@car.__send__(@name).zip(@expected) { |value, expected| value.should equal(expected) }
|
407
407
|
end
|
408
408
|
|
409
409
|
it 'should relate associated Resource' do
|
410
|
-
pending_if
|
410
|
+
pending_if Car.relationships[@name].kind_of?(DataMapper::Associations::ManyToMany::Relationship) do
|
411
411
|
@expected.each { |resource| resource.car.should == @car }
|
412
412
|
end
|
413
413
|
end
|
414
414
|
|
415
415
|
it 'should persist the Resource' do
|
416
416
|
@car.save.should be_true
|
417
|
-
@car.model.get(*@car.key).
|
417
|
+
@car.model.get(*@car.key).__send__(@name).should == @expected
|
418
418
|
end
|
419
419
|
|
420
420
|
it 'should persist the associated Resource' do
|
@@ -432,6 +432,7 @@ describe DataMapper::Associations do
|
|
432
432
|
include DataMapper::Resource
|
433
433
|
|
434
434
|
property :id, Serial
|
435
|
+
property :name, String
|
435
436
|
end
|
436
437
|
|
437
438
|
class ::Engine
|
@@ -464,7 +465,7 @@ describe DataMapper::Associations do
|
|
464
465
|
@model = Engine
|
465
466
|
@name = :engine
|
466
467
|
|
467
|
-
Car.belongs_to(@name, :
|
468
|
+
Car.belongs_to(@name, :required => false)
|
468
469
|
Engine.has(1, :car)
|
469
470
|
end
|
470
471
|
|
@@ -561,8 +562,7 @@ describe DataMapper::Associations do
|
|
561
562
|
before :all do
|
562
563
|
@car = Car.create
|
563
564
|
|
564
|
-
@engine = Engine.new
|
565
|
-
@engine.car_id = @car.id
|
565
|
+
@engine = Engine.new(:car_id => @car.id)
|
566
566
|
end
|
567
567
|
|
568
568
|
it 'should set the associated resource' do
|
@@ -611,6 +611,66 @@ describe DataMapper::Associations do
|
|
611
611
|
end
|
612
612
|
end
|
613
613
|
end
|
614
|
+
|
615
|
+
describe 'with a model' do
|
616
|
+
before :all do
|
617
|
+
Engine.belongs_to(:vehicle, Car)
|
618
|
+
end
|
619
|
+
|
620
|
+
it 'should set the relationship target model' do
|
621
|
+
Engine.relationships[:vehicle].target_model.should == Car
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
625
|
+
describe 'with a :model option' do
|
626
|
+
before :all do
|
627
|
+
Engine.belongs_to(:vehicle, :model => Car)
|
628
|
+
end
|
629
|
+
|
630
|
+
it 'should set the relationship target model' do
|
631
|
+
Engine.relationships[:vehicle].target_model.should == Car
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
describe 'with a single element as :child_key option' do
|
636
|
+
before :all do
|
637
|
+
Engine.belongs_to(:vehicle, :model => Car, :child_key => :bike_id)
|
638
|
+
end
|
639
|
+
|
640
|
+
it 'should set the relationship child key' do
|
641
|
+
Engine.relationships[:vehicle].child_key.map { |property| property.name }.should == [:bike_id]
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
describe 'with an array as :child_key option' do
|
646
|
+
before :all do
|
647
|
+
Engine.belongs_to(:vehicle, :model => Car, :child_key => [:bike_id])
|
648
|
+
end
|
649
|
+
|
650
|
+
it 'should set the relationship child key' do
|
651
|
+
Engine.relationships[:vehicle].child_key.map { |property| property.name }.should == [:bike_id]
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
describe 'with a single element as :parent_key option' do
|
656
|
+
before :all do
|
657
|
+
Engine.belongs_to(:vehicle, :model => Car, :parent_key => :name)
|
658
|
+
end
|
659
|
+
|
660
|
+
it 'should set the relationship parent key' do
|
661
|
+
Engine.relationships[:vehicle].parent_key.map { |property| property.name }.should == [:name]
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
describe 'with an array as :parent_key option' do
|
666
|
+
before :all do
|
667
|
+
Engine.belongs_to(:vehicle, :model => Car, :parent_key => [:name])
|
668
|
+
end
|
669
|
+
|
670
|
+
it 'should set the relationship parent key' do
|
671
|
+
Engine.relationships[:vehicle].parent_key.map { |property| property.name }.should == [:name]
|
672
|
+
end
|
673
|
+
end
|
614
674
|
end
|
615
675
|
|
616
676
|
it { Car.should respond_to(:has) }
|
@@ -679,7 +739,7 @@ describe DataMapper::Associations do
|
|
679
739
|
@name = :doors
|
680
740
|
|
681
741
|
Car.has(1..4, @name)
|
682
|
-
Door.belongs_to(:car, :
|
742
|
+
Door.belongs_to(:car, :required => false)
|
683
743
|
end
|
684
744
|
|
685
745
|
supported_by :all do
|
@@ -902,7 +962,7 @@ describe DataMapper::Associations do
|
|
902
962
|
property :id, Serial
|
903
963
|
property :name, String
|
904
964
|
|
905
|
-
belongs_to :owner, Employee, :
|
965
|
+
belongs_to :owner, Employee, :required => false
|
906
966
|
has n, :employees
|
907
967
|
end
|
908
968
|
end
|