dm-core 0.10.2 → 1.0.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 (183) hide show
  1. data/.gitignore +10 -1
  2. data/Gemfile +143 -0
  3. data/Rakefile +9 -5
  4. data/VERSION +1 -1
  5. data/dm-core.gemspec +160 -57
  6. data/lib/dm-core.rb +131 -56
  7. data/lib/dm-core/adapters.rb +98 -14
  8. data/lib/dm-core/adapters/abstract_adapter.rb +24 -4
  9. data/lib/dm-core/adapters/in_memory_adapter.rb +7 -2
  10. data/lib/dm-core/associations/many_to_many.rb +19 -30
  11. data/lib/dm-core/associations/many_to_one.rb +58 -42
  12. data/lib/dm-core/associations/one_to_many.rb +33 -23
  13. data/lib/dm-core/associations/one_to_one.rb +27 -11
  14. data/lib/dm-core/associations/relationship.rb +4 -4
  15. data/lib/dm-core/collection.rb +23 -16
  16. data/lib/dm-core/core_ext/array.rb +36 -0
  17. data/lib/dm-core/core_ext/hash.rb +30 -0
  18. data/lib/dm-core/core_ext/module.rb +46 -0
  19. data/lib/dm-core/core_ext/object.rb +31 -0
  20. data/lib/dm-core/core_ext/pathname.rb +20 -0
  21. data/lib/dm-core/core_ext/string.rb +22 -0
  22. data/lib/dm-core/core_ext/try_dup.rb +44 -0
  23. data/lib/dm-core/model.rb +88 -27
  24. data/lib/dm-core/model/hook.rb +75 -18
  25. data/lib/dm-core/model/property.rb +50 -9
  26. data/lib/dm-core/model/relationship.rb +31 -31
  27. data/lib/dm-core/model/scope.rb +3 -3
  28. data/lib/dm-core/property.rb +196 -516
  29. data/lib/dm-core/property/binary.rb +7 -0
  30. data/lib/dm-core/property/boolean.rb +35 -0
  31. data/lib/dm-core/property/class.rb +24 -0
  32. data/lib/dm-core/property/date.rb +47 -0
  33. data/lib/dm-core/property/date_time.rb +48 -0
  34. data/lib/dm-core/property/decimal.rb +43 -0
  35. data/lib/dm-core/property/discriminator.rb +48 -0
  36. data/lib/dm-core/property/float.rb +24 -0
  37. data/lib/dm-core/property/integer.rb +32 -0
  38. data/lib/dm-core/property/numeric.rb +43 -0
  39. data/lib/dm-core/property/object.rb +32 -0
  40. data/lib/dm-core/property/serial.rb +8 -0
  41. data/lib/dm-core/property/string.rb +49 -0
  42. data/lib/dm-core/property/text.rb +12 -0
  43. data/lib/dm-core/property/time.rb +48 -0
  44. data/lib/dm-core/property/typecast/numeric.rb +32 -0
  45. data/lib/dm-core/property/typecast/time.rb +28 -0
  46. data/lib/dm-core/property_set.rb +10 -4
  47. data/lib/dm-core/query.rb +14 -37
  48. data/lib/dm-core/query/conditions/comparison.rb +8 -6
  49. data/lib/dm-core/query/conditions/operation.rb +33 -2
  50. data/lib/dm-core/query/operator.rb +2 -5
  51. data/lib/dm-core/query/path.rb +4 -6
  52. data/lib/dm-core/repository.rb +21 -6
  53. data/lib/dm-core/resource.rb +316 -133
  54. data/lib/dm-core/resource/state.rb +79 -0
  55. data/lib/dm-core/resource/state/clean.rb +40 -0
  56. data/lib/dm-core/resource/state/deleted.rb +30 -0
  57. data/lib/dm-core/resource/state/dirty.rb +86 -0
  58. data/lib/dm-core/resource/state/immutable.rb +34 -0
  59. data/lib/dm-core/resource/state/persisted.rb +29 -0
  60. data/lib/dm-core/resource/state/transient.rb +70 -0
  61. data/lib/dm-core/spec/lib/adapter_helpers.rb +52 -0
  62. data/lib/dm-core/spec/lib/collection_helpers.rb +20 -0
  63. data/{spec → lib/dm-core/spec}/lib/counter_adapter.rb +5 -1
  64. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  65. data/lib/dm-core/spec/lib/spec_helper.rb +68 -0
  66. data/lib/dm-core/spec/setup.rb +165 -0
  67. data/lib/dm-core/spec/{adapter_shared_spec.rb → shared/adapter_spec.rb} +21 -7
  68. data/{spec/public/shared/resource_shared_spec.rb → lib/dm-core/spec/shared/resource_spec.rb} +120 -83
  69. data/{spec/public/shared/sel_shared_spec.rb → lib/dm-core/spec/shared/sel_spec.rb} +5 -6
  70. data/lib/dm-core/support/assertions.rb +8 -0
  71. data/lib/dm-core/support/equalizer.rb +1 -0
  72. data/lib/dm-core/support/hook.rb +420 -0
  73. data/lib/dm-core/support/lazy_array.rb +453 -0
  74. data/lib/dm-core/support/local_object_space.rb +12 -0
  75. data/lib/dm-core/support/logger.rb +193 -6
  76. data/lib/dm-core/support/naming_conventions.rb +8 -8
  77. data/lib/dm-core/support/subject.rb +33 -0
  78. data/lib/dm-core/type.rb +4 -0
  79. data/lib/dm-core/types/boolean.rb +2 -0
  80. data/lib/dm-core/types/decimal.rb +9 -0
  81. data/lib/dm-core/types/discriminator.rb +2 -0
  82. data/lib/dm-core/types/object.rb +3 -0
  83. data/lib/dm-core/types/serial.rb +2 -0
  84. data/lib/dm-core/types/text.rb +2 -0
  85. data/lib/dm-core/version.rb +1 -1
  86. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +67 -0
  87. data/spec/public/model/hook_spec.rb +209 -0
  88. data/spec/public/model/property_spec.rb +35 -0
  89. data/spec/public/model/relationship_spec.rb +33 -20
  90. data/spec/public/model_spec.rb +142 -10
  91. data/spec/public/property/binary_spec.rb +14 -0
  92. data/spec/public/property/boolean_spec.rb +14 -0
  93. data/spec/public/property/class_spec.rb +20 -0
  94. data/spec/public/property/date_spec.rb +14 -0
  95. data/spec/public/property/date_time_spec.rb +14 -0
  96. data/spec/public/property/decimal_spec.rb +14 -0
  97. data/spec/public/{types → property}/discriminator_spec.rb +2 -12
  98. data/spec/public/property/float_spec.rb +14 -0
  99. data/spec/public/property/integer_spec.rb +14 -0
  100. data/spec/public/property/object_spec.rb +9 -17
  101. data/spec/public/property/serial_spec.rb +14 -0
  102. data/spec/public/property/string_spec.rb +14 -0
  103. data/spec/public/property/text_spec.rb +52 -0
  104. data/spec/public/property/time_spec.rb +14 -0
  105. data/spec/public/property_spec.rb +28 -87
  106. data/spec/public/resource_spec.rb +101 -0
  107. data/spec/public/sel_spec.rb +5 -15
  108. data/spec/public/shared/collection_shared_spec.rb +16 -30
  109. data/spec/public/shared/finder_shared_spec.rb +2 -4
  110. data/spec/public/shared/property_shared_spec.rb +176 -0
  111. data/spec/semipublic/adapters/abstract_adapter_spec.rb +1 -1
  112. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +2 -2
  113. data/spec/semipublic/associations/many_to_many_spec.rb +89 -0
  114. data/spec/semipublic/associations/many_to_one_spec.rb +24 -1
  115. data/spec/semipublic/associations/one_to_many_spec.rb +51 -0
  116. data/spec/semipublic/associations/one_to_one_spec.rb +49 -0
  117. data/spec/semipublic/associations/relationship_spec.rb +3 -3
  118. data/spec/semipublic/associations_spec.rb +1 -1
  119. data/spec/semipublic/property/binary_spec.rb +13 -0
  120. data/spec/semipublic/property/boolean_spec.rb +65 -0
  121. data/spec/semipublic/property/class_spec.rb +33 -0
  122. data/spec/semipublic/property/date_spec.rb +43 -0
  123. data/spec/semipublic/property/date_time_spec.rb +46 -0
  124. data/spec/semipublic/property/decimal_spec.rb +82 -0
  125. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  126. data/spec/semipublic/property/float_spec.rb +82 -0
  127. data/spec/semipublic/property/integer_spec.rb +82 -0
  128. data/spec/semipublic/property/serial_spec.rb +13 -0
  129. data/spec/semipublic/property/string_spec.rb +13 -0
  130. data/spec/semipublic/property/text_spec.rb +31 -0
  131. data/spec/semipublic/property/time_spec.rb +50 -0
  132. data/spec/semipublic/property_spec.rb +2 -532
  133. data/spec/semipublic/query/conditions/comparison_spec.rb +171 -169
  134. data/spec/semipublic/query/conditions/operation_spec.rb +53 -51
  135. data/spec/semipublic/query/path_spec.rb +17 -17
  136. data/spec/semipublic/query_spec.rb +47 -78
  137. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  138. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  139. data/spec/semipublic/resource/state/dirty_spec.rb +133 -0
  140. data/spec/semipublic/resource/state/immutable_spec.rb +99 -0
  141. data/spec/semipublic/resource/state/transient_spec.rb +128 -0
  142. data/spec/semipublic/resource/state_spec.rb +226 -0
  143. data/spec/semipublic/shared/property_shared_spec.rb +143 -0
  144. data/spec/semipublic/shared/resource_shared_spec.rb +16 -15
  145. data/spec/semipublic/shared/resource_state_shared_spec.rb +78 -0
  146. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  147. data/spec/spec_helper.rb +21 -97
  148. data/spec/support/types/huge_integer.rb +17 -0
  149. data/spec/unit/array_spec.rb +48 -0
  150. data/spec/unit/hash_spec.rb +35 -0
  151. data/spec/unit/hook_spec.rb +1234 -0
  152. data/spec/unit/lazy_array_spec.rb +1959 -0
  153. data/spec/unit/module_spec.rb +70 -0
  154. data/spec/unit/object_spec.rb +37 -0
  155. data/spec/unit/try_dup_spec.rb +45 -0
  156. data/tasks/local_gemfile.rake +18 -0
  157. data/tasks/spec.rake +0 -3
  158. metadata +197 -71
  159. data/deps.rip +0 -2
  160. data/lib/dm-core/adapters/data_objects_adapter.rb +0 -712
  161. data/lib/dm-core/adapters/mysql_adapter.rb +0 -42
  162. data/lib/dm-core/adapters/oracle_adapter.rb +0 -229
  163. data/lib/dm-core/adapters/postgres_adapter.rb +0 -22
  164. data/lib/dm-core/adapters/sqlite3_adapter.rb +0 -17
  165. data/lib/dm-core/adapters/sqlserver_adapter.rb +0 -114
  166. data/lib/dm-core/adapters/yaml_adapter.rb +0 -111
  167. data/lib/dm-core/core_ext/enumerable.rb +0 -28
  168. data/lib/dm-core/migrations.rb +0 -1427
  169. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +0 -366
  170. data/lib/dm-core/transaction.rb +0 -508
  171. data/lib/dm-core/types/paranoid_boolean.rb +0 -42
  172. data/lib/dm-core/types/paranoid_datetime.rb +0 -41
  173. data/spec/lib/adapter_helpers.rb +0 -105
  174. data/spec/lib/collection_helpers.rb +0 -18
  175. data/spec/lib/pending_helpers.rb +0 -46
  176. data/spec/public/migrations_spec.rb +0 -503
  177. data/spec/public/transaction_spec.rb +0 -153
  178. data/spec/semipublic/adapters/mysql_adapter_spec.rb +0 -17
  179. data/spec/semipublic/adapters/oracle_adapter_spec.rb +0 -194
  180. data/spec/semipublic/adapters/postgres_adapter_spec.rb +0 -17
  181. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +0 -17
  182. data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +0 -17
  183. data/spec/semipublic/adapters/yaml_adapter_spec.rb +0 -12
