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.
- data/.autotest +17 -14
- data/.gitignore +3 -1
- data/FAQ +6 -5
- data/History.txt +5 -39
- data/Manifest.txt +67 -76
- data/QUICKLINKS +1 -1
- data/README.txt +21 -15
- data/Rakefile +16 -15
- data/SPECS +2 -29
- data/TODO +1 -1
- data/dm-core.gemspec +11 -15
- data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
- data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
- data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
- data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
- data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
- data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
- data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
- data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
- data/lib/dm-core/adapters.rb +135 -16
- data/lib/dm-core/associations/many_to_many.rb +372 -90
- data/lib/dm-core/associations/many_to_one.rb +220 -73
- data/lib/dm-core/associations/one_to_many.rb +319 -255
- data/lib/dm-core/associations/one_to_one.rb +66 -53
- data/lib/dm-core/associations/relationship.rb +560 -158
- data/lib/dm-core/collection.rb +1104 -381
- data/lib/dm-core/core_ext/kernel.rb +12 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +4 -34
- data/lib/dm-core/migrations.rb +1283 -0
- data/lib/dm-core/model/descendant_set.rb +81 -0
- data/lib/dm-core/model/hook.rb +45 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +248 -0
- data/lib/dm-core/model/relationship.rb +335 -0
- data/lib/dm-core/model/scope.rb +90 -0
- data/lib/dm-core/model.rb +570 -369
- data/lib/dm-core/property.rb +753 -280
- data/lib/dm-core/property_set.rb +141 -98
- data/lib/dm-core/query/conditions/comparison.rb +814 -0
- data/lib/dm-core/query/conditions/operation.rb +247 -0
- data/lib/dm-core/query/direction.rb +43 -0
- data/lib/dm-core/query/operator.rb +42 -0
- data/lib/dm-core/query/path.rb +102 -0
- data/lib/dm-core/query/sort.rb +45 -0
- data/lib/dm-core/query.rb +974 -492
- data/lib/dm-core/repository.rb +147 -107
- data/lib/dm-core/resource.rb +644 -429
- data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
- data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
- data/lib/dm-core/support/chainable.rb +20 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/equalizer.rb +23 -0
- data/lib/dm-core/support/logger.rb +13 -0
- data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
- data/lib/dm-core/transaction.rb +333 -92
- data/lib/dm-core/type.rb +98 -60
- data/lib/dm-core/types/boolean.rb +1 -1
- data/lib/dm-core/types/discriminator.rb +34 -20
- data/lib/dm-core/types/object.rb +7 -4
- data/lib/dm-core/types/paranoid_boolean.rb +11 -9
- data/lib/dm-core/types/paranoid_datetime.rb +11 -9
- data/lib/dm-core/types/serial.rb +3 -3
- data/lib/dm-core/types/text.rb +3 -4
- data/lib/dm-core/version.rb +1 -1
- data/lib/dm-core.rb +106 -110
- data/script/performance.rb +102 -109
- data/script/profile.rb +169 -38
- data/spec/lib/adapter_helpers.rb +105 -0
- data/spec/lib/collection_helpers.rb +18 -0
- data/spec/lib/counter_adapter.rb +34 -0
- data/spec/lib/pending_helpers.rb +27 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
- data/spec/public/associations/many_to_many_spec.rb +193 -0
- data/spec/public/associations/many_to_one_spec.rb +73 -0
- data/spec/public/associations/one_to_many_spec.rb +77 -0
- data/spec/public/associations/one_to_one_spec.rb +156 -0
- data/spec/public/collection_spec.rb +65 -0
- data/spec/public/model/relationship_spec.rb +924 -0
- data/spec/public/model_spec.rb +159 -0
- data/spec/public/property_spec.rb +829 -0
- data/spec/public/resource_spec.rb +71 -0
- data/spec/public/sel_spec.rb +44 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +317 -0
- data/spec/public/shared/collection_shared_spec.rb +1723 -0
- data/spec/public/shared/finder_shared_spec.rb +1619 -0
- data/spec/public/shared/resource_shared_spec.rb +924 -0
- data/spec/public/shared/sel_shared_spec.rb +112 -0
- data/spec/public/transaction_spec.rb +129 -0
- data/spec/public/types/discriminator_spec.rb +130 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
- data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
- data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +194 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +142 -0
- data/spec/semipublic/property_spec.rb +61 -0
- data/spec/semipublic/query/conditions_spec.rb +528 -0
- data/spec/semipublic/query/path_spec.rb +443 -0
- data/spec/semipublic/query_spec.rb +2626 -0
- data/spec/semipublic/resource_spec.rb +47 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
- data/spec/spec.opts +3 -1
- data/spec/spec_helper.rb +80 -57
- data/tasks/ci.rb +19 -31
- data/tasks/dm.rb +43 -48
- data/tasks/doc.rb +8 -11
- data/tasks/gemspec.rb +5 -5
- data/tasks/hoe.rb +15 -16
- data/tasks/install.rb +8 -10
- metadata +72 -93
- data/lib/dm-core/associations/relationship_chain.rb +0 -81
- data/lib/dm-core/associations.rb +0 -207
- data/lib/dm-core/auto_migrations.rb +0 -105
- data/lib/dm-core/dependency_queue.rb +0 -32
- data/lib/dm-core/hook.rb +0 -11
- data/lib/dm-core/is.rb +0 -16
- data/lib/dm-core/logger.rb +0 -232
- data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
- data/lib/dm-core/migrator.rb +0 -29
- data/lib/dm-core/scope.rb +0 -58
- data/lib/dm-core/support/array.rb +0 -13
- data/lib/dm-core/support/assertions.rb +0 -8
- data/lib/dm-core/support/errors.rb +0 -23
- data/lib/dm-core/support/kernel.rb +0 -11
- data/lib/dm-core/support/symbol.rb +0 -41
- data/lib/dm-core/support.rb +0 -7
- data/lib/dm-core/type_map.rb +0 -80
- data/lib/dm-core/types.rb +0 -19
- data/script/all +0 -4
- data/spec/integration/association_spec.rb +0 -1382
- data/spec/integration/association_through_spec.rb +0 -203
- data/spec/integration/associations/many_to_many_spec.rb +0 -449
- data/spec/integration/associations/many_to_one_spec.rb +0 -163
- data/spec/integration/associations/one_to_many_spec.rb +0 -188
- data/spec/integration/auto_migrations_spec.rb +0 -413
- data/spec/integration/collection_spec.rb +0 -1073
- data/spec/integration/data_objects_adapter_spec.rb +0 -32
- data/spec/integration/dependency_queue_spec.rb +0 -46
- data/spec/integration/model_spec.rb +0 -197
- data/spec/integration/mysql_adapter_spec.rb +0 -85
- data/spec/integration/postgres_adapter_spec.rb +0 -731
- data/spec/integration/property_spec.rb +0 -253
- data/spec/integration/query_spec.rb +0 -514
- data/spec/integration/repository_spec.rb +0 -61
- data/spec/integration/resource_spec.rb +0 -513
- data/spec/integration/sqlite3_adapter_spec.rb +0 -352
- data/spec/integration/sti_spec.rb +0 -273
- data/spec/integration/strategic_eager_loading_spec.rb +0 -156
- data/spec/integration/transaction_spec.rb +0 -75
- data/spec/integration/type_spec.rb +0 -275
- data/spec/lib/logging_helper.rb +0 -18
- data/spec/lib/mock_adapter.rb +0 -27
- data/spec/lib/model_loader.rb +0 -100
- data/spec/lib/publicize_methods.rb +0 -28
- data/spec/models/content.rb +0 -16
- data/spec/models/vehicles.rb +0 -34
- data/spec/models/zoo.rb +0 -48
- data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
- data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
- data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
- data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
- data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
- data/spec/unit/associations/many_to_many_spec.rb +0 -32
- data/spec/unit/associations/many_to_one_spec.rb +0 -159
- data/spec/unit/associations/one_to_many_spec.rb +0 -393
- data/spec/unit/associations/one_to_one_spec.rb +0 -7
- data/spec/unit/associations/relationship_spec.rb +0 -71
- data/spec/unit/associations_spec.rb +0 -242
- data/spec/unit/auto_migrations_spec.rb +0 -111
- data/spec/unit/collection_spec.rb +0 -182
- data/spec/unit/data_mapper_spec.rb +0 -35
- data/spec/unit/identity_map_spec.rb +0 -126
- data/spec/unit/is_spec.rb +0 -80
- data/spec/unit/migrator_spec.rb +0 -33
- data/spec/unit/model_spec.rb +0 -321
- data/spec/unit/naming_conventions_spec.rb +0 -36
- data/spec/unit/property_set_spec.rb +0 -90
- data/spec/unit/property_spec.rb +0 -753
- data/spec/unit/query_spec.rb +0 -571
- data/spec/unit/repository_spec.rb +0 -93
- data/spec/unit/resource_spec.rb +0 -649
- data/spec/unit/scope_spec.rb +0 -142
- data/spec/unit/transaction_spec.rb +0 -493
- data/spec/unit/type_map_spec.rb +0 -114
- data/spec/unit/type_spec.rb +0 -119
|
@@ -0,0 +1,2626 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
|
2
|
+
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
|
|
5
|
+
# TODO: make some of specs for Query.new shared. the assertions and
|
|
6
|
+
# normalizations should happen for Query#update, Query#relative and
|
|
7
|
+
# Query#merge and should probably be in shared specs
|
|
8
|
+
|
|
9
|
+
# class methods
|
|
10
|
+
describe DataMapper::Query do
|
|
11
|
+
before :all do
|
|
12
|
+
class ::Password < DataMapper::Type
|
|
13
|
+
primitive String
|
|
14
|
+
length 40
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ::User
|
|
18
|
+
include DataMapper::Resource
|
|
19
|
+
|
|
20
|
+
property :name, String, :key => true
|
|
21
|
+
property :password, Password
|
|
22
|
+
property :balance, BigDecimal
|
|
23
|
+
|
|
24
|
+
belongs_to :referrer, self, :nullable => true
|
|
25
|
+
has n, :referrals, self, :inverse => :referrer
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@repository = DataMapper::Repository.new(:default)
|
|
29
|
+
@model = User
|
|
30
|
+
|
|
31
|
+
@fields = [ :name ].freeze
|
|
32
|
+
@links = [ :referrer ].freeze
|
|
33
|
+
@conditions = { :name => 'Dan Kubb' }
|
|
34
|
+
@offset = 0
|
|
35
|
+
@limit = 1
|
|
36
|
+
@order = [ :name ].freeze
|
|
37
|
+
@unique = false
|
|
38
|
+
@add_reversed = false
|
|
39
|
+
@reload = false
|
|
40
|
+
|
|
41
|
+
@options = {
|
|
42
|
+
:fields => @fields,
|
|
43
|
+
:links => @links,
|
|
44
|
+
:conditions => @conditions,
|
|
45
|
+
:offset => @offset,
|
|
46
|
+
:limit => @limit,
|
|
47
|
+
:order => @order,
|
|
48
|
+
:unique => @unique,
|
|
49
|
+
:add_reversed => @add_reversed,
|
|
50
|
+
:reload => @reload,
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it { DataMapper::Query.should respond_to(:new) }
|
|
55
|
+
|
|
56
|
+
describe '.new' do
|
|
57
|
+
describe 'with a repository' do
|
|
58
|
+
describe 'that is valid' do
|
|
59
|
+
before :all do
|
|
60
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
64
|
+
|
|
65
|
+
it 'should set the repository' do
|
|
66
|
+
@return.repository.should == @repository
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe 'that is invalid' do
|
|
71
|
+
it 'should raise an exception' do
|
|
72
|
+
lambda {
|
|
73
|
+
DataMapper::Query.new('invalid', @model, @options)
|
|
74
|
+
}.should raise_error(ArgumentError, '+repository+ should be DataMapper::Repository, but was String')
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe 'with a model' do
|
|
80
|
+
describe 'that is valid' do
|
|
81
|
+
before :all do
|
|
82
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
86
|
+
|
|
87
|
+
it 'should set the model' do
|
|
88
|
+
@return.model.should == @model
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe 'that is invalid' do
|
|
93
|
+
it 'should raise an exception' do
|
|
94
|
+
lambda {
|
|
95
|
+
DataMapper::Query.new(@repository, 'invalid', @options)
|
|
96
|
+
}.should raise_error(ArgumentError, '+model+ should be DataMapper::Model, but was String')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe 'with a fields option' do
|
|
102
|
+
describe 'that is an Array containing a Symbol' do
|
|
103
|
+
before :all do
|
|
104
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
108
|
+
|
|
109
|
+
it 'should set the fields' do
|
|
110
|
+
@return.fields.should == @model.properties.values_at(*@fields)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe 'that is an Array containing a String' do
|
|
115
|
+
before :all do
|
|
116
|
+
@options[:fields] = [ 'name' ]
|
|
117
|
+
|
|
118
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
122
|
+
|
|
123
|
+
it 'should set the fields' do
|
|
124
|
+
@return.fields.should == @model.properties.values_at('name')
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe 'that is an Array containing a Property' do
|
|
129
|
+
before :all do
|
|
130
|
+
@options[:fields] = @model.properties.values_at(:name)
|
|
131
|
+
|
|
132
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
136
|
+
|
|
137
|
+
it 'should set the fields' do
|
|
138
|
+
@return.fields.should == @model.properties.values_at(:name)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe 'that is an Array containing a Property from an ancestor' do
|
|
143
|
+
before :all do
|
|
144
|
+
class ::Contact < User; end
|
|
145
|
+
|
|
146
|
+
@options[:fields] = User.properties.values_at(:name)
|
|
147
|
+
|
|
148
|
+
@return = DataMapper::Query.new(@repository, Contact, @options.freeze)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
152
|
+
|
|
153
|
+
it 'should set the fields' do
|
|
154
|
+
@return.fields.should == User.properties.values_at(:name)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe 'that is missing' do
|
|
159
|
+
before :all do
|
|
160
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:fields).freeze)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
164
|
+
|
|
165
|
+
it 'should set fields to the model default properties' do
|
|
166
|
+
@return.fields.should == @model.properties.defaults
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
describe 'that is invalid' do
|
|
171
|
+
it 'should raise an exception' do
|
|
172
|
+
lambda {
|
|
173
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => :name))
|
|
174
|
+
}.should raise_error(ArgumentError, '+options[:fields]+ should be Array, but was Symbol')
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe 'that is an empty Array and the unique option is false' do
|
|
179
|
+
it 'should raise an exception' do
|
|
180
|
+
lambda {
|
|
181
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => [], :unique => false))
|
|
182
|
+
}.should raise_error(ArgumentError, '+options[:fields]+ should not be empty if +options[:unique]+ is false')
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
describe 'that is an Array containing an unknown Symbol' do
|
|
187
|
+
it 'should raise an exception' do
|
|
188
|
+
lambda {
|
|
189
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => [ :unknown ]))
|
|
190
|
+
}.should raise_error(ArgumentError, "+options[:fields]+ entry :unknown does not map to a property in #{@model}")
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe 'that is an Array containing an unknown String' do
|
|
195
|
+
it 'should raise an exception' do
|
|
196
|
+
lambda {
|
|
197
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => [ 'unknown' ]))
|
|
198
|
+
}.should raise_error(ArgumentError, "+options[:fields]+ entry \"unknown\" does not map to a property in #{@model}")
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe 'that is an Array containing an invalid object' do
|
|
203
|
+
it 'should raise an exception' do
|
|
204
|
+
lambda {
|
|
205
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => [ 1 ]))
|
|
206
|
+
}.should raise_error(ArgumentError, '+options[:fields]+ entry 1 of an unsupported object Fixnum')
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
describe 'that is an Array containing an unknown Property' do
|
|
211
|
+
it 'should raise an exception' do
|
|
212
|
+
lambda {
|
|
213
|
+
DataMapper::Query.new(@repository, @model, @options.update(:fields => [ DataMapper::Property.new(@model, :unknown, String) ]))
|
|
214
|
+
}.should raise_error(ArgumentError, "+options[:field]+ entry :unknown does not map to a property in #{@model}")
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
describe 'with a links option' do
|
|
220
|
+
describe 'that is an Array containing a Symbol' do
|
|
221
|
+
before :all do
|
|
222
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
226
|
+
|
|
227
|
+
it 'should set the links' do
|
|
228
|
+
@return.links.should == @model.relationships.values_at(*@links)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
describe 'that is an Array containing a String' do
|
|
233
|
+
before :all do
|
|
234
|
+
@options[:links] = [ 'referrer' ]
|
|
235
|
+
|
|
236
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
240
|
+
|
|
241
|
+
it 'should set the links' do
|
|
242
|
+
@return.links.should == @model.relationships.values_at('referrer')
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
describe 'that is an Array containing a Relationship' do
|
|
247
|
+
before :all do
|
|
248
|
+
@options[:links] = @model.relationships.values_at(:referrer)
|
|
249
|
+
|
|
250
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
254
|
+
|
|
255
|
+
it 'should set the links' do
|
|
256
|
+
@return.links.should == @model.relationships.values_at(:referrer)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
describe 'that is missing' do
|
|
261
|
+
before :all do
|
|
262
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:links).freeze)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
266
|
+
|
|
267
|
+
it 'should set links to an empty Array' do
|
|
268
|
+
@return.links.should == []
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
describe 'that is invalid' do
|
|
273
|
+
it 'should raise an exception' do
|
|
274
|
+
lambda {
|
|
275
|
+
DataMapper::Query.new(@repository, @model, @options.update(:links => :referral))
|
|
276
|
+
}.should raise_error(ArgumentError, '+options[:links]+ should be Array, but was Symbol')
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe 'that is an empty Array' do
|
|
281
|
+
it 'should raise an exception' do
|
|
282
|
+
lambda {
|
|
283
|
+
DataMapper::Query.new(@repository, @model, @options.update(:links => []))
|
|
284
|
+
}.should raise_error(ArgumentError, '+options[:links]+ should not be empty')
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
describe 'that is an Array containing an unknown Symbol' do
|
|
289
|
+
it 'should raise an exception' do
|
|
290
|
+
lambda {
|
|
291
|
+
DataMapper::Query.new(@repository, @model, @options.update(:links => [ :unknown ]))
|
|
292
|
+
}.should raise_error(ArgumentError, "+options[:links]+ entry :unknown does not map to a relationship in #{@model}")
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe 'that is an Array containing an unknown String' do
|
|
297
|
+
it 'should raise an exception' do
|
|
298
|
+
lambda {
|
|
299
|
+
DataMapper::Query.new(@repository, @model, @options.update(:links => [ 'unknown' ]))
|
|
300
|
+
}.should raise_error(ArgumentError, "+options[:links]+ entry \"unknown\" does not map to a relationship in #{@model}")
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
describe 'that is an Array containing an invalid object' do
|
|
305
|
+
it 'should raise an exception' do
|
|
306
|
+
lambda {
|
|
307
|
+
DataMapper::Query.new(@repository, @model, @options.update(:links => [ 1 ]))
|
|
308
|
+
}.should raise_error(ArgumentError, '+options[:links]+ entry 1 of an unsupported object Fixnum')
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
describe 'with a conditions option' do
|
|
314
|
+
describe 'that is a valid Hash' do
|
|
315
|
+
describe 'with the Property key' do
|
|
316
|
+
before :all do
|
|
317
|
+
@options[:conditions] = { @model.properties[:name] => 'Dan Kubb' }
|
|
318
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
322
|
+
|
|
323
|
+
it 'should set the conditions' do
|
|
324
|
+
@return.conditions.should ==
|
|
325
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
326
|
+
:and,
|
|
327
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
328
|
+
:eql,
|
|
329
|
+
@model.properties[:name],
|
|
330
|
+
'Dan Kubb'
|
|
331
|
+
)
|
|
332
|
+
)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
it 'should be valid' do
|
|
336
|
+
@return.should be_valid
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
describe 'with the Symbol key mapping to a Property' do
|
|
341
|
+
before :all do
|
|
342
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
346
|
+
|
|
347
|
+
it 'should set the conditions' do
|
|
348
|
+
@return.conditions.should ==
|
|
349
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
350
|
+
:and,
|
|
351
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
352
|
+
:eql,
|
|
353
|
+
@model.properties[:name],
|
|
354
|
+
'Dan Kubb'
|
|
355
|
+
)
|
|
356
|
+
)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'should be valid' do
|
|
360
|
+
@return.should be_valid
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
describe 'with the String key mapping to a Property' do
|
|
365
|
+
before :all do
|
|
366
|
+
@options[:conditions] = { 'name' => 'Dan Kubb' }
|
|
367
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
371
|
+
|
|
372
|
+
it 'should set the conditions' do
|
|
373
|
+
@return.conditions.should ==
|
|
374
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
375
|
+
:and,
|
|
376
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
377
|
+
:eql,
|
|
378
|
+
@model.properties[:name],
|
|
379
|
+
'Dan Kubb'
|
|
380
|
+
)
|
|
381
|
+
)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it 'should be valid' do
|
|
385
|
+
@return.should be_valid
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
supported_by :all do
|
|
390
|
+
describe 'with the Symbol key mapping to a Relationship' do
|
|
391
|
+
before :all do
|
|
392
|
+
@user = @model.create(:name => 'Dan Kubb')
|
|
393
|
+
|
|
394
|
+
@options[:conditions] = { :referrer => @user }
|
|
395
|
+
|
|
396
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
400
|
+
|
|
401
|
+
it 'should set the conditions' do
|
|
402
|
+
@return.conditions.should ==
|
|
403
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
404
|
+
:and,
|
|
405
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
406
|
+
:eql,
|
|
407
|
+
@model.relationships[:referrer],
|
|
408
|
+
@user
|
|
409
|
+
)
|
|
410
|
+
)
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it 'should be valid' do
|
|
414
|
+
@return.should be_valid
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
describe 'with the String key mapping to a Relationship' do
|
|
419
|
+
before :all do
|
|
420
|
+
@user = @model.create(:name => 'Dan Kubb')
|
|
421
|
+
|
|
422
|
+
@options[:conditions] = { 'referrer' => @user }
|
|
423
|
+
|
|
424
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
428
|
+
|
|
429
|
+
it 'should set the conditions' do
|
|
430
|
+
@return.conditions.should ==
|
|
431
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
432
|
+
:and,
|
|
433
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
434
|
+
:eql,
|
|
435
|
+
@model.relationships['referrer'],
|
|
436
|
+
@user
|
|
437
|
+
)
|
|
438
|
+
)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
it 'should be valid' do
|
|
442
|
+
@return.should be_valid
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
describe 'with the Symbol key mapping to a Relationship and a nil value' do
|
|
447
|
+
before :all do
|
|
448
|
+
@options[:conditions] = { :referrer => nil }
|
|
449
|
+
|
|
450
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
454
|
+
|
|
455
|
+
it 'should set the conditions' do
|
|
456
|
+
@return.conditions.should ==
|
|
457
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
458
|
+
:and,
|
|
459
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
460
|
+
:eql,
|
|
461
|
+
@model.relationships[:referrer],
|
|
462
|
+
nil
|
|
463
|
+
)
|
|
464
|
+
)
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it 'should be valid' do
|
|
468
|
+
@return.should be_valid
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
describe 'with the Symbol key mapping to a Relationship and an empty Array' do
|
|
473
|
+
before :all do
|
|
474
|
+
@options[:conditions] = { :referrer => [] }
|
|
475
|
+
|
|
476
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
480
|
+
|
|
481
|
+
it 'should set the conditions' do
|
|
482
|
+
@return.conditions.should ==
|
|
483
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
484
|
+
:and,
|
|
485
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
486
|
+
:in,
|
|
487
|
+
@model.relationships[:referrer],
|
|
488
|
+
[]
|
|
489
|
+
)
|
|
490
|
+
)
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
it 'should be invalid' do
|
|
494
|
+
@return.should_not be_valid
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
describe 'with the Query::Operator key' do
|
|
500
|
+
before :all do
|
|
501
|
+
@options[:conditions] = { :name.gte => 'Dan Kubb' }
|
|
502
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
506
|
+
|
|
507
|
+
it 'should set the conditions' do
|
|
508
|
+
@return.conditions.should ==
|
|
509
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
510
|
+
:and,
|
|
511
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
512
|
+
:gte,
|
|
513
|
+
@model.properties[:name],
|
|
514
|
+
'Dan Kubb'
|
|
515
|
+
)
|
|
516
|
+
)
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
it 'should be valid' do
|
|
520
|
+
@return.should be_valid
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
describe 'with the Query::Path key' do
|
|
525
|
+
before :all do
|
|
526
|
+
@options[:conditions] = { @model.referrer.name => 'Dan Kubb' }
|
|
527
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
531
|
+
|
|
532
|
+
it 'should set the conditions' do
|
|
533
|
+
@return.conditions.should ==
|
|
534
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
535
|
+
:and,
|
|
536
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
537
|
+
:eql,
|
|
538
|
+
@model.referrer.name,
|
|
539
|
+
'Dan Kubb'
|
|
540
|
+
)
|
|
541
|
+
)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
it 'should set the links' do
|
|
545
|
+
@return.links.should == [ @model.relationships[:referrals], @model.relationships[:referrer] ]
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
it 'should be valid' do
|
|
549
|
+
@return.should be_valid
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
describe 'with the String key mapping to a Query::Path' do
|
|
554
|
+
before :all do
|
|
555
|
+
@options[:conditions] = { 'referrer.name' => 'Dan Kubb' }
|
|
556
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
560
|
+
|
|
561
|
+
it 'should set the conditions' do
|
|
562
|
+
@return.conditions.should ==
|
|
563
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
564
|
+
:and,
|
|
565
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
566
|
+
:eql,
|
|
567
|
+
@model.referrer.name,
|
|
568
|
+
'Dan Kubb'
|
|
569
|
+
)
|
|
570
|
+
)
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
it 'should set the links' do
|
|
574
|
+
@return.links.should == [ @model.relationships[:referrals], @model.relationships[:referrer] ]
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
it 'should be valid' do
|
|
578
|
+
@return.should be_valid
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
describe 'with a Proc value' do
|
|
583
|
+
before :all do
|
|
584
|
+
@options[:conditions] = { :name => lambda { 'Dan Kubb' } }
|
|
585
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
589
|
+
|
|
590
|
+
it 'should set the conditions' do
|
|
591
|
+
@return.conditions.should ==
|
|
592
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
593
|
+
:and,
|
|
594
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
595
|
+
:eql,
|
|
596
|
+
@model.properties[:name],
|
|
597
|
+
'Dan Kubb'
|
|
598
|
+
)
|
|
599
|
+
)
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
it 'should be valid' do
|
|
603
|
+
@return.should be_valid
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
describe 'with an Array with 1 entry' do
|
|
608
|
+
before :all do
|
|
609
|
+
@options[:conditions] = { :name => [ 'Dan Kubb' ] }
|
|
610
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
614
|
+
|
|
615
|
+
it 'should set the conditions' do
|
|
616
|
+
pending do
|
|
617
|
+
@return.conditions.should ==
|
|
618
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
619
|
+
:and,
|
|
620
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
621
|
+
:eql,
|
|
622
|
+
@model.properties[:name],
|
|
623
|
+
'Dan Kubb'
|
|
624
|
+
)
|
|
625
|
+
)
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it 'should be valid' do
|
|
630
|
+
@return.should be_valid
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
describe 'with an Array with duplicate entries' do
|
|
635
|
+
before :all do
|
|
636
|
+
@options[:conditions] = { :name => [ 'John Doe', 'Dan Kubb', 'John Doe' ] }
|
|
637
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
641
|
+
|
|
642
|
+
it 'should set the conditions' do
|
|
643
|
+
@return.conditions.should ==
|
|
644
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
645
|
+
:and,
|
|
646
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
647
|
+
:in,
|
|
648
|
+
@model.properties[:name],
|
|
649
|
+
[ 'John Doe', 'Dan Kubb' ]
|
|
650
|
+
)
|
|
651
|
+
)
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
it 'should be valid' do
|
|
655
|
+
@return.should be_valid
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
describe 'with a custom Property' do
|
|
660
|
+
before :all do
|
|
661
|
+
@options[:conditions] = { :password => 'password' }
|
|
662
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
666
|
+
|
|
667
|
+
it 'should set the conditions' do
|
|
668
|
+
@return.conditions.should ==
|
|
669
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
670
|
+
:and,
|
|
671
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
672
|
+
:eql,
|
|
673
|
+
@model.properties[:password],
|
|
674
|
+
'password'
|
|
675
|
+
)
|
|
676
|
+
)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
it 'should be valid' do
|
|
680
|
+
@return.should be_valid
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
describe 'with a Symbol for a String property' do
|
|
685
|
+
before :all do
|
|
686
|
+
@options[:conditions] = { :name => 'Dan Kubb'.to_sym }
|
|
687
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
691
|
+
|
|
692
|
+
it 'should set the conditions' do
|
|
693
|
+
@return.conditions.should ==
|
|
694
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
695
|
+
:and,
|
|
696
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
697
|
+
:eql,
|
|
698
|
+
@model.properties[:name],
|
|
699
|
+
'Dan Kubb' # typecast value
|
|
700
|
+
)
|
|
701
|
+
)
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
it 'should be valid' do
|
|
705
|
+
@return.should be_valid
|
|
706
|
+
end
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
describe 'with a Float for a BigDecimal property' do
|
|
710
|
+
before :all do
|
|
711
|
+
@options[:conditions] = { :balance => 50.5 }
|
|
712
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
716
|
+
|
|
717
|
+
it 'should set the conditions' do
|
|
718
|
+
@return.conditions.should ==
|
|
719
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
720
|
+
:and,
|
|
721
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
722
|
+
:eql,
|
|
723
|
+
@model.properties[:balance],
|
|
724
|
+
BigDecimal('50.5') # typecast value
|
|
725
|
+
)
|
|
726
|
+
)
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
it 'should be valid' do
|
|
730
|
+
@return.should be_valid
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
describe 'that is a valid Array' do
|
|
736
|
+
before :all do
|
|
737
|
+
@options[:conditions] = [ 'name = ?', 'Dan Kubb' ]
|
|
738
|
+
|
|
739
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
743
|
+
|
|
744
|
+
it 'should set the conditions' do
|
|
745
|
+
@return.conditions.should == DataMapper::Query::Conditions::Operation.new(:and, [ 'name = ?', [ 'Dan Kubb' ] ])
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
it 'should be valid' do
|
|
749
|
+
@return.should be_valid
|
|
750
|
+
end
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
describe 'that is missing' do
|
|
754
|
+
before :all do
|
|
755
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:conditions).freeze)
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
759
|
+
|
|
760
|
+
it 'should set conditions to nil by default' do
|
|
761
|
+
@return.conditions.should be_nil
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
it 'should be valid' do
|
|
765
|
+
@return.should be_valid
|
|
766
|
+
end
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
describe 'that is invalid' do
|
|
770
|
+
it 'should raise an exception' do
|
|
771
|
+
lambda {
|
|
772
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => 'invalid'))
|
|
773
|
+
}.should raise_error(ArgumentError, '+options[:conditions]+ should be DataMapper::Query::Conditions::AbstractOperation or DataMapper::Query::Conditions::AbstractComparison or Hash or Array, but was String')
|
|
774
|
+
end
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
describe 'that is an empty Array' do
|
|
778
|
+
it 'should raise an exception' do
|
|
779
|
+
lambda {
|
|
780
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => []))
|
|
781
|
+
}.should raise_error(ArgumentError, '+options[:conditions]+ should not be empty')
|
|
782
|
+
end
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
describe 'that is an Array with a blank statement' do
|
|
786
|
+
it 'should raise an exception' do
|
|
787
|
+
lambda {
|
|
788
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => [ ' ' ]))
|
|
789
|
+
}.should raise_error(ArgumentError, '+options[:conditions]+ should have a statement for the first entry')
|
|
790
|
+
end
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
describe 'that is a Hash with a Symbol key that is not for a Property in the model' do
|
|
794
|
+
it 'should raise an exception' do
|
|
795
|
+
lambda {
|
|
796
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => { :unknown => 1 }))
|
|
797
|
+
}.should raise_error(ArgumentError, "condition :unknown does not map to a property or relationship in #{@model}")
|
|
798
|
+
end
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
describe 'that is a Hash with a String key that is not for a Property in the model' do
|
|
802
|
+
it 'should raise an exception' do
|
|
803
|
+
lambda {
|
|
804
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => { 'unknown' => 1 }))
|
|
805
|
+
}.should raise_error(ArgumentError, "condition \"unknown\" does not map to a property or relationship in #{@model}")
|
|
806
|
+
end
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
describe 'that is a Hash with a Query::Operator key that is not for a Property in the model' do
|
|
810
|
+
it 'should raise an exception' do
|
|
811
|
+
lambda {
|
|
812
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => { :unknown.asc => 1 }))
|
|
813
|
+
}.should raise_error(ArgumentError, 'condition #<DataMapper::Query::Operator @target=:unknown @operator=:asc> used an invalid operator asc')
|
|
814
|
+
end
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
describe 'that is a Hash with a not operator that has an empty Array' do
|
|
818
|
+
it 'should raise an exception' do
|
|
819
|
+
lambda {
|
|
820
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => { :name.not => [] }))
|
|
821
|
+
}.should raise_error(ArgumentError, 'Cannot use \'not\' operator with a bind value that is an empty Array for #<DataMapper::Query::Operator @target=:name @operator=:not>')
|
|
822
|
+
end
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
describe 'that is a Hash with a key of a type that is not permitted' do
|
|
826
|
+
it 'should raise an exception' do
|
|
827
|
+
lambda {
|
|
828
|
+
DataMapper::Query.new(@repository, @model, @options.update(:conditions => { 1 => 1 }))
|
|
829
|
+
}.should raise_error(ArgumentError, 'condition 1 of an unsupported object Fixnum')
|
|
830
|
+
end
|
|
831
|
+
end
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
describe 'with an offset option' do
|
|
835
|
+
describe 'that is valid' do
|
|
836
|
+
before :all do
|
|
837
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
841
|
+
|
|
842
|
+
it 'should set the offset' do
|
|
843
|
+
@return.offset.should == @offset
|
|
844
|
+
end
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
describe 'that is missing' do
|
|
848
|
+
before :all do
|
|
849
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:offset).freeze)
|
|
850
|
+
end
|
|
851
|
+
|
|
852
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
853
|
+
|
|
854
|
+
it 'should set offset to 0' do
|
|
855
|
+
@return.offset.should == 0
|
|
856
|
+
end
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
describe 'that is invalid' do
|
|
860
|
+
it 'should raise an exception' do
|
|
861
|
+
lambda {
|
|
862
|
+
DataMapper::Query.new(@repository, @model, @options.update(:offset => '0'))
|
|
863
|
+
}.should raise_error(ArgumentError, '+options[:offset]+ should be Integer, but was String')
|
|
864
|
+
end
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
describe 'that is less than 0' do
|
|
868
|
+
it 'should raise an exception' do
|
|
869
|
+
lambda {
|
|
870
|
+
DataMapper::Query.new(@repository, @model, @options.update(:offset => -1))
|
|
871
|
+
}.should raise_error(ArgumentError, '+options[:offset]+ must be greater than or equal to 0, but was -1')
|
|
872
|
+
end
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
describe 'that is greater than 0 and a nil limit' do
|
|
876
|
+
it 'should raise an exception' do
|
|
877
|
+
lambda {
|
|
878
|
+
DataMapper::Query.new(@repository, @model, @options.except(:limit).update(:offset => 1))
|
|
879
|
+
}.should raise_error(ArgumentError, '+options[:offset]+ cannot be greater than 0 if limit is not specified')
|
|
880
|
+
end
|
|
881
|
+
end
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
describe 'with a limit option' do
|
|
885
|
+
describe 'that is valid' do
|
|
886
|
+
before :all do
|
|
887
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
891
|
+
|
|
892
|
+
it 'should set the limit' do
|
|
893
|
+
@return.limit.should == @limit
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
describe 'that is missing' do
|
|
898
|
+
before :all do
|
|
899
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:limit).freeze)
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
903
|
+
|
|
904
|
+
it 'should set limit to nil' do
|
|
905
|
+
@return.limit.should be_nil
|
|
906
|
+
end
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
describe 'that is invalid' do
|
|
910
|
+
it 'should raise an exception' do
|
|
911
|
+
lambda {
|
|
912
|
+
DataMapper::Query.new(@repository, @model, @options.update(:limit => '1'))
|
|
913
|
+
}.should raise_error(ArgumentError, '+options[:limit]+ should be Integer, but was String')
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
describe 'that is less than 0' do
|
|
918
|
+
it 'should raise an exception' do
|
|
919
|
+
lambda {
|
|
920
|
+
DataMapper::Query.new(@repository, @model, @options.update(:limit => -1))
|
|
921
|
+
}.should raise_error(ArgumentError, '+options[:limit]+ must be greater than or equal to 0, but was -1')
|
|
922
|
+
end
|
|
923
|
+
end
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
describe 'with an order option' do
|
|
927
|
+
describe 'that is an Array containing a Symbol' do
|
|
928
|
+
before :all do
|
|
929
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
933
|
+
|
|
934
|
+
it 'should set the order' do
|
|
935
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
|
|
936
|
+
end
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
describe 'that is an Array containing a String' do
|
|
940
|
+
before :all do
|
|
941
|
+
@options[:order] = [ 'name' ]
|
|
942
|
+
|
|
943
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
944
|
+
end
|
|
945
|
+
|
|
946
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
947
|
+
|
|
948
|
+
it 'should set the order' do
|
|
949
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
|
|
950
|
+
end
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
describe 'that is an Array containing a Property' do
|
|
954
|
+
before :all do
|
|
955
|
+
@options[:order] = @model.properties.values_at(:name)
|
|
956
|
+
|
|
957
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
961
|
+
|
|
962
|
+
it 'should set the order' do
|
|
963
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
describe 'that is an Array containing a Property from an ancestor' do
|
|
968
|
+
before :all do
|
|
969
|
+
class ::Contact < User; end
|
|
970
|
+
|
|
971
|
+
@options[:order] = User.properties.values_at(:name)
|
|
972
|
+
|
|
973
|
+
@return = DataMapper::Query.new(@repository, Contact, @options.freeze)
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
977
|
+
|
|
978
|
+
it 'should set the order' do
|
|
979
|
+
@return.order.should == [ DataMapper::Query::Direction.new(User.properties[:name]) ]
|
|
980
|
+
end
|
|
981
|
+
end
|
|
982
|
+
|
|
983
|
+
describe 'that is an Array containing an Operator' do
|
|
984
|
+
before :all do
|
|
985
|
+
@options[:order] = [ :name.asc ]
|
|
986
|
+
|
|
987
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
991
|
+
|
|
992
|
+
it 'should set the order' do
|
|
993
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name], :asc) ]
|
|
994
|
+
end
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
describe 'that is an Array containing an Query::Direction' do
|
|
998
|
+
before :all do
|
|
999
|
+
@options[:order] = [ DataMapper::Query::Direction.new(@model.properties[:name], :asc) ]
|
|
1000
|
+
|
|
1001
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1005
|
+
|
|
1006
|
+
it 'should set the order' do
|
|
1007
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name], :asc) ]
|
|
1008
|
+
end
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
describe 'that is an Array containing an Query::Direction with a Property from an ancestor' do
|
|
1012
|
+
before :all do
|
|
1013
|
+
class ::Contact < User; end
|
|
1014
|
+
|
|
1015
|
+
@options[:order] = [ DataMapper::Query::Direction.new(User.properties[:name], :asc) ]
|
|
1016
|
+
|
|
1017
|
+
@return = DataMapper::Query.new(@repository, Contact, @options.freeze)
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1021
|
+
|
|
1022
|
+
it 'should set the order' do
|
|
1023
|
+
@return.order.should == [ DataMapper::Query::Direction.new(User.properties[:name], :asc) ]
|
|
1024
|
+
end
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
describe 'that is missing' do
|
|
1028
|
+
before :all do
|
|
1029
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:order).freeze)
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1033
|
+
|
|
1034
|
+
it 'should set order to the model default order' do
|
|
1035
|
+
@return.order.should == @model.default_order(@repository.name)
|
|
1036
|
+
end
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
describe 'that is invalid' do
|
|
1040
|
+
it 'should raise an exception' do
|
|
1041
|
+
lambda {
|
|
1042
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => :name))
|
|
1043
|
+
}.should raise_error(ArgumentError, '+options[:order]+ should be Array, but was Symbol')
|
|
1044
|
+
end
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
describe 'that is an empty Array and the fields option contains a non-operator' do
|
|
1048
|
+
it 'should raise an exception' do
|
|
1049
|
+
lambda {
|
|
1050
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [], :fields => [ :name ]))
|
|
1051
|
+
}.should raise_error(ArgumentError, '+options[:order]+ should not be empty if +options[:fields] contains a non-operator')
|
|
1052
|
+
end
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
describe 'that is an Array containing an unknown String' do
|
|
1056
|
+
it 'should raise an exception' do
|
|
1057
|
+
lambda {
|
|
1058
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ 'unknown' ]))
|
|
1059
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry \"unknown\" does not map to a property in #{@model}")
|
|
1060
|
+
end
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
describe 'that is an Array containing an invalid object' do
|
|
1064
|
+
it 'should raise an exception' do
|
|
1065
|
+
lambda {
|
|
1066
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ 1 ]))
|
|
1067
|
+
}.should raise_error(ArgumentError, '+options[:order]+ entry 1 of an unsupported object Fixnum')
|
|
1068
|
+
end
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
describe 'that contains a Query::Direction with a property that is not part of the model' do
|
|
1072
|
+
before :all do
|
|
1073
|
+
@property = DataMapper::Property.new(@model, :unknown, String)
|
|
1074
|
+
@direction = DataMapper::Query::Direction.new(@property, :desc)
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
it 'should raise an exception' do
|
|
1078
|
+
lambda {
|
|
1079
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ @direction ]))
|
|
1080
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
|
|
1081
|
+
end
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
describe 'that contains a Query::Operator with a target that is not part of the model' do
|
|
1085
|
+
it 'should raise an exception' do
|
|
1086
|
+
lambda {
|
|
1087
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ :unknown.desc ]))
|
|
1088
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
|
|
1089
|
+
end
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
describe 'that contains a Query::Operator with an unknown operator' do
|
|
1093
|
+
it 'should raise an exception' do
|
|
1094
|
+
lambda {
|
|
1095
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ :name.gt ]))
|
|
1096
|
+
}.should raise_error(ArgumentError, '+options[:order]+ entry #<DataMapper::Query::Operator @target=:name @operator=:gt> used an invalid operator gt')
|
|
1097
|
+
end
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
describe 'that contains a Property that is not part of the model' do
|
|
1101
|
+
before :all do
|
|
1102
|
+
@property = DataMapper::Property.new(@model, :unknown, String)
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1105
|
+
it 'should raise an exception' do
|
|
1106
|
+
lambda {
|
|
1107
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ @property ]))
|
|
1108
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
|
|
1109
|
+
end
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
describe 'that contains a Symbol that is not for a Property in the model' do
|
|
1113
|
+
it 'should raise an exception' do
|
|
1114
|
+
lambda {
|
|
1115
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ :unknown ]))
|
|
1116
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry :unknown does not map to a property in #{@model}")
|
|
1117
|
+
end
|
|
1118
|
+
end
|
|
1119
|
+
|
|
1120
|
+
describe 'that contains a String that is not for a Property in the model' do
|
|
1121
|
+
it 'should raise an exception' do
|
|
1122
|
+
lambda {
|
|
1123
|
+
DataMapper::Query.new(@repository, @model, @options.update(:order => [ 'unknown' ]))
|
|
1124
|
+
}.should raise_error(ArgumentError, "+options[:order]+ entry \"unknown\" does not map to a property in #{@model}")
|
|
1125
|
+
end
|
|
1126
|
+
end
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
describe 'with a unique option' do
|
|
1130
|
+
describe 'that is valid' do
|
|
1131
|
+
before :all do
|
|
1132
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1136
|
+
|
|
1137
|
+
it 'should set the unique? flag' do
|
|
1138
|
+
@return.unique?.should == @unique
|
|
1139
|
+
end
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
describe 'that is missing' do
|
|
1143
|
+
before :all do
|
|
1144
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:unique).freeze)
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1148
|
+
|
|
1149
|
+
it 'should set the query to not be unique' do
|
|
1150
|
+
@return.should_not be_unique
|
|
1151
|
+
end
|
|
1152
|
+
end
|
|
1153
|
+
|
|
1154
|
+
describe 'that is invalid' do
|
|
1155
|
+
it 'should raise an exception' do
|
|
1156
|
+
lambda {
|
|
1157
|
+
DataMapper::Query.new(@repository, @model, @options.update(:unique => nil))
|
|
1158
|
+
}.should raise_error(ArgumentError, '+options[:unique]+ should be true or false, but was nil')
|
|
1159
|
+
end
|
|
1160
|
+
end
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
describe 'with an add_reversed option' do
|
|
1164
|
+
describe 'that is valid' do
|
|
1165
|
+
before :all do
|
|
1166
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1170
|
+
|
|
1171
|
+
it 'should set the add_reversed? flag' do
|
|
1172
|
+
@return.add_reversed?.should == @add_reversed
|
|
1173
|
+
end
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1176
|
+
describe 'that is missing' do
|
|
1177
|
+
before :all do
|
|
1178
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:add_reversed).freeze)
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1182
|
+
|
|
1183
|
+
it 'should set the query to not add in reverse order' do
|
|
1184
|
+
# TODO: think about renaming the flag to not sound 'clumsy'
|
|
1185
|
+
@return.should_not be_add_reversed
|
|
1186
|
+
end
|
|
1187
|
+
end
|
|
1188
|
+
|
|
1189
|
+
describe 'that is invalid' do
|
|
1190
|
+
it 'should raise an exception' do
|
|
1191
|
+
lambda {
|
|
1192
|
+
DataMapper::Query.new(@repository, @model, @options.update(:add_reversed => nil))
|
|
1193
|
+
}.should raise_error(ArgumentError, '+options[:add_reversed]+ should be true or false, but was nil')
|
|
1194
|
+
end
|
|
1195
|
+
end
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
describe 'with a reload option' do
|
|
1199
|
+
describe 'that is valid' do
|
|
1200
|
+
before :all do
|
|
1201
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1205
|
+
|
|
1206
|
+
it 'should set the reload? flag' do
|
|
1207
|
+
@return.reload?.should == @reload
|
|
1208
|
+
end
|
|
1209
|
+
end
|
|
1210
|
+
|
|
1211
|
+
describe 'that is missing' do
|
|
1212
|
+
before :all do
|
|
1213
|
+
@return = DataMapper::Query.new(@repository, @model, @options.except(:reload).freeze)
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1217
|
+
|
|
1218
|
+
it 'should set the query to not reload' do
|
|
1219
|
+
@return.should_not be_reload
|
|
1220
|
+
end
|
|
1221
|
+
end
|
|
1222
|
+
|
|
1223
|
+
describe 'that is invalid' do
|
|
1224
|
+
it 'should raise an exception' do
|
|
1225
|
+
lambda {
|
|
1226
|
+
DataMapper::Query.new(@repository, @model, @options.update(:reload => nil))
|
|
1227
|
+
}.should raise_error(ArgumentError, '+options[:reload]+ should be true or false, but was nil')
|
|
1228
|
+
end
|
|
1229
|
+
end
|
|
1230
|
+
end
|
|
1231
|
+
|
|
1232
|
+
describe 'with options' do
|
|
1233
|
+
describe 'that are unknown' do
|
|
1234
|
+
before :all do
|
|
1235
|
+
@options.update(@options.delete(:conditions))
|
|
1236
|
+
|
|
1237
|
+
@return = DataMapper::Query.new(@repository, @model, @options.freeze)
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1241
|
+
|
|
1242
|
+
it 'should set the conditions' do
|
|
1243
|
+
@return.conditions.should ==
|
|
1244
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
1245
|
+
:and,
|
|
1246
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
1247
|
+
:eql,
|
|
1248
|
+
@model.properties[:name],
|
|
1249
|
+
@conditions[:name]
|
|
1250
|
+
)
|
|
1251
|
+
)
|
|
1252
|
+
end
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
describe 'that are invalid' do
|
|
1256
|
+
it 'should raise an exception' do
|
|
1257
|
+
lambda {
|
|
1258
|
+
DataMapper::Query.new(@repository, @model, 'invalid')
|
|
1259
|
+
}.should raise_error(ArgumentError, '+options+ should be Hash, but was String')
|
|
1260
|
+
end
|
|
1261
|
+
end
|
|
1262
|
+
end
|
|
1263
|
+
|
|
1264
|
+
describe 'with no options' do
|
|
1265
|
+
before :all do
|
|
1266
|
+
@return = DataMapper::Query.new(@repository, @model)
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1270
|
+
|
|
1271
|
+
it 'should set options to an empty Hash' do
|
|
1272
|
+
@return.options.should == {}
|
|
1273
|
+
end
|
|
1274
|
+
end
|
|
1275
|
+
end
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
# instance methods
|
|
1279
|
+
describe DataMapper::Query do
|
|
1280
|
+
before :all do
|
|
1281
|
+
class ::User
|
|
1282
|
+
include DataMapper::Resource
|
|
1283
|
+
|
|
1284
|
+
property :name, String, :key => true
|
|
1285
|
+
property :citizenship, String
|
|
1286
|
+
|
|
1287
|
+
belongs_to :referrer, self, :nullable => true
|
|
1288
|
+
has n, :referrals, self, :inverse => :referrer
|
|
1289
|
+
|
|
1290
|
+
# TODO: figure out a way to remove this
|
|
1291
|
+
assert_valid
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
@repository = DataMapper::Repository.new(:default)
|
|
1295
|
+
@model = User
|
|
1296
|
+
@options = { :limit => 3 }
|
|
1297
|
+
@query = DataMapper::Query.new(@repository, @model, @options)
|
|
1298
|
+
@original = @query
|
|
1299
|
+
end
|
|
1300
|
+
|
|
1301
|
+
before :all do
|
|
1302
|
+
@other_options = {
|
|
1303
|
+
:fields => [ @model.properties[:name] ].freeze,
|
|
1304
|
+
:links => [ @model.relationships[:referrer] ].freeze,
|
|
1305
|
+
:conditions => [ 'name = ?', 'Dan Kubb' ].freeze,
|
|
1306
|
+
:offset => 1,
|
|
1307
|
+
:limit => 2,
|
|
1308
|
+
:order => [ DataMapper::Query::Direction.new(@model.properties[:name], :desc) ].freeze,
|
|
1309
|
+
:unique => true,
|
|
1310
|
+
:add_reversed => true,
|
|
1311
|
+
:reload => true,
|
|
1312
|
+
}
|
|
1313
|
+
end
|
|
1314
|
+
|
|
1315
|
+
it { @query.should respond_to(:==) }
|
|
1316
|
+
|
|
1317
|
+
describe '#==' do
|
|
1318
|
+
describe 'when other is equal' do
|
|
1319
|
+
before :all do
|
|
1320
|
+
@return = @query == @query
|
|
1321
|
+
end
|
|
1322
|
+
|
|
1323
|
+
it { @return.should be_true }
|
|
1324
|
+
end
|
|
1325
|
+
|
|
1326
|
+
describe 'when other is equivalent' do
|
|
1327
|
+
before :all do
|
|
1328
|
+
@return = @query == @query.dup
|
|
1329
|
+
end
|
|
1330
|
+
|
|
1331
|
+
it { @return.should be_true }
|
|
1332
|
+
end
|
|
1333
|
+
|
|
1334
|
+
DataMapper::Query::OPTIONS.each do |name|
|
|
1335
|
+
describe "when other has an inequalvalent #{name}" do
|
|
1336
|
+
before :all do
|
|
1337
|
+
@return = @query == @query.merge(name => @other_options[name])
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
it { @return.should be_false }
|
|
1341
|
+
end
|
|
1342
|
+
end
|
|
1343
|
+
|
|
1344
|
+
describe 'when other is a different type of object that can be compared, and is equivalent' do
|
|
1345
|
+
before :all do
|
|
1346
|
+
@other = OpenStruct.new(
|
|
1347
|
+
:repository => @query.repository,
|
|
1348
|
+
:model => @query.model,
|
|
1349
|
+
:sorted_fields => @query.sorted_fields,
|
|
1350
|
+
:links => @query.links,
|
|
1351
|
+
:conditions => @query.conditions,
|
|
1352
|
+
:order => @query.order,
|
|
1353
|
+
:limit => @query.limit,
|
|
1354
|
+
:offset => @query.offset,
|
|
1355
|
+
:reload? => @query.reload?,
|
|
1356
|
+
:unique? => @query.unique?,
|
|
1357
|
+
:add_reversed? => @query.add_reversed?
|
|
1358
|
+
)
|
|
1359
|
+
|
|
1360
|
+
@return = @query == @other
|
|
1361
|
+
end
|
|
1362
|
+
|
|
1363
|
+
it { @return.should be_true }
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
describe 'when other is a different type of object that can be compared, and is not equivalent' do
|
|
1367
|
+
before :all do
|
|
1368
|
+
@other = OpenStruct.new(
|
|
1369
|
+
:repository => @query.repository,
|
|
1370
|
+
:model => @query.model,
|
|
1371
|
+
:sorted_fields => @query.sorted_fields,
|
|
1372
|
+
:links => @query.links,
|
|
1373
|
+
:conditions => @query.conditions,
|
|
1374
|
+
:order => @query.order,
|
|
1375
|
+
:limit => @query.limit,
|
|
1376
|
+
:offset => @query.offset,
|
|
1377
|
+
:reload? => true,
|
|
1378
|
+
:unique? => @query.unique?,
|
|
1379
|
+
:add_reversed? => @query.add_reversed?
|
|
1380
|
+
)
|
|
1381
|
+
|
|
1382
|
+
@return = @query == @other
|
|
1383
|
+
end
|
|
1384
|
+
|
|
1385
|
+
it { @return.should be_false }
|
|
1386
|
+
end
|
|
1387
|
+
|
|
1388
|
+
describe 'when other is a different type of object that cannot be compared' do
|
|
1389
|
+
before :all do
|
|
1390
|
+
@return = @query == 'invalid'
|
|
1391
|
+
end
|
|
1392
|
+
|
|
1393
|
+
it { @return.should be_false }
|
|
1394
|
+
end
|
|
1395
|
+
end
|
|
1396
|
+
|
|
1397
|
+
it { @query.should respond_to(:conditions) }
|
|
1398
|
+
|
|
1399
|
+
describe '#conditions' do
|
|
1400
|
+
before :all do
|
|
1401
|
+
@query.update(:name => 'Dan Kubb')
|
|
1402
|
+
|
|
1403
|
+
@return = @query.conditions
|
|
1404
|
+
end
|
|
1405
|
+
|
|
1406
|
+
it { @return.should be_kind_of(DataMapper::Query::Conditions::AndOperation) }
|
|
1407
|
+
|
|
1408
|
+
it 'should return expected value' do
|
|
1409
|
+
@return.should ==
|
|
1410
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
1411
|
+
:and,
|
|
1412
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
1413
|
+
:eql,
|
|
1414
|
+
@model.properties[:name],
|
|
1415
|
+
'Dan Kubb'
|
|
1416
|
+
)
|
|
1417
|
+
)
|
|
1418
|
+
end
|
|
1419
|
+
end
|
|
1420
|
+
|
|
1421
|
+
it { @query.should respond_to(:dup) }
|
|
1422
|
+
|
|
1423
|
+
describe '#dup' do
|
|
1424
|
+
it 'should be awesome'
|
|
1425
|
+
end
|
|
1426
|
+
|
|
1427
|
+
it { @query.should respond_to(:eql?) }
|
|
1428
|
+
|
|
1429
|
+
describe '#eql?' do
|
|
1430
|
+
describe 'when other is equal' do
|
|
1431
|
+
before :all do
|
|
1432
|
+
@return = @query.eql?(@query)
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
it { @return.should be_true }
|
|
1436
|
+
end
|
|
1437
|
+
|
|
1438
|
+
describe 'when other is eql' do
|
|
1439
|
+
before :all do
|
|
1440
|
+
@return = @query.eql?(@query.dup)
|
|
1441
|
+
end
|
|
1442
|
+
|
|
1443
|
+
it { @return.should be_true }
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
DataMapper::Query::OPTIONS.each do |name|
|
|
1447
|
+
describe "when other has an not eql #{name}" do
|
|
1448
|
+
before :all do
|
|
1449
|
+
@return = @query.eql?(@query.merge(name => @other_options[name]))
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
it { @return.should be_false }
|
|
1453
|
+
end
|
|
1454
|
+
end
|
|
1455
|
+
|
|
1456
|
+
describe 'when other is a different type of object' do
|
|
1457
|
+
before :all do
|
|
1458
|
+
@other = OpenStruct.new(
|
|
1459
|
+
:repository => @query.repository,
|
|
1460
|
+
:model => @query.model,
|
|
1461
|
+
:sorted_fields => @query.sorted_fields,
|
|
1462
|
+
:links => @query.links,
|
|
1463
|
+
:conditions => @query.conditions,
|
|
1464
|
+
:order => @query.order,
|
|
1465
|
+
:limit => @query.limit,
|
|
1466
|
+
:offset => @query.offset,
|
|
1467
|
+
:reload? => @query.reload?,
|
|
1468
|
+
:unique? => @query.unique?,
|
|
1469
|
+
:add_reversed? => @query.add_reversed?
|
|
1470
|
+
)
|
|
1471
|
+
|
|
1472
|
+
@return = @query.eql?(@other)
|
|
1473
|
+
end
|
|
1474
|
+
|
|
1475
|
+
it { @return.should be_false }
|
|
1476
|
+
end
|
|
1477
|
+
end
|
|
1478
|
+
|
|
1479
|
+
it { @query.should respond_to(:fields) }
|
|
1480
|
+
|
|
1481
|
+
describe '#fields' do
|
|
1482
|
+
before :all do
|
|
1483
|
+
@return = @query.fields
|
|
1484
|
+
end
|
|
1485
|
+
|
|
1486
|
+
it { @return.should be_kind_of(Array) }
|
|
1487
|
+
|
|
1488
|
+
it 'should return expected value' do
|
|
1489
|
+
@return.should == [ @model.properties[:name], @model.properties[:citizenship], @model.properties[:referrer_name] ]
|
|
1490
|
+
end
|
|
1491
|
+
end
|
|
1492
|
+
|
|
1493
|
+
it { @query.should respond_to(:filter_records) }
|
|
1494
|
+
|
|
1495
|
+
supported_by :all do
|
|
1496
|
+
describe '#filter_records' do
|
|
1497
|
+
before :all do
|
|
1498
|
+
@john = { 'name' => 'John Doe', 'referrer_name' => nil }
|
|
1499
|
+
@sam = { 'name' => 'Sam Smoot', 'referrer_name' => nil }
|
|
1500
|
+
@dan = { 'name' => 'Dan Kubb', 'referrer_name' => 'Sam Smoot' }
|
|
1501
|
+
|
|
1502
|
+
@records = [ @john, @sam, @dan ]
|
|
1503
|
+
|
|
1504
|
+
@query.update(:name.not => @sam['name'])
|
|
1505
|
+
|
|
1506
|
+
@return = @query.filter_records(@records)
|
|
1507
|
+
end
|
|
1508
|
+
|
|
1509
|
+
it 'should return Enumerable' do
|
|
1510
|
+
@return.should be_kind_of(Enumerable)
|
|
1511
|
+
end
|
|
1512
|
+
|
|
1513
|
+
it 'should not be the records provided' do
|
|
1514
|
+
@return.should_not equal(@records)
|
|
1515
|
+
end
|
|
1516
|
+
|
|
1517
|
+
it 'should return expected values' do
|
|
1518
|
+
@return.should == [ @dan, @john ]
|
|
1519
|
+
end
|
|
1520
|
+
end
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
it { @query.should respond_to(:inspect) }
|
|
1524
|
+
|
|
1525
|
+
describe '#inspect' do
|
|
1526
|
+
before :all do
|
|
1527
|
+
@return = @query.inspect
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
it 'should return expected value' do
|
|
1531
|
+
@return.should == <<-INSPECT.compress_lines
|
|
1532
|
+
#<DataMapper::Query
|
|
1533
|
+
@repository=:default
|
|
1534
|
+
@model=User
|
|
1535
|
+
@fields=[#<DataMapper::Property @model=User @name=:name>, #<DataMapper::Property @model=User @name=:citizenship>, #<DataMapper::Property @model=User @name=:referrer_name>]
|
|
1536
|
+
@links=[]
|
|
1537
|
+
@conditions=nil
|
|
1538
|
+
@order=[#<DataMapper::Query::Direction @target=#<DataMapper::Property @model=User @name=:name> @operator=:asc>]
|
|
1539
|
+
@limit=3
|
|
1540
|
+
@offset=0
|
|
1541
|
+
@reload=false
|
|
1542
|
+
@unique=false>
|
|
1543
|
+
INSPECT
|
|
1544
|
+
end
|
|
1545
|
+
end
|
|
1546
|
+
|
|
1547
|
+
it { @query.should respond_to(:limit) }
|
|
1548
|
+
|
|
1549
|
+
describe '#limit' do
|
|
1550
|
+
before :all do
|
|
1551
|
+
@return = @query.limit
|
|
1552
|
+
end
|
|
1553
|
+
|
|
1554
|
+
it { @return.should be_kind_of(Integer) }
|
|
1555
|
+
|
|
1556
|
+
it 'should return expected value' do
|
|
1557
|
+
@return.should == 3
|
|
1558
|
+
end
|
|
1559
|
+
end
|
|
1560
|
+
|
|
1561
|
+
it { @query.should respond_to(:limit_records) }
|
|
1562
|
+
|
|
1563
|
+
supported_by :all do
|
|
1564
|
+
describe '#limit_records' do
|
|
1565
|
+
before :all do
|
|
1566
|
+
@john = { 'name' => 'John Doe', 'referrer_name' => nil }
|
|
1567
|
+
@sam = { 'name' => 'Sam Smoot', 'referrer_name' => nil }
|
|
1568
|
+
@dan = { 'name' => 'Dan Kubb', 'referrer_name' => 'Sam Smoot' }
|
|
1569
|
+
|
|
1570
|
+
@records = [ @john, @sam, @dan ]
|
|
1571
|
+
|
|
1572
|
+
@query.update(:limit => 1, :offset => 1)
|
|
1573
|
+
|
|
1574
|
+
@return = @query.limit_records(@records)
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1577
|
+
it 'should return Enumerable' do
|
|
1578
|
+
@return.should be_kind_of(Enumerable)
|
|
1579
|
+
end
|
|
1580
|
+
|
|
1581
|
+
it 'should not be the records provided' do
|
|
1582
|
+
@return.should_not equal(@records)
|
|
1583
|
+
end
|
|
1584
|
+
|
|
1585
|
+
it 'should return expected values' do
|
|
1586
|
+
@return.should == [ @sam ]
|
|
1587
|
+
end
|
|
1588
|
+
end
|
|
1589
|
+
end
|
|
1590
|
+
|
|
1591
|
+
it { @query.should respond_to(:links) }
|
|
1592
|
+
|
|
1593
|
+
describe '#links' do
|
|
1594
|
+
before :all do
|
|
1595
|
+
@return = @query.links
|
|
1596
|
+
end
|
|
1597
|
+
|
|
1598
|
+
it { @return.should be_kind_of(Array) }
|
|
1599
|
+
|
|
1600
|
+
it { @return.should be_empty }
|
|
1601
|
+
end
|
|
1602
|
+
|
|
1603
|
+
it { @query.should respond_to(:match_records) }
|
|
1604
|
+
|
|
1605
|
+
supported_by :all do
|
|
1606
|
+
describe '#match_records' do
|
|
1607
|
+
before :all do
|
|
1608
|
+
@john = { 'name' => 'John Doe', 'referrer_name' => nil }
|
|
1609
|
+
@sam = { 'name' => 'Sam Smoot', 'referrer_name' => nil }
|
|
1610
|
+
@dan = { 'name' => 'Dan Kubb', 'referrer_name' => 'Sam Smoot' }
|
|
1611
|
+
|
|
1612
|
+
@records = [ @john, @sam, @dan ]
|
|
1613
|
+
|
|
1614
|
+
@query.update(:name.not => @sam['name'])
|
|
1615
|
+
|
|
1616
|
+
@return = @query.match_records(@records)
|
|
1617
|
+
end
|
|
1618
|
+
|
|
1619
|
+
it 'should return Enumerable' do
|
|
1620
|
+
@return.should be_kind_of(Enumerable)
|
|
1621
|
+
end
|
|
1622
|
+
|
|
1623
|
+
it 'should not be the records provided' do
|
|
1624
|
+
@return.should_not equal(@records)
|
|
1625
|
+
end
|
|
1626
|
+
|
|
1627
|
+
it 'should return expected values' do
|
|
1628
|
+
@return.should == [ @john, @dan ]
|
|
1629
|
+
end
|
|
1630
|
+
end
|
|
1631
|
+
end
|
|
1632
|
+
|
|
1633
|
+
it { @query.should respond_to(:merge) }
|
|
1634
|
+
|
|
1635
|
+
describe '#merge' do
|
|
1636
|
+
describe "with a Hash" do
|
|
1637
|
+
before(:each) do
|
|
1638
|
+
@return = @query.merge({ :limit => 202 })
|
|
1639
|
+
end
|
|
1640
|
+
|
|
1641
|
+
it "does not affect the receiver" do
|
|
1642
|
+
@query.options[:limit].should == 3
|
|
1643
|
+
end
|
|
1644
|
+
end
|
|
1645
|
+
|
|
1646
|
+
describe "with a Query" do
|
|
1647
|
+
before(:each) do
|
|
1648
|
+
@other = DataMapper::Query.new(@repository, @model, @options.update(@other_options))
|
|
1649
|
+
@return = @query.merge(@other)
|
|
1650
|
+
end
|
|
1651
|
+
|
|
1652
|
+
it "does not affect the receiver" do
|
|
1653
|
+
@query.options[:limit].should == 3
|
|
1654
|
+
end
|
|
1655
|
+
end
|
|
1656
|
+
end
|
|
1657
|
+
|
|
1658
|
+
it { @query.should respond_to(:model) }
|
|
1659
|
+
|
|
1660
|
+
describe '#model' do
|
|
1661
|
+
before :all do
|
|
1662
|
+
@return = @query.model
|
|
1663
|
+
end
|
|
1664
|
+
|
|
1665
|
+
it { @return.should be_kind_of(Class) }
|
|
1666
|
+
|
|
1667
|
+
it 'should return expected value' do
|
|
1668
|
+
@return.should == @model
|
|
1669
|
+
end
|
|
1670
|
+
end
|
|
1671
|
+
|
|
1672
|
+
it { @query.should respond_to(:offset) }
|
|
1673
|
+
|
|
1674
|
+
describe '#offset' do
|
|
1675
|
+
before :all do
|
|
1676
|
+
@return = @query.offset
|
|
1677
|
+
end
|
|
1678
|
+
|
|
1679
|
+
it { @return.should be_kind_of(Integer) }
|
|
1680
|
+
|
|
1681
|
+
it 'should return expected value' do
|
|
1682
|
+
@return.should == 0
|
|
1683
|
+
end
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
it { @query.should respond_to(:order) }
|
|
1687
|
+
|
|
1688
|
+
describe '#order' do
|
|
1689
|
+
before :all do
|
|
1690
|
+
@return = @query.order
|
|
1691
|
+
end
|
|
1692
|
+
|
|
1693
|
+
it { @return.should be_kind_of(Array) }
|
|
1694
|
+
|
|
1695
|
+
it 'should return expected value' do
|
|
1696
|
+
@return.should == [ DataMapper::Query::Direction.new(@model.properties[:name]) ]
|
|
1697
|
+
end
|
|
1698
|
+
end
|
|
1699
|
+
|
|
1700
|
+
it { @query.should respond_to(:raw?) }
|
|
1701
|
+
|
|
1702
|
+
describe '#raw?' do
|
|
1703
|
+
describe 'when the query contains raw conditions' do
|
|
1704
|
+
before :all do
|
|
1705
|
+
@query.update(:conditions => [ 'name = ?', 'Dan Kubb' ])
|
|
1706
|
+
end
|
|
1707
|
+
|
|
1708
|
+
it { @query.should be_raw }
|
|
1709
|
+
end
|
|
1710
|
+
|
|
1711
|
+
describe 'when the query does not contain raw conditions' do
|
|
1712
|
+
it { @query.should_not be_raw }
|
|
1713
|
+
end
|
|
1714
|
+
end
|
|
1715
|
+
|
|
1716
|
+
it { @query.should respond_to(:relative) }
|
|
1717
|
+
|
|
1718
|
+
describe '#relative' do
|
|
1719
|
+
describe 'with a Hash' do
|
|
1720
|
+
describe 'that is empty' do
|
|
1721
|
+
before :all do
|
|
1722
|
+
@return = @query.relative({})
|
|
1723
|
+
end
|
|
1724
|
+
|
|
1725
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1726
|
+
|
|
1727
|
+
it 'should not return self' do
|
|
1728
|
+
@return.should_not equal(@query)
|
|
1729
|
+
end
|
|
1730
|
+
|
|
1731
|
+
it 'should return a copy' do
|
|
1732
|
+
@return.should be_eql(@query)
|
|
1733
|
+
end
|
|
1734
|
+
end
|
|
1735
|
+
|
|
1736
|
+
describe 'using a different repository as a Repository' do
|
|
1737
|
+
before :all do
|
|
1738
|
+
@repository = DataMapper::Repository.new(:other)
|
|
1739
|
+
@return = @query.relative(:repository => @repository)
|
|
1740
|
+
end
|
|
1741
|
+
|
|
1742
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1743
|
+
|
|
1744
|
+
it 'should not return self' do
|
|
1745
|
+
@return.should_not equal(@original)
|
|
1746
|
+
end
|
|
1747
|
+
|
|
1748
|
+
it 'should set the repository' do
|
|
1749
|
+
@return.repository.should equal(@repository)
|
|
1750
|
+
end
|
|
1751
|
+
end
|
|
1752
|
+
|
|
1753
|
+
describe 'using a different repository as a Symbol' do
|
|
1754
|
+
before :all do
|
|
1755
|
+
@other_adapter = DataMapper.setup(:other, :adapter => :in_memory)
|
|
1756
|
+
|
|
1757
|
+
@return = @query.relative(:repository => :other)
|
|
1758
|
+
end
|
|
1759
|
+
|
|
1760
|
+
after :all do
|
|
1761
|
+
DataMapper::Repository.adapters.delete(@other_adapter.name)
|
|
1762
|
+
end
|
|
1763
|
+
|
|
1764
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1765
|
+
|
|
1766
|
+
it 'should not return self' do
|
|
1767
|
+
@return.should_not equal(@original)
|
|
1768
|
+
end
|
|
1769
|
+
|
|
1770
|
+
it 'should set the repository' do
|
|
1771
|
+
@return.repository.should == DataMapper::Repository.new(:other)
|
|
1772
|
+
end
|
|
1773
|
+
end
|
|
1774
|
+
|
|
1775
|
+
describe 'using different options' do
|
|
1776
|
+
before :all do
|
|
1777
|
+
@return = @query.relative(@other_options)
|
|
1778
|
+
end
|
|
1779
|
+
|
|
1780
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1781
|
+
|
|
1782
|
+
it 'should not return self' do
|
|
1783
|
+
@return.should_not equal(@original)
|
|
1784
|
+
end
|
|
1785
|
+
|
|
1786
|
+
it 'should update the fields' do
|
|
1787
|
+
@return.fields.should == @other_options[:fields]
|
|
1788
|
+
end
|
|
1789
|
+
|
|
1790
|
+
it 'should update the links' do
|
|
1791
|
+
@return.links.should == @other_options[:links]
|
|
1792
|
+
end
|
|
1793
|
+
|
|
1794
|
+
it 'should update the conditions' do
|
|
1795
|
+
@return.conditions.should == DataMapper::Query::Conditions::Operation.new(:and, [ 'name = ?', [ 'Dan Kubb' ] ])
|
|
1796
|
+
end
|
|
1797
|
+
|
|
1798
|
+
it 'should update the offset' do
|
|
1799
|
+
@return.offset.should == @other_options[:offset]
|
|
1800
|
+
end
|
|
1801
|
+
|
|
1802
|
+
it 'should update the limit' do
|
|
1803
|
+
@return.limit.should == @other_options[:limit]
|
|
1804
|
+
end
|
|
1805
|
+
|
|
1806
|
+
it 'should update the order' do
|
|
1807
|
+
@return.order.should == @other_options[:order]
|
|
1808
|
+
end
|
|
1809
|
+
|
|
1810
|
+
it 'should update the unique' do
|
|
1811
|
+
@return.unique?.should == @other_options[:unique]
|
|
1812
|
+
end
|
|
1813
|
+
|
|
1814
|
+
it 'should update the add_reversed' do
|
|
1815
|
+
@return.add_reversed?.should == @other_options[:add_reversed]
|
|
1816
|
+
end
|
|
1817
|
+
|
|
1818
|
+
it 'should update the reload' do
|
|
1819
|
+
@return.reload?.should == @other_options[:reload]
|
|
1820
|
+
end
|
|
1821
|
+
end
|
|
1822
|
+
|
|
1823
|
+
describe 'using extra options' do
|
|
1824
|
+
before :all do
|
|
1825
|
+
@options = { :name => 'Dan Kubb' }
|
|
1826
|
+
|
|
1827
|
+
@return = @query.relative(@options)
|
|
1828
|
+
end
|
|
1829
|
+
|
|
1830
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1831
|
+
|
|
1832
|
+
it 'should not return self' do
|
|
1833
|
+
@return.should_not equal(@original)
|
|
1834
|
+
end
|
|
1835
|
+
|
|
1836
|
+
it 'should update the conditions' do
|
|
1837
|
+
@return.conditions.should ==
|
|
1838
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
1839
|
+
:and,
|
|
1840
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
1841
|
+
:eql,
|
|
1842
|
+
@model.properties[:name],
|
|
1843
|
+
@options[:name]
|
|
1844
|
+
)
|
|
1845
|
+
)
|
|
1846
|
+
end
|
|
1847
|
+
end
|
|
1848
|
+
|
|
1849
|
+
describe 'using an offset when query offset is greater than 0' do
|
|
1850
|
+
before :all do
|
|
1851
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
1852
|
+
|
|
1853
|
+
@return = @query.relative(:offset => 1)
|
|
1854
|
+
end
|
|
1855
|
+
|
|
1856
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1857
|
+
|
|
1858
|
+
it 'should not return self' do
|
|
1859
|
+
@return.should_not equal(@original)
|
|
1860
|
+
end
|
|
1861
|
+
|
|
1862
|
+
it 'should update the offset to be relative to the original offset' do
|
|
1863
|
+
@return.offset.should == 2
|
|
1864
|
+
end
|
|
1865
|
+
end
|
|
1866
|
+
|
|
1867
|
+
describe 'using an limit when query limit specified' do
|
|
1868
|
+
before :all do
|
|
1869
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
1870
|
+
|
|
1871
|
+
@return = @query.relative(:limit => 1)
|
|
1872
|
+
end
|
|
1873
|
+
|
|
1874
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1875
|
+
|
|
1876
|
+
it 'should not return self' do
|
|
1877
|
+
@return.should_not equal(@original)
|
|
1878
|
+
end
|
|
1879
|
+
|
|
1880
|
+
it 'should update the limit' do
|
|
1881
|
+
@return.limit.should == 1
|
|
1882
|
+
end
|
|
1883
|
+
end
|
|
1884
|
+
end
|
|
1885
|
+
end
|
|
1886
|
+
|
|
1887
|
+
it { @query.should respond_to(:reload?) }
|
|
1888
|
+
|
|
1889
|
+
describe '#reload?' do
|
|
1890
|
+
describe 'when the query should reload' do
|
|
1891
|
+
before :all do
|
|
1892
|
+
@query.update(:reload => true)
|
|
1893
|
+
end
|
|
1894
|
+
|
|
1895
|
+
it { @query.should be_reload }
|
|
1896
|
+
end
|
|
1897
|
+
|
|
1898
|
+
describe 'when the query should not reload' do
|
|
1899
|
+
it { @query.should_not be_reload }
|
|
1900
|
+
end
|
|
1901
|
+
end
|
|
1902
|
+
|
|
1903
|
+
it { @query.should respond_to(:repository) }
|
|
1904
|
+
|
|
1905
|
+
describe '#repository' do
|
|
1906
|
+
before :all do
|
|
1907
|
+
@return = @query.repository
|
|
1908
|
+
end
|
|
1909
|
+
|
|
1910
|
+
it { @return.should be_kind_of(DataMapper::Repository) }
|
|
1911
|
+
|
|
1912
|
+
it 'should return expected value' do
|
|
1913
|
+
@return.should == @repository
|
|
1914
|
+
end
|
|
1915
|
+
end
|
|
1916
|
+
|
|
1917
|
+
it { @query.should respond_to(:reverse) }
|
|
1918
|
+
|
|
1919
|
+
describe '#reverse' do
|
|
1920
|
+
before :all do
|
|
1921
|
+
@return = @query.reverse
|
|
1922
|
+
end
|
|
1923
|
+
|
|
1924
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1925
|
+
|
|
1926
|
+
it 'should copy the Query' do
|
|
1927
|
+
@return.should_not equal(@original)
|
|
1928
|
+
end
|
|
1929
|
+
|
|
1930
|
+
# TODO: push this into dup spec
|
|
1931
|
+
it 'should not reference original order' do
|
|
1932
|
+
@return.order.should_not equal(@original.order)
|
|
1933
|
+
end
|
|
1934
|
+
|
|
1935
|
+
it 'should have a reversed order' do
|
|
1936
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name], :desc) ]
|
|
1937
|
+
end
|
|
1938
|
+
|
|
1939
|
+
[ :repository, :model, :fields, :links, :conditions, :offset, :limit, :unique?, :add_reversed?, :reload? ].each do |attribute|
|
|
1940
|
+
it "should have an equivalent #{attribute}" do
|
|
1941
|
+
@return.send(attribute).should == @original.send(attribute)
|
|
1942
|
+
end
|
|
1943
|
+
end
|
|
1944
|
+
end
|
|
1945
|
+
|
|
1946
|
+
it { @query.should respond_to(:reverse!) }
|
|
1947
|
+
|
|
1948
|
+
describe '#reverse!' do
|
|
1949
|
+
before :all do
|
|
1950
|
+
@return = @query.reverse!
|
|
1951
|
+
end
|
|
1952
|
+
|
|
1953
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1954
|
+
|
|
1955
|
+
it { @return.should equal(@original) }
|
|
1956
|
+
|
|
1957
|
+
it 'should have a reversed order' do
|
|
1958
|
+
@return.order.should == [ DataMapper::Query::Direction.new(@model.properties[:name], :desc) ]
|
|
1959
|
+
end
|
|
1960
|
+
end
|
|
1961
|
+
|
|
1962
|
+
[ :slice, :[] ].each do |method|
|
|
1963
|
+
it { @query.should respond_to(method) }
|
|
1964
|
+
|
|
1965
|
+
describe "##{method}" do
|
|
1966
|
+
describe 'with a positive offset' do
|
|
1967
|
+
before :all do
|
|
1968
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
1969
|
+
|
|
1970
|
+
@return = @query.send(method, 1)
|
|
1971
|
+
end
|
|
1972
|
+
|
|
1973
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1974
|
+
|
|
1975
|
+
it 'should not return self' do
|
|
1976
|
+
@return.should_not equal(@original)
|
|
1977
|
+
end
|
|
1978
|
+
|
|
1979
|
+
it 'should update the offset to be relative to the original offset' do
|
|
1980
|
+
@return.offset.should == 2
|
|
1981
|
+
end
|
|
1982
|
+
|
|
1983
|
+
it 'should update the limit to 1' do
|
|
1984
|
+
@return.limit.should == 1
|
|
1985
|
+
end
|
|
1986
|
+
end
|
|
1987
|
+
|
|
1988
|
+
describe 'with a positive offset and length' do
|
|
1989
|
+
before :all do
|
|
1990
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
1991
|
+
|
|
1992
|
+
@return = @query.send(method, 1, 1)
|
|
1993
|
+
end
|
|
1994
|
+
|
|
1995
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
1996
|
+
|
|
1997
|
+
it 'should not return self' do
|
|
1998
|
+
@return.should_not equal(@original)
|
|
1999
|
+
end
|
|
2000
|
+
|
|
2001
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2002
|
+
@return.offset.should == 2
|
|
2003
|
+
end
|
|
2004
|
+
|
|
2005
|
+
it 'should update the limit' do
|
|
2006
|
+
@return.limit.should == 1
|
|
2007
|
+
end
|
|
2008
|
+
end
|
|
2009
|
+
|
|
2010
|
+
describe 'with a positive range' do
|
|
2011
|
+
before :all do
|
|
2012
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2013
|
+
|
|
2014
|
+
@return = @query.send(method, 1..2)
|
|
2015
|
+
end
|
|
2016
|
+
|
|
2017
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2018
|
+
|
|
2019
|
+
it 'should not return self' do
|
|
2020
|
+
@return.should_not equal(@original)
|
|
2021
|
+
end
|
|
2022
|
+
|
|
2023
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2024
|
+
@return.offset.should == 2
|
|
2025
|
+
end
|
|
2026
|
+
|
|
2027
|
+
it 'should update the limit' do
|
|
2028
|
+
@return.limit.should == 2
|
|
2029
|
+
end
|
|
2030
|
+
end
|
|
2031
|
+
|
|
2032
|
+
describe 'with a negative offset' do
|
|
2033
|
+
before :all do
|
|
2034
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2035
|
+
|
|
2036
|
+
@return = @query.send(method, -1)
|
|
2037
|
+
end
|
|
2038
|
+
|
|
2039
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2040
|
+
|
|
2041
|
+
it 'should not return self' do
|
|
2042
|
+
@return.should_not equal(@original)
|
|
2043
|
+
end
|
|
2044
|
+
|
|
2045
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2046
|
+
pending "TODO: update Query##{method} handle negative offset" do
|
|
2047
|
+
@return.offset.should == 2
|
|
2048
|
+
end
|
|
2049
|
+
end
|
|
2050
|
+
|
|
2051
|
+
it 'should update the limit to 1' do
|
|
2052
|
+
@return.limit.should == 1
|
|
2053
|
+
end
|
|
2054
|
+
end
|
|
2055
|
+
|
|
2056
|
+
describe 'with a negative offset and length' do
|
|
2057
|
+
before :all do
|
|
2058
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2059
|
+
|
|
2060
|
+
@return = @query.send(method, -1, 1)
|
|
2061
|
+
end
|
|
2062
|
+
|
|
2063
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2064
|
+
|
|
2065
|
+
it 'should not return self' do
|
|
2066
|
+
@return.should_not equal(@original)
|
|
2067
|
+
end
|
|
2068
|
+
|
|
2069
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2070
|
+
pending "TODO: update Query##{method} handle negative offset and length" do
|
|
2071
|
+
@return.offset.should == 2
|
|
2072
|
+
end
|
|
2073
|
+
end
|
|
2074
|
+
|
|
2075
|
+
it 'should update the limit to 1' do
|
|
2076
|
+
@return.limit.should == 1
|
|
2077
|
+
end
|
|
2078
|
+
end
|
|
2079
|
+
|
|
2080
|
+
describe 'with a negative range' do
|
|
2081
|
+
before :all do
|
|
2082
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2083
|
+
|
|
2084
|
+
rescue_if "TODO: update Query##{method} handle negative range" do
|
|
2085
|
+
@return = @query.send(method, -2..-1)
|
|
2086
|
+
end
|
|
2087
|
+
end
|
|
2088
|
+
|
|
2089
|
+
before do
|
|
2090
|
+
pending_if "TODO: update Query##{method} handle negative range", !defined?(@return)
|
|
2091
|
+
end
|
|
2092
|
+
|
|
2093
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2094
|
+
|
|
2095
|
+
it 'should not return self' do
|
|
2096
|
+
@return.should_not equal(@original)
|
|
2097
|
+
end
|
|
2098
|
+
|
|
2099
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2100
|
+
@return.offset.should == 2
|
|
2101
|
+
end
|
|
2102
|
+
|
|
2103
|
+
it 'should update the limit to 1' do
|
|
2104
|
+
@return.limit.should == 2
|
|
2105
|
+
end
|
|
2106
|
+
end
|
|
2107
|
+
|
|
2108
|
+
describe 'with an offset not within range' do
|
|
2109
|
+
before :all do
|
|
2110
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2111
|
+
end
|
|
2112
|
+
|
|
2113
|
+
it 'should raise an exception' do
|
|
2114
|
+
lambda {
|
|
2115
|
+
@query.send(method, 12)
|
|
2116
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2117
|
+
end
|
|
2118
|
+
end
|
|
2119
|
+
|
|
2120
|
+
describe 'with an offset and length not within range' do
|
|
2121
|
+
before :all do
|
|
2122
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2123
|
+
end
|
|
2124
|
+
|
|
2125
|
+
it 'should raise an exception' do
|
|
2126
|
+
lambda {
|
|
2127
|
+
@query.send(method, 12, 1)
|
|
2128
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2129
|
+
end
|
|
2130
|
+
end
|
|
2131
|
+
|
|
2132
|
+
describe 'with a range not within range' do
|
|
2133
|
+
before :all do
|
|
2134
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2135
|
+
end
|
|
2136
|
+
|
|
2137
|
+
it 'should raise an exception' do
|
|
2138
|
+
lambda {
|
|
2139
|
+
@query.send(method, 12..12)
|
|
2140
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2141
|
+
end
|
|
2142
|
+
end
|
|
2143
|
+
|
|
2144
|
+
describe 'with invalid arguments' do
|
|
2145
|
+
it 'should raise an exception' do
|
|
2146
|
+
lambda {
|
|
2147
|
+
@query.send(method, 'invalid')
|
|
2148
|
+
}.should raise_error(ArgumentError, 'arguments may be 1 or 2 Integers, or 1 Range object, was: ["invalid"]')
|
|
2149
|
+
end
|
|
2150
|
+
end
|
|
2151
|
+
end
|
|
2152
|
+
end
|
|
2153
|
+
|
|
2154
|
+
it { @query.should respond_to(:slice!) }
|
|
2155
|
+
|
|
2156
|
+
describe '#slice!' do
|
|
2157
|
+
describe 'with a positive offset' do
|
|
2158
|
+
before :all do
|
|
2159
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2160
|
+
|
|
2161
|
+
@return = @query.slice!(1)
|
|
2162
|
+
end
|
|
2163
|
+
|
|
2164
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2165
|
+
|
|
2166
|
+
it 'should return self' do
|
|
2167
|
+
@return.should equal(@original)
|
|
2168
|
+
end
|
|
2169
|
+
|
|
2170
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2171
|
+
@return.offset.should == 2
|
|
2172
|
+
end
|
|
2173
|
+
|
|
2174
|
+
it 'should update the limit to 1' do
|
|
2175
|
+
@return.limit.should == 1
|
|
2176
|
+
end
|
|
2177
|
+
end
|
|
2178
|
+
|
|
2179
|
+
describe 'with a positive offset and length' do
|
|
2180
|
+
before :all do
|
|
2181
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2182
|
+
|
|
2183
|
+
@return = @query.slice!(1, 1)
|
|
2184
|
+
end
|
|
2185
|
+
|
|
2186
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2187
|
+
|
|
2188
|
+
it 'should return self' do
|
|
2189
|
+
@return.should equal(@original)
|
|
2190
|
+
end
|
|
2191
|
+
|
|
2192
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2193
|
+
@return.offset.should == 2
|
|
2194
|
+
end
|
|
2195
|
+
|
|
2196
|
+
it 'should update the limit' do
|
|
2197
|
+
@return.limit.should == 1
|
|
2198
|
+
end
|
|
2199
|
+
end
|
|
2200
|
+
|
|
2201
|
+
describe 'with a positive range' do
|
|
2202
|
+
before :all do
|
|
2203
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2204
|
+
|
|
2205
|
+
@return = @query.slice!(1..2)
|
|
2206
|
+
end
|
|
2207
|
+
|
|
2208
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2209
|
+
|
|
2210
|
+
it 'should return self' do
|
|
2211
|
+
@return.should equal(@original)
|
|
2212
|
+
end
|
|
2213
|
+
|
|
2214
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2215
|
+
@return.offset.should == 2
|
|
2216
|
+
end
|
|
2217
|
+
|
|
2218
|
+
it 'should update the limit' do
|
|
2219
|
+
@return.limit.should == 2
|
|
2220
|
+
end
|
|
2221
|
+
end
|
|
2222
|
+
|
|
2223
|
+
describe 'with a negative offset' do
|
|
2224
|
+
before :all do
|
|
2225
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2226
|
+
|
|
2227
|
+
@return = @query.slice!(-1)
|
|
2228
|
+
end
|
|
2229
|
+
|
|
2230
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2231
|
+
|
|
2232
|
+
it 'should return self' do
|
|
2233
|
+
@return.should equal(@original)
|
|
2234
|
+
end
|
|
2235
|
+
|
|
2236
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2237
|
+
pending 'TODO: update Query#slice! handle negative offset' do
|
|
2238
|
+
@return.offset.should == 2
|
|
2239
|
+
end
|
|
2240
|
+
end
|
|
2241
|
+
|
|
2242
|
+
it 'should update the limit to 1' do
|
|
2243
|
+
@return.limit.should == 1
|
|
2244
|
+
end
|
|
2245
|
+
end
|
|
2246
|
+
|
|
2247
|
+
describe 'with a negative offset and length' do
|
|
2248
|
+
before :all do
|
|
2249
|
+
@query = @query.update(:offset => 1, :limit => 2)
|
|
2250
|
+
|
|
2251
|
+
@return = @query.slice!(-1, 1)
|
|
2252
|
+
end
|
|
2253
|
+
|
|
2254
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2255
|
+
|
|
2256
|
+
it 'should return self' do
|
|
2257
|
+
@return.should equal(@original)
|
|
2258
|
+
end
|
|
2259
|
+
|
|
2260
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2261
|
+
pending 'TODO: update Query#slice! handle negative offset and length' do
|
|
2262
|
+
@return.offset.should == 2
|
|
2263
|
+
end
|
|
2264
|
+
end
|
|
2265
|
+
|
|
2266
|
+
it 'should update the limit to 1' do
|
|
2267
|
+
@return.limit.should == 1
|
|
2268
|
+
end
|
|
2269
|
+
end
|
|
2270
|
+
|
|
2271
|
+
describe 'with a negative range' do
|
|
2272
|
+
before :all do
|
|
2273
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2274
|
+
|
|
2275
|
+
rescue_if 'TODO: update Query#slice! handle negative range' do
|
|
2276
|
+
@return = @query.slice!(-2..-1)
|
|
2277
|
+
end
|
|
2278
|
+
end
|
|
2279
|
+
|
|
2280
|
+
before do
|
|
2281
|
+
pending_if 'TODO: update Query#slice! handle negative range', !defined?(@return)
|
|
2282
|
+
end
|
|
2283
|
+
|
|
2284
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2285
|
+
|
|
2286
|
+
it 'should return self' do
|
|
2287
|
+
@return.should equal(@original)
|
|
2288
|
+
end
|
|
2289
|
+
|
|
2290
|
+
it 'should update the offset to be relative to the original offset' do
|
|
2291
|
+
@return.offset.should == 2
|
|
2292
|
+
end
|
|
2293
|
+
|
|
2294
|
+
it 'should update the limit to 1' do
|
|
2295
|
+
@return.limit.should == 2
|
|
2296
|
+
end
|
|
2297
|
+
end
|
|
2298
|
+
|
|
2299
|
+
describe 'with an offset not within range' do
|
|
2300
|
+
before :all do
|
|
2301
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2302
|
+
end
|
|
2303
|
+
|
|
2304
|
+
it 'should raise an exception' do
|
|
2305
|
+
lambda {
|
|
2306
|
+
@query.slice!(12)
|
|
2307
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2308
|
+
end
|
|
2309
|
+
end
|
|
2310
|
+
|
|
2311
|
+
describe 'with an offset and length not within range' do
|
|
2312
|
+
before :all do
|
|
2313
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2314
|
+
end
|
|
2315
|
+
|
|
2316
|
+
it 'should raise an exception' do
|
|
2317
|
+
lambda {
|
|
2318
|
+
@query.slice!(12, 1)
|
|
2319
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2320
|
+
end
|
|
2321
|
+
end
|
|
2322
|
+
|
|
2323
|
+
describe 'with a range not within range' do
|
|
2324
|
+
before :all do
|
|
2325
|
+
@query = @query.update(:offset => 1, :limit => 3)
|
|
2326
|
+
end
|
|
2327
|
+
|
|
2328
|
+
it 'should raise an exception' do
|
|
2329
|
+
lambda {
|
|
2330
|
+
@query.slice!(12..12)
|
|
2331
|
+
}.should raise_error(RangeError, 'offset 12 and limit 1 are outside allowed range')
|
|
2332
|
+
end
|
|
2333
|
+
end
|
|
2334
|
+
|
|
2335
|
+
describe 'with invalid arguments' do
|
|
2336
|
+
it 'should raise an exception' do
|
|
2337
|
+
lambda {
|
|
2338
|
+
@query.slice!('invalid')
|
|
2339
|
+
}.should raise_error(ArgumentError, 'arguments may be 1 or 2 Integers, or 1 Range object, was: ["invalid"]')
|
|
2340
|
+
end
|
|
2341
|
+
end
|
|
2342
|
+
end
|
|
2343
|
+
|
|
2344
|
+
it { @query.should respond_to(:sort_records) }
|
|
2345
|
+
|
|
2346
|
+
supported_by :all do
|
|
2347
|
+
describe '#sort_records' do
|
|
2348
|
+
before :all do
|
|
2349
|
+
@john = { 'name' => 'John Doe', 'referrer_name' => nil }
|
|
2350
|
+
@sam = { 'name' => 'Sam Smoot', 'referrer_name' => nil }
|
|
2351
|
+
@dan = { 'name' => 'Dan Kubb', 'referrer_name' => 'Sam Smoot' }
|
|
2352
|
+
|
|
2353
|
+
@records = [ @john, @sam, @dan ]
|
|
2354
|
+
|
|
2355
|
+
@query.update(:order => [ :name ])
|
|
2356
|
+
|
|
2357
|
+
@return = @query.sort_records(@records)
|
|
2358
|
+
end
|
|
2359
|
+
|
|
2360
|
+
it 'should return Enumerable' do
|
|
2361
|
+
@return.should be_kind_of(Enumerable)
|
|
2362
|
+
end
|
|
2363
|
+
|
|
2364
|
+
it 'should not be the records provided' do
|
|
2365
|
+
@return.should_not equal(@records)
|
|
2366
|
+
end
|
|
2367
|
+
|
|
2368
|
+
it 'should return expected values' do
|
|
2369
|
+
@return.should == [ @dan, @john, @sam ]
|
|
2370
|
+
end
|
|
2371
|
+
end
|
|
2372
|
+
end
|
|
2373
|
+
|
|
2374
|
+
it { @query.should respond_to(:unique?) }
|
|
2375
|
+
|
|
2376
|
+
describe '#unique?' do
|
|
2377
|
+
describe 'when the query is unique' do
|
|
2378
|
+
before :all do
|
|
2379
|
+
@query.update(:unique => true)
|
|
2380
|
+
end
|
|
2381
|
+
|
|
2382
|
+
it { @query.should be_unique }
|
|
2383
|
+
end
|
|
2384
|
+
|
|
2385
|
+
describe 'when the query is not unique' do
|
|
2386
|
+
it { @query.should_not be_unique }
|
|
2387
|
+
end
|
|
2388
|
+
end
|
|
2389
|
+
|
|
2390
|
+
it { @query.should respond_to(:update) }
|
|
2391
|
+
|
|
2392
|
+
describe '#update' do
|
|
2393
|
+
describe 'with a Query' do
|
|
2394
|
+
describe 'that is equivalent' do
|
|
2395
|
+
before :all do
|
|
2396
|
+
@other = DataMapper::Query.new(@repository, @model, @options)
|
|
2397
|
+
|
|
2398
|
+
@return = @query.update(@other)
|
|
2399
|
+
end
|
|
2400
|
+
|
|
2401
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2402
|
+
|
|
2403
|
+
it { @return.should equal(@original) }
|
|
2404
|
+
end
|
|
2405
|
+
|
|
2406
|
+
describe 'that has conditions set' do
|
|
2407
|
+
before :all do
|
|
2408
|
+
@and_operation = DataMapper::Query::Conditions::Operation.new(:and)
|
|
2409
|
+
@or_operation = DataMapper::Query::Conditions::Operation.new(:or)
|
|
2410
|
+
|
|
2411
|
+
@and_operation << DataMapper::Query::Conditions::Comparison.new(:eql,User.name,"Dan Kubb")
|
|
2412
|
+
@and_operation << DataMapper::Query::Conditions::Comparison.new(:eql,User.citizenship,"Canada")
|
|
2413
|
+
|
|
2414
|
+
@or_operation << DataMapper::Query::Conditions::Comparison.new(:eql,User.name,"Ted Han")
|
|
2415
|
+
@or_operation << DataMapper::Query::Conditions::Comparison.new(:eql,User.citizenship,"USA")
|
|
2416
|
+
@query_one = DataMapper::Query.new(@repository, @model, {:conditions=>@and_operation})
|
|
2417
|
+
@query_two = DataMapper::Query.new(@repository, @model, {:conditions=>@or_operation})
|
|
2418
|
+
|
|
2419
|
+
@conditions = @query_one.merge(@query_two).conditions
|
|
2420
|
+
end
|
|
2421
|
+
|
|
2422
|
+
it { @conditions.should == (@and_operation << @or_operation) }
|
|
2423
|
+
end
|
|
2424
|
+
|
|
2425
|
+
describe 'that is for an ancestor model' do
|
|
2426
|
+
before :all do
|
|
2427
|
+
class ::Contact < User; end
|
|
2428
|
+
|
|
2429
|
+
@query = DataMapper::Query.new(@repository, Contact, @options)
|
|
2430
|
+
@original = @query
|
|
2431
|
+
|
|
2432
|
+
@other = DataMapper::Query.new(@repository, User, @options)
|
|
2433
|
+
|
|
2434
|
+
@return = @query.update(@other)
|
|
2435
|
+
end
|
|
2436
|
+
|
|
2437
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2438
|
+
|
|
2439
|
+
it { @return.should equal(@original) }
|
|
2440
|
+
end
|
|
2441
|
+
|
|
2442
|
+
describe 'using a different repository' do
|
|
2443
|
+
it 'should raise an exception' do
|
|
2444
|
+
lambda {
|
|
2445
|
+
@query.update(DataMapper::Query.new(DataMapper::Repository.new(:other), User))
|
|
2446
|
+
}.should raise_error(ArgumentError, '+other+ DataMapper::Query must be for the default repository, not other')
|
|
2447
|
+
end
|
|
2448
|
+
end
|
|
2449
|
+
|
|
2450
|
+
describe 'using a different model' do
|
|
2451
|
+
before :all do
|
|
2452
|
+
class ::Clone
|
|
2453
|
+
include DataMapper::Resource
|
|
2454
|
+
|
|
2455
|
+
property :name, String, :key => true
|
|
2456
|
+
end
|
|
2457
|
+
end
|
|
2458
|
+
|
|
2459
|
+
it 'should raise an exception' do
|
|
2460
|
+
lambda {
|
|
2461
|
+
@query.update(DataMapper::Query.new(@repository, Clone))
|
|
2462
|
+
}.should raise_error(ArgumentError, '+other+ DataMapper::Query must be for the User model, not Clone')
|
|
2463
|
+
end
|
|
2464
|
+
end
|
|
2465
|
+
|
|
2466
|
+
describe 'using different options' do
|
|
2467
|
+
before :all do
|
|
2468
|
+
@other = DataMapper::Query.new(@repository, @model, @options.update(@other_options))
|
|
2469
|
+
|
|
2470
|
+
@return = @query.update(@other)
|
|
2471
|
+
end
|
|
2472
|
+
|
|
2473
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2474
|
+
|
|
2475
|
+
it { @return.should equal(@original) }
|
|
2476
|
+
|
|
2477
|
+
it 'should update the fields' do
|
|
2478
|
+
@return.fields.should == @options[:fields]
|
|
2479
|
+
end
|
|
2480
|
+
|
|
2481
|
+
it 'should update the links' do
|
|
2482
|
+
@return.links.should == @options[:links]
|
|
2483
|
+
end
|
|
2484
|
+
|
|
2485
|
+
it 'should update the conditions' do
|
|
2486
|
+
@return.conditions.should == DataMapper::Query::Conditions::Operation.new(:and, [ 'name = ?', [ 'Dan Kubb' ] ])
|
|
2487
|
+
end
|
|
2488
|
+
|
|
2489
|
+
it 'should update the offset' do
|
|
2490
|
+
@return.offset.should == @options[:offset]
|
|
2491
|
+
end
|
|
2492
|
+
|
|
2493
|
+
it 'should update the limit' do
|
|
2494
|
+
@return.limit.should == @options[:limit]
|
|
2495
|
+
end
|
|
2496
|
+
|
|
2497
|
+
it 'should update the order' do
|
|
2498
|
+
@return.order.should == @options[:order]
|
|
2499
|
+
end
|
|
2500
|
+
|
|
2501
|
+
it 'should update the unique' do
|
|
2502
|
+
@return.unique?.should == @options[:unique]
|
|
2503
|
+
end
|
|
2504
|
+
|
|
2505
|
+
it 'should update the add_reversed' do
|
|
2506
|
+
@return.add_reversed?.should == @options[:add_reversed]
|
|
2507
|
+
end
|
|
2508
|
+
|
|
2509
|
+
it 'should update the reload' do
|
|
2510
|
+
@return.reload?.should == @options[:reload]
|
|
2511
|
+
end
|
|
2512
|
+
end
|
|
2513
|
+
|
|
2514
|
+
describe 'using extra options' do
|
|
2515
|
+
before :all do
|
|
2516
|
+
@options.update(:name => 'Dan Kubb')
|
|
2517
|
+
@other = DataMapper::Query.new(@repository, @model, @options)
|
|
2518
|
+
|
|
2519
|
+
@return = @query.update(@other)
|
|
2520
|
+
end
|
|
2521
|
+
|
|
2522
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2523
|
+
|
|
2524
|
+
it { @return.should equal(@original) }
|
|
2525
|
+
|
|
2526
|
+
it 'should update the conditions' do
|
|
2527
|
+
@return.conditions.should ==
|
|
2528
|
+
DataMapper::Query::Conditions::Operation.new(
|
|
2529
|
+
:and,
|
|
2530
|
+
DataMapper::Query::Conditions::Comparison.new(
|
|
2531
|
+
:eql,
|
|
2532
|
+
@model.properties[:name],
|
|
2533
|
+
@options[:name]
|
|
2534
|
+
)
|
|
2535
|
+
)
|
|
2536
|
+
end
|
|
2537
|
+
end
|
|
2538
|
+
end
|
|
2539
|
+
|
|
2540
|
+
describe 'with a Hash' do
|
|
2541
|
+
describe 'that is empty' do
|
|
2542
|
+
before :all do
|
|
2543
|
+
@copy = @query.dup
|
|
2544
|
+
@return = @query.update({})
|
|
2545
|
+
end
|
|
2546
|
+
|
|
2547
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2548
|
+
|
|
2549
|
+
it { @return.should equal(@original) }
|
|
2550
|
+
|
|
2551
|
+
it 'should not change the Query' do
|
|
2552
|
+
@return.should == @copy
|
|
2553
|
+
end
|
|
2554
|
+
end
|
|
2555
|
+
|
|
2556
|
+
describe 'using different options' do
|
|
2557
|
+
before :all do
|
|
2558
|
+
@return = @query.update(@other_options)
|
|
2559
|
+
end
|
|
2560
|
+
|
|
2561
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2562
|
+
|
|
2563
|
+
it { @return.should equal(@original) }
|
|
2564
|
+
|
|
2565
|
+
it 'should update the fields' do
|
|
2566
|
+
@return.fields.should == @other_options[:fields]
|
|
2567
|
+
end
|
|
2568
|
+
|
|
2569
|
+
it 'should update the links' do
|
|
2570
|
+
@return.links.should == @other_options[:links]
|
|
2571
|
+
end
|
|
2572
|
+
|
|
2573
|
+
it 'should update the conditions' do
|
|
2574
|
+
@return.conditions.should == DataMapper::Query::Conditions::Operation.new(:and, [ 'name = ?', [ 'Dan Kubb' ] ])
|
|
2575
|
+
end
|
|
2576
|
+
|
|
2577
|
+
it 'should update the offset' do
|
|
2578
|
+
@return.offset.should == @other_options[:offset]
|
|
2579
|
+
end
|
|
2580
|
+
|
|
2581
|
+
it 'should update the limit' do
|
|
2582
|
+
@return.limit.should == @other_options[:limit]
|
|
2583
|
+
end
|
|
2584
|
+
|
|
2585
|
+
it 'should update the order' do
|
|
2586
|
+
@return.order.should == @other_options[:order]
|
|
2587
|
+
end
|
|
2588
|
+
|
|
2589
|
+
it 'should update the unique' do
|
|
2590
|
+
@return.unique?.should == @other_options[:unique]
|
|
2591
|
+
end
|
|
2592
|
+
|
|
2593
|
+
it 'should update the add_reversed' do
|
|
2594
|
+
@return.add_reversed?.should == @other_options[:add_reversed]
|
|
2595
|
+
end
|
|
2596
|
+
|
|
2597
|
+
it 'should update the reload' do
|
|
2598
|
+
@return.reload?.should == @other_options[:reload]
|
|
2599
|
+
end
|
|
2600
|
+
end
|
|
2601
|
+
|
|
2602
|
+
describe 'using extra options' do
|
|
2603
|
+
before :all do
|
|
2604
|
+
@options = { :name => 'Dan Kubb' }
|
|
2605
|
+
|
|
2606
|
+
@return = @query.update(@options)
|
|
2607
|
+
end
|
|
2608
|
+
|
|
2609
|
+
it { @return.should be_kind_of(DataMapper::Query) }
|
|
2610
|
+
|
|
2611
|
+
it { @return.should equal(@original) }
|
|
2612
|
+
|
|
2613
|
+
it 'should update the conditions' do
|
|
2614
|
+
@return.conditions.should == DataMapper::Query::Conditions::Operation.new(
|
|
2615
|
+
:and,
|
|
2616
|
+
DataMapper::Query::Conditions::Comparison.new(:eql,
|
|
2617
|
+
@model.properties[:name],
|
|
2618
|
+
@options[:name]
|
|
2619
|
+
)
|
|
2620
|
+
)
|
|
2621
|
+
#@return.conditions.should == [ [ :eql, @model.properties[:name], @options[:name] ] ]
|
|
2622
|
+
end
|
|
2623
|
+
end
|
|
2624
|
+
end
|
|
2625
|
+
end
|
|
2626
|
+
end
|