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.
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