@@ -0,0 +1,209 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Model::Hook do
4
+ before :all do
5
+ class ::ModelHookSpecs
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+
10
+ def an_instance_method
11
+ end
12
+ end
13
+
14
+ class ::ModelHookSpecsSubclass < ModelHookSpecs; end
15
+ end
16
+
17
+ before :all do
18
+ @resource = ModelHookSpecs.new
19
+ end
20
+
21
+ describe '#before' do
22
+ describe 'an instance method' do
23
+ before do
24
+ @hooks = hooks = []
25
+ ModelHookSpecs.before(:an_instance_method) { hooks << :before_instance_method }
26
+
27
+ @resource.an_instance_method
28
+ end
29
+
30
+ it 'should execute before instance method hook' do
31
+ @hooks.should == [ :before_instance_method ]
32
+ end
33
+ end
34
+
35
+ describe 'save' do
36
+ supported_by :all do
37
+ before do
38
+ @hooks = hooks = []
39
+ ModelHookSpecs.before(:save) { hooks << :before_save }
40
+
41
+ @resource.save
42
+ end
43
+
44
+ it 'should execute before save hook' do
45
+ @hooks.should == [ :before_save ]
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'create' do
51
+ supported_by :all do
52
+ before do
53
+ @hooks = hooks = []
54
+ ModelHookSpecs.before(:create) { hooks << :before_create }
55
+
56
+ @resource.save
57
+ end
58
+
59
+ it 'should execute before create hook' do
60
+ @hooks.should == [ :before_create ]
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'update' do
66
+ supported_by :all do
67
+ before do
68
+ @hooks = hooks = []
69
+ ModelHookSpecs.before(:update) { hooks << :before_update }
70
+
71
+ @resource.save
72
+ @resource.update(:id => 2)
73
+ end
74
+
75
+ it 'should execute before update hook' do
76
+ @hooks.should == [ :before_update ]
77
+ end
78
+ end
79
+ end
80
+
81
+ describe 'destroy' do
82
+ supported_by :all do
83
+ before do
84
+ @hooks = hooks = []
85
+ ModelHookSpecs.before(:destroy) { hooks << :before_destroy }
86
+
87
+ @resource.save
88
+ @resource.destroy
89
+ end
90
+
91
+ it 'should execute before destroy hook' do
92
+ @hooks.should == [ :before_destroy ]
93
+ end
94
+ end
95
+ end
96
+
97
+ describe 'with an inherited hook' do
98
+ supported_by :all do
99
+ before do
100
+ @hooks = hooks = []
101
+ ModelHookSpecs.before(:create) { hooks << :inherited_hook }
102
+ end
103
+
104
+ it 'should execute inherited hook' do
105
+ ModelHookSpecsSubclass.create
106
+ @hooks.should == [ :inherited_hook ]
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'with a hook declared in the subclasss' do
112
+ supported_by :all do
113
+ before do
114
+ @hooks = hooks = []
115
+ ModelHookSpecsSubclass.before(:create) { hooks << :hook }
116
+ end
117
+
118
+ it 'should execute hook' do
119
+ ModelHookSpecsSubclass.create
120
+ @hooks.should == [ :hook ]
121
+ end
122
+
123
+ it 'should not alter hooks in the parent class' do
124
+ @hooks.should be_empty
125
+ ModelHookSpecs.create
126
+ @hooks.should == []
127
+ end
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ describe '#after' do
134
+ describe 'an instance method' do
135
+ before do
136
+ @hooks = hooks = []
137
+ ModelHookSpecs.after(:an_instance_method) { hooks << :after_instance_method }
138
+
139
+ @resource.an_instance_method
140
+ end
141
+
142
+ it 'should execute after instance method hook' do
143
+ @hooks.should == [ :after_instance_method ]
144
+ end
145
+ end
146
+
147
+ describe 'save' do
148
+ supported_by :all do
149
+ before do
150
+ @hooks = hooks = []
151
+ ModelHookSpecs.after(:save) { hooks << :after_save }
152
+
153
+ @resource.save
154
+ end
155
+
156
+ it 'should execute after save hook' do
157
+ @hooks.should == [ :after_save ]
158
+ end
159
+ end
160
+ end
161
+
162
+ describe 'create' do
163
+ supported_by :all do
164
+ before do
165
+ @hooks = hooks = []
166
+ ModelHookSpecs.after(:create) { hooks << :after_create }
167
+
168
+ @resource.save
169
+ end
170
+
171
+ it 'should execute after create hook' do
172
+ @hooks.should == [ :after_create ]
173
+ end
174
+ end
175
+ end
176
+
177
+ describe 'update' do
178
+ supported_by :all do
179
+ before do
180
+ @hooks = hooks = []
181
+ ModelHookSpecs.after(:update) { hooks << :after_update }
182
+
183
+ @resource.save
184
+ @resource.update(:id => 2)
185
+ end
186
+
187
+ it 'should execute after update hook' do
188
+ @hooks.should == [ :after_update ]
189
+ end
190
+ end
191
+ end
192
+
193
+ describe 'destroy' do
194
+ supported_by :all do
195
+ before do
196
+ @hooks = hooks = []
197
+ ModelHookSpecs.after(:destroy) { hooks << :after_destroy }
198
+
199
+ @resource.save
200
+ @resource.destroy
201
+ end
202
+
203
+ it 'should execute after destroy hook' do
204
+ @hooks.should == [ :after_destroy ]
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Model::Property do
4
+ before :each do
5
+ Object.send(:remove_const, :ModelPropertySpecs) if defined?(ModelPropertySpecs)
6
+ class ::ModelPropertySpecs
7
+ include DataMapper::Resource
8
+
9
+ property :id, Serial
10
+ end
11
+ end
12
+
13
+ describe '#property' do
14
+
15
+ subject { ModelPropertySpecs.property(:name, String) }
16
+
17
+ it 'should define a name accessor' do
18
+ ModelPropertySpecs.should_not be_method_defined(:name)
19
+ subject
20
+ ModelPropertySpecs.should be_method_defined(:name)
21
+ end
22
+
23
+ it 'should define a name= mutator' do
24
+ ModelPropertySpecs.should_not be_method_defined(:name=)
25
+ subject
26
+ ModelPropertySpecs.should be_method_defined(:name=)
27
+ end
28
+
29
+ it 'should raise an exception if the method exists' do
30
+ lambda {
31
+ ModelPropertySpecs.property(:key, String)
32
+ }.should raise_error(ArgumentError, '+name+ was :key, which cannot be used as a property name since it collides with an existing method')
33
+ end
34
+ end
35
+ end
@@ -110,12 +110,12 @@ share_examples_for 'it creates a one mutator' do
110
110
  end
