datamapper-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 (192) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -39
  5. data/Manifest.txt +67 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +16 -15
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/dm-core.gemspec +11 -15
  12. data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
  13. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  14. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  15. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  16. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  17. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  18. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  19. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  20. data/lib/dm-core/adapters.rb +135 -16
  21. data/lib/dm-core/associations/many_to_many.rb +372 -90
  22. data/lib/dm-core/associations/many_to_one.rb +220 -73
  23. data/lib/dm-core/associations/one_to_many.rb +319 -255
  24. data/lib/dm-core/associations/one_to_one.rb +66 -53
  25. data/lib/dm-core/associations/relationship.rb +560 -158
  26. data/lib/dm-core/collection.rb +1104 -381
  27. data/lib/dm-core/core_ext/kernel.rb +12 -0
  28. data/lib/dm-core/core_ext/symbol.rb +10 -0
  29. data/lib/dm-core/identity_map.rb +4 -34
  30. data/lib/dm-core/migrations.rb +1283 -0
  31. data/lib/dm-core/model/descendant_set.rb +81 -0
  32. data/lib/dm-core/model/hook.rb +45 -0
  33. data/lib/dm-core/model/is.rb +32 -0
  34. data/lib/dm-core/model/property.rb +248 -0
  35. data/lib/dm-core/model/relationship.rb +335 -0
  36. data/lib/dm-core/model/scope.rb +90 -0
  37. data/lib/dm-core/model.rb +570 -369
  38. data/lib/dm-core/property.rb +753 -280
  39. data/lib/dm-core/property_set.rb +141 -98
  40. data/lib/dm-core/query/conditions/comparison.rb +814 -0
  41. data/lib/dm-core/query/conditions/operation.rb +247 -0
  42. data/lib/dm-core/query/direction.rb +43 -0
  43. data/lib/dm-core/query/operator.rb +42 -0
  44. data/lib/dm-core/query/path.rb +102 -0
  45. data/lib/dm-core/query/sort.rb +45 -0
  46. data/lib/dm-core/query.rb +974 -492
  47. data/lib/dm-core/repository.rb +147 -107
  48. data/lib/dm-core/resource.rb +644 -429
  49. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  50. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  51. data/lib/dm-core/support/chainable.rb +20 -0
  52. data/lib/dm-core/support/deprecate.rb +12 -0
  53. data/lib/dm-core/support/equalizer.rb +23 -0
  54. data/lib/dm-core/support/logger.rb +13 -0
  55. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  56. data/lib/dm-core/transaction.rb +333 -92
  57. data/lib/dm-core/type.rb +98 -60
  58. data/lib/dm-core/types/boolean.rb +1 -1
  59. data/lib/dm-core/types/discriminator.rb +34 -20
  60. data/lib/dm-core/types/object.rb +7 -4
  61. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  62. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  63. data/lib/dm-core/types/serial.rb +3 -3
  64. data/lib/dm-core/types/text.rb +3 -4
  65. data/lib/dm-core/version.rb +1 -1
  66. data/lib/dm-core.rb +106 -110
  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/model/relationship_spec.rb +924 -0
  80. data/spec/public/model_spec.rb +159 -0
  81. data/spec/public/property_spec.rb +829 -0
  82. data/spec/public/resource_spec.rb +71 -0
  83. data/spec/public/sel_spec.rb +44 -0
  84. data/spec/public/setup_spec.rb +145 -0
  85. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  86. data/spec/public/shared/collection_shared_spec.rb +1723 -0
  87. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  88. data/spec/public/shared/resource_shared_spec.rb +924 -0
  89. data/spec/public/shared/sel_shared_spec.rb +112 -0
  90. data/spec/public/transaction_spec.rb +129 -0
  91. data/spec/public/types/discriminator_spec.rb +130 -0
  92. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  93. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  94. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  95. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  96. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  97. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  99. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  100. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  101. data/spec/semipublic/associations_spec.rb +177 -0
  102. data/spec/semipublic/collection_spec.rb +142 -0
  103. data/spec/semipublic/property_spec.rb +61 -0
  104. data/spec/semipublic/query/conditions_spec.rb +528 -0
  105. data/spec/semipublic/query/path_spec.rb +443 -0
  106. data/spec/semipublic/query_spec.rb +2626 -0
  107. data/spec/semipublic/resource_spec.rb +47 -0
  108. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  109. data/spec/spec.opts +3 -1
  110. data/spec/spec_helper.rb +80 -57
  111. data/tasks/ci.rb +19 -31
  112. data/tasks/dm.rb +43 -48
  113. data/tasks/doc.rb +8 -11
  114. data/tasks/gemspec.rb +5 -5
  115. data/tasks/hoe.rb +15 -16
  116. data/tasks/install.rb +8 -10
  117. metadata +72 -93
  118. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  119. data/lib/dm-core/associations.rb +0 -207
  120. data/lib/dm-core/auto_migrations.rb +0 -105
  121. data/lib/dm-core/dependency_queue.rb +0 -32
  122. data/lib/dm-core/hook.rb +0 -11
  123. data/lib/dm-core/is.rb +0 -16
  124. data/lib/dm-core/logger.rb +0 -232
  125. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  126. data/lib/dm-core/migrator.rb +0 -29
  127. data/lib/dm-core/scope.rb +0 -58
  128. data/lib/dm-core/support/array.rb +0 -13
  129. data/lib/dm-core/support/assertions.rb +0 -8
  130. data/lib/dm-core/support/errors.rb +0 -23
  131. data/lib/dm-core/support/kernel.rb +0 -11
  132. data/lib/dm-core/support/symbol.rb +0 -41
  133. data/lib/dm-core/support.rb +0 -7
  134. data/lib/dm-core/type_map.rb +0 -80
  135. data/lib/dm-core/types.rb +0 -19
  136. data/script/all +0 -4
  137. data/spec/integration/association_spec.rb +0 -1382
  138. data/spec/integration/association_through_spec.rb +0 -203
  139. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  140. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  141. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  142. data/spec/integration/auto_migrations_spec.rb +0 -413
  143. data/spec/integration/collection_spec.rb +0 -1073
  144. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  145. data/spec/integration/dependency_queue_spec.rb +0 -46
  146. data/spec/integration/model_spec.rb +0 -197
  147. data/spec/integration/mysql_adapter_spec.rb +0 -85
  148. data/spec/integration/postgres_adapter_spec.rb +0 -731
  149. data/spec/integration/property_spec.rb +0 -253
  150. data/spec/integration/query_spec.rb +0 -514
  151. data/spec/integration/repository_spec.rb +0 -61
  152. data/spec/integration/resource_spec.rb +0 -513
  153. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  154. data/spec/integration/sti_spec.rb +0 -273
  155. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  156. data/spec/integration/transaction_spec.rb +0 -75
  157. data/spec/integration/type_spec.rb +0 -275
  158. data/spec/lib/logging_helper.rb +0 -18
  159. data/spec/lib/mock_adapter.rb +0 -27
  160. data/spec/lib/model_loader.rb +0 -100
  161. data/spec/lib/publicize_methods.rb +0 -28
  162. data/spec/models/content.rb +0 -16
  163. data/spec/models/vehicles.rb +0 -34
  164. data/spec/models/zoo.rb +0 -48
  165. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  166. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  167. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  168. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  169. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  170. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  171. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  172. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  173. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  174. data/spec/unit/associations/relationship_spec.rb +0 -71
  175. data/spec/unit/associations_spec.rb +0 -242
  176. data/spec/unit/auto_migrations_spec.rb +0 -111
  177. data/spec/unit/collection_spec.rb +0 -182
  178. data/spec/unit/data_mapper_spec.rb +0 -35
  179. data/spec/unit/identity_map_spec.rb +0 -126
  180. data/spec/unit/is_spec.rb +0 -80
  181. data/spec/unit/migrator_spec.rb +0 -33
  182. data/spec/unit/model_spec.rb +0 -321
  183. data/spec/unit/naming_conventions_spec.rb +0 -36
  184. data/spec/unit/property_set_spec.rb +0 -90
  185. data/spec/unit/property_spec.rb +0 -753
  186. data/spec/unit/query_spec.rb +0 -571
  187. data/spec/unit/repository_spec.rb +0 -93
  188. data/spec/unit/resource_spec.rb +0 -649
  189. data/spec/unit/scope_spec.rb +0 -142
  190. data/spec/unit/transaction_spec.rb +0 -493
  191. data/spec/unit/type_map_spec.rb +0 -114
  192. data/spec/unit/type_spec.rb +0 -119
