dm-core 0.10.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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