111
111
 
112
112
  it 'should persist the Resource' do
113
- @car.save.should be_true
113
+ @car.save.should be(true)
114
114
  @car.model.get(*@car.key).__send__(@name).should == @expected
115
115
  end
116
116
 
117
117
  it 'should persist the associated Resource' do
118
- @car.save.should be_true
118
+ @car.save.should be(true)
119
119
  @expected.should be_saved
120
120
  @expected.model.get(*@expected.key).car.should == @car
121
121
  end
@@ -150,12 +150,12 @@ share_examples_for 'it creates a one mutator' do
150
150
  end
151
151
 
152
152
  it 'should persist the Resource' do
153
- @car.save.should be_true
153
+ @car.save.should be(true)
154
154
  @car.model.get(*@car.key).__send__(@name).should == @return
155
155
  end
156
156
 
157
157
  it 'should persist the associated Resource' do
158
- @car.save.should be_true
158
+ @car.save.should be(true)
159
159
  @return.should be_saved
160
160
  @return.model.get(*@return.key).car.should == @car
161
161
  end
@@ -177,7 +177,7 @@ share_examples_for 'it creates a one mutator' do
177
177
  end
178
178
 
179
179
  it 'should persist as nil' do
180
- @car.save.should be_true
180
+ @car.save.should be(true)
181
181
  @car.model.get(*@car.key).__send__(@name).should be_nil
