thinking-sphinx 3.0.6 → 3.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +11 -6
- data/Appraisals +5 -5
- data/Gemfile +3 -3
- data/HISTORY +32 -0
- data/README.textile +16 -5
- data/gemfiles/rails_3_2.gemfile +2 -1
- data/gemfiles/rails_4_0.gemfile +3 -2
- data/gemfiles/{rails_3_1.gemfile → rails_4_1.gemfile} +3 -2
- data/lib/thinking_sphinx.rb +5 -0
- data/lib/thinking_sphinx/active_record.rb +2 -1
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +1 -1
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +6 -7
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +2 -2
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +1 -1
- data/lib/thinking_sphinx/active_record/column_sql_presenter.rb +34 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/index.rb +2 -1
- data/lib/thinking_sphinx/active_record/interpreter.rb +7 -0
- data/lib/thinking_sphinx/active_record/property.rb +1 -1
- data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +10 -16
- data/lib/thinking_sphinx/active_record/sql_builder.rb +7 -1
- data/lib/thinking_sphinx/active_record/sql_builder/query.rb +0 -7
- data/lib/thinking_sphinx/active_record/sql_source.rb +20 -20
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +1 -1
- data/lib/thinking_sphinx/capistrano.rb +6 -65
- data/lib/thinking_sphinx/capistrano/v2.rb +58 -0
- data/lib/thinking_sphinx/capistrano/v3.rb +101 -0
- data/lib/thinking_sphinx/configuration.rb +8 -3
- data/lib/thinking_sphinx/configuration/distributed_indices.rb +29 -0
- data/lib/thinking_sphinx/connection.rb +90 -34
- data/lib/thinking_sphinx/controller.rb +20 -0
- data/lib/thinking_sphinx/core/index.rb +4 -0
- data/lib/thinking_sphinx/deletion.rb +15 -11
- data/lib/thinking_sphinx/deltas.rb +9 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +2 -0
- data/lib/thinking_sphinx/distributed.rb +5 -0
- data/lib/thinking_sphinx/distributed/index.rb +24 -0
- data/lib/thinking_sphinx/excerpter.rb +7 -3
- data/lib/thinking_sphinx/facet_search.rb +1 -1
- data/lib/thinking_sphinx/index.rb +2 -6
- data/lib/thinking_sphinx/index_set.rb +10 -8
- data/lib/thinking_sphinx/middlewares.rb +0 -2
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +1 -0
- data/lib/thinking_sphinx/middlewares/geographer.rb +1 -1
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +8 -6
- data/lib/thinking_sphinx/middlewares/utf8.rb +6 -1
- data/lib/thinking_sphinx/query.rb +9 -0
- data/lib/thinking_sphinx/railtie.rb +0 -13
- data/lib/thinking_sphinx/search/query.rb +3 -21
- data/lib/thinking_sphinx/sphinxql.rb +1 -1
- data/lib/thinking_sphinx/wildcard.rb +34 -0
- data/spec/acceptance/geosearching_spec.rb +13 -0
- data/spec/acceptance/indexing_spec.rb +27 -0
- data/spec/acceptance/remove_deleted_records_spec.rb +8 -0
- data/spec/acceptance/searching_with_sti_spec.rb +7 -0
- data/spec/acceptance/searching_within_a_model_spec.rb +8 -0
- data/spec/acceptance/sorting_search_results_spec.rb +1 -1
- data/spec/acceptance/spec_helper.rb +13 -0
- data/spec/acceptance/specifying_sql_spec.rb +2 -2
- data/spec/acceptance/support/sphinx_controller.rb +5 -5
- data/spec/acceptance/support/sphinx_helpers.rb +3 -0
- data/spec/acceptance/suspended_deltas_spec.rb +34 -0
- data/spec/internal/config/database.yml +1 -0
- data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +13 -6
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +2 -2
- data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +7 -0
- data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +6 -0
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +27 -0
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +18 -7
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +17 -7
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +84 -82
- data/spec/thinking_sphinx/configuration_spec.rb +5 -4
- data/spec/thinking_sphinx/connection_spec.rb +1 -1
- data/spec/thinking_sphinx/deletion_spec.rb +10 -28
- data/spec/thinking_sphinx/excerpter_spec.rb +3 -3
- data/spec/thinking_sphinx/facet_search_spec.rb +13 -4
- data/spec/thinking_sphinx/index_set_spec.rb +9 -4
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +8 -0
- data/spec/thinking_sphinx/middlewares/geographer_spec.rb +7 -7
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +17 -1
- data/spec/thinking_sphinx/search/query_spec.rb +10 -53
- data/spec/thinking_sphinx/wildcard_spec.rb +41 -0
- data/thinking-sphinx.gemspec +6 -5
- metadata +38 -14
- data/lib/thinking_sphinx/active_record/associations.rb +0 -98
- data/spec/thinking_sphinx/active_record/associations_spec.rb +0 -230
|
@@ -90,11 +90,12 @@ describe ThinkingSphinx::Configuration do
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "uses app/indices in the Rails engines" do
|
|
93
|
-
engine =
|
|
94
|
-
|
|
95
|
-
} }
|
|
93
|
+
engine = double :engine, { :paths => { 'app/indices' =>
|
|
94
|
+
double(:path, { :existent => '/engine/app/indices' } )
|
|
95
|
+
} }
|
|
96
|
+
engine_class = double :instance => engine
|
|
96
97
|
|
|
97
|
-
Rails::Engine
|
|
98
|
+
Rails::Engine.should_receive(:subclasses).and_return([ engine_class ])
|
|
98
99
|
|
|
99
100
|
config.index_paths.should include('/engine/app/indices')
|
|
100
101
|
end
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
|
3
3
|
describe ThinkingSphinx::Connection do
|
|
4
4
|
describe '.take' do
|
|
5
5
|
let(:pool) { double 'pool' }
|
|
6
|
-
let(:connection) { double 'connection' }
|
|
6
|
+
let(:connection) { double 'connection', :base_error => StandardError }
|
|
7
7
|
let(:error) { ThinkingSphinx::QueryExecutionError.new 'failed' }
|
|
8
8
|
let(:translated_error) { ThinkingSphinx::SphinxError.new }
|
|
9
9
|
|
|
@@ -4,8 +4,7 @@ describe ThinkingSphinx::Deletion do
|
|
|
4
4
|
describe '.perform' do
|
|
5
5
|
let(:connection) { double('connection', :execute => nil) }
|
|
6
6
|
let(:index) { double('index', :name => 'foo_core',
|
|
7
|
-
:document_id_for_key => 14, :type => 'plain') }
|
|
8
|
-
let(:instance) { double('instance', :id => 7) }
|
|
7
|
+
:document_id_for_key => 14, :type => 'plain', :distributed? => false) }
|
|
9
8
|
|
|
10
9
|
before :each do
|
|
11
10
|
ThinkingSphinx::Connection.stub(:take).and_yield(connection)
|
|
@@ -14,30 +13,13 @@ describe ThinkingSphinx::Deletion do
|
|
|
14
13
|
|
|
15
14
|
context 'index is SQL-backed' do
|
|
16
15
|
it "updates the deleted flag to false" do
|
|
17
|
-
connection.should_receive(:execute).with
|
|
16
|
+
connection.should_receive(:execute).with <<-SQL
|
|
17
|
+
UPDATE foo_core
|
|
18
|
+
SET sphinx_deleted = 1
|
|
19
|
+
WHERE id IN (14)
|
|
20
|
+
SQL
|
|
18
21
|
|
|
19
|
-
ThinkingSphinx::Deletion.perform index,
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "builds the update query for the given index" do
|
|
23
|
-
Riddle::Query.should_receive(:update).
|
|
24
|
-
with('foo_core', anything, anything).and_return('')
|
|
25
|
-
|
|
26
|
-
ThinkingSphinx::Deletion.perform index, instance
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "builds the update query for the sphinx document id" do
|
|
30
|
-
Riddle::Query.should_receive(:update).
|
|
31
|
-
with(anything, 14, anything).and_return('')
|
|
32
|
-
|
|
33
|
-
ThinkingSphinx::Deletion.perform index, instance
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "builds the update query for setting sphinx_deleted to true" do
|
|
37
|
-
Riddle::Query.should_receive(:update).
|
|
38
|
-
with(anything, anything, :sphinx_deleted => true).and_return('')
|
|
39
|
-
|
|
40
|
-
ThinkingSphinx::Deletion.perform index, instance
|
|
22
|
+
ThinkingSphinx::Deletion.perform index, 7
|
|
41
23
|
end
|
|
42
24
|
|
|
43
25
|
it "doesn't care about Sphinx errors" do
|
|
@@ -45,7 +27,7 @@ describe ThinkingSphinx::Deletion do
|
|
|
45
27
|
and_raise(ThinkingSphinx::ConnectionError.new(''))
|
|
46
28
|
|
|
47
29
|
lambda {
|
|
48
|
-
ThinkingSphinx::Deletion.perform index,
|
|
30
|
+
ThinkingSphinx::Deletion.perform index, 7
|
|
49
31
|
}.should_not raise_error
|
|
50
32
|
end
|
|
51
33
|
end
|
|
@@ -59,7 +41,7 @@ describe ThinkingSphinx::Deletion do
|
|
|
59
41
|
connection.should_receive(:execute).
|
|
60
42
|
with('DELETE FROM foo_core WHERE id = 14')
|
|
61
43
|
|
|
62
|
-
ThinkingSphinx::Deletion.perform index,
|
|
44
|
+
ThinkingSphinx::Deletion.perform index, 7
|
|
63
45
|
end
|
|
64
46
|
|
|
65
47
|
it "doesn't care about Sphinx errors" do
|
|
@@ -67,7 +49,7 @@ describe ThinkingSphinx::Deletion do
|
|
|
67
49
|
and_raise(ThinkingSphinx::ConnectionError.new(''))
|
|
68
50
|
|
|
69
51
|
lambda {
|
|
70
|
-
ThinkingSphinx::Deletion.perform index,
|
|
52
|
+
ThinkingSphinx::Deletion.perform index, 7
|
|
71
53
|
}.should_not raise_error
|
|
72
54
|
end
|
|
73
55
|
end
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
|
3
3
|
describe ThinkingSphinx::Excerpter do
|
|
4
4
|
let(:excerpter) { ThinkingSphinx::Excerpter.new('index', 'all words') }
|
|
5
5
|
let(:connection) {
|
|
6
|
-
double('connection', :
|
|
6
|
+
double('connection', :execute => [{'snippet' => 'some highlighted words'}])
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
before :each do
|
|
@@ -35,14 +35,14 @@ describe ThinkingSphinx::Excerpter do
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "sends the snippets call to Sphinx" do
|
|
38
|
-
connection.should_receive(:
|
|
38
|
+
connection.should_receive(:execute).with('CALL SNIPPETS').
|
|
39
39
|
and_return([{'snippet' => ''}])
|
|
40
40
|
|
|
41
41
|
excerpter.excerpt!('all of the words')
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "returns the first value returned by Sphinx" do
|
|
45
|
-
connection.stub :
|
|
45
|
+
connection.stub :execute => [{'snippet' => 'some highlighted words'}]
|
|
46
46
|
|
|
47
47
|
excerpter.excerpt!('all of the words').should == 'some highlighted words'
|
|
48
48
|
end
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'thinking_sphinx/facet_search'
|
|
4
|
-
require 'thinking_sphinx/facet'
|
|
1
|
+
require 'spec_helper'
|
|
5
2
|
|
|
6
3
|
describe ThinkingSphinx::FacetSearch do
|
|
7
4
|
let(:facet_search) { ThinkingSphinx::FacetSearch.new '', {} }
|
|
@@ -118,6 +115,18 @@ describe ThinkingSphinx::FacetSearch do
|
|
|
118
115
|
search.options[setting].should == 42
|
|
119
116
|
}
|
|
120
117
|
end
|
|
118
|
+
|
|
119
|
+
it "allows separate #{setting} and max_matches settings to support pagination" do
|
|
120
|
+
configuration.settings['max_matches'] = 500
|
|
121
|
+
facet_search = ThinkingSphinx::FacetSearch.new '', {setting => 10}
|
|
122
|
+
|
|
123
|
+
facet_search.populate
|
|
124
|
+
|
|
125
|
+
batch.searches.each do |search|
|
|
126
|
+
search.options[setting].should == 10
|
|
127
|
+
search.options[:max_matches].should == 500
|
|
128
|
+
end
|
|
129
|
+
end
|
|
121
130
|
end
|
|
122
131
|
end
|
|
123
132
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module ThinkingSphinx; end
|
|
2
2
|
|
|
3
3
|
require 'active_support/core_ext/string/inflections'
|
|
4
|
+
require 'active_support/core_ext/module/delegation'
|
|
4
5
|
require 'thinking_sphinx/index_set'
|
|
5
6
|
|
|
6
7
|
describe ThinkingSphinx::IndexSet do
|
|
@@ -29,10 +30,14 @@ describe ThinkingSphinx::IndexSet do
|
|
|
29
30
|
set.to_a
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
it "returns all indices when no models or indices are specified" do
|
|
33
|
-
article_core = double
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
it "returns all non-distributed indices when no models or indices are specified" do
|
|
34
|
+
article_core = double 'index', :name => 'article_core',
|
|
35
|
+
:distributed? => false
|
|
36
|
+
user_core = double 'index', :name => 'user_core',
|
|
37
|
+
:distributed? => false
|
|
38
|
+
distributed = double 'index', :name => 'user', :distributed? => true
|
|
39
|
+
|
|
40
|
+
configuration.indices.replace [article_core, user_core, distributed]
|
|
36
41
|
|
|
37
42
|
set.to_a.should == [article_core, user_core]
|
|
38
43
|
end
|
|
@@ -143,6 +143,14 @@ describe ThinkingSphinx::Middlewares::ActiveRecordTranslator do
|
|
|
143
143
|
|
|
144
144
|
middleware.call [context]
|
|
145
145
|
end
|
|
146
|
+
|
|
147
|
+
it "passes through SQL group options to the relation" do
|
|
148
|
+
search.options[:sql] = {:group => :column}
|
|
149
|
+
|
|
150
|
+
relation.should_receive(:group).with(:column).and_return(relation)
|
|
151
|
+
|
|
152
|
+
middleware.call [context]
|
|
153
|
+
end
|
|
146
154
|
end
|
|
147
155
|
end
|
|
148
156
|
end
|
|
@@ -26,7 +26,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "doesn't add anything if :geo is nil" do
|
|
29
|
-
sphinx_sql.should_not_receive(:
|
|
29
|
+
sphinx_sql.should_not_receive(:prepend_values)
|
|
30
30
|
|
|
31
31
|
middleware.call [context]
|
|
32
32
|
end
|
|
@@ -38,7 +38,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "adds the geodist function when given a :geo option" do
|
|
41
|
-
sphinx_sql.should_receive(:
|
|
41
|
+
sphinx_sql.should_receive(:prepend_values).
|
|
42
42
|
with('GEODIST(0.1, 0.2, lat, lng) AS geodist').
|
|
43
43
|
and_return(sphinx_sql)
|
|
44
44
|
|
|
@@ -46,7 +46,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it "adds the distance pane" do
|
|
49
|
-
sphinx_sql.stub :
|
|
49
|
+
sphinx_sql.stub :prepend_values => sphinx_sql
|
|
50
50
|
|
|
51
51
|
middleware.call [context]
|
|
52
52
|
|
|
@@ -57,7 +57,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
57
57
|
search.options[:latitude_attr] = 'side_to_side'
|
|
58
58
|
search.options[:longitude_attr] = 'up_or_down'
|
|
59
59
|
|
|
60
|
-
sphinx_sql.should_receive(:
|
|
60
|
+
sphinx_sql.should_receive(:prepend_values).
|
|
61
61
|
with('GEODIST(0.1, 0.2, side_to_side, up_or_down) AS geodist').
|
|
62
62
|
and_return(sphinx_sql)
|
|
63
63
|
|
|
@@ -68,7 +68,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
68
68
|
context[:indices] << double('index',
|
|
69
69
|
:unique_attribute_names => ['latitude'], :name => 'an_index')
|
|
70
70
|
|
|
71
|
-
sphinx_sql.should_receive(:
|
|
71
|
+
sphinx_sql.should_receive(:prepend_values).
|
|
72
72
|
with('GEODIST(0.1, 0.2, latitude, lng) AS geodist').
|
|
73
73
|
and_return(sphinx_sql)
|
|
74
74
|
|
|
@@ -79,7 +79,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
79
79
|
context[:indices] << double('index',
|
|
80
80
|
:unique_attribute_names => ['longitude'], :name => 'an_index')
|
|
81
81
|
|
|
82
|
-
sphinx_sql.should_receive(:
|
|
82
|
+
sphinx_sql.should_receive(:prepend_values).
|
|
83
83
|
with('GEODIST(0.1, 0.2, lat, longitude) AS geodist').
|
|
84
84
|
and_return(sphinx_sql)
|
|
85
85
|
|
|
@@ -89,7 +89,7 @@ describe ThinkingSphinx::Middlewares::Geographer do
|
|
|
89
89
|
it "handles very small values" do
|
|
90
90
|
search.options[:geo] = [0.0000001, 0.00000000002]
|
|
91
91
|
|
|
92
|
-
sphinx_sql.should_receive(:
|
|
92
|
+
sphinx_sql.should_receive(:prepend_values).
|
|
93
93
|
with('GEODIST(0.0000001, 0.00000000002, lat, lng) AS geodist').
|
|
94
94
|
and_return(sphinx_sql)
|
|
95
95
|
|
|
@@ -23,7 +23,7 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
|
23
23
|
:offset => 0, :per_page => 5) }
|
|
24
24
|
let(:index_set) { [double(:name => 'article_core', :options => {})] }
|
|
25
25
|
let(:sphinx_sql) { double('sphinx_sql', :from => true, :offset => true,
|
|
26
|
-
:limit => true, :where => true, :matching => true) }
|
|
26
|
+
:limit => true, :where => true, :matching => true, :values => true) }
|
|
27
27
|
let(:query) { double('query') }
|
|
28
28
|
let(:configuration) { double('configuration', :settings => {}) }
|
|
29
29
|
|
|
@@ -301,6 +301,22 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
|
301
301
|
middleware.call [context]
|
|
302
302
|
end
|
|
303
303
|
|
|
304
|
+
it "adds the provided group-best count" do
|
|
305
|
+
search.options[:group_best] = 5
|
|
306
|
+
|
|
307
|
+
sphinx_sql.should_receive(:group_best).with(5).and_return(sphinx_sql)
|
|
308
|
+
|
|
309
|
+
middleware.call [context]
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it "adds the provided having clause" do
|
|
313
|
+
search.options[:having] = 'foo > 1'
|
|
314
|
+
|
|
315
|
+
sphinx_sql.should_receive(:having).with('foo > 1').and_return(sphinx_sql)
|
|
316
|
+
|
|
317
|
+
middleware.call [context]
|
|
318
|
+
end
|
|
319
|
+
|
|
304
320
|
it "uses any provided field weights" do
|
|
305
321
|
search.options[:field_weights] = {:title => 3}
|
|
306
322
|
|
|
@@ -6,6 +6,10 @@ require 'active_support/core_ext/object/blank'
|
|
|
6
6
|
require './lib/thinking_sphinx/search/query'
|
|
7
7
|
|
|
8
8
|
describe ThinkingSphinx::Search::Query do
|
|
9
|
+
before :each do
|
|
10
|
+
stub_const 'ThinkingSphinx::Query', double(wildcard: '')
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
describe '#to_s' do
|
|
10
14
|
it "passes through the keyword as provided" do
|
|
11
15
|
query = ThinkingSphinx::Search::Query.new 'pancakes'
|
|
@@ -26,15 +30,17 @@ describe ThinkingSphinx::Search::Query do
|
|
|
26
30
|
end
|
|
27
31
|
|
|
28
32
|
it "automatically stars keywords if requested" do
|
|
29
|
-
|
|
33
|
+
ThinkingSphinx::Query.should_receive(:wildcard).with('cake', true).
|
|
34
|
+
and_return('*cake*')
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
ThinkingSphinx::Search::Query.new('cake', {}, true).to_s
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
it "automatically stars condition keywords if requested" do
|
|
35
|
-
|
|
40
|
+
ThinkingSphinx::Query.should_receive(:wildcard).with('pan', true).
|
|
41
|
+
and_return('*pan*')
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
ThinkingSphinx::Search::Query.new('', {:title => 'pan'}, true).to_s
|
|
38
44
|
end
|
|
39
45
|
|
|
40
46
|
it "does not star the sphinx_internal_class field keyword" do
|
|
@@ -44,49 +50,6 @@ describe ThinkingSphinx::Search::Query do
|
|
|
44
50
|
query.to_s.should == '@sphinx_internal_class_name article'
|
|
45
51
|
end
|
|
46
52
|
|
|
47
|
-
it "treats escapes as word characters" do
|
|
48
|
-
query = ThinkingSphinx::Search::Query.new '', {:title => 'sauce\\@pan'},
|
|
49
|
-
true
|
|
50
|
-
|
|
51
|
-
query.to_s.should == '@title *sauce\\@pan*'
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "does not star manually provided field tags" do
|
|
55
|
-
query = ThinkingSphinx::Search::Query.new "@title pan", {}, true
|
|
56
|
-
|
|
57
|
-
query.to_s.should == "@title *pan*"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "does not star manually provided arrays of field tags" do
|
|
61
|
-
query = ThinkingSphinx::Search::Query.new "@(title, body) pan", {}, true
|
|
62
|
-
|
|
63
|
-
query.to_s.should == "@(title, body) *pan*"
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "stars keywords that begin with an escaped @" do
|
|
67
|
-
query = ThinkingSphinx::Search::Query.new "\\@pan", {}, true
|
|
68
|
-
|
|
69
|
-
query.to_s.should == "*\\@pan*"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it "ignores escaped slashes" do
|
|
73
|
-
query = ThinkingSphinx::Search::Query.new "\\/\\/pan", {}, true
|
|
74
|
-
|
|
75
|
-
query.to_s.should == "\\/\\/*pan*"
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it "does not star quorum operators" do
|
|
79
|
-
query = ThinkingSphinx::Search::Query.new "foo/3", {}, true
|
|
80
|
-
|
|
81
|
-
query.to_s.should == "*foo*/3"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "does not star proximity operators or quoted strings" do
|
|
85
|
-
query = ThinkingSphinx::Search::Query.new %q{"hello world"~3}, {}, true
|
|
86
|
-
|
|
87
|
-
query.to_s.should == %q{"hello world"~3}
|
|
88
|
-
end
|
|
89
|
-
|
|
90
53
|
it "handles null values by removing them from the conditions hash" do
|
|
91
54
|
query = ThinkingSphinx::Search::Query.new '', :title => nil
|
|
92
55
|
|
|
@@ -105,12 +68,6 @@ describe ThinkingSphinx::Search::Query do
|
|
|
105
68
|
query.to_s.should == ''
|
|
106
69
|
end
|
|
107
70
|
|
|
108
|
-
it "handles nil queries when starring" do
|
|
109
|
-
query = ThinkingSphinx::Search::Query.new nil, {}, true
|
|
110
|
-
|
|
111
|
-
query.to_s.should == ''
|
|
112
|
-
end
|
|
113
|
-
|
|
114
71
|
it "allows mixing of blank and non-blank conditions" do
|
|
115
72
|
query = ThinkingSphinx::Search::Query.new 'tasty', :title => 'pancakes',
|
|
116
73
|
:ingredients => nil
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module ThinkingSphinx; end
|
|
2
|
+
|
|
3
|
+
require './lib/thinking_sphinx/wildcard'
|
|
4
|
+
|
|
5
|
+
describe ThinkingSphinx::Wildcard do
|
|
6
|
+
describe '.call' do
|
|
7
|
+
it "does not star quorum operators" do
|
|
8
|
+
ThinkingSphinx::Wildcard.call("foo/3").should == "*foo*/3"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "does not star proximity operators or quoted strings" do
|
|
12
|
+
ThinkingSphinx::Wildcard.call(%q{"hello world"~3}).
|
|
13
|
+
should == %q{"hello world"~3}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "treats slashes as a separator when starring" do
|
|
17
|
+
ThinkingSphinx::Wildcard.call("a\\/c").should == "*a*\\/*c*"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "separates escaping from the end of words" do
|
|
21
|
+
ThinkingSphinx::Wildcard.call("\\(913\\)").should == "\\(*913*\\)"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "ignores escaped slashes" do
|
|
25
|
+
ThinkingSphinx::Wildcard.call("\\/\\/pan").should == "\\/\\/*pan*"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "does not star manually provided field tags" do
|
|
29
|
+
ThinkingSphinx::Wildcard.call("@title pan").should == "@title *pan*"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "does not star manually provided arrays of field tags" do
|
|
33
|
+
ThinkingSphinx::Wildcard.call("@(title, body) pan").
|
|
34
|
+
should == "@(title, body) *pan*"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "handles nil queries" do
|
|
38
|
+
ThinkingSphinx::Wildcard.call(nil).should == ''
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/thinking-sphinx.gemspec
CHANGED
|
@@ -3,11 +3,11 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = 'thinking-sphinx'
|
|
6
|
-
s.version = '3.0
|
|
6
|
+
s.version = '3.1.0'
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
|
8
8
|
s.authors = ["Pat Allan"]
|
|
9
9
|
s.email = ["pat@freelancing-gods.com"]
|
|
10
|
-
s.homepage = 'http://pat.github.
|
|
10
|
+
s.homepage = 'http://pat.github.io/thinking-sphinx/'
|
|
11
11
|
s.summary = 'A smart wrapper over Sphinx for ActiveRecord'
|
|
12
12
|
s.description = %Q{An intelligent layer for ActiveRecord (via Rails and Sinatra) for the Sphinx full-text search tool.}
|
|
13
13
|
s.license = 'MIT'
|
|
@@ -23,12 +23,13 @@ Gem::Specification.new do |s|
|
|
|
23
23
|
|
|
24
24
|
s.add_runtime_dependency 'activerecord', '>= 3.1.0'
|
|
25
25
|
s.add_runtime_dependency 'builder', '>= 2.1.2'
|
|
26
|
+
s.add_runtime_dependency 'joiner', '>= 0.2.0'
|
|
26
27
|
s.add_runtime_dependency 'middleware', '>= 0.1.0'
|
|
27
28
|
s.add_runtime_dependency 'innertube', '>= 1.0.2'
|
|
28
|
-
s.add_runtime_dependency 'riddle', '>= 1.5.
|
|
29
|
+
s.add_runtime_dependency 'riddle', '>= 1.5.10'
|
|
29
30
|
|
|
30
|
-
s.add_development_dependency 'appraisal', '~> 0.
|
|
31
|
+
s.add_development_dependency 'appraisal', '~> 0.5.2'
|
|
31
32
|
s.add_development_dependency 'combustion', '~> 0.4.0'
|
|
32
|
-
s.add_development_dependency 'database_cleaner', '~>
|
|
33
|
+
s.add_development_dependency 'database_cleaner', '~> 1.2.0'
|
|
33
34
|
s.add_development_dependency 'rspec', '~> 2.13.0'
|
|
34
35
|
end
|