@@ -1,571 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- GOOD_OPTIONS = [
4
- [ :reload, false ],
5
- [ :reload, true ],
6
- [ :offset, 0 ],
7
- [ :offset, 1 ],
8
- [ :limit, 1 ],
9
- [ :limit, 2 ],
10
- [ :order, [ DataMapper::Query::Direction.new(Article.properties[:created_at], :desc) ] ],
11
- [ :fields, Article.properties.defaults.to_a ], # TODO: fill in allowed default value
12
- #[ :links, [ :stub ] ], # TODO: fill in allowed default value
13
- [ :includes, [ :stub ] ], # TODO: fill in allowed default value
14
- ]
15
-
16
- BAD_OPTIONS = {
17
- :reload => 'true',
18
- :offset => -1,
19
- :limit => 0,
20
- # :order => [], # TODO: spec conditions where :order may be empty
21
- # :fields => [], # TODO: spec conditions where :fields may be empty
22
- :links => [],
23
- :includes => [],
24
- :conditions => [],
25
- }
26
-
27
- # flatten GOOD_OPTIONS into a Hash to remove default values, since
28
- # default value, when defined, is always listed first in GOOD_OPTIONS
29
- UPDATED_OPTIONS = GOOD_OPTIONS.inject({}) do |options,(attribute,value)|
30
- options.update attribute => value
31
- end
32
-
33
- UPDATED_OPTIONS.merge!({ :fields => [ :id, :author ]})
34
-
35
- describe DataMapper::Query do
36
- before do
37
- @adapter = mock('adapter')
38
- @repository = mock('repository', :kind_of? => true, :name => 'mock', :adapter => @adapter)
39
-
40
- @query = DataMapper::Query.new(@repository, Article)
41
- end
42
-
43
- it 'should provide .new' do
44
- DataMapper::Query.should respond_to(:new)
45
- end
46
-
47
- describe '.new' do
48
- describe 'should set the attribute' do
49
- it '#model with model' do
50
- query = DataMapper::Query.new(@repository, Article)
51
- query.model.should == Article
52
- end
53
-
54
- GOOD_OPTIONS.each do |(attribute,value)|
55
- it "##{attribute} with options[:#{attribute}] if it is #{value.inspect}" do
56
- query = DataMapper::Query.new(@repository, Article, attribute => value)
57
- query.send(attribute == :reload ? :reload? : attribute).should == value
58
- end
59
- end
60
-
61
- describe ' #conditions with options[:conditions]' do
62
- it 'when they are a Hash' do
63
- query = DataMapper::Query.new(@repository, Article, :conditions => { :author => 'dkubb' })
64
- query.conditions.should == [ [ :eql, Article.properties[:author], 'dkubb' ] ]
65
- end
66
-
67
- it 'when they have a one element Array' do
68
- query = DataMapper::Query.new(@repository, Article, :conditions => [ 'name = "dkubb"' ])
69
- query.conditions.should == [ [ :raw, 'name = "dkubb"' ] ]
70
- query.bind_values.should == []
71
- end
72
-
73
- it 'when they have a two or more element Array' do
74
- bind_values = %w[ dkubb ]
75
- query = DataMapper::Query.new(@repository, Article, :conditions => [ 'name = ?', *bind_values ])
76
- query.conditions.should == [ [ :raw, 'name = ?', bind_values ] ]
77
- query.bind_values.should == bind_values
78
-
79
- bind_values = [ 'dkubb', 32 ]
80
- query = DataMapper::Query.new(@repository, Article, :conditions => [ 'name = ? OR age = ?', *bind_values ])
81
- query.conditions.should == [ [ :raw, 'name = ? OR age = ?', bind_values ] ]
82
- query.bind_values.should == bind_values
83
-
84
- bind_values = [ %w[ dkubb ssmoot ] ]
85
- query = DataMapper::Query.new(@repository, Article, :conditions => [ 'name IN ?', *bind_values ])
86
- query.conditions.should == [ [ :raw, 'name IN ?', bind_values ] ]
87
- query.bind_values.should == bind_values
88
- end
89
-
90
- it 'when they have another DM:Query as the value of sub-select' do
91
- class Acl
92
- include DataMapper::Resource
93
- property :id, Integer
94
- property :resource_id, Integer
95
- end
96
-
97
- acl_query = DataMapper::Query.new(@repository, Acl, :fields=>[:resource_id]) #this would normally have conditions
98
- query = DataMapper::Query.new(@repository, Article, :id.in => acl_query)
99
- query.conditions.each do |operator, property, value|
100
- operator.should == :in
101
- property.name.should == :id
102
- value.should == acl_query
103
- end
104
- end
105
- end
106
-
107
- describe ' #conditions with unknown options' do
108
- it 'when a Symbol object is a key' do
109
- query = DataMapper::Query.new(@repository, Article, :author => 'dkubb')
110
- query.conditions.should == [ [ :eql, Article.properties[:author], 'dkubb' ] ]
111
- end
112
-
113
- it 'when a Query::Operator object is a key' do
114
- query = DataMapper::Query.new(@repository, Article, :author.like => /\Ad(?:an\.)kubb\z/)
115
- query.conditions.should == [ [ :like, Article.properties[:author], /\Ad(?:an\.)kubb\z/ ] ]
116
- end
117
- end
118
-
119
- it '#order with model.default_order if none provided' do
120
- query = DataMapper::Query.new(@repository, Article)
121
- query.order.should == [ DataMapper::Query::Direction.new(Article.properties[:id], :asc) ]
122
- end
123
- end
124
-
125
- describe 'should raise an ArgumentError' do
126
- it 'when repository is nil' do
127
- lambda {
128
- DataMapper::Query.new(nil, NormalClass)
129
- }.should raise_error(ArgumentError)
130
- end
131
-
132
- it 'when model is nil' do
133
- lambda {
134
- DataMapper::Query.new(@repository, nil)
135
- }.should raise_error(ArgumentError)
136
- end
137
-
138
- it 'when model is a Class that does not include DataMapper::Resource' do
139
- lambda {
140
- DataMapper::Query.new(@repository, NormalClass)
141
- }.should raise_error(ArgumentError)
142
- end
143
-
144
- it 'when options is not a Hash' do
145
- lambda {
146
- DataMapper::Query.new(@repository, Article, nil)
147
- }.should raise_error(ArgumentError)
148
- end
149
-
150
- BAD_OPTIONS.each do |attribute,value|
151
- it "when options[:#{attribute}] is nil" do
152
- lambda {
153
- DataMapper::Query.new(@repository, Article, attribute => nil)
154
- }.should raise_error(ArgumentError)
155
- end
156
-
157
- it "when options[:#{attribute}] is #{value.kind_of?(Array) && value.empty? ? 'an empty Array' : value.inspect}" do
158
- lambda {
159
- DataMapper::Query.new(@repository, Article, attribute => value)
160
- }.should raise_error(ArgumentError)
161
- end
162
- end
163
-
164
- it 'when unknown options use something that is not a Query::Operator, Symbol or String is a key' do
165
- lambda {
166
- DataMapper::Query.new(@repository, Article, nil => nil)
167
- }.should raise_error(ArgumentError)
168
- end
169
- end
170
-
171
- describe 'should normalize' do
172
- it '#fields' do
173
- DataMapper::Query.new(@repository, Article, :fields => [:id]).fields.should == Article.properties.slice(:id)
174
- end
175
- end
176
-
177
- describe 'should translate custom types' do
178
- before(:each) do
179
- class Acl
180
- include DataMapper::Resource
181
- property :id, Integer
182
- property :is_custom_type, DM::Boolean
183
- end
184
- end
185
- it "should call Boolean#dump for :is_custom_type options" do
186
- DM::Boolean.should_receive(:dump).with(:false, Acl.properties[:is_custom_type])
187
- DataMapper::Query.new(@repository, Acl, :is_custom_type => :false)
188
- end
189
- end
190
- end
191
-
192
- it 'should provide #update' do
193
- @query.should respond_to(:update)
194
- end
195
-
196
- describe '#update' do
197
- before do
198
- @query = DataMapper::Query.new(@repository, Article, UPDATED_OPTIONS)
199
- end
200
-
201
- it 'should instantiate a DataMapper::Query object from other when it is a Hash' do
202
- other = { :reload => :true }
203
-
204
- @query.should_receive(:class).with(no_args).exactly(3).times.ordered.and_return(DataMapper::Query)
205
- DataMapper::Query.should_receive(:new).with(@repository, @query.model, other).ordered.and_return(@query)
206
-
207
- @query.update(other)
208
- end
209
-
210
- it 'should raise an ArgumentError if other query model is different' do
211
- lambda {
212
- other = DataMapper::Query.new(@repository, Comment)
213
- @query.update(other)
214
- }.should raise_error(ArgumentError)
215
- end
216
-
217
- it 'should return self' do
218
- other = DataMapper::Query.new(@repository, Article)
219
- @query.update(other).should == @query
220
- end
221
-
222
- describe 'should overwrite the attribute' do
223
- it '#reload? with other reload?' do
224
- other = DataMapper::Query.new(@repository, Article, :reload => true)
225
- @query.update(other).reload?.should == true
226
- end
227
-
228
- it '#offset with other offset when it is not equal to 0' do
229
- other = DataMapper::Query.new(@repository, Article, :offset => 1)
230
- @query.update(other).offset.should == 1
231
- end
232
-
233
- it '#limit with other limit when it is not nil' do
234
- other = DataMapper::Query.new(@repository, Article, :limit => 1)
235
- @query.update(other).limit.should == 1
236
- end
237
-
238
- it '#the operator if condition is the same and operater is changed (:not / :eql)' do
239
- # especially needed for collection#update where you might do something like:
240
- # all(:name.not => "John").update(:name => "John")
241
- pending do
242
- other = DataMapper::Query.new(@repository, Article, :author.not => "dkubb")
243
- @query.update(other).conditions.should == [ [ :not, Article.properties[:author], 'dkubb' ] ]
244
- @query.update(:author => "dkubb").conditions.should == [ [ :eql, Article.properties[:author], 'dkubb' ] ]
245
- end
246
- end
247
-
248
- [ :eql, :like ].each do |operator|
249
- it "#conditions with other conditions when updating the '#{operator}' clause to a different value than in self" do
250
- # set the initial conditions
251
- @query.update(:author.send(operator) => 'ssmoot')
252
-
253
- # update the conditions, and overwrite with the new value
254
- other = DataMapper::Query.new(@repository, Article, :author.send(operator) => 'dkubb')
255
- @query.update(other).conditions.should == [ [ operator, Article.properties[:author], 'dkubb' ] ]
256
- end
257
- end
258
-
259
- [ :gt, :gte ].each do |operator|
260
- it "#conditions with other conditions when updating the '#{operator}' clause to a value less than in self" do
261
- # set the initial conditions
262
- @query.update(:created_at.send(operator) => Time.at(1))
263
-
264
- # update the conditions, and overwrite with the new value is less
265
- other = DataMapper::Query.new(@repository, Article, :created_at.send(operator) => Time.at(0))
266
- @query.update(other).conditions.should == [ [ operator, Article.properties[:created_at], Time.at(0) ] ]
267
- end
268
- end
269
-
270
- [ :lt, :lte ].each do |operator|
271
- it "#conditions with other conditions when updating the '#{operator}' clause to a value greater than in self" do
272
- # set the initial conditions
273
- @query.update(:created_at.send(operator) => Time.at(0))
274
-
275
- # update the conditions, and overwrite with the new value is more
276
- other = DataMapper::Query.new(@repository, Article, :created_at.send(operator) => Time.at(1))
277
- @query.update(other).conditions.should == [ [ operator, Article.properties[:created_at], Time.at(1) ] ]
278
- end
279
- end
280
-
281
- it "#order with other order unique values" do
282
- order = [
283
- DataMapper::Query::Direction.new(Article.properties[:created_at], :desc),
284
- DataMapper::Query::Direction.new(Article.properties[:author], :desc),
285
- DataMapper::Query::Direction.new(Article.properties[:title], :desc),
286
- ]
287
-
288
- other = DataMapper::Query.new(@repository, Article, :order => order)
289
- @query.update(other).order.should == order
290
- end
291
-
292
- # dkubb: I am not sure i understand the intent here. link now needs to be
293
- # a DM::Assoc::Relationship or the name (Symbol or String) of an
294
- # association on the Resource -- thx guyvdb
295
- #
296
- # NOTE: I have commented out :links in the GOOD_OPTIONS above
297
- #
298
- [ :links, :includes ].each do |attribute|
299
- it "##{attribute} with other #{attribute} unique values" do
300
- pending 'DataMapper::Query::Path not ready'
301
- other = DataMapper::Query.new(@repository, Article, attribute => [ :stub, :other, :new ])
302
- @query.update(other).send(attribute).should == [ :stub, :other, :new ]
303
- end
304
- end
305
-
306
- it "#fields with other fields unique values" do
307
- other = DataMapper::Query.new(@repository, Article, :fields => [ :blog_id ])
308
- @query.update(other).fields.should == Article.properties.slice(:blog_id)
309
- end
310
-
311
- it '#conditions with other conditions when they are unique' do
312
- # set the initial conditions
313
- @query.update(:title => 'On DataMapper')
314
-
315
- # update the conditions, but merge the conditions together
316
- other = DataMapper::Query.new(@repository, Article, :author => 'dkubb')
317
- @query.update(other).conditions.should == [ [ :eql, Article.properties[:title], 'On DataMapper' ], [ :eql, Article.properties[:author], 'dkubb' ] ]
318
- end
319
-
320
- [ :not, :in ].each do |operator|
321
- it "#conditions with other conditions when updating the '#{operator}' clause" do
322
- # set the initial conditions
323
- @query.update(:created_at.send(operator) => [ Time.at(0) ])
324
-
325
- # update the conditions, and overwrite with the new value is more
326
- other = DataMapper::Query.new(@repository, Article, :created_at.send(operator) => [ Time.at(1) ])
327
- @query.update(other).conditions.should == [ [ operator, Article.properties[:created_at], [ Time.at(0), Time.at(1) ] ] ]
328
- end
329
- end
330
-
331
- it '#conditions with other conditions when they have a one element condition' do
332
- # set the initial conditions
333
- @query.update(:title => 'On DataMapper')
334
-
335
- # update the conditions, but merge the conditions together
336
- other = DataMapper::Query.new(@repository, Article, :conditions => [ 'author = "dkubb"' ])
337
- @query.update(other).conditions.should == [ [ :eql, Article.properties[:title], 'On DataMapper' ], [ :raw, 'author = "dkubb"' ] ]
338
- end
339
-
340
- it '#conditions with other conditions when they have a two or more element condition' do
341
- # set the initial conditions
342
- @query.update(:title => 'On DataMapper')
343
-
344
- # update the conditions, but merge the conditions together
345
- other = DataMapper::Query.new(@repository, Article, :conditions => [ 'author = ?', 'dkubb' ])
346
- @query.update(other).conditions.should == [ [ :eql, Article.properties[:title], 'On DataMapper' ], [ :raw, 'author = ?', [ 'dkubb' ] ] ]
347
- end
348
- end
349
-
350
- describe 'should not update the attribute' do
351
- it '#offset when other offset is equal to 0' do
352
- other = DataMapper::Query.new(@repository, Article, :offset => 0)
353
- other.offset.should == 0
354
- @query.update(other).offset.should == 1
355
- end
356
-
357
- it '#limit when other limit is nil' do
358
- other = DataMapper::Query.new(@repository, Article)
359
- other.limit.should be_nil
360
- @query.update(other).offset.should == 1
361
- end
362
-
363
- [ :gt, :gte ].each do |operator|
364
- it "#conditions with other conditions when they have a '#{operator}' clause with a value greater than in self" do
365
- # set the initial conditions
366
- @query.update(:created_at.send(operator) => Time.at(0))
367
-
368
- # do not overwrite with the new value if it is more
369
- other = DataMapper::Query.new(@repository, Article, :created_at.send(operator) => Time.at(1))
370
- @query.update(other).conditions.should == [ [ operator, Article.properties[:created_at], Time.at(0) ] ]
371
- end
372
- end
373
-
374
- [ :lt, :lte ].each do |operator|
375
- it "#conditions with other conditions when they have a '#{operator}' clause with a value less than in self" do
376
- # set the initial conditions
377
- @query.update(:created_at.send(operator) => Time.at(1))
378
-
379
- # do not overwrite with the new value if it is less
380
- other = DataMapper::Query.new(@repository, Article, :created_at.send(operator) => Time.at(0))
381
- @query.update(other).conditions.should == [ [ operator, Article.properties[:created_at], Time.at(1) ] ]
382
- end
383
- end
384
- end
385
- end
386
-
387
- it 'should provide #merge' do
388
- @query.should respond_to(:merge)
389
- end
390
-
391
- describe '#merge' do
392
- it 'should pass arguments as-is to duplicate object\'s #update method' do
393
- dupe_query = @query.dup
394
- @query.should_receive(:dup).with(no_args).ordered.and_return(dupe_query)
395
- dupe_query.should_receive(:update).with(:author => 'dkubb').ordered
396
- @query.merge(:author => 'dkubb')
397
- end
398
-
399
- it 'should return the duplicate object' do
400
- dupe_query = @query.merge(:author => 'dkubb')
401
- @query.object_id.should_not == dupe_query.object_id
402
- @query.merge(:author => 'dkubb').should == dupe_query
403
- end
404
- end
405
-
406
- it 'should provide #==' do
407
- @query.should respond_to(:==)
408
- end
409
-
410
- describe '#==' do
411
- describe 'should be equal' do
412
- it 'when other is same object' do
413
- @query.update(:author => 'dkubb').should == @query
414
- end
415
-
416
- it 'when other has the same attributes' do
417
- other = DataMapper::Query.new(@repository, Article)
418
- @query.object_id.should_not == other.object_id
419
- @query.should == other
420
- end
421
-
422
- it 'when other has the same conditions sorted differently' do
423
- @query.update(:author => 'dkubb')
424
- @query.update(:title => 'On DataMapper')
425
-
426
- other = DataMapper::Query.new(@repository, Article, :title => 'On DataMapper')
427
- other.update(:author => 'dkubb')
428
-
429
- # query conditions are in different order
430
- @query.conditions.should == [ [ :eql, Article.properties[:author], 'dkubb' ], [ :eql, Article.properties[:title], 'On DataMapper' ] ]
431
- other.conditions.should == [ [ :eql, Article.properties[:title], 'On DataMapper' ], [ :eql, Article.properties[:author], 'dkubb' ] ]
432
-
433
- @query.should == other
434
- end
435
- end
436
-
437
- describe 'should be different' do
438
- it 'when other model is different than self.model' do
439
- @query.should_not == DataMapper::Query.new(@repository, Comment)
440
- end
441
-
442
- UPDATED_OPTIONS.each do |attribute,value|
443
- it "when other #{attribute} is different than self.#{attribute}" do
444
- @query.should_not == DataMapper::Query.new(@repository, Article, attribute => value)
445
- end
446
- end
447
-
448
- it 'when other conditions are different than self.conditions' do
449
- @query.should_not == DataMapper::Query.new(@repository, Article, :author => 'dkubb')
450
- end
451
- end
452
- end
453
-
454
- it 'should provide #reverse' do
455
- @query.should respond_to(:reverse)
456
- end
457
-
458
- describe '#reverse' do
459
- it 'should create a duplicate query and delegate to #reverse!' do
460
- copy = @query.dup
461
- copy.should_receive(:reverse!).with(no_args).and_return(@query)
462
- @query.should_receive(:dup).with(no_args).and_return(copy)
463
-
464
- @query.reverse.should == @query
465
- end
466
- end
467
-
468
- it 'should provide #reverse!' do
469
- @query.should respond_to(:reverse!)
470
- end
471
-
472
- describe '#reverse!' do
473
- it 'should update the query with the reverse order' do
474
- normal_order = Article.key.map { |p| DataMapper::Query::Direction.new(p, :asc) }
475
- reverse_order = Article.key.map { |p| DataMapper::Query::Direction.new(p, :desc) }
476
-
477
- normal_order.should_not be_empty
478
- reverse_order.should_not be_empty
479
-
480
- @query.order.should == normal_order
481
- @query.should_receive(:update).with(:order => reverse_order)
482
- @query.reverse!.object_id.should == @query.object_id
483
- end
484
- end
485
-
486
- describe 'inheritance properties' do
487
- before(:each) do
488
- class Parent
489
- include DataMapper::Resource
490
- property :id, Serial
491
- property :type, Discriminator
492
- end
493
- @query = DataMapper::Query.new(@repository, Parent)
494
- @other_query = DataMapper::Query.new(@repository, Article)
495
- end
496
-
497
- it 'should provide #inheritance_property' do
498
- @query.should respond_to(:inheritance_property)
499
- end
500
-
501
- describe '#inheritance_property' do
502
- it 'should return a Property object if there is a Discriminator field' do
503
- @query.inheritance_property.should be_kind_of(DataMapper::Property)
504
- @query.inheritance_property.name.should == :type
505
- @query.inheritance_property.type.should == DM::Discriminator
506
- end
507
-
508
- it 'should return nil if there is no Discriminator field' do
509
- @other_query.inheritance_property.should be_nil
510
- end
511
- end
512
-
513
- it 'should provide #inheritance_property_index' do
514
- @query.should respond_to(:inheritance_property_index)
515
- end
516
-
517
- describe '#inheritance_property_index' do
518
- it 'should return integer index if there is a Discriminator field' do
519
- @query.inheritance_property_index.should be_kind_of(Integer)
520
- @query.inheritance_property_index.should == 1
521
- end
522
-
523
- it 'should return nil if there is no Discriminator field'
524
- end
525
- end
526
- end
527
-
528
- describe DataMapper::Query::Operator do
529
- before do
530
- @operator = :thing.gte
531
- end
532
-
533
- it 'should provide #==' do
534
- @operator.should respond_to(:==)
535
- end
536
-
537
- describe '#==' do
538
- describe 'should be equal' do
539
- it 'when other is same object' do
540
- @operator.should == @operator
541
- end
542
-
543
- it 'when other has the same target and operator' do
544
- other = :thing.gte
545
- @operator.target.should == other.target
546
- @operator.operator.should == other.operator
547
- @operator.should == other
548
- end
549
- end
550
-
551
- describe 'should be different' do
552
- it 'when other class is not a descendant of self.class' do
553
- other = :thing
554
- other.class.should_not be_kind_of(@operator.class)
555
- @operator.should_not == other
556
- end
557
-
558
- it 'when other has a different target' do
559
- other = :other.gte
560
- @operator.target.should_not == other.target
561
- @operator.should_not == other
562
- end
563
-
564
- it 'when other has a different operator' do
565
- other = :thing.gt
566
- @operator.operator.should_not == other.operator
567
- @operator.should_not == other
568
- end
569
- end
570
- end
571
- end
@@ -1,93 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- describe DataMapper::Repository do
4
- before do
5
- @adapter = mock('adapter')
6
- @identity_map = mock('identity map', :[]= => nil)
7
- @identity_maps = mock('identity maps', :[] => @identity_map)
8
-
9
- @repository = repository(:mock)
10
- @repository.stub!(:adapter).and_return(@adapter)
11
-
12
- # TODO: stub out other external dependencies in repository
13
- end
14
-
15
- describe "managing transactions" do
16
- it "should create a new Transaction with itself as argument when #transaction is called" do
17
- transaction = mock('transaction')
18
- DataMapper::Transaction.should_receive(:new).with(@repository).and_return(transaction)
19
- @repository.transaction.should == transaction
20
- end
21
- end
22
-
23
- it 'should provide .storage_exists?' do
24
- @repository.should respond_to(:storage_exists?)
25
- end
26
-
27
- it '.storage_exists? should whether or not the storage exists' do
28
- @adapter.should_receive(:storage_exists?).with(:vegetable).and_return(true)
29
-
30
- @repository.storage_exists?(:vegetable).should == true
31
- end
32
-
33
- it "should provide persistance methods" do
34
- @repository.should respond_to(:create)
35
- @repository.should respond_to(:read_many)
36
- @repository.should respond_to(:read_one)
37
- @repository.should respond_to(:update)
38
- @repository.should respond_to(:delete)
39
- end
40
-
41
- it "should be reused in inner scope" do
42
- DataMapper.repository(:default) do |outer_repos|
43
- DataMapper.repository(:default) do |inner_repos|
44
- outer_repos.object_id.should == inner_repos.object_id
45
- end
46
- end
47
- end
48
-
49
- it 'should provide default_name' do
50
- DataMapper::Repository.should respond_to(:default_name)
51
- end
52
-
53
- it 'should return :default for default_name' do
54
- DataMapper::Repository.default_name.should == :default
55
- end
56
-
57
- describe "#migrate!" do
58
- it "should call DataMapper::Migrator.migrate with itself as the repository argument" do
59
- DataMapper::Migrator.should_receive(:migrate).with(@repository.name)
60
-
61
- @repository.migrate!
62
- end
63
- end
64
-
65
- describe "#auto_migrate!" do
66
- it "should call DataMapper::AutoMigrator.auto_migrate with itself as the repository argument" do
67
- DataMapper::AutoMigrator.should_receive(:auto_migrate).with(@repository.name)
68
-
69
- @repository.auto_migrate!
70
- end
71
- end
72
-
73
- describe "#auto_upgrade!" do
74
- it "should call DataMapper::AutoMigrator.auto_upgrade with itself as the repository argument" do
75
- DataMapper::AutoMigrator.should_receive(:auto_upgrade).with(@repository.name)
76
-
77
- @repository.auto_upgrade!
78
- end
79
- end
80
-
81
- describe "#map" do
82
- it "should call type_map.map with the arguments" do
83
- type_map = mock('type map')
84
-
85
- @adapter.class.should_receive(:type_map).and_return(type_map)
86
- DataMapper::TypeMap.should_receive(:new).with(type_map).and_return(type_map)
87
-
88
- type_map.should_receive(:map).with(:type, :arg)
89
-
90
- @repository.map(:type, :arg)
91
- end
92
- end
93
- end