182
182
  end
183
183
  end
@@ -209,12 +209,12 @@ share_examples_for 'it creates a one mutator' do
209
209
  end
210
210
 
211
211
  it 'should persist the Resource' do
212
- @car.save.should be_true
212
+ @car.save.should be(true)
213
213
  @car.model.get(*@car.key).__send__(@name).should == @expected
214
214
  end
215
215
 
216
216
  it 'should persist the associated Resource' do
217
- @car.save.should be_true
217
+ @car.save.should be(true)
218
218
  @expected.should be_saved
219
219
  @expected.model.get(*@expected.key).car.should == @car
220
220
  end
@@ -226,7 +226,7 @@ share_examples_for 'it creates a many accessor' do
226
226
  describe 'accessor' do
227
227
  describe 'when there is no child resource and the source is saved' do
228
228
  before :all do
229
- @car.save.should be_true
229
+ @car.save.should be(true)
230
230
  @return = @car.__send__(@name)
231
231
  end
232
232
 
@@ -278,6 +278,7 @@ share_examples_for 'it creates a many accessor' do
278
278
  @car.save
279
279
 
280
280
  @expected = @car.__send__(@name).first
281
+ @expected.should_not be_nil
281
282
 
282
283
  # set the model scope to only return the first record
283
284
  @model.default_scope.update(@model.key(@repository.name).zip(@expected.key).to_hash)
