thinking-sphinx 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/Appraisals +13 -0
- data/Gemfile +2 -1
- data/HISTORY +19 -0
- data/README.textile +3 -2
- data/gemfiles/rails_3_2.gemfile +2 -1
- data/gemfiles/rails_4_0.gemfile +2 -1
- data/gemfiles/rails_4_1.gemfile +2 -1
- data/gemfiles/rails_4_2.gemfile +2 -1
- data/gemfiles/rails_5_0.gemfile +12 -0
- data/lib/thinking_sphinx.rb +2 -0
- data/lib/thinking_sphinx/active_record/attribute/type.rb +17 -3
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +12 -4
- data/lib/thinking_sphinx/active_record/database_adapters.rb +1 -1
- data/lib/thinking_sphinx/active_record/sql_builder/query.rb +4 -0
- data/lib/thinking_sphinx/active_record/sql_source.rb +1 -1
- data/lib/thinking_sphinx/configuration.rb +3 -2
- data/lib/thinking_sphinx/connection.rb +23 -10
- data/lib/thinking_sphinx/deltas/index_job.rb +6 -2
- data/lib/thinking_sphinx/errors.rb +25 -0
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +14 -2
- data/lib/thinking_sphinx/railtie.rb +1 -1
- data/lib/thinking_sphinx/rake_interface.rb +71 -23
- data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +15 -7
- data/lib/thinking_sphinx/real_time/populator.rb +3 -3
- data/lib/thinking_sphinx/tasks.rb +7 -8
- data/lib/thinking_sphinx/wildcard.rb +1 -1
- data/spec/acceptance/association_scoping_spec.rb +5 -5
- data/spec/acceptance/attribute_access_spec.rb +4 -4
- data/spec/acceptance/attribute_updates_spec.rb +3 -3
- data/spec/acceptance/batch_searching_spec.rb +4 -4
- data/spec/acceptance/big_integers_spec.rb +6 -6
- data/spec/acceptance/connection_spec.rb +23 -0
- data/spec/acceptance/excerpts_spec.rb +8 -8
- data/spec/acceptance/facets_spec.rb +13 -13
- data/spec/acceptance/geosearching_spec.rb +8 -8
- data/spec/acceptance/grouping_by_attributes_spec.rb +10 -10
- data/spec/acceptance/index_options_spec.rb +16 -16
- data/spec/acceptance/indexing_spec.rb +3 -3
- data/spec/acceptance/paginating_search_results_spec.rb +3 -3
- data/spec/acceptance/real_time_updates_spec.rb +4 -4
- data/spec/acceptance/remove_deleted_records_spec.rb +12 -12
- data/spec/acceptance/search_counts_spec.rb +2 -2
- data/spec/acceptance/search_for_just_ids_spec.rb +2 -2
- data/spec/acceptance/searching_across_models_spec.rb +6 -6
- data/spec/acceptance/searching_across_schemas_spec.rb +10 -10
- data/spec/acceptance/searching_on_fields_spec.rb +9 -9
- data/spec/acceptance/searching_with_filters_spec.rb +16 -16
- data/spec/acceptance/searching_with_sti_spec.rb +9 -9
- data/spec/acceptance/searching_within_a_model_spec.rb +17 -17
- data/spec/acceptance/sorting_search_results_spec.rb +6 -6
- data/spec/acceptance/specifying_sql_spec.rb +62 -62
- data/spec/acceptance/sphinx_scopes_spec.rb +9 -9
- data/spec/acceptance/sql_deltas_spec.rb +7 -7
- data/spec/acceptance/support/database_cleaner.rb +1 -1
- data/spec/acceptance/support/sphinx_controller.rb +4 -1
- data/spec/acceptance/support/sphinx_helpers.rb +4 -0
- data/spec/acceptance/suspended_deltas_spec.rb +9 -9
- data/spec/internal/app/indices/article_index.rb +2 -2
- data/spec/internal/app/indices/book_index.rb +2 -1
- data/spec/internal/app/indices/product_index.rb +0 -2
- data/spec/internal/app/models/categorisation.rb +8 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/json_column.rb +5 -1
- data/spec/support/multi_schema.rb +3 -1
- data/spec/support/sphinx_yaml_helpers.rb +1 -1
- data/spec/thinking_sphinx/active_record/association_spec.rb +1 -1
- data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +41 -38
- data/spec/thinking_sphinx/active_record/base_spec.rb +29 -29
- data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +10 -10
- data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +48 -25
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +8 -8
- data/spec/thinking_sphinx/active_record/column_spec.rb +13 -13
- data/spec/thinking_sphinx/active_record/column_sql_presenter_spec.rb +5 -5
- data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +5 -5
- data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +11 -11
- data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +13 -13
- data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +48 -48
- data/spec/thinking_sphinx/active_record/field_spec.rb +7 -7
- data/spec/thinking_sphinx/active_record/filter_reflection_spec.rb +32 -32
- data/spec/thinking_sphinx/active_record/index_spec.rb +35 -36
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +51 -51
- data/spec/thinking_sphinx/active_record/polymorpher_spec.rb +14 -14
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +67 -67
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +140 -140
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +97 -95
- data/spec/thinking_sphinx/configuration_spec.rb +81 -81
- data/spec/thinking_sphinx/connection_spec.rb +13 -13
- data/spec/thinking_sphinx/deletion_spec.rb +11 -11
- data/spec/thinking_sphinx/deltas/default_delta_spec.rb +20 -20
- data/spec/thinking_sphinx/deltas_spec.rb +12 -12
- data/spec/thinking_sphinx/errors_spec.rb +30 -30
- data/spec/thinking_sphinx/excerpter_spec.rb +7 -7
- data/spec/thinking_sphinx/facet_search_spec.rb +16 -16
- data/spec/thinking_sphinx/index_set_spec.rb +7 -7
- data/spec/thinking_sphinx/index_spec.rb +24 -24
- data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +20 -20
- data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +18 -18
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +22 -22
- data/spec/thinking_sphinx/middlewares/geographer_spec.rb +9 -9
- data/spec/thinking_sphinx/middlewares/glazier_spec.rb +4 -4
- data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +7 -7
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +53 -53
- data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +5 -5
- data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +15 -15
- data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +1 -1
- data/spec/thinking_sphinx/panes/distance_pane_spec.rb +4 -4
- data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +5 -5
- data/spec/thinking_sphinx/panes/weight_pane_spec.rb +1 -1
- data/spec/thinking_sphinx/rake_interface_spec.rb +66 -53
- data/spec/thinking_sphinx/real_time/attribute_spec.rb +13 -13
- data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +107 -23
- data/spec/thinking_sphinx/real_time/field_spec.rb +14 -14
- data/spec/thinking_sphinx/real_time/index_spec.rb +29 -30
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +30 -30
- data/spec/thinking_sphinx/scopes_spec.rb +5 -5
- data/spec/thinking_sphinx/search/glaze_spec.rb +15 -15
- data/spec/thinking_sphinx/search/query_spec.rb +10 -10
- data/spec/thinking_sphinx/search_spec.rb +28 -28
- data/spec/thinking_sphinx/wildcard_spec.rb +16 -11
- data/spec/thinking_sphinx_spec.rb +6 -6
- data/thinking-sphinx.gemspec +4 -4
- metadata +12 -9
@@ -13,23 +13,23 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
13
13
|
let(:block) { Proc.new { } }
|
14
14
|
|
15
15
|
before :each do
|
16
|
-
ThinkingSphinx::ActiveRecord::SQLSource.
|
17
|
-
source.
|
16
|
+
allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages :new => source
|
17
|
+
allow(source).to receive_messages :model => model
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '.translate!' do
|
21
21
|
let(:instance) { double('interpreter', :translate! => true) }
|
22
22
|
|
23
23
|
it "creates a new interpreter instance with the given block and index" do
|
24
|
-
ThinkingSphinx::ActiveRecord::Interpreter.
|
24
|
+
expect(ThinkingSphinx::ActiveRecord::Interpreter).to receive(:new).
|
25
25
|
with(index, block).and_return(instance)
|
26
26
|
|
27
27
|
ThinkingSphinx::ActiveRecord::Interpreter.translate! index, block
|
28
28
|
end
|
29
29
|
|
30
30
|
it "calls translate! on the instance" do
|
31
|
-
ThinkingSphinx::ActiveRecord::Interpreter.
|
32
|
-
instance.
|
31
|
+
allow(ThinkingSphinx::ActiveRecord::Interpreter).to receive_messages(:new => instance)
|
32
|
+
expect(instance).to receive(:translate!)
|
33
33
|
|
34
34
|
ThinkingSphinx::ActiveRecord::Interpreter.translate! index, block
|
35
35
|
end
|
@@ -37,13 +37,13 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
37
37
|
|
38
38
|
describe '#group_by' do
|
39
39
|
it "adds a source to the index" do
|
40
|
-
index.
|
40
|
+
expect(index).to receive(:append_source).and_return(source)
|
41
41
|
|
42
42
|
instance.group_by 'lat'
|
43
43
|
end
|
44
44
|
|
45
45
|
it "only adds a single source for the given context" do
|
46
|
-
index.
|
46
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
47
47
|
|
48
48
|
instance.group_by 'lat'
|
49
49
|
instance.group_by 'lng'
|
@@ -52,7 +52,7 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
52
52
|
it "appends a new grouping statement to the source" do
|
53
53
|
instance.group_by 'lat'
|
54
54
|
|
55
|
-
source.groupings.
|
55
|
+
expect(source.groupings).to include('lat')
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -61,31 +61,31 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
61
61
|
let(:attribute) { double('attribute') }
|
62
62
|
|
63
63
|
before :each do
|
64
|
-
ThinkingSphinx::ActiveRecord::Attribute.
|
64
|
+
allow(ThinkingSphinx::ActiveRecord::Attribute).to receive_messages :new => attribute
|
65
65
|
end
|
66
66
|
|
67
67
|
it "adds a source to the index" do
|
68
|
-
index.
|
68
|
+
expect(index).to receive(:append_source).and_return(source)
|
69
69
|
|
70
70
|
instance.has column
|
71
71
|
end
|
72
72
|
|
73
73
|
it "only adds a single source for the given context" do
|
74
|
-
index.
|
74
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
75
75
|
|
76
76
|
instance.has column
|
77
77
|
instance.has column
|
78
78
|
end
|
79
79
|
|
80
80
|
it "creates a new attribute with the provided column" do
|
81
|
-
ThinkingSphinx::ActiveRecord::Attribute.
|
81
|
+
expect(ThinkingSphinx::ActiveRecord::Attribute).to receive(:new).
|
82
82
|
with(model, column, {}).and_return(attribute)
|
83
83
|
|
84
84
|
instance.has column
|
85
85
|
end
|
86
86
|
|
87
87
|
it "passes through options to the attribute" do
|
88
|
-
ThinkingSphinx::ActiveRecord::Attribute.
|
88
|
+
expect(ThinkingSphinx::ActiveRecord::Attribute).to receive(:new).
|
89
89
|
with(model, column, :as => :other_name).and_return(attribute)
|
90
90
|
|
91
91
|
instance.has column, :as => :other_name
|
@@ -94,15 +94,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
94
94
|
it "adds an attribute to the source" do
|
95
95
|
instance.has column
|
96
96
|
|
97
|
-
source.attributes.
|
97
|
+
expect(source.attributes).to include(attribute)
|
98
98
|
end
|
99
99
|
|
100
100
|
it "adds multiple attributes when passed multiple columns" do
|
101
101
|
instance.has column, column
|
102
102
|
|
103
|
-
source.attributes.select { |saved_attribute|
|
103
|
+
expect(source.attributes.select { |saved_attribute|
|
104
104
|
saved_attribute == attribute
|
105
|
-
}.length.
|
105
|
+
}.length).to eq(2)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -111,31 +111,31 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
111
111
|
let(:field) { double('field') }
|
112
112
|
|
113
113
|
before :each do
|
114
|
-
ThinkingSphinx::ActiveRecord::Field.
|
114
|
+
allow(ThinkingSphinx::ActiveRecord::Field).to receive_messages :new => field
|
115
115
|
end
|
116
116
|
|
117
117
|
it "adds a source to the index" do
|
118
|
-
index.
|
118
|
+
expect(index).to receive(:append_source).and_return(source)
|
119
119
|
|
120
120
|
instance.indexes column
|
121
121
|
end
|
122
122
|
|
123
123
|
it "only adds a single source for the given context" do
|
124
|
-
index.
|
124
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
125
125
|
|
126
126
|
instance.indexes column
|
127
127
|
instance.indexes column
|
128
128
|
end
|
129
129
|
|
130
130
|
it "creates a new field with the provided column" do
|
131
|
-
ThinkingSphinx::ActiveRecord::Field.
|
131
|
+
expect(ThinkingSphinx::ActiveRecord::Field).to receive(:new).
|
132
132
|
with(model, column, {}).and_return(field)
|
133
133
|
|
134
134
|
instance.indexes column
|
135
135
|
end
|
136
136
|
|
137
137
|
it "passes through options to the field" do
|
138
|
-
ThinkingSphinx::ActiveRecord::Field.
|
138
|
+
expect(ThinkingSphinx::ActiveRecord::Field).to receive(:new).
|
139
139
|
with(model, column, :as => :other_name).and_return(field)
|
140
140
|
|
141
141
|
instance.indexes column, :as => :other_name
|
@@ -144,15 +144,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
144
144
|
it "adds a field to the source" do
|
145
145
|
instance.indexes column
|
146
146
|
|
147
|
-
source.fields.
|
147
|
+
expect(source.fields).to include(field)
|
148
148
|
end
|
149
149
|
|
150
150
|
it "adds multiple fields when passed multiple columns" do
|
151
151
|
instance.indexes column, column
|
152
152
|
|
153
|
-
source.fields.select { |saved_field|
|
153
|
+
expect(source.fields.select { |saved_field|
|
154
154
|
saved_field == field
|
155
|
-
}.length.
|
155
|
+
}.length).to eq(2)
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
@@ -161,24 +161,24 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
161
161
|
let(:association) { double('association') }
|
162
162
|
|
163
163
|
before :each do
|
164
|
-
ThinkingSphinx::ActiveRecord::Association.
|
164
|
+
allow(ThinkingSphinx::ActiveRecord::Association).to receive_messages :new => association
|
165
165
|
end
|
166
166
|
|
167
167
|
it "adds a source to the index" do
|
168
|
-
index.
|
168
|
+
expect(index).to receive(:append_source).and_return(source)
|
169
169
|
|
170
170
|
instance.join column
|
171
171
|
end
|
172
172
|
|
173
173
|
it "only adds a single source for the given context" do
|
174
|
-
index.
|
174
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
175
175
|
|
176
176
|
instance.join column
|
177
177
|
instance.join column
|
178
178
|
end
|
179
179
|
|
180
180
|
it "creates a new association with the provided column" do
|
181
|
-
ThinkingSphinx::ActiveRecord::Association.
|
181
|
+
expect(ThinkingSphinx::ActiveRecord::Association).to receive(:new).
|
182
182
|
with(column).and_return(association)
|
183
183
|
|
184
184
|
instance.join column
|
@@ -187,15 +187,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
187
187
|
it "adds an association to the source" do
|
188
188
|
instance.join column
|
189
189
|
|
190
|
-
source.associations.
|
190
|
+
expect(source.associations).to include(association)
|
191
191
|
end
|
192
192
|
|
193
193
|
it "adds multiple fields when passed multiple columns" do
|
194
194
|
instance.join column, column
|
195
195
|
|
196
|
-
source.associations.select { |saved_assoc|
|
196
|
+
expect(source.associations.select { |saved_assoc|
|
197
197
|
saved_assoc == association
|
198
|
-
}.length.
|
198
|
+
}.length).to eq(2)
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
@@ -203,15 +203,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
203
203
|
let(:column) { double('column') }
|
204
204
|
|
205
205
|
before :each do
|
206
|
-
ThinkingSphinx::ActiveRecord::Column.
|
206
|
+
allow(ThinkingSphinx::ActiveRecord::Column).to receive_messages(:new => column)
|
207
207
|
end
|
208
208
|
|
209
209
|
it "returns a new column for the given method" do
|
210
|
-
instance.id.
|
210
|
+
expect(instance.id).to eq(column)
|
211
211
|
end
|
212
212
|
|
213
213
|
it "should initialise the column with the method name and arguments" do
|
214
|
-
ThinkingSphinx::ActiveRecord::Column.
|
214
|
+
expect(ThinkingSphinx::ActiveRecord::Column).to receive(:new).
|
215
215
|
with(:users, :posts, :subject).and_return(column)
|
216
216
|
|
217
217
|
instance.users(:posts, :subject)
|
@@ -220,26 +220,26 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
220
220
|
|
221
221
|
describe '#set_database' do
|
222
222
|
before :each do
|
223
|
-
source.
|
223
|
+
allow(source).to receive_messages :set_database_settings => true
|
224
224
|
|
225
225
|
stub_const 'ActiveRecord::Base',
|
226
226
|
double(:configurations => {'other' => {'baz' => 'qux'}})
|
227
227
|
end
|
228
228
|
|
229
229
|
it "sends through a hash if provided" do
|
230
|
-
source.
|
230
|
+
expect(source).to receive(:set_database_settings).with(:foo => :bar)
|
231
231
|
|
232
232
|
instance.set_database :foo => :bar
|
233
233
|
end
|
234
234
|
|
235
235
|
it "finds the environment settings if given a string key" do
|
236
|
-
source.
|
236
|
+
expect(source).to receive(:set_database_settings).with(:baz => 'qux')
|
237
237
|
|
238
238
|
instance.set_database 'other'
|
239
239
|
end
|
240
240
|
|
241
241
|
it "finds the environment settings if given a symbol key" do
|
242
|
-
source.
|
242
|
+
expect(source).to receive(:set_database_settings).with(:baz => 'qux')
|
243
243
|
|
244
244
|
instance.set_database :other
|
245
245
|
end
|
@@ -247,19 +247,19 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
247
247
|
|
248
248
|
describe '#set_property' do
|
249
249
|
before :each do
|
250
|
-
index.class.
|
251
|
-
source.class.
|
250
|
+
allow(index.class).to receive_messages :settings => [:morphology]
|
251
|
+
allow(source.class).to receive_messages :settings => [:mysql_ssl_cert]
|
252
252
|
end
|
253
253
|
|
254
254
|
it 'saves other settings as index options' do
|
255
255
|
instance.set_property :field_weights => {:name => 10}
|
256
256
|
|
257
|
-
index.options[:field_weights].
|
257
|
+
expect(index.options[:field_weights]).to eq({:name => 10})
|
258
258
|
end
|
259
259
|
|
260
260
|
context 'index settings' do
|
261
261
|
it "sets the provided setting" do
|
262
|
-
index.
|
262
|
+
expect(index).to receive(:morphology=).with('stem_en')
|
263
263
|
|
264
264
|
instance.set_property :morphology => 'stem_en'
|
265
265
|
end
|
@@ -267,24 +267,24 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
267
267
|
|
268
268
|
context 'source settings' do
|
269
269
|
before :each do
|
270
|
-
source.
|
270
|
+
allow(source).to receive_messages :mysql_ssl_cert= => true
|
271
271
|
end
|
272
272
|
|
273
273
|
it "adds a source to the index" do
|
274
|
-
index.
|
274
|
+
expect(index).to receive(:append_source).and_return(source)
|
275
275
|
|
276
276
|
instance.set_property :mysql_ssl_cert => 'private.cert'
|
277
277
|
end
|
278
278
|
|
279
279
|
it "only adds a single source for the given context" do
|
280
|
-
index.
|
280
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
281
281
|
|
282
282
|
instance.set_property :mysql_ssl_cert => 'private.cert'
|
283
283
|
instance.set_property :mysql_ssl_cert => 'private.cert'
|
284
284
|
end
|
285
285
|
|
286
286
|
it "sets the provided setting" do
|
287
|
-
source.
|
287
|
+
expect(source).to receive(:mysql_ssl_cert=).with('private.cert')
|
288
288
|
|
289
289
|
instance.set_property :mysql_ssl_cert => 'private.cert'
|
290
290
|
end
|
@@ -298,20 +298,20 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
298
298
|
}
|
299
299
|
|
300
300
|
interpreter = ThinkingSphinx::ActiveRecord::Interpreter.new index, block
|
301
|
-
interpreter.translate
|
302
|
-
|
301
|
+
expect(interpreter.translate!).
|
302
|
+
to eq(interpreter.__id__)
|
303
303
|
end
|
304
304
|
end
|
305
305
|
|
306
306
|
describe '#where' do
|
307
307
|
it "adds a source to the index" do
|
308
|
-
index.
|
308
|
+
expect(index).to receive(:append_source).and_return(source)
|
309
309
|
|
310
310
|
instance.where 'id > 100'
|
311
311
|
end
|
312
312
|
|
313
313
|
it "only adds a single source for the given context" do
|
314
|
-
index.
|
314
|
+
expect(index).to receive(:append_source).once.and_return(source)
|
315
315
|
|
316
316
|
instance.where 'id > 100'
|
317
317
|
instance.where 'id < 150'
|
@@ -320,7 +320,7 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
320
320
|
it "appends a new grouping statement to the source" do
|
321
321
|
instance.where 'id > 100'
|
322
322
|
|
323
|
-
source.conditions.
|
323
|
+
expect(source.conditions).to include('id > 100')
|
324
324
|
end
|
325
325
|
end
|
326
326
|
end
|
@@ -23,29 +23,29 @@ describe ThinkingSphinx::ActiveRecord::Polymorpher do
|
|
23
23
|
let(:animal_reflection) { double 'Animal Reflection' }
|
24
24
|
|
25
25
|
before :each do
|
26
|
-
ThinkingSphinx::ActiveRecord::FilterReflection.
|
27
|
-
|
26
|
+
allow(ThinkingSphinx::ActiveRecord::FilterReflection).
|
27
|
+
to receive(:call).
|
28
28
|
and_return(article_reflection, animal_reflection)
|
29
29
|
|
30
|
-
model.
|
30
|
+
allow(model).to receive(:reflect_on_association) do |name|
|
31
31
|
name == :foo ? reflection : nil
|
32
32
|
end
|
33
33
|
|
34
34
|
if ActiveRecord::Reflection.respond_to?(:add_reflection)
|
35
|
-
ActiveRecord::Reflection.
|
35
|
+
allow(ActiveRecord::Reflection).to receive :add_reflection
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
it "creates a new reflection for each class" do
|
40
|
-
ThinkingSphinx::ActiveRecord::FilterReflection.
|
41
|
-
|
40
|
+
allow(ThinkingSphinx::ActiveRecord::FilterReflection).
|
41
|
+
to receive(:call).and_call_original
|
42
42
|
|
43
|
-
ThinkingSphinx::ActiveRecord::FilterReflection.
|
44
|
-
|
43
|
+
expect(ThinkingSphinx::ActiveRecord::FilterReflection).
|
44
|
+
to receive(:call).
|
45
45
|
with(reflection, :foo_article, 'Article').
|
46
46
|
and_return(article_reflection)
|
47
|
-
ThinkingSphinx::ActiveRecord::FilterReflection.
|
48
|
-
|
47
|
+
expect(ThinkingSphinx::ActiveRecord::FilterReflection).
|
48
|
+
to receive(:call).
|
49
49
|
with(reflection, :foo_animal, 'Animal').
|
50
50
|
and_return(animal_reflection)
|
51
51
|
|
@@ -54,9 +54,9 @@ describe ThinkingSphinx::ActiveRecord::Polymorpher do
|
|
54
54
|
|
55
55
|
it "adds the new reflections to the end-of-stack model" do
|
56
56
|
if ActiveRecord::Reflection.respond_to?(:add_reflection)
|
57
|
-
ActiveRecord::Reflection.
|
57
|
+
expect(ActiveRecord::Reflection).to receive(:add_reflection).
|
58
58
|
with(model, :foo_article, article_reflection)
|
59
|
-
ActiveRecord::Reflection.
|
59
|
+
expect(ActiveRecord::Reflection).to receive(:add_reflection).
|
60
60
|
with(model, :foo_animal, animal_reflection)
|
61
61
|
|
62
62
|
polymorpher.morph!
|
@@ -69,14 +69,14 @@ describe ThinkingSphinx::ActiveRecord::Polymorpher do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
it "rebases each field" do
|
72
|
-
field.
|
72
|
+
expect(field).to receive(:rebase).with([:a, :b, :foo],
|
73
73
|
:to => [[:a, :b, :foo_article], [:a, :b, :foo_animal]])
|
74
74
|
|
75
75
|
polymorpher.morph!
|
76
76
|
end
|
77
77
|
|
78
78
|
it "rebases each attribute" do
|
79
|
-
attribute.
|
79
|
+
expect(attribute).to receive(:rebase).with([:a, :b, :foo],
|
80
80
|
:to => [[:a, :b, :foo_article], [:a, :b, :foo_animal]])
|
81
81
|
|
82
82
|
polymorpher.morph!
|
@@ -7,7 +7,7 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
7
7
|
let(:path) { double :aggregate? => false, :model => model }
|
8
8
|
|
9
9
|
before :each do
|
10
|
-
adapter.
|
10
|
+
allow(adapter).to receive(:quote) { |column| column }
|
11
11
|
|
12
12
|
stub_const 'Joiner::Path', double(:new => path)
|
13
13
|
end
|
@@ -25,95 +25,95 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
25
25
|
|
26
26
|
describe '#to_group' do
|
27
27
|
it "returns the column name as a string" do
|
28
|
-
presenter.to_group.
|
28
|
+
expect(presenter.to_group).to eq('articles.title')
|
29
29
|
end
|
30
30
|
|
31
31
|
it "gets the column's table alias from the associations object" do
|
32
|
-
column.
|
32
|
+
allow(column).to receive_messages(:__stack => [:users, :posts])
|
33
33
|
|
34
|
-
associations.
|
34
|
+
expect(associations).to receive(:alias_for).with([:users, :posts]).
|
35
35
|
and_return('posts')
|
36
36
|
|
37
37
|
presenter.to_group
|
38
38
|
end
|
39
39
|
|
40
40
|
it "returns nil if the property is an aggregate" do
|
41
|
-
path.
|
41
|
+
allow(path).to receive_messages :aggregate? => true
|
42
42
|
|
43
|
-
presenter.to_group.
|
43
|
+
expect(presenter.to_group).to be_nil
|
44
44
|
end
|
45
45
|
|
46
46
|
it "returns nil if the field is sourced via a separate query" do
|
47
|
-
field.
|
47
|
+
allow(field).to receive_messages :source_type => 'query'
|
48
48
|
|
49
|
-
presenter.to_group.
|
49
|
+
expect(presenter.to_group).to be_nil
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
describe '#to_select' do
|
54
54
|
it "returns the column name as a string" do
|
55
|
-
presenter.to_select.
|
55
|
+
expect(presenter.to_select).to eq('articles.title AS title')
|
56
56
|
end
|
57
57
|
|
58
58
|
it "gets the column's table alias from the associations object" do
|
59
|
-
column.
|
59
|
+
allow(column).to receive_messages(:__stack => [:users, :posts])
|
60
60
|
|
61
|
-
associations.
|
61
|
+
expect(associations).to receive(:alias_for).with([:users, :posts]).
|
62
62
|
and_return('posts')
|
63
63
|
|
64
64
|
presenter.to_select
|
65
65
|
end
|
66
66
|
|
67
67
|
it "returns the column name with an alias when provided" do
|
68
|
-
field.
|
68
|
+
allow(field).to receive_messages(:name => :subject)
|
69
69
|
|
70
|
-
presenter.to_select.
|
70
|
+
expect(presenter.to_select).to eq('articles.title AS subject')
|
71
71
|
end
|
72
72
|
|
73
73
|
it "groups and concatenates aggregated columns" do
|
74
|
-
adapter.
|
74
|
+
allow(adapter).to receive :group_concatenate do |clause, separator|
|
75
75
|
"GROUP_CONCAT(#{clause} SEPARATOR '#{separator}')"
|
76
76
|
end
|
77
77
|
|
78
|
-
path.
|
78
|
+
allow(path).to receive_messages :aggregate? => true
|
79
79
|
|
80
|
-
presenter.to_select.
|
81
|
-
|
80
|
+
expect(presenter.to_select).
|
81
|
+
to eq("GROUP_CONCAT(articles.title SEPARATOR ' ') AS title")
|
82
82
|
end
|
83
83
|
|
84
84
|
it "concatenates multiple columns" do
|
85
|
-
adapter.
|
85
|
+
allow(adapter).to receive :concatenate do |clause, separator|
|
86
86
|
"CONCAT_WS('#{separator}', #{clause})"
|
87
87
|
end
|
88
88
|
|
89
|
-
field.
|
89
|
+
allow(field).to receive_messages(:columns => [column, column])
|
90
90
|
|
91
|
-
presenter.to_select.
|
92
|
-
|
91
|
+
expect(presenter.to_select).
|
92
|
+
to eq("CONCAT_WS(' ', articles.title, articles.title) AS title")
|
93
93
|
end
|
94
94
|
|
95
95
|
it "does not include columns that don't exist" do
|
96
|
-
adapter.
|
96
|
+
allow(adapter).to receive :concatenate do |clause, separator|
|
97
97
|
"CONCAT_WS('#{separator}', #{clause})"
|
98
98
|
end
|
99
99
|
|
100
|
-
field.
|
100
|
+
allow(field).to receive_messages(:columns => [column, double('column', :string? => false,
|
101
101
|
:__stack => [], :__name => 'body')])
|
102
102
|
|
103
|
-
presenter.to_select.
|
104
|
-
|
103
|
+
expect(presenter.to_select).
|
104
|
+
to eq("CONCAT_WS(' ', articles.title) AS title")
|
105
105
|
end
|
106
106
|
|
107
107
|
it "returns nil for query sourced fields" do
|
108
|
-
field.
|
108
|
+
allow(field).to receive_messages :source_type => :query
|
109
109
|
|
110
|
-
presenter.to_select.
|
110
|
+
expect(presenter.to_select).to be_nil
|
111
111
|
end
|
112
112
|
|
113
113
|
it "returns nil for ranged query sourced fields" do
|
114
|
-
field.
|
114
|
+
allow(field).to receive_messages :source_type => :ranged_query
|
115
115
|
|
116
|
-
presenter.to_select.
|
116
|
+
expect(presenter.to_select).to be_nil
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
@@ -131,131 +131,131 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
131
131
|
:__name => 'created_at') }
|
132
132
|
|
133
133
|
before :each do
|
134
|
-
adapter.
|
134
|
+
allow(adapter).to receive :cast_to_timestamp do |clause|
|
135
135
|
"UNIX_TIMESTAMP(#{clause})"
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
139
|
describe '#to_group' do
|
140
140
|
it "returns the column name as a string" do
|
141
|
-
presenter.to_group.
|
141
|
+
expect(presenter.to_group).to eq('articles.created_at')
|
142
142
|
end
|
143
143
|
|
144
144
|
it "gets the column's table alias from the associations object" do
|
145
|
-
column.
|
145
|
+
allow(column).to receive_messages(:__stack => [:users, :posts])
|
146
146
|
|
147
|
-
associations.
|
147
|
+
expect(associations).to receive(:alias_for).with([:users, :posts]).
|
148
148
|
and_return('posts')
|
149
149
|
|
150
150
|
presenter.to_group
|
151
151
|
end
|
152
152
|
|
153
153
|
it "returns nil if the column is a string" do
|
154
|
-
column.
|
154
|
+
allow(column).to receive_messages(:string? => true)
|
155
155
|
|
156
|
-
presenter.to_group.
|
156
|
+
expect(presenter.to_group).to be_nil
|
157
157
|
end
|
158
158
|
|
159
159
|
it "returns nil if the property is an aggregate" do
|
160
|
-
path.
|
160
|
+
allow(path).to receive_messages :aggregate? => true
|
161
161
|
|
162
|
-
presenter.to_group.
|
162
|
+
expect(presenter.to_group).to be_nil
|
163
163
|
end
|
164
164
|
|
165
165
|
it "returns nil if the attribute is sourced via a separate query" do
|
166
|
-
attribute.
|
166
|
+
allow(attribute).to receive_messages :source_type => 'query'
|
167
167
|
|
168
|
-
presenter.to_group.
|
168
|
+
expect(presenter.to_group).to be_nil
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
172
|
describe '#to_select' do
|
173
173
|
it "returns the column name as a string" do
|
174
|
-
presenter.to_select.
|
174
|
+
expect(presenter.to_select).to eq('articles.created_at AS created_at')
|
175
175
|
end
|
176
176
|
|
177
177
|
it "gets the column's table alias from the associations object" do
|
178
|
-
column.
|
178
|
+
allow(column).to receive_messages(:__stack => [:users, :posts])
|
179
179
|
|
180
|
-
associations.
|
180
|
+
expect(associations).to receive(:alias_for).with([:users, :posts]).
|
181
181
|
and_return('posts')
|
182
182
|
|
183
183
|
presenter.to_select
|
184
184
|
end
|
185
185
|
|
186
186
|
it "returns the column name with an alias when provided" do
|
187
|
-
attribute.
|
187
|
+
allow(attribute).to receive_messages(:name => :creation_timestamp)
|
188
188
|
|
189
|
-
presenter.to_select.
|
190
|
-
|
189
|
+
expect(presenter.to_select).
|
190
|
+
to eq('articles.created_at AS creation_timestamp')
|
191
191
|
end
|
192
192
|
|
193
193
|
it "ensures datetime attributes are converted to timestamps" do
|
194
|
-
attribute.
|
194
|
+
allow(attribute).to receive_messages :type => :timestamp
|
195
195
|
|
196
|
-
presenter.to_select.
|
197
|
-
|
196
|
+
expect(presenter.to_select).
|
197
|
+
to eq('UNIX_TIMESTAMP(articles.created_at) AS created_at')
|
198
198
|
end
|
199
199
|
|
200
200
|
it "does not include columns that don't exist" do
|
201
|
-
adapter.
|
201
|
+
allow(adapter).to receive :concatenate do |clause, separator|
|
202
202
|
"CONCAT_WS('#{separator}', #{clause})"
|
203
203
|
end
|
204
|
-
adapter.
|
204
|
+
allow(adapter).to receive :cast_to_string do |clause|
|
205
205
|
"CAST(#{clause} AS varchar)"
|
206
206
|
end
|
207
207
|
|
208
|
-
attribute.
|
208
|
+
allow(attribute).to receive_messages(:columns => [column, double('column',
|
209
209
|
:string? => false, :__stack => [], :__name => 'updated_at')])
|
210
210
|
|
211
|
-
presenter.to_select.
|
211
|
+
expect(presenter.to_select).to eq("CONCAT_WS(',', CAST(articles.created_at AS varchar)) AS created_at")
|
212
212
|
end
|
213
213
|
|
214
214
|
it "casts and concatenates multiple columns for attributes" do
|
215
|
-
adapter.
|
215
|
+
allow(adapter).to receive :concatenate do |clause, separator|
|
216
216
|
"CONCAT_WS('#{separator}', #{clause})"
|
217
217
|
end
|
218
|
-
adapter.
|
218
|
+
allow(adapter).to receive :cast_to_string do |clause|
|
219
219
|
"CAST(#{clause} AS varchar)"
|
220
220
|
end
|
221
221
|
|
222
|
-
attribute.
|
222
|
+
allow(attribute).to receive_messages(:columns => [column, column])
|
223
223
|
|
224
|
-
presenter.to_select.
|
224
|
+
expect(presenter.to_select).to eq("CONCAT_WS(',', CAST(articles.created_at AS varchar), CAST(articles.created_at AS varchar)) AS created_at")
|
225
225
|
end
|
226
226
|
|
227
227
|
it "double-casts and concatenates multiple columns for timestamp attributes" do
|
228
|
-
adapter.
|
228
|
+
allow(adapter).to receive :concatenate do |clause, separator|
|
229
229
|
"CONCAT_WS('#{separator}', #{clause})"
|
230
230
|
end
|
231
|
-
adapter.
|
231
|
+
allow(adapter).to receive :cast_to_string do |clause|
|
232
232
|
"CAST(#{clause} AS varchar)"
|
233
233
|
end
|
234
234
|
|
235
|
-
attribute.
|
235
|
+
allow(attribute).to receive_messages :columns => [column, column], :type => :timestamp
|
236
236
|
|
237
|
-
presenter.to_select.
|
237
|
+
expect(presenter.to_select).to eq("CONCAT_WS(',', CAST(UNIX_TIMESTAMP(articles.created_at) AS varchar), CAST(UNIX_TIMESTAMP(articles.created_at) AS varchar)) AS created_at")
|
238
238
|
end
|
239
239
|
|
240
240
|
it "does not split attribute clause for timestamp casting if it looks like a function call" do
|
241
|
-
column.
|
241
|
+
allow(column).to receive_messages :__name => "COALESCE(articles.updated_at, articles.created_at)", :string? => true
|
242
242
|
|
243
|
-
attribute.
|
243
|
+
allow(attribute).to receive_messages :name => 'mod_date', :columns => [column],
|
244
244
|
:type => :timestamp
|
245
245
|
|
246
|
-
presenter.to_select.
|
246
|
+
expect(presenter.to_select).to eq("UNIX_TIMESTAMP(COALESCE(articles.updated_at, articles.created_at)) AS mod_date")
|
247
247
|
end
|
248
248
|
|
249
249
|
it "returns nil for query sourced attributes" do
|
250
|
-
attribute.
|
250
|
+
allow(attribute).to receive_messages :source_type => :query
|
251
251
|
|
252
|
-
presenter.to_select.
|
252
|
+
expect(presenter.to_select).to be_nil
|
253
253
|
end
|
254
254
|
|
255
255
|
it "returns nil for ranged query sourced attributes" do
|
256
|
-
attribute.
|
256
|
+
allow(attribute).to receive_messages :source_type => :ranged_query
|
257
257
|
|
258
|
-
presenter.to_select.
|
258
|
+
expect(presenter.to_select).to be_nil
|
259
259
|
end
|
260
260
|
end
|
261
261
|
end
|