thinking-sphinx 3.0.6 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +11 -6
  3. data/Appraisals +5 -5
  4. data/Gemfile +3 -3
  5. data/HISTORY +32 -0
  6. data/README.textile +16 -5
  7. data/gemfiles/rails_3_2.gemfile +2 -1
  8. data/gemfiles/rails_4_0.gemfile +3 -2
  9. data/gemfiles/{rails_3_1.gemfile → rails_4_1.gemfile} +3 -2
  10. data/lib/thinking_sphinx.rb +5 -0
  11. data/lib/thinking_sphinx/active_record.rb +2 -1
  12. data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +1 -1
  13. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +6 -7
  14. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +2 -2
  15. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +1 -1
  16. data/lib/thinking_sphinx/active_record/column_sql_presenter.rb +34 -0
  17. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +4 -0
  18. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +4 -0
  19. data/lib/thinking_sphinx/active_record/index.rb +2 -1
  20. data/lib/thinking_sphinx/active_record/interpreter.rb +7 -0
  21. data/lib/thinking_sphinx/active_record/property.rb +1 -1
  22. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +10 -16
  23. data/lib/thinking_sphinx/active_record/sql_builder.rb +7 -1
  24. data/lib/thinking_sphinx/active_record/sql_builder/query.rb +0 -7
  25. data/lib/thinking_sphinx/active_record/sql_source.rb +20 -20
  26. data/lib/thinking_sphinx/active_record/sql_source/template.rb +1 -1
  27. data/lib/thinking_sphinx/capistrano.rb +6 -65
  28. data/lib/thinking_sphinx/capistrano/v2.rb +58 -0
  29. data/lib/thinking_sphinx/capistrano/v3.rb +101 -0
  30. data/lib/thinking_sphinx/configuration.rb +8 -3
  31. data/lib/thinking_sphinx/configuration/distributed_indices.rb +29 -0
  32. data/lib/thinking_sphinx/connection.rb +90 -34
  33. data/lib/thinking_sphinx/controller.rb +20 -0
  34. data/lib/thinking_sphinx/core/index.rb +4 -0
  35. data/lib/thinking_sphinx/deletion.rb +15 -11
  36. data/lib/thinking_sphinx/deltas.rb +9 -0
  37. data/lib/thinking_sphinx/deltas/default_delta.rb +2 -0
  38. data/lib/thinking_sphinx/distributed.rb +5 -0
  39. data/lib/thinking_sphinx/distributed/index.rb +24 -0
  40. data/lib/thinking_sphinx/excerpter.rb +7 -3
  41. data/lib/thinking_sphinx/facet_search.rb +1 -1
  42. data/lib/thinking_sphinx/index.rb +2 -6
  43. data/lib/thinking_sphinx/index_set.rb +10 -8
  44. data/lib/thinking_sphinx/middlewares.rb +0 -2
  45. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +1 -0
  46. data/lib/thinking_sphinx/middlewares/geographer.rb +1 -1
  47. data/lib/thinking_sphinx/middlewares/sphinxql.rb +8 -6
  48. data/lib/thinking_sphinx/middlewares/utf8.rb +6 -1
  49. data/lib/thinking_sphinx/query.rb +9 -0
  50. data/lib/thinking_sphinx/railtie.rb +0 -13
  51. data/lib/thinking_sphinx/search/query.rb +3 -21
  52. data/lib/thinking_sphinx/sphinxql.rb +1 -1
  53. data/lib/thinking_sphinx/wildcard.rb +34 -0
  54. data/spec/acceptance/geosearching_spec.rb +13 -0
  55. data/spec/acceptance/indexing_spec.rb +27 -0
  56. data/spec/acceptance/remove_deleted_records_spec.rb +8 -0
  57. data/spec/acceptance/searching_with_sti_spec.rb +7 -0
  58. data/spec/acceptance/searching_within_a_model_spec.rb +8 -0
  59. data/spec/acceptance/sorting_search_results_spec.rb +1 -1
  60. data/spec/acceptance/spec_helper.rb +13 -0
  61. data/spec/acceptance/specifying_sql_spec.rb +2 -2
  62. data/spec/acceptance/support/sphinx_controller.rb +5 -5
  63. data/spec/acceptance/support/sphinx_helpers.rb +3 -0
  64. data/spec/acceptance/suspended_deltas_spec.rb +34 -0
  65. data/spec/internal/config/database.yml +1 -0
  66. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +13 -6
  67. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +2 -2
  68. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +7 -0
  69. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +6 -0
  70. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +27 -0
  71. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +18 -7
  72. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +17 -7
  73. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +84 -82
  74. data/spec/thinking_sphinx/configuration_spec.rb +5 -4
  75. data/spec/thinking_sphinx/connection_spec.rb +1 -1
  76. data/spec/thinking_sphinx/deletion_spec.rb +10 -28
  77. data/spec/thinking_sphinx/excerpter_spec.rb +3 -3
  78. data/spec/thinking_sphinx/facet_search_spec.rb +13 -4
  79. data/spec/thinking_sphinx/index_set_spec.rb +9 -4
  80. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +8 -0
  81. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +7 -7
  82. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +17 -1
  83. data/spec/thinking_sphinx/search/query_spec.rb +10 -53
  84. data/spec/thinking_sphinx/wildcard_spec.rb +41 -0
  85. data/thinking-sphinx.gemspec +6 -5
  86. metadata +38 -14
  87. data/lib/thinking_sphinx/active_record/associations.rb +0 -98
  88. 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 = stub(:engine, { :paths => { 'app/indices' =>
94
- stub(:path, { :existent => '/engine/app/indices' } )
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::Railties.should_receive(:engines).and_return([ 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('UPDATE STATEMENT')
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, instance
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, instance
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, instance
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, instance
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', :query => [{'snippet' => 'some highlighted words'}])
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(:query).with('CALL SNIPPETS').
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 :query => [{'snippet' => 'some highlighted words'}]
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
- module ThinkingSphinx; end
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('index', :name => 'article_core')
34
- user_core = double('index', :name => 'user_core')
35
- configuration.indices.replace [article_core, user_core]
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(:values)
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(:values).
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 :values => sphinx_sql
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(:values).
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(:values).
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(:values).
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(:values).
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
- query = ThinkingSphinx::Search::Query.new 'cake', {}, true
33
+ ThinkingSphinx::Query.should_receive(:wildcard).with('cake', true).
34
+ and_return('*cake*')
30
35
 
31
- query.to_s.should == '*cake*'
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
- query = ThinkingSphinx::Search::Query.new '', {:title => 'pan'}, true
40
+ ThinkingSphinx::Query.should_receive(:wildcard).with('pan', true).
41
+ and_return('*pan*')
36
42
 
37
- query.to_s.should == '@title *pan*'
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
@@ -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'
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.com/ts/en'
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.9'
29
+ s.add_runtime_dependency 'riddle', '>= 1.5.10'
29
30
 
30
- s.add_development_dependency 'appraisal', '~> 0.4.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', '~> 0.7.1'
33
+ s.add_development_dependency 'database_cleaner', '~> 1.2.0'
33
34
  s.add_development_dependency 'rspec', '~> 2.13.0'
34
35
  end