@@ -321,12 +322,12 @@ share_examples_for 'it creates a many mutator' do
321
322
  end
322
323
 
323
324
  it 'should persist the Collection' do
324
- @car.save.should be_true
325
+ @car.save.should be(true)
325
326
  @car.model.get(*@car.key).__send__(@name).should == @expected
326
327
  end
327
328
 
328
329
  it 'should persist the associated Resource' do
329
- @car.save.should be_true
330
+ @car.save.should be(true)
330
331
  @expected.each { |resource| resource.should be_saved }
331
332
  @expected.each { |resource| resource.model.get(*resource.key).car.should == @car }
332
333
  end
@@ -356,12 +357,12 @@ share_examples_for 'it creates a many mutator' do
356
357
  end
357
358
 
358
359
  it 'should persist the Collection' do
359
- @car.save.should be_true
360
+ @car.save.should be(true)
360
361
  @car.model.get(*@car.key).__send__(@name).should == @return
361
362
  end
362
363
 
363
364
  it 'should persist the associated Resource' do
364
- @car.save.should be_true
365
+ @car.save.should be(true)
365
366
  @return.each { |resource| resource.should be_saved }
366
367
  @return.each { |resource| resource.model.get(*resource.key).car.should == @car }
367
368
  end
@@ -383,7 +384,7 @@ share_examples_for 'it creates a many mutator' do
383
384
  end
