dm-core 0.9.11 → 0.10.0

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 (194) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -50
  5. data/Manifest.txt +66 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +6 -7
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/deps.rip +2 -0
  12. data/dm-core.gemspec +11 -15
  13. data/lib/dm-core.rb +105 -110
  14. data/lib/dm-core/adapters.rb +135 -16
  15. data/lib/dm-core/adapters/abstract_adapter.rb +251 -181
  16. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  17. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  18. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  19. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  20. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  21. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  22. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  23. data/lib/dm-core/associations/many_to_many.rb +372 -90
  24. data/lib/dm-core/associations/many_to_one.rb +220 -73
  25. data/lib/dm-core/associations/one_to_many.rb +319 -255
  26. data/lib/dm-core/associations/one_to_one.rb +66 -53
  27. data/lib/dm-core/associations/relationship.rb +561 -156
  28. data/lib/dm-core/collection.rb +1101 -379
  29. data/lib/dm-core/core_ext/kernel.rb +12 -0
  30. data/lib/dm-core/core_ext/symbol.rb +10 -0
  31. data/lib/dm-core/identity_map.rb +4 -34
  32. data/lib/dm-core/migrations.rb +1283 -0
  33. data/lib/dm-core/model.rb +570 -369
  34. data/lib/dm-core/model/descendant_set.rb +81 -0
  35. data/lib/dm-core/model/hook.rb +45 -0
  36. data/lib/dm-core/model/is.rb +32 -0
  37. data/lib/dm-core/model/property.rb +247 -0
  38. data/lib/dm-core/model/relationship.rb +335 -0
  39. data/lib/dm-core/model/scope.rb +90 -0
  40. data/lib/dm-core/property.rb +808 -273
  41. data/lib/dm-core/property_set.rb +141 -98
  42. data/lib/dm-core/query.rb +1037 -483
  43. data/lib/dm-core/query/conditions/comparison.rb +872 -0
  44. data/lib/dm-core/query/conditions/operation.rb +221 -0
  45. data/lib/dm-core/query/direction.rb +43 -0
  46. data/lib/dm-core/query/operator.rb +84 -0
  47. data/lib/dm-core/query/path.rb +138 -0
  48. data/lib/dm-core/query/sort.rb +45 -0
  49. data/lib/dm-core/repository.rb +210 -94
  50. data/lib/dm-core/resource.rb +641 -421
  51. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  52. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  53. data/lib/dm-core/support/chainable.rb +22 -0
  54. data/lib/dm-core/support/deprecate.rb +12 -0
  55. data/lib/dm-core/support/logger.rb +13 -0
  56. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  57. data/lib/dm-core/transaction.rb +333 -92
  58. data/lib/dm-core/type.rb +98 -60
  59. data/lib/dm-core/types/boolean.rb +1 -1
  60. data/lib/dm-core/types/discriminator.rb +34 -20
  61. data/lib/dm-core/types/object.rb +7 -4
  62. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  63. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  64. data/lib/dm-core/types/serial.rb +3 -3
  65. data/lib/dm-core/types/text.rb +3 -4
  66. data/lib/dm-core/version.rb +1 -1
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/migrations_spec.rb +359 -0
  80. data/spec/public/model/relationship_spec.rb +924 -0
  81. data/spec/public/model_spec.rb +159 -0
  82. data/spec/public/property_spec.rb +829 -0
  83. data/spec/public/resource_spec.rb +71 -0
  84. data/spec/public/sel_spec.rb +44 -0
  85. data/spec/public/setup_spec.rb +145 -0
  86. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  87. data/spec/public/shared/collection_shared_spec.rb +1670 -0
  88. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  89. data/spec/public/shared/resource_shared_spec.rb +924 -0
  90. data/spec/public/shared/sel_shared_spec.rb +112 -0
  91. data/spec/public/transaction_spec.rb +129 -0
  92. data/spec/public/types/discriminator_spec.rb +130 -0
  93. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  94. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  95. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  96. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  97. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  99. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  100. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  101. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  102. data/spec/semipublic/associations_spec.rb +177 -0
  103. data/spec/semipublic/collection_spec.rb +142 -0
  104. data/spec/semipublic/property_spec.rb +61 -0
  105. data/spec/semipublic/query/conditions_spec.rb +528 -0
  106. data/spec/semipublic/query/path_spec.rb +443 -0
  107. data/spec/semipublic/query_spec.rb +2626 -0
  108. data/spec/semipublic/resource_spec.rb +47 -0
  109. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  110. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  111. data/spec/spec.opts +3 -1
  112. data/spec/spec_helper.rb +80 -57
  113. data/tasks/ci.rb +19 -31
  114. data/tasks/dm.rb +43 -48
  115. data/tasks/doc.rb +8 -11
  116. data/tasks/gemspec.rb +5 -5
  117. data/tasks/hoe.rb +15 -16
  118. data/tasks/install.rb +8 -10
  119. metadata +74 -111
  120. data/lib/dm-core/associations.rb +0 -207
  121. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  122. data/lib/dm-core/auto_migrations.rb +0 -105
  123. data/lib/dm-core/dependency_queue.rb +0 -32
  124. data/lib/dm-core/hook.rb +0 -11
  125. data/lib/dm-core/is.rb +0 -16
  126. data/lib/dm-core/logger.rb +0 -232
  127. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  128. data/lib/dm-core/migrator.rb +0 -29
  129. data/lib/dm-core/scope.rb +0 -58
  130. data/lib/dm-core/support.rb +0 -7
  131. data/lib/dm-core/support/array.rb +0 -13
  132. data/lib/dm-core/support/assertions.rb +0 -8
  133. data/lib/dm-core/support/errors.rb +0 -23
  134. data/lib/dm-core/support/kernel.rb +0 -11
  135. data/lib/dm-core/support/symbol.rb +0 -41
  136. data/lib/dm-core/type_map.rb +0 -80
  137. data/lib/dm-core/types.rb +0 -19
  138. data/script/all +0 -4
  139. data/spec/integration/association_spec.rb +0 -1382
  140. data/spec/integration/association_through_spec.rb +0 -203
  141. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  142. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  143. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  144. data/spec/integration/auto_migrations_spec.rb +0 -413
  145. data/spec/integration/collection_spec.rb +0 -1073
  146. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  147. data/spec/integration/dependency_queue_spec.rb +0 -46
  148. data/spec/integration/model_spec.rb +0 -197
  149. data/spec/integration/mysql_adapter_spec.rb +0 -85
  150. data/spec/integration/postgres_adapter_spec.rb +0 -731
  151. data/spec/integration/property_spec.rb +0 -253
  152. data/spec/integration/query_spec.rb +0 -514
  153. data/spec/integration/repository_spec.rb +0 -61
  154. data/spec/integration/resource_spec.rb +0 -513
  155. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  156. data/spec/integration/sti_spec.rb +0 -273
  157. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  158. data/spec/integration/transaction_spec.rb +0 -75
  159. data/spec/integration/type_spec.rb +0 -275
  160. data/spec/lib/logging_helper.rb +0 -18
  161. data/spec/lib/mock_adapter.rb +0 -27
  162. data/spec/lib/model_loader.rb +0 -100
  163. data/spec/lib/publicize_methods.rb +0 -28
  164. data/spec/models/content.rb +0 -16
  165. data/spec/models/vehicles.rb +0 -34
  166. data/spec/models/zoo.rb +0 -48
  167. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  168. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  169. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  170. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  171. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  172. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  173. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  174. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  175. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  176. data/spec/unit/associations/relationship_spec.rb +0 -71
  177. data/spec/unit/associations_spec.rb +0 -242
  178. data/spec/unit/auto_migrations_spec.rb +0 -111
  179. data/spec/unit/collection_spec.rb +0 -182
  180. data/spec/unit/data_mapper_spec.rb +0 -35
  181. data/spec/unit/identity_map_spec.rb +0 -126
  182. data/spec/unit/is_spec.rb +0 -80
  183. data/spec/unit/migrator_spec.rb +0 -33
  184. data/spec/unit/model_spec.rb +0 -321
  185. data/spec/unit/naming_conventions_spec.rb +0 -36
  186. data/spec/unit/property_set_spec.rb +0 -90
  187. data/spec/unit/property_spec.rb +0 -753
  188. data/spec/unit/query_spec.rb +0 -571
  189. data/spec/unit/repository_spec.rb +0 -93
  190. data/spec/unit/resource_spec.rb +0 -649
  191. data/spec/unit/scope_spec.rb +0 -142
  192. data/spec/unit/transaction_spec.rb +0 -493
  193. data/spec/unit/type_map_spec.rb +0 -114
  194. data/spec/unit/type_spec.rb +0 -119
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ describe 'Adapter' do
9
+ supported_by :postgres do
10
+ describe DataMapper::Adapters::PostgresAdapter do
11
+
12
+ it_should_behave_like 'An Adapter'
13
+ it_should_behave_like 'A DataObjects Adapter'
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ describe 'Adapter' do
9
+ supported_by :sqlite3 do
10
+ describe DataMapper::Adapters::Sqlite3Adapter do
11
+
12
+ it_should_behave_like 'An Adapter'
13
+ it_should_behave_like 'A DataObjects Adapter'
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+ require DataMapper.root / 'lib' / 'dm-core' / 'spec' / 'adapter_shared_spec'
3
+
4
+ describe 'Adapter' do
5
+ supported_by :yaml do
6
+ describe DataMapper::Adapters::YamlAdapter do
7
+
8
+ it_should_behave_like 'An Adapter'
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe 'Many to One Associations' do
4
+ before :all do
5
+ class ::User
6
+ include DataMapper::Resource
7
+
8
+ property :name, String, :key => true
9
+ property :age, Integer
10
+ property :description, Text
11
+
12
+ has n, :comments
13
+ end
14
+
15
+ # This is a special class that needs to be an exact copy of User
16
+ class ::Clone
17
+ include DataMapper::Resource
18
+
19
+ property :name, String, :key => true
20
+ property :age, Integer
21
+ property :description, Text
22
+ end
23
+
24
+ class ::Comment
25
+ include DataMapper::Resource
26
+
27
+ property :id, Serial
28
+ property :body, Text
29
+
30
+ belongs_to :user
31
+ end
32
+
33
+ class ::Default
34
+ include DataMapper::Resource
35
+
36
+ property :name, String, :key => true, :default => 'a default value'
37
+ end
38
+
39
+ @user_model = User
40
+ @comment_model = Comment
41
+ end
42
+
43
+ supported_by :all do
44
+ before :all do
45
+ comment = @comment_model.create(:body => 'Cool spec', :user => User.create(:name => 'dbussink', :age => 25, :description => 'Test'))
46
+
47
+ comment = @comment_model.get(*comment.key)
48
+ @user = comment.user
49
+ end
50
+
51
+ it_should_behave_like 'A semipublic Resource'
52
+ end
53
+ end
@@ -0,0 +1,194 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Associations::Relationship do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :title, String, :key => true
10
+ end
11
+
12
+ class Comment
13
+ include DataMapper::Resource
14
+
15
+ property :id, Serial
16
+ property :body, Text
17
+ end
18
+ end
19
+
20
+ @article_model = Blog::Article
21
+ @comment_model = Blog::Comment
22
+ end
23
+
24
+ def n
25
+ 1.0/0
26
+ end
27
+
28
+ describe '#inverse' do
29
+ describe 'with matching relationships' do
30
+ before :all do
31
+ @comments_relationship = @article_model.has(n, :comments)
32
+ @article_relationship = @comment_model.belongs_to(:article)
33
+
34
+ # TODO: move this to spec/public/model/relationship_spec.rb
35
+ @comments_relationship.child_repository_name.should be_nil
36
+ @comments_relationship.parent_repository_name.should == :default
37
+
38
+ # TODO: move this to spec/public/model/relationship_spec.rb
39
+ @article_relationship.child_repository_name.should == :default
40
+ @article_relationship.parent_repository_name.should be_nil
41
+ end
42
+
43
+ it 'should return the inverted relationships' do
44
+ @comments_relationship.inverse.should equal(@article_relationship)
45
+ @article_relationship.inverse.should equal(@comments_relationship)
46
+ end
47
+ end
48
+
49
+ describe 'with matching relationships where the child repository is not nil' do
50
+ before :all do
51
+ @comments_relationship = @article_model.has(n, :comments, :repository => :default)
52
+ @article_relationship = @comment_model.belongs_to(:article)
53
+
54
+ # TODO: move this to spec/public/model/relationship_spec.rb
55
+ @comments_relationship.child_repository_name.should == :default
56
+ @comments_relationship.parent_repository_name.should == :default
57
+
58
+ # TODO: move this to spec/public/model/relationship_spec.rb
59
+ @article_relationship.child_repository_name.should == :default
60
+ @article_relationship.parent_repository_name.should be_nil
61
+ end
62
+
63
+ it 'should return the inverted relationships' do
64
+ @comments_relationship.inverse.should equal(@article_relationship)
65
+ @article_relationship.inverse.should equal(@comments_relationship)
66
+ end
67
+ end
68
+
69
+ describe 'with matching relationships where the parent repository is not nil' do
70
+ before :all do
71
+ @comments_relationship = @article_model.has(n, :comments)
72
+ @article_relationship = @comment_model.belongs_to(:article, :repository => :default)
73
+
74
+ # TODO: move this to spec/public/model/relationship_spec.rb
75
+ @comments_relationship.child_repository_name.should be_nil
76
+ @comments_relationship.parent_repository_name.should == :default
77
+
78
+ # TODO: move this to spec/public/model/relationship_spec.rb
79
+ @article_relationship.child_repository_name.should == :default
80
+ @article_relationship.parent_repository_name.should == :default
81
+ end
82
+
83
+ it 'should return the inverted relationships' do
84
+ @comments_relationship.inverse.should equal(@article_relationship)
85
+ @article_relationship.inverse.should equal(@comments_relationship)
86
+ end
87
+ end
88
+
89
+ describe 'with no matching relationship', 'from the parent side' do
90
+ before :all do
91
+ # added to force OneToMany::Relationship#inverse to consider the
92
+ # child_key differences
93
+ @comment_model.belongs_to(:other_article, @article_model, :child_key => [ :other_article_id ])
94
+
95
+ @relationship = @article_model.has(n, :comments)
96
+
97
+ @inverse = @relationship.inverse
98
+
99
+ # after Relationship#inverse to ensure no match
100
+ @expected = @comment_model.belongs_to(:article)
101
+ end
102
+
103
+ it 'should return a Relationship' do
104
+ @inverse.should be_kind_of(DataMapper::Associations::Relationship)
105
+ end
106
+
107
+ it 'should return an inverted relationship' do
108
+ @inverse.should == @expected
109
+ end
110
+
111
+ it 'should be an anonymous relationship' do
112
+ @inverse.should_not equal(@expected)
113
+ end
114
+
115
+ it 'should have a source repository equal to the target repository of the relationship' do
116
+ @inverse.source_repository_name.should == @relationship.target_repository_name
117
+ end
118
+
119
+ it "should be have the relationship as it's inverse" do
120
+ @inverse.inverse.should equal(@relationship)
121
+ end
122
+ end
123
+
124
+ describe 'with no matching relationship', 'from the child side' do
125
+ before :all do
126
+ @relationship = @comment_model.belongs_to(:article)
127
+
128
+ @inverse = @relationship.inverse
129
+
130
+ # after Relationship#inverse to ensure no match
131
+ @expected = @article_model.has(n, :comments)
132
+ end
133
+
134
+ it 'should return a Relationship' do
135
+ @inverse.should be_kind_of(DataMapper::Associations::Relationship)
136
+ end
137
+
138
+ it 'should return an inverted relationship' do
139
+ @inverse.should == @expected
140
+ end
141
+
142
+ it 'should be an anonymous relationship' do
143
+ @inverse.should_not equal(@expected)
144
+ end
145
+
146
+ it 'should have a source repository equal to the target repository of the relationship' do
147
+ @inverse.source_repository_name.should == @relationship.target_repository_name
148
+ end
149
+
150
+ it "should be have the relationship as it's inverse" do
151
+ @inverse.inverse.should equal(@relationship)
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '#valid?' do
157
+ before :all do
158
+ @relationship = @article_model.has(n, :comments)
159
+ end
160
+
161
+ supported_by :all do
162
+ describe 'with valid resource' do
163
+ before :all do
164
+ @article = @article_model.create(:title => 'Relationships in DataMapper')
165
+ @resource = @article.comments.create
166
+ end
167
+
168
+ it 'should return true' do
169
+ @relationship.valid?(@resource).should be_true
170
+ end
171
+ end
172
+
173
+ describe 'with a resource of the wrong class' do
174
+ before :all do
175
+ @resource = @article_model.new
176
+ end
177
+
178
+ it 'should return false' do
179
+ @relationship.valid?(@resource).should be_false
180
+ end
181
+ end
182
+
183
+ describe 'with a resource without a valid parent' do
184
+ before :all do
185
+ @resource = @comment_model.new
186
+ end
187
+
188
+ it 'should return false' do
189
+ @relationship.valid?(@resource).should be_false
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,177 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Associations do
4
+ before :all do
5
+ class ::Car
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ end
10
+
11
+ class ::Engine
12
+ include DataMapper::Resource
13
+
14
+ property :id, Serial
15
+ end
16
+
17
+ class ::Door
18
+ include DataMapper::Resource
19
+
20
+ property :id, Serial
21
+ end
22
+
23
+ class ::Window
24
+ include DataMapper::Resource
25
+
26
+ property :id, Serial
27
+ end
28
+ end
29
+
30
+ def n
31
+ 1.0/0
32
+ end
33
+
34
+ describe '#has' do
35
+ describe '1' do
36
+ before :all do
37
+ @relationship = Car.has(1, :engine)
38
+ end
39
+
40
+ it 'should return a Relationship' do
41
+ @relationship.should be_a_kind_of(DataMapper::Associations::OneToOne::Relationship)
42
+ end
43
+
44
+ it 'should return a Relationship with the child model' do
45
+ @relationship.child_model.should == Engine
46
+ end
47
+
48
+ it 'should return a Relationship with a min of 1' do
49
+ @relationship.min.should == 1
50
+ end
51
+
52
+ it 'should return a Relationship with a max of 1' do
53
+ @relationship.max.should == 1
54
+ end
55
+ end
56
+
57
+ describe 'n..n' do
58
+ before :all do
59
+ @relationship = Car.has(1..4, :doors)
60
+ end
61
+
62
+ it 'should return a Relationship' do
63
+ @relationship.should be_a_kind_of(DataMapper::Associations::OneToMany::Relationship)
64
+ end
65
+
66
+ it 'should return a Relationship with the child model' do
67
+ @relationship.child_model.should == Door
68
+ end
69
+
70
+ it 'should return a Relationship with a min of 1' do
71
+ @relationship.min.should == 1
72
+ end
73
+
74
+ it 'should return a Relationship with a max of 4' do
75
+ @relationship.max.should == 4
76
+ end
77
+ end
78
+
79
+ describe 'n..n through' do
80
+ before :all do
81
+ Door.has(1, :window)
82
+ Car.has(1..4, :doors)
83
+
84
+ @relationship = Car.has(1..4, :windows, :through => :doors)
85
+ end
86
+
87
+ it 'should return a Relationship' do
88
+ @relationship.should be_a_kind_of(DataMapper::Associations::ManyToMany::Relationship)
89
+ end
90
+
91
+ it 'should return a Relationship with the child model' do
92
+ @relationship.child_model.should == Window
93
+ end
94
+
95
+ it 'should return a Relationship with a min of 1' do
96
+ @relationship.min.should == 1
97
+ end
98
+
99
+ it 'should return a Relationship with a max of 4' do
100
+ @relationship.max.should == 4
101
+ end
102
+ end
103
+
104
+ describe 'n' do
105
+ before :all do
106
+ @relationship = Car.has(n, :doors)
107
+ end
108
+
109
+ it 'should return a Relationship' do
110
+ @relationship.should be_a_kind_of(DataMapper::Associations::OneToMany::Relationship)
111
+ end
112
+
113
+ it 'should return a Relationship with the child model' do
114
+ @relationship.child_model.should == Door
115
+ end
116
+
117
+ it 'should return a Relationship with a min of 0' do
118
+ @relationship.min.should == 0
119
+ end
120
+
121
+ it 'should return a Relationship with a max of n' do
122
+ @relationship.max.should == n
123
+ end
124
+ end
125
+
126
+ describe 'n through' do
127
+ before :all do
128
+ Door.has(1, :windows)
129
+ Car.has(1..4, :doors)
130
+
131
+ @relationship = Car.has(n, :windows, :through => :doors)
132
+ end
133
+
134
+ it 'should return a Relationship' do
135
+ @relationship.should be_a_kind_of(DataMapper::Associations::ManyToMany::Relationship)
136
+ end
137
+
138
+ it 'should return a Relationship with the child model' do
139
+ @relationship.child_model.should == Window
140
+ end
141
+
142
+ it 'should return a Relationship with a min of 0' do
143
+ @relationship.min.should == 0
144
+ end
145
+
146
+ it 'should return a Relationship with a max of n' do
147
+ @relationship.max.should == n
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#belongs_to' do
153
+ before :all do
154
+ @relationship = Engine.belongs_to(:car)
155
+ end
156
+
157
+ it 'should return a Relationship' do
158
+ @relationship.should be_a_kind_of(DataMapper::Associations::ManyToOne::Relationship)
159
+ end
160
+
161
+ it 'should return a Relationship with the parent model' do
162
+ @relationship.parent_model.should == Car
163
+ end
164
+
165
+ it 'should return a Relationship with a min of 1' do
166
+ @relationship.min.should == 1
167
+ end
168
+
169
+ it 'should return a Relationship with a max of 1' do
170
+ @relationship.max.should == 1
171
+ end
172
+
173
+ it 'should return a Relationship that is not nullable' do
174
+ @relationship.nullable?.should be_false
175
+ end
176
+ end
177
+ end