384
385
 
385
386
  it 'should persist as an empty Collection' do
386
- @car.save.should be_true
387
+ @car.save.should be(true)
387
388
  @car.model.get(*@car.key).__send__(@name).should be_empty
388
389
  end
389
390
  end
@@ -413,12 +414,12 @@ share_examples_for 'it creates a many mutator' do
413
414
  end
414
415
 
415
416
  it 'should persist the Resource' do
416
- @car.save.should be_true
417
+ @car.save.should be(true)
417
418
  @car.model.get(*@car.key).__send__(@name).should == @expected
418
419
  end
419
420
 
420
421
  it 'should persist the associated Resource' do
421
- @car.save.should be_true
422
+ @car.save.should be(true)
422
423
  @expected.each { |resource| resource.should be_saved }
423
424
  @expected.each { |resource| resource.model.get(*resource.key).car.should == @car }
424
425
  end
@@ -481,6 +482,18 @@ describe DataMapper::Associations do
481
482
  it { @car.should respond_to("#{@name}=") }
482
483
 
483
484
  it_should_behave_like 'it creates a one mutator'
485
+
486
+ describe 'with a :key option' do
487
+ before :all do
488
+ @relationship = Car.belongs_to("#{@name}_with_key".to_sym, @model, :required => false, :key => true)
489
+ end
490
+
491
+ it 'should create a foreign key that is part of the key' do
492
+ @relationship.child_key.each do |property|
493
+ property.should be_key
494
+ end
495
+ end
496
+ end
484
497
  end
485
498
 
486
499
  # TODO: refactor these specs into above structure once they pass
@@ -847,7 +860,7 @@ describe DataMapper::Associations do
847
860
  describe 'when a relationship is inherited' do
848
861
  describe 'has an inverse' do
849
862
  before :all do
850
- Car.property(:type, DataMapper::Types::Discriminator)
863
+ Car.property(:type, DataMapper::Property::Discriminator)
851
864
 
852
865
  class ::ElectricCar < Car; end
853
866
 
@@ -871,7 +884,7 @@ describe DataMapper::Associations do
871
884
 
872
885
  describe 'does not have an inverse' do
873
886
  before :all do
874
- Car.property(:type, DataMapper::Types::Discriminator)
887
+ Car.property(:type, DataMapper::Property::Discriminator)
875
888
 
876
889
  class ::ElectricCar < Car; end
877
890
 
@@ -897,7 +910,7 @@ describe DataMapper::Associations do
897
910
  describe "when a subclass defines it's own relationship" do
898
911
  describe 'has an inverse' do
899
912
  before :all do
900
- Car.property(:type, DataMapper::Types::Discriminator)
913
+ Car.property(:type, DataMapper::Property::Discriminator)
901
914
 
902
915
  class ::ElectricCar < Car; end
903
916
 
@@ -921,7 +934,7 @@ describe DataMapper::Associations do
921
934
 
922
935
  describe 'does not have an inverse' do
923
936
  before :all do
924
- Car.property(:type, DataMapper::Types::Discriminator)
937
+ Car.property(:type, DataMapper::Property::Discriminator)
925
938
 
926
939
  class ::ElectricCar < Car; end
927
940
 
@@ -976,7 +989,7 @@ describe DataMapper::Associations do
976
989
  it 'should save the child as a parent' do
977
990
  lambda {
978
991
  @company.owner = @employee
979
- @company.save.should be_true
992
+ @company.save.should be(true)
980
993
  }.should_not raise_error
981
994
  end
982
995
  end
@@ -37,7 +37,7 @@ describe DataMapper::Model do
37
37
  with_alternate_adapter do
38
38
  describe 'between identical models' do
39
39
  before :all do
40
- @return = @resources = @article_model.copy(@repository.name, @alternate_adapter.name)
40
+ @return = @resources = @article_model.copy(@repository.name, @adapter.name)
41
41
  end
42
42
 
43
43
  it 'should return a Collection' do
@@ -49,11 +49,11 @@ describe DataMapper::Model do
49
49
  end
50
50
 
51
51
  it 'should have each Resource set to the expected Repository' do
52
- @resources.each { |resource| resource.repository.name.should == @alternate_adapter.name }
52
+ @resources.each { |resource| resource.repository.name.should == @adapter.name }
53
53
  end
54
54
 
55
55
  it 'should create the Resources in the expected Repository' do
56
- @article_model.all(:repository => DataMapper.repository(@alternate_adapter.name)).should == @resources
56
+ @article_model.all(:repository => DataMapper.repository(@adapter.name)).should == @resources
57
57
  end
58
58
  end
59
59
 
@@ -67,21 +67,22 @@ describe DataMapper::Model do
67
67
  @article_model.all(:repository => @repository).should be_empty
68
68
 
69
69
  # add an extra property to the alternate model
70
- DataMapper.repository(@alternate_adapter.name) do
70
+ DataMapper.repository(@adapter.name) do
71
71
  @article_model.property :status, String, :default => 'new'
72
72
  end
73
73
 
74
74
  if @article_model.respond_to?(:auto_migrate!)
75
- @article_model.auto_migrate!(@alternate_adapter.name)
75
+ @article_model.auto_migrate!(@adapter.name)
76
76
  end
77
77
 
78
78
  # add new resources to the alternate repository
79
- DataMapper.repository(@alternate_adapter.name) do
80
- @heff1 = @article_model.create(:title => 'Alternate Repository', :author => @author)
79
+ DataMapper.repository(@adapter.name) do
80
+ # use an id value that is unique
81
+ @heff1 = @article_model.create(:id => 99, :title => 'Alternate Repository', :author => @author)
81
82
  end
82
83
 
83
84
  # copy from the alternate to the default repository
84
- @return = @resources = @article_model.copy(@alternate_adapter.name, :default)
85
+ @return = @resources = @article_model.copy(@adapter.name, :default)
85
86
  end
86
87
 
87
88
  it 'should return a Collection' do
@@ -96,8 +97,13 @@ describe DataMapper::Model do
96
97
  @resources.each { |resource| resource.repository.name.should == :default }
97
98
  end
98
99
 
99
- it 'should create the Resources in the expected Repository' do
100
- @article_model.all.should == @resources
100
+ it 'should return the expected resources' do
101
+ # match on id because resources from different repositories are different
102
+ @resources.map { |resource| resource.id }.should == [ @heff1.id ]
103
+ end
104
+
105
+ it 'should add the resources to the alternate repository' do
106
+ @article.model.get(*@heff1.key).should_not be_nil
101
107
  end
102
108
  end
103
109
  end
@@ -155,5 +161,131 @@ describe DataMapper::Model do
155
161
  end
156
162
 
157
163
  it_should_behave_like 'Finder Interface'
164
+
165
+ it 'DataMapper::Model should respond to raise_on_save_failure' do
166
+ DataMapper::Model.should respond_to(:raise_on_save_failure)
167
+ end
168
+
169
+ describe '.raise_on_save_failure' do
170
+ subject { DataMapper::Model.raise_on_save_failure }
171
+
172
+ it { should be(false) }
173
+ end
174
+
175
+ it 'DataMapper::Model should respond to raise_on_save_failure=' do
176
+ DataMapper::Model.should respond_to(:raise_on_save_failure=)
177
+ end
178
+
179
+ describe '.raise_on_save_failure=' do
180
+ after do
181
+ # reset to the default value
182
+ reset_raise_on_save_failure(DataMapper::Model)
183
+ end
184
+
185
+ subject { DataMapper::Model.raise_on_save_failure = @value }
186
+
187
+ describe 'with a true value' do
188
+ before do
189
+ @value = true
190
+ end
191
+
192
+ it { should be(true) }
193
+
194
+ it 'should set raise_on_save_failure' do
195
+ method(:subject).should change {
196
+ DataMapper::Model.raise_on_save_failure
197
+ }.from(false).to(true)
198
+ end
199
+ end
200
+
201
+ describe 'with a false value' do
202
+ before do
203
+ @value = false
204
+ end
205
+
206
+ it { should be(false) }
207
+
208
+ it 'should set raise_on_save_failure' do
209
+ method(:subject).should_not change {
210
+ DataMapper::Model.raise_on_save_failure
211
+ }
212
+ end
213
+ end
214
+ end
215
+
216
+ it 'A model should respond to raise_on_save_failure' do
217
+ @article_model.should respond_to(:raise_on_save_failure)
218
+ end
219
+
220
+ describe '#raise_on_save_failure' do
221
+ after do
222
+ # reset to the default value
223
+ reset_raise_on_save_failure(DataMapper::Model)
224
+ reset_raise_on_save_failure(@article_model)
225
+ end
226
+
227
+ subject { @article_model.raise_on_save_failure }
228
+
229
+ describe 'when DataMapper::Model.raise_on_save_failure has not been set' do
230
+ it { should be(false) }
231
+ end
232
+
233
+ describe 'when DataMapper::Model.raise_on_save_failure has been set to true' do
234
+ before do
235
+ DataMapper::Model.raise_on_save_failure = true
236
+ end
237
+
238
+ it { should be(true) }
239
+ end
240
+
241
+ describe 'when model.raise_on_save_failure has been set to true' do
242
+ before do
243
+ @article_model.raise_on_save_failure = true
244
+ end
245
+
246
+ it { should be(true) }
247
+ end
248
+ end
249
+
250
+ it 'A model should respond to raise_on_save_failure=' do
251
+ @article_model.should respond_to(:raise_on_save_failure=)
252
+ end
253
+
254
+ describe '#raise_on_save_failure=' do
255
+ after do
256
+ # reset to the default value
257
+ reset_raise_on_save_failure(@article_model)
258
+ end
259
+
260
+ subject { @article_model.raise_on_save_failure = @value }
261
+
262
+ describe 'with a true value' do
263
+ before do
264
+ @value = true
265
+ end
266
+
267
+ it { should be(true) }
268
+
269
+ it 'should set raise_on_save_failure' do
270
+ method(:subject).should change {
271
+ @article_model.raise_on_save_failure
272
+ }.from(false).to(true)
273
+ end
274
+ end
275
+
276
+ describe 'with a false value' do
277
+ before do
278
+ @value = false
279
+ end
280
+
281
+ it { should be(false) }
282
+
283
+ it 'should set raise_on_save_failure' do
284
+ method(:subject).should_not change {
285
+ @article_model.raise_on_save_failure
286
+ }
287
+ end
288
+ end
289
+ end
158
290
  end
159
291
  end