thorsson_thinking-sphinx 1.3.18 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/README.textile +5 -0
  2. data/VERSION +1 -1
  3. data/features/facets.feature +9 -1
  4. data/features/searching_across_models.feature +1 -1
  5. data/features/sphinx_scopes.feature +26 -0
  6. data/features/step_definitions/scope_steps.rb +4 -0
  7. data/features/thinking_sphinx/models/alpha.rb +1 -0
  8. data/lib/cucumber/thinking_sphinx/external_world.rb +8 -4
  9. data/lib/thinking_sphinx.rb +1 -0
  10. data/lib/thinking_sphinx/active_record.rb +4 -0
  11. data/lib/thinking_sphinx/active_record/scopes.rb +7 -0
  12. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +2 -1
  13. data/lib/thinking_sphinx/auto_version.rb +2 -0
  14. data/lib/thinking_sphinx/bundled_search.rb +44 -0
  15. data/lib/thinking_sphinx/class_facet.rb +3 -2
  16. data/lib/thinking_sphinx/configuration.rb +8 -7
  17. data/lib/thinking_sphinx/context.rb +4 -2
  18. data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
  19. data/lib/thinking_sphinx/facet.rb +6 -5
  20. data/lib/thinking_sphinx/facet_search.rb +51 -23
  21. data/lib/thinking_sphinx/search.rb +75 -32
  22. data/lib/thinking_sphinx/tasks.rb +6 -1
  23. data/spec/thinking_sphinx/active_record/delta_spec.rb +1 -1
  24. data/spec/thinking_sphinx/active_record/scopes_spec.rb +2 -3
  25. data/spec/thinking_sphinx/auto_version_spec.rb +8 -0
  26. data/spec/thinking_sphinx/context_spec.rb +3 -2
  27. data/spec/thinking_sphinx/facet_search_spec.rb +75 -81
  28. data/spec/thinking_sphinx/facet_spec.rb +4 -4
  29. data/spec/thinking_sphinx/search_methods_spec.rb +4 -0
  30. data/spec/thinking_sphinx/search_spec.rb +26 -8
  31. data/spec/thinking_sphinx/test_spec.rb +20 -0
  32. data/tasks/distribution.rb +4 -2
  33. metadata +53 -45
  34. data/features/thinking_sphinx/database.yml +0 -3
@@ -167,3 +167,8 @@ Since I first released this library, there's been quite a few people who have su
167
167
  * James Brooks
168
168
  * Mark Dodwell
169
169
  * Frédéric Malamitsas
170
+ * Jon Gubman
171
+ * Michael Schuerig
172
+ * Ben Hutton
173
+ * Alfonso Jiménez
174
+ * Szymon Nowak
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.18
1
+ 1.3.20
@@ -27,7 +27,7 @@ Feature: Search and browse models by their defined facets
27
27
  And I should have the facet State
28
28
  And I should have the facet Age
29
29
 
30
- Scenario: Requseting float facets
30
+ Scenario: Requesting float facets
31
31
  Given Sphinx is running
32
32
  And I am searching on alphas
33
33
  When I am requesting facet results
@@ -80,3 +80,11 @@ Feature: Search and browse models by their defined facets
80
80
  And I am searching on posts
81
81
  When I am requesting facet results
82
82
  Then the Comment Ids facet should have 9 keys
83
+
84
+ Scenario: Requesting facets from a subclass
85
+ Given Sphinx is running
86
+ And I am searching on animals
87
+ When I am requesting facet results
88
+ And I want classes included
89
+ Then I should have the facet Class
90
+
@@ -7,7 +7,7 @@ Feature: Searching across multiple model
7
7
  Given Sphinx is running
8
8
  When I search for James
9
9
  And I am retrieving the result count
10
- Then I should get a value of 3
10
+ Then I should get a value of 6
11
11
 
12
12
  Scenario: Confirming existance of a document id in a given index
13
13
  Given Sphinx is running
@@ -40,3 +40,29 @@ Feature: Sphinx Scopes
40
40
  When I use the with_first_name scope set to "Andrew"
41
41
  And I am retrieving the scoped result count
42
42
  Then I should get a value of 7
43
+
44
+ Scenario: Counts with scopes and additional query terms
45
+ Given Sphinx is running
46
+ And I am searching on people
47
+ When I use the with_first_name scope set to "Andrew"
48
+ And I am retrieving the scoped result count for "Byrne"
49
+ Then I should get a value of 1
50
+
51
+ Scenario: Default Scope
52
+ Given Sphinx is running
53
+ And I am searching on andrews
54
+ Then I should get 7 results
55
+
56
+ Scenario: Default Scope and additional query terms
57
+ Given Sphinx is running
58
+ And I am searching on andrews
59
+ When I search for "Byrne"
60
+ Then I should get 1 result
61
+
62
+ Scenario: Explicit scope plus search over a default scope
63
+ Given Sphinx is running
64
+ And I am searching on andrews
65
+ When I use the locked_last_name scope
66
+ And I search for "Cecil"
67
+ Then I should get 1 result
68
+
@@ -13,3 +13,7 @@ end
13
13
  When /^I am retrieving the scoped result count$/ do
14
14
  @results = results.search_count
15
15
  end
16
+
17
+ When /^I am retrieving the scoped result count for "([^"]*)"$/ do |query|
18
+ @results = results.search_count query
19
+ end
@@ -14,6 +14,7 @@ class Alpha < ActiveRecord::Base
14
14
 
15
15
  has value, created_at, created_on
16
16
  has cost, :facet => true
17
+ has active
17
18
 
18
19
  set_property :field_weights => {'alternative_name' => 10}
19
20
 
@@ -1,8 +1,12 @@
1
1
  require 'thinking_sphinx/test'
2
2
 
3
- class Cucumber::ThinkingSphinx::ExternalWorld
4
- def initialize(suppress_delta_output = true)
5
- ::ThinkingSphinx::Test.init
6
- ::ThinkingSphinx::Test.start_with_autostop
3
+ module Cucumber
4
+ module ThinkingSphinx
5
+ class ExternalWorld
6
+ def initialize(suppress_delta_output = true)
7
+ ::ThinkingSphinx::Test.init
8
+ ::ThinkingSphinx::Test.start_with_autostop
9
+ end
10
+ end
7
11
  end
8
12
  end
@@ -10,6 +10,7 @@ require 'thinking_sphinx/property'
10
10
  require 'thinking_sphinx/active_record'
11
11
  require 'thinking_sphinx/association'
12
12
  require 'thinking_sphinx/attribute'
13
+ require 'thinking_sphinx/bundled_search'
13
14
  require 'thinking_sphinx/configuration'
14
15
  require 'thinking_sphinx/context'
15
16
  require 'thinking_sphinx/excerpter'
@@ -322,6 +322,10 @@ module ThinkingSphinx
322
322
  end
323
323
  end
324
324
 
325
+ attr_accessor :excerpts
326
+ attr_accessor :sphinx_attributes
327
+ attr_accessor :matching_fields
328
+
325
329
  def in_index?(suffix)
326
330
  self.class.search_for_id self.sphinx_document_id, sphinx_index_name(suffix)
327
331
  end
@@ -53,6 +53,13 @@ module ThinkingSphinx
53
53
 
54
54
  ThinkingSphinx::Search.new(options)
55
55
  end
56
+
57
+ define_method("#{method}_without_default".to_sym) do |*args|
58
+ options = {:classes => classes_option, :ignore_default => true}
59
+ options.merge! block.call(*args)
60
+
61
+ ThinkingSphinx::Search.new(options)
62
+ end
56
63
  end
57
64
  end
58
65
 
@@ -13,7 +13,8 @@ module ThinkingSphinx
13
13
  case model.connection.class.name
14
14
  when "ActiveRecord::ConnectionAdapters::MysqlAdapter",
15
15
  "ActiveRecord::ConnectionAdapters::MysqlplusAdapter",
16
- "ActiveRecord::ConnectionAdapters::Mysql2Adapter"
16
+ "ActiveRecord::ConnectionAdapters::Mysql2Adapter",
17
+ "ActiveRecord::ConnectionAdapters::NullDBAdapter"
17
18
  ThinkingSphinx::MysqlAdapter.new model
18
19
  when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
19
20
  ThinkingSphinx::PostgreSQLAdapter.new model
@@ -5,6 +5,8 @@ module ThinkingSphinx
5
5
  case version
6
6
  when '0.9.8', '0.9.9'
7
7
  require "riddle/#{version}"
8
+ when '1.10-beta'
9
+ require 'riddle/1.10'
8
10
  else
9
11
  STDERR.puts %Q{
10
12
  Sphinx cannot be found on your system. You may need to configure the following
@@ -0,0 +1,44 @@
1
+ module ThinkingSphinx
2
+ class BundledSearch
3
+ attr_reader :client
4
+
5
+ def initialize
6
+ @searches = []
7
+ end
8
+
9
+ def search(*args)
10
+ @searches << ThinkingSphinx.search(*args)
11
+ @searches.last.append_to client
12
+ end
13
+
14
+ def search_for_ids(*args)
15
+ @searches << ThinkingSphinx.search_for_ids(*args)
16
+ @searches.last.append_to client
17
+ end
18
+
19
+ def searches
20
+ populate
21
+ @searches
22
+ end
23
+
24
+ private
25
+
26
+ def client
27
+ @client ||= ThinkingSphinx::Configuration.instance.client
28
+ end
29
+
30
+ def populated?
31
+ @populated
32
+ end
33
+
34
+ def populate
35
+ return if populated?
36
+
37
+ @populated = true
38
+
39
+ client.run.each_with_index do |results, index|
40
+ searches[index].populate_from_queue results
41
+ end
42
+ end
43
+ end
44
+ end
@@ -8,8 +8,9 @@ module ThinkingSphinx
8
8
  "class_crc"
9
9
  end
10
10
 
11
- def value(object, attribute_value)
12
- object.class.name
11
+ def value(object, attribute_hash)
12
+ crc = attribute_hash['class_crc']
13
+ ThinkingSphinx::Configuration.instance.models_by_crc[crc]
13
14
  end
14
15
  end
15
16
  end
@@ -54,13 +54,14 @@ module ThinkingSphinx
54
54
  sql_query_killlist sql_ranged_throttle sql_query_post_index unpack_zlib
55
55
  unpack_mysqlcompress unpack_mysqlcompress_maxsize )
56
56
 
57
- IndexOptions = %w( charset_table charset_type charset_dictpath docinfo
58
- enable_star exceptions html_index_attrs html_remove_elements html_strip
59
- index_exact_words ignore_chars inplace_docinfo_gap inplace_enable
60
- inplace_hit_gap inplace_reloc_factor inplace_write_factor min_infix_len
61
- min_prefix_len min_stemming_len min_word_len mlock morphology ngram_chars
62
- ngram_len ondisk_dict overshort_step phrase_boundary phrase_boundary_step
63
- preopen stopwords stopwords_step wordforms )
57
+ IndexOptions = %w( blend_chars charset_table charset_type charset_dictpath
58
+ docinfo enable_star exceptions expand_keywords hitless_words
59
+ html_index_attrs html_remove_elements html_strip index_exact_words
60
+ ignore_chars inplace_docinfo_gap inplace_enable inplace_hit_gap
61
+ inplace_reloc_factor inplace_write_factor min_infix_len min_prefix_len
62
+ min_stemming_len min_word_len mlock morphology ngram_chars ngram_len
63
+ ondisk_dict overshort_step phrase_boundary phrase_boundary_step preopen
64
+ stopwords stopwords_step wordforms )
64
65
 
65
66
  CustomOptions = %w( disable_range )
66
67
 
@@ -65,8 +65,10 @@ class ThinkingSphinx::Context
65
65
  model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
66
66
  rescue NameError
67
67
  next
68
- rescue StandardError
69
- STDERR.puts "Warning: Error loading #{file}"
68
+ rescue StandardError => err
69
+ STDERR.puts "Warning: Error loading #{file}:"
70
+ STDERR.puts err.message
71
+ STDERR.puts err.backtrace.join("\n"), ''
70
72
  end
71
73
  end
72
74
  end
@@ -44,7 +44,7 @@ module ThinkingSphinx
44
44
  config = ThinkingSphinx::Configuration.instance
45
45
  rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : ""
46
46
 
47
- output = `#{config.bin_path}#{config.indexer_binary_name} --config '#{config.config_file}' #{rotate} #{model.delta_index_names.join(' ')}`
47
+ output = `#{config.bin_path}#{config.indexer_binary_name} --config "#{config.config_file}" #{rotate} #{model.delta_index_names.join(' ')}`
48
48
  puts(output) unless ThinkingSphinx.suppress_delta_output?
49
49
  end
50
50
 
@@ -71,7 +71,12 @@ module ThinkingSphinx
71
71
  @property.is_a?(Field) ? :string : @property.type
72
72
  end
73
73
 
74
- def value(object, attribute_value)
74
+ def float?
75
+ @property.type == :float
76
+ end
77
+
78
+ def value(object, attribute_hash)
79
+ attribute_value = attribute_hash['@groupby']
75
80
  return translate(object, attribute_value) if translate? || float?
76
81
 
77
82
  case @property.type
@@ -117,9 +122,5 @@ module ThinkingSphinx
117
122
  def column
118
123
  @property.columns.first
119
124
  end
120
-
121
- def float?
122
- @property.type == :float
123
- end
124
125
  end
125
126
  end
@@ -44,23 +44,21 @@ module ThinkingSphinx
44
44
  end
45
45
 
46
46
  def populate
47
- facet_names.each do |name|
48
- search_options = facet_search_options.merge(:group_by => name)
49
- add_from_results name, ThinkingSphinx.search(
50
- *(args + [search_options])
51
- )
52
- end
47
+ ThinkingSphinx::Search.bundle_searches(facet_names) { |sphinx, name|
48
+ sphinx.search *(args + [facet_search_options(name)])
49
+ }.each_with_index { |search, index|
50
+ add_from_results facet_names[index], search
51
+ }
53
52
  end
54
53
 
55
- def facet_search_options
56
- config = ThinkingSphinx::Configuration.instance
57
- max = config.configuration.searchd.max_matches || 1000
58
-
54
+ def facet_search_options(facet_name)
59
55
  options.merge(
60
56
  :group_function => :attr,
61
- :limit => max,
62
- :max_matches => max,
63
- :page => 1
57
+ :limit => max_matches,
58
+ :max_matches => max_matches,
59
+ :page => 1,
60
+ :group_by => facet_name,
61
+ :ids_only => !translate?(facet_name)
64
62
  )
65
63
  end
66
64
 
@@ -101,21 +99,34 @@ module ThinkingSphinx
101
99
  }
102
100
  end
103
101
 
104
- def add_from_results(facet, results)
105
- name = ThinkingSphinx::Facet.name_for(facet)
102
+ def translate?(name)
103
+ facet = facet_from_name(name)
104
+ facet.translate? || facet.float?
105
+ end
106
+
107
+ def config
108
+ ThinkingSphinx::Configuration.instance
109
+ end
110
+
111
+ def max_matches
112
+ @max_matches ||= config.configuration.searchd.max_matches || 1000
113
+ end
114
+
115
+ # example: facet = country_facet; name = :country
116
+ def add_from_results(facet, search)
117
+ name = ThinkingSphinx::Facet.name_for(facet)
118
+ facet = facet_from_name(facet)
106
119
 
107
120
  self[name] ||= {}
108
121
 
109
- return if results.empty?
110
-
111
- facet = facet_from_object(results.first, facet) if facet.is_a?(String)
122
+ return if search.empty?
112
123
 
113
- results.each_with_groupby_and_count { |result, group, count|
114
- facet_value = facet.value(result, group)
124
+ search.each_with_match do |result, match|
125
+ facet_value = facet.value(result, match[:attributes])
115
126
 
116
127
  self[name][facet_value] ||= 0
117
- self[name][facet_value] += count
118
- }
128
+ self[name][facet_value] += match[:attributes]["@count"]
129
+ end
119
130
  end
120
131
 
121
132
  def underlying_value(key, value)
@@ -130,7 +141,24 @@ module ThinkingSphinx
130
141
  end
131
142
 
132
143
  def facet_from_object(object, name)
133
- object.sphinx_facets.detect { |facet| facet.attribute_name == name }
144
+ facet = nil
145
+ klass = object.class
146
+
147
+ while klass != ::ActiveRecord::Base && facet.nil?
148
+ facet = klass.sphinx_facets.detect { |facet|
149
+ facet.attribute_name == name
150
+ }
151
+ klass = klass.superclass
152
+ end
153
+
154
+ facet
155
+ end
156
+
157
+ def facet_from_name(name)
158
+ name = ThinkingSphinx::Facet.name_for(name)
159
+ all_facets.detect { |facet|
160
+ facet.name == name
161
+ }
134
162
  end
135
163
  end
136
164
  end
@@ -57,6 +57,18 @@ module ThinkingSphinx
57
57
  ThinkingSphinx.facets *args
58
58
  end
59
59
 
60
+ def self.bundle_searches(enum = nil)
61
+ bundle = ThinkingSphinx::BundledSearch.new
62
+
63
+ if enum.nil?
64
+ yield bundle
65
+ else
66
+ enum.each { |item| yield bundle, item }
67
+ end
68
+
69
+ bundle.searches
70
+ end
71
+
60
72
  def self.matching_fields(fields, bitmask)
61
73
  matches = []
62
74
  bitstring = bitmask.to_s(2).rjust(32, '0').reverse
@@ -74,6 +86,8 @@ module ThinkingSphinx
74
86
  @options = args.extract_options!
75
87
  @args = args
76
88
 
89
+ add_default_scope unless options[:ignore_default]
90
+
77
91
  populate if @options[:populate]
78
92
  end
79
93
 
@@ -111,6 +125,7 @@ module ThinkingSphinx
111
125
  add_scope(method, *args, &block)
112
126
  return self
113
127
  elsif method == :search_count
128
+ merge_search one_class.search(*args)
114
129
  return scoped_count
115
130
  elsif method.to_s[/^each_with_.*/].nil? && !@array.respond_to?(method)
116
131
  super
@@ -186,6 +201,17 @@ module ThinkingSphinx
186
201
  # Compatibility with older versions of will_paginate
187
202
  alias_method :page_count, :total_pages
188
203
 
204
+ # Query time taken
205
+ #
206
+ # @return [Integer]
207
+ #
208
+ def query_time
209
+ populate
210
+ return 0 if @results[:time].nil?
211
+
212
+ @query_time ||= @results[:time]
213
+ end
214
+
189
215
  # The total number of search results available.
190
216
  #
191
217
  # @return [Integer]
@@ -232,6 +258,13 @@ module ThinkingSphinx
232
258
  end
233
259
  end
234
260
 
261
+ def each_with_match(&block)
262
+ populate
263
+ results[:matches].each_with_index do |match, index|
264
+ yield self[index], match
265
+ end
266
+ end
267
+
235
268
  def excerpt_for(string, model = nil)
236
269
  if model.nil? && one_class
237
270
  model ||= one_class
@@ -241,16 +274,45 @@ module ThinkingSphinx
241
274
  client.excerpts(
242
275
  :docs => [string],
243
276
  :words => results[:words].keys.join(' '),
244
- :index => "#{model.source_of_sphinx_index.sphinx_name}_core"
277
+ :index => options[:index] || "#{model.source_of_sphinx_index.sphinx_name}_core"
245
278
  ).first
246
279
  end
247
280
 
248
281
  def search(*args)
249
- add_default_scope
282
+ args << args.extract_options!.merge(:ignore_default => true)
250
283
  merge_search ThinkingSphinx::Search.new(*args)
251
284
  self
252
285
  end
253
286
 
287
+ def client
288
+ client = options[:client] || config.client
289
+
290
+ prepare client
291
+ end
292
+
293
+ def append_to(client)
294
+ prepare client
295
+ client.append_query query, indexes, comment
296
+ client.reset
297
+ end
298
+
299
+ def populate_from_queue(results)
300
+ return if @populated
301
+ @populated = true
302
+ @results = results
303
+
304
+ if options[:ids_only]
305
+ replace @results[:matches].collect { |match|
306
+ match[:attributes]["sphinx_internal_id"]
307
+ }
308
+ else
309
+ replace instances_from_matches
310
+ add_excerpter
311
+ add_sphinx_attributes
312
+ add_matching_fields if client.rank_mode == :fieldmask
313
+ end
314
+ end
315
+
254
316
  private
255
317
 
256
318
  def config
@@ -289,43 +351,32 @@ module ThinkingSphinx
289
351
 
290
352
  def add_excerpter
291
353
  each do |object|
292
- next if object.respond_to?(:excerpts)
354
+ next if object.nil?
293
355
 
294
- excerpter = ThinkingSphinx::Excerpter.new self, object
295
- block = lambda { excerpter }
296
-
297
- object.singleton_class.instance_eval do
298
- define_method(:excerpts, &block)
299
- end
356
+ object.excerpts = ThinkingSphinx::Excerpter.new self, object
300
357
  end
301
358
  end
302
359
 
303
360
  def add_sphinx_attributes
304
361
  each do |object|
305
- next if object.nil? || object.respond_to?(:sphinx_attributes)
362
+ next if object.nil?
306
363
 
307
364
  match = match_hash object
308
365
  next if match.nil?
309
366
 
310
- object.singleton_class.instance_eval do
311
- define_method(:sphinx_attributes) { match[:attributes] }
312
- end
367
+ object.sphinx_attributes = match[:attributes]
313
368
  end
314
369
  end
315
370
 
316
371
  def add_matching_fields
317
372
  each do |object|
318
- next if object.nil? || object.respond_to?(:matching_fields)
373
+ next if object.nil?
319
374
 
320
375
  match = match_hash object
321
376
  next if match.nil?
322
- fields = ThinkingSphinx::Search.matching_fields(
377
+ object.matching_fields = ThinkingSphinx::Search.matching_fields(
323
378
  @results[:fields], match[:weight]
324
379
  )
325
-
326
- object.singleton_class.instance_eval do
327
- define_method(:matching_fields) { fields }
328
- end
329
380
  end
330
381
  end
331
382
 
@@ -349,9 +400,7 @@ module ThinkingSphinx
349
400
  self.class.log(*args)
350
401
  end
351
402
 
352
- def client
353
- client = config.client
354
-
403
+ def prepare(client)
355
404
  index_options = one_class ?
356
405
  one_class.sphinx_indexes.first.local_options : {}
357
406
 
@@ -588,14 +637,6 @@ MSG
588
637
  end
589
638
 
590
639
  # When passed a Time instance, returns the integer timestamp.
591
- #
592
- # If using Rails 2.1+, need to handle timezones to translate them back to
593
- # UTC, as that's what datetimes will be stored as by MySQL.
594
- #
595
- # in_time_zone is a method that was added for the timezone support in
596
- # Rails 2.1, which is why it's used for testing. I'm sure there's better
597
- # ways, but this does the job.
598
- #
599
640
  def filter_value(value)
600
641
  case value
601
642
  when Range
@@ -603,7 +644,7 @@ MSG
603
644
  when Array
604
645
  value.collect { |v| filter_value(v) }.flatten
605
646
  when Time
606
- value.respond_to?(:in_time_zone) ? [value.utc.to_i] : [value.to_i]
647
+ [value.to_i]
607
648
  when NilClass
608
649
  0
609
650
  else
@@ -747,10 +788,12 @@ MSG
747
788
 
748
789
  # Adds the default_sphinx_scope if set.
749
790
  def add_default_scope
750
- add_scope(one_class.get_default_sphinx_scope) if one_class && one_class.has_default_sphinx_scope?
791
+ return unless one_class && one_class.has_default_sphinx_scope?
792
+ add_scope(one_class.get_default_sphinx_scope.to_sym)
751
793
  end
752
794
 
753
795
  def add_scope(method, *args, &block)
796
+ method = "#{method}_without_default".to_sym
754
797
  merge_search one_class.send(method, *args, &block)
755
798
  end
756
799
 
@@ -4,7 +4,12 @@ namespace :thinking_sphinx do
4
4
  task :app_env do
5
5
  if defined?(RAILS_ROOT)
6
6
  Rake::Task[:environment].invoke
7
- Rails.configuration.cache_classes = false
7
+
8
+ if defined?(Rails.configuration)
9
+ Rails.configuration.cache_classes = false
10
+ else
11
+ Rails::Initializer.run { |config| config.cache_classes = false }
12
+ end
8
13
  end
9
14
 
10
15
  Rake::Task[:merb_env].invoke if defined?(Merb)
@@ -106,7 +106,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
106
106
 
107
107
  it "should call indexer for the delta index" do
108
108
  Person.sphinx_indexes.first.delta_object.should_receive(:`).with(
109
- "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config '#{ThinkingSphinx::Configuration.instance.config_file}' --rotate person_delta"
109
+ "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config \"#{ThinkingSphinx::Configuration.instance.config_file}\" --rotate person_delta"
110
110
  )
111
111
 
112
112
  @person.send(:index_delta)
@@ -87,10 +87,9 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
87
87
  search.by_foo('foo').search.options[:conditions].should == {:foo => 'foo', :name => 'foo'}
88
88
  end
89
89
 
90
- # FIXME: Probably the other way around is more logical? How to do this?
91
- it "should apply the default scope options after other scope options to the underlying search object" do
90
+ it "should apply the default scope options before other scope options to the underlying search object" do
92
91
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
93
- search.by_name('bar').search.options[:conditions].should == {:name => 'foo'}
92
+ search.by_name('bar').search.options[:conditions].should == {:name => 'bar'}
94
93
  end
95
94
  end
96
95
 
@@ -22,6 +22,14 @@ describe ThinkingSphinx::AutoVersion do
22
22
  ThinkingSphinx::AutoVersion.detect
23
23
  end
24
24
 
25
+ it "should require 1.10-beta if that is the detected version" do
26
+ ThinkingSphinx::AutoVersion.should_receive(:require).
27
+ with('riddle/1.10')
28
+
29
+ @config.stub!(:version => '1.10-beta')
30
+ ThinkingSphinx::AutoVersion.detect
31
+ end
32
+
25
33
  it "should output a warning if the detected version is something else" do
26
34
  STDERR.should_receive(:puts)
27
35
 
@@ -53,8 +53,9 @@ describe ThinkingSphinx::Context do
53
53
 
54
54
  it "should catch database errors with a warning" do
55
55
  @class_name.should_receive(:constantize).and_raise(Mysql::Error)
56
- STDERR.should_receive(:puts).with('Warning: Error loading a.rb')
57
-
56
+ STDERR.stub!(:puts => '')
57
+ STDERR.should_receive(:puts).with('Warning: Error loading a.rb:')
58
+
58
59
  lambda {
59
60
  @context.prepare
60
61
  }.should_not raise_error
@@ -1,28 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::FacetSearch do
4
+ let(:search) { stub('search', :append_to => nil, :empty? => true) }
5
+ let(:config) { ThinkingSphinx::Configuration.instance }
6
+ let(:client) { stub('client', :run => []) }
7
+
8
+ before :each do
9
+ config.stub!(:client => client)
10
+ end
11
+
4
12
  describe 'populate' do
5
- it "should make separate Sphinx queries for each facet" do
6
- ThinkingSphinx.should_receive(:search).with(
7
- hash_including(:group_by => 'city_facet')
8
- ).and_return([])
9
- ThinkingSphinx.should_receive(:search).with(
10
- hash_including(:group_by => 'state_facet')
11
- ).and_return([])
12
- ThinkingSphinx.should_receive(:search).with(
13
- hash_including(:group_by => 'birthday')
14
- ).and_return([])
15
-
16
- ThinkingSphinx::FacetSearch.new(:classes => [Person])
13
+ before :each do
14
+ config.configuration.searchd.max_matches = 10_000
17
15
  end
18
-
16
+
19
17
  it "should request all shared facets in a multi-model request by default" do
20
- ThinkingSphinx.stub!(:search => [])
18
+ ThinkingSphinx.stub!(:search => search)
21
19
  ThinkingSphinx::FacetSearch.new.facet_names.should == ['class_crc']
22
20
  end
23
21
 
24
22
  it "should request all facets in a multi-model request if specified" do
25
- ThinkingSphinx.stub!(:search => [])
23
+ ThinkingSphinx.stub!(:search => search)
26
24
  ThinkingSphinx::FacetSearch.new(
27
25
  :all_facets => true
28
26
  ).facet_names.should == [
@@ -30,80 +28,22 @@ describe ThinkingSphinx::FacetSearch do
30
28
  ]
31
29
  end
32
30
 
33
- describe ':facets option' do
34
- it "should limit facets to the requested set" do
35
- ThinkingSphinx.should_receive(:search).once.and_return([])
36
-
37
- ThinkingSphinx::FacetSearch.new(
38
- :classes => [Person], :facets => :state
39
- )
40
- end
41
- end
42
-
43
- describe "empty result set for attributes" do
44
- before :each do
45
- ThinkingSphinx.stub!(:search => [])
46
- @facets = ThinkingSphinx::FacetSearch.new(
47
- :classes => [Person], :facets => :state
48
- )
49
- end
50
-
51
- it "should add key as attribute" do
52
- @facets.should have_key(:state)
53
- end
54
-
55
- it "should return an empty hash for the facet results" do
56
- @facets[:state].should be_empty
57
- end
58
- end
59
-
60
- describe "non-empty result set" do
61
- before :each do
62
- @person = Person.find(:first)
63
- @people = [@person]
64
- @people.stub!(:each_with_groupby_and_count).
65
- and_yield(@person, @person.city.to_crc32, 1)
66
- ThinkingSphinx.stub!(:search => @people)
67
-
68
- @facets = ThinkingSphinx::FacetSearch.new(
69
- :classes => [Person], :facets => :city
70
- )
71
- end
72
-
73
- it "should return a hash" do
74
- @facets.should be_a_kind_of(Hash)
75
- end
76
-
77
- it "should add key as attribute" do
78
- @facets.keys.should include(:city)
79
- end
80
-
81
- it "should return a hash" do
82
- @facets[:city].should == {@person.city => 1}
83
- end
84
- end
85
-
86
- before :each do
87
- @config = ThinkingSphinx::Configuration.instance
88
- @config.configuration.searchd.max_matches = 10_000
89
- end
90
-
91
31
  it "should use the system-set max_matches for limit on facet calls" do
92
32
  ThinkingSphinx.should_receive(:search) do |options|
93
33
  options[:max_matches].should == 10_000
94
34
  options[:limit].should == 10_000
95
- []
35
+ search
96
36
  end
97
37
 
98
38
  ThinkingSphinx::FacetSearch.new
99
39
  end
100
40
 
101
41
  it "should use the default max-matches if there is no explicit setting" do
102
- @config.configuration.searchd.max_matches = nil
42
+ config.configuration.searchd.max_matches = nil
103
43
  ThinkingSphinx.should_receive(:search) do |options|
104
44
  options[:max_matches].should == 1000
105
45
  options[:limit].should == 1000
106
- []
46
+ search
107
47
  end
108
48
 
109
49
  ThinkingSphinx::FacetSearch.new
@@ -113,7 +53,7 @@ describe ThinkingSphinx::FacetSearch do
113
53
  ThinkingSphinx.should_receive(:search) do |options|
114
54
  options[:max_matches].should == 10_000
115
55
  options[:limit].should == 10_000
116
- []
56
+ search
117
57
  end
118
58
 
119
59
  ThinkingSphinx::FacetSearch.new(
@@ -125,7 +65,7 @@ describe ThinkingSphinx::FacetSearch do
125
65
  it "should not use an explicit :page" do
126
66
  ThinkingSphinx.should_receive(:search) do |options|
127
67
  options[:page].should == 1
128
- []
68
+ search
129
69
  end
130
70
 
131
71
  ThinkingSphinx::FacetSearch.new(:page => 3)
@@ -149,15 +89,69 @@ describe ThinkingSphinx::FacetSearch do
149
89
  }.should raise_error
150
90
  end
151
91
  end
92
+
93
+ describe ':facets option' do
94
+ it "should limit facets to the requested set" do
95
+ ThinkingSphinx.should_receive(:search).once.and_return(search)
96
+
97
+ ThinkingSphinx::FacetSearch.new(
98
+ :classes => [Person], :facets => :state
99
+ )
100
+ end
101
+ end
102
+
103
+ describe "empty result set for attributes" do
104
+ before :each do
105
+ ThinkingSphinx.stub!(:search => search)
106
+ @facets = ThinkingSphinx::FacetSearch.new(
107
+ :classes => [Person], :facets => :state
108
+ )
109
+ end
110
+
111
+ it "should add key as attribute" do
112
+ @facets.should have_key(:state)
113
+ end
114
+
115
+ it "should return an empty hash for the facet results" do
116
+ @facets[:state].should be_empty
117
+ end
118
+ end
119
+
120
+ describe "non-empty result set" do
121
+ before :each do
122
+ @person = Person.find(:first)
123
+ @people = [@person]
124
+ search.stub!(:empty? => false)
125
+ search.stub!(:each_with_match).
126
+ and_yield(@person, {:attributes => {'@groupby' => @person.city.to_crc32, '@count' => 1}})
127
+ ThinkingSphinx::Search.stub!(:bundle_searches => [search])
128
+
129
+ @facets = ThinkingSphinx::FacetSearch.new(
130
+ :classes => [Person], :facets => :city
131
+ )
132
+ end
133
+
134
+ it "should return a hash" do
135
+ @facets.should be_a_kind_of(Hash)
136
+ end
137
+
138
+ it "should add key as attribute" do
139
+ @facets.keys.should include(:city)
140
+ end
141
+
142
+ it "should return a hash" do
143
+ @facets[:city].should == {@person.city => 1}
144
+ end
145
+ end
152
146
  end
153
147
 
154
148
  describe "#for" do
155
149
  before do
156
150
  @person = Person.find(:first)
157
151
  @people = [@person]
158
- @people.stub!(:each_with_groupby_and_count).
159
- and_yield(@person, @person.city.to_crc32, 1)
160
- ThinkingSphinx.stub!(:search => @people)
152
+ search.stub!(:each_with_match).
153
+ and_yield(@person, {:attributes => {'@groupby' => @person.city.to_crc32, '@count' => 1}})
154
+ ThinkingSphinx::Search.stub!(:bundle_searches => [search])
161
155
 
162
156
  @facets = ThinkingSphinx::FacetSearch.new(
163
157
  :classes => [Person], :facets => :city
@@ -291,13 +291,13 @@ describe ThinkingSphinx::Facet do
291
291
  person = Person.find(:first)
292
292
  friendship = Friendship.new(:person => person)
293
293
 
294
- @facet.value(friendship, 1).should == person.first_name
294
+ @facet.value(friendship, {'first_name_facet' => 1}).should == person.first_name
295
295
  end
296
296
 
297
297
  it "should return nil if the association is nil" do
298
298
  friendship = Friendship.new(:person => nil)
299
299
 
300
- @facet.value(friendship, 1).should be_nil
300
+ @facet.value(friendship, {'first_name_facet' => 1}).should be_nil
301
301
  end
302
302
 
303
303
  it "should return multi-level association values" do
@@ -308,7 +308,7 @@ describe ThinkingSphinx::Facet do
308
308
  field = ThinkingSphinx::Field.new(
309
309
  @source, ThinkingSphinx::Index::FauxColumn.new(:person, :tags, :name)
310
310
  )
311
- ThinkingSphinx::Facet.new(field).value(friendship, 'buried'.to_crc32).
311
+ ThinkingSphinx::Facet.new(field).value(friendship, {'name_facet' => 'buried'.to_crc32}).
312
312
  should == 'buried'
313
313
  end
314
314
  end
@@ -326,7 +326,7 @@ describe ThinkingSphinx::Facet do
326
326
  it "should translate using the given model" do
327
327
  alpha = Alpha.new(:cost => 10.5)
328
328
 
329
- @facet.value(alpha, 1093140480).should == 10.5
329
+ @facet.value(alpha, {'cost' => 1093140480}).should == 10.5
330
330
  end
331
331
  end
332
332
  end
@@ -135,6 +135,10 @@ describe ThinkingSphinx::SearchMethods do
135
135
  end
136
136
 
137
137
  describe '.facets' do
138
+ before :each do
139
+ ThinkingSphinx::Search.stub!(:bundle_searches => [])
140
+ end
141
+
138
142
  it "should return a FacetSearch instance" do
139
143
  Alpha.facets.should be_a(ThinkingSphinx::FacetSearch)
140
144
  end
@@ -785,9 +785,10 @@ describe ThinkingSphinx::Search do
785
785
  end
786
786
 
787
787
  it "should set up the excerpter with the instances and search" do
788
- ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_a)
789
- ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_b)
790
-
788
+ [@alpha_a, @beta_b, @alpha_b, @beta_a].each do |object|
789
+ ThinkingSphinx::Excerpter.should_receive(:new).with(@search, object)
790
+ end
791
+
791
792
  @search.first
792
793
  end
793
794
  end
@@ -822,11 +823,6 @@ describe ThinkingSphinx::Search do
822
823
  search.first.should respond_to(:matching_fields)
823
824
  end
824
825
 
825
- it "should not add matching_fields method if using a different ranking mode" do
826
- search = ThinkingSphinx::Search.new :rank_mode => :bm25
827
- search.first.should_not respond_to(:matching_fields)
828
- end
829
-
830
826
  it "should not add matching_fields method if object already have one" do
831
827
  search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
832
828
  search.last.matching_fields.should_not be_an(Array)
@@ -1112,6 +1108,15 @@ describe ThinkingSphinx::Search do
1112
1108
  @search.excerpt_for('string')
1113
1109
  end
1114
1110
 
1111
+ it "should respect the provided index option" do
1112
+ @search = ThinkingSphinx::Search.new(:classes => [Alpha], :index => 'foo')
1113
+ @client.should_receive(:excerpts) do |options|
1114
+ options[:index].should == 'foo'
1115
+ end
1116
+
1117
+ @search.excerpt_for('string')
1118
+ end
1119
+
1115
1120
  it "should optionally take a second argument to allow for multi-model searches" do
1116
1121
  @client.should_receive(:excerpts) do |options|
1117
1122
  options[:index].should == 'beta_core'
@@ -1197,6 +1202,19 @@ describe ThinkingSphinx::Search do
1197
1202
  @search.freeze.should be_a(ThinkingSphinx::Search)
1198
1203
  end
1199
1204
  end
1205
+
1206
+ describe '#client' do
1207
+ let(:client) { Riddle::Client.new }
1208
+ it "should respect the client in options" do
1209
+ search = ThinkingSphinx::Search.new :client => client
1210
+ search.client.should == client
1211
+ end
1212
+
1213
+ it "should get a new client from the configuration singleton by default" do
1214
+ ThinkingSphinx::Configuration.instance.stub!(:client => client)
1215
+ ThinkingSphinx::Search.new.client.should == client
1216
+ end
1217
+ end
1200
1218
  end
1201
1219
 
1202
1220
  describe ThinkingSphinx::Search, "playing nice with Search model" do
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require "#{File.dirname(__FILE__)}/../../lib/thinking_sphinx/test"
3
+
4
+ describe ThinkingSphinx::Test do
5
+ describe ".run" do
6
+ before :each do
7
+ ThinkingSphinx::Test.stub!(:start)
8
+ end
9
+
10
+ it "should call stop when an exception is raised by passed block" do
11
+ ThinkingSphinx::Test.should_receive(:stop)
12
+
13
+ begin
14
+ ThinkingSphinx::Test.run { raise FakeError }
15
+ rescue => FakeError
16
+ # we raised it manually ourselves!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -23,11 +23,13 @@ Jeweler::Tasks.new do |gem|
23
23
  "VERSION"
24
24
  ]
25
25
  gem.test_files = FileList[
26
- "features/**/*",
26
+ "features/**/*.rb",
27
+ "features/**/*.feature",
28
+ "features/**/*.example.yml",
27
29
  "spec/**/*_spec.rb"
28
30
  ]
29
31
 
30
- gem.add_dependency 'activerecord', '>= 1.15.6'
32
+ gem.add_dependency 'activerecord', '>= 1.15.6', '< 3.0.0'
31
33
  gem.add_dependency 'riddle', '>= 1.0.10'
32
34
  gem.add_dependency 'after_commit', '>= 1.0.6'
33
35
 
metadata CHANGED
@@ -3,10 +3,9 @@ name: thorsson_thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 1
7
- - 3
8
- - 18
9
- version: 1.3.18
6
+ - 2
7
+ - 0
8
+ version: "2.0"
10
9
  platform: ruby
11
10
  authors:
12
11
  - Pat Allan
@@ -14,7 +13,7 @@ autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
15
 
17
- date: 2010-06-29 00:00:00 +02:00
16
+ date: 2010-09-03 00:00:00 +02:00
18
17
  default_executable:
19
18
  dependencies:
20
19
  - !ruby/object:Gem::Dependency
@@ -30,6 +29,13 @@ dependencies:
30
29
  - 15
31
30
  - 6
32
31
  version: 1.15.6
32
+ - - <
33
+ - !ruby/object:Gem::Version
34
+ segments:
35
+ - 3
36
+ - 0
37
+ - 0
38
+ version: 3.0.0
33
39
  type: :runtime
34
40
  version_requirements: *id001
35
41
  - !ruby/object:Gem::Dependency
@@ -175,6 +181,7 @@ files:
175
181
  - lib/thinking_sphinx/association.rb
176
182
  - lib/thinking_sphinx/attribute.rb
177
183
  - lib/thinking_sphinx/auto_version.rb
184
+ - lib/thinking_sphinx/bundled_search.rb
178
185
  - lib/thinking_sphinx/class_facet.rb
179
186
  - lib/thinking_sphinx/configuration.rb
180
187
  - lib/thinking_sphinx/context.rb
@@ -204,24 +211,6 @@ files:
204
211
  - tasks/distribution.rb
205
212
  - tasks/rails.rake
206
213
  - tasks/testing.rb
207
- - features/abstract_inheritance.feature
208
- - features/alternate_primary_key.feature
209
- - features/attribute_transformation.feature
210
- - features/attribute_updates.feature
211
- - features/deleting_instances.feature
212
- - features/direct_attributes.feature
213
- - features/excerpts.feature
214
- - features/extensible_delta_indexing.feature
215
- - features/facets.feature
216
- - features/facets_across_model.feature
217
- - features/handling_edits.feature
218
- - features/retry_stale_indexes.feature
219
- - features/searching_across_models.feature
220
- - features/searching_by_index.feature
221
- - features/searching_by_model.feature
222
- - features/searching_with_find_arguments.feature
223
- - features/sphinx_detection.feature
224
- - features/sphinx_scopes.feature
225
214
  - features/step_definitions/alpha_steps.rb
226
215
  - features/step_definitions/beta_steps.rb
227
216
  - features/step_definitions/common_steps.rb
@@ -232,11 +221,9 @@ files:
232
221
  - features/step_definitions/scope_steps.rb
233
222
  - features/step_definitions/search_steps.rb
234
223
  - features/step_definitions/sphinx_steps.rb
235
- - features/sti_searching.feature
236
224
  - features/support/env.rb
237
225
  - features/support/lib/generic_delta_handler.rb
238
226
  - features/thinking_sphinx/database.example.yml
239
- - features/thinking_sphinx/database.yml
240
227
  - features/thinking_sphinx/db/fixtures/alphas.rb
241
228
  - features/thinking_sphinx/db/fixtures/authors.rb
242
229
  - features/thinking_sphinx/db/fixtures/betas.rb
@@ -293,6 +280,25 @@ files:
293
280
  - features/thinking_sphinx/models/robot.rb
294
281
  - features/thinking_sphinx/models/tag.rb
295
282
  - features/thinking_sphinx/models/tagging.rb
283
+ - features/abstract_inheritance.feature
284
+ - features/alternate_primary_key.feature
285
+ - features/attribute_transformation.feature
286
+ - features/attribute_updates.feature
287
+ - features/deleting_instances.feature
288
+ - features/direct_attributes.feature
289
+ - features/excerpts.feature
290
+ - features/extensible_delta_indexing.feature
291
+ - features/facets.feature
292
+ - features/facets_across_model.feature
293
+ - features/handling_edits.feature
294
+ - features/retry_stale_indexes.feature
295
+ - features/searching_across_models.feature
296
+ - features/searching_by_index.feature
297
+ - features/searching_by_model.feature
298
+ - features/searching_with_find_arguments.feature
299
+ - features/sphinx_detection.feature
300
+ - features/sphinx_scopes.feature
301
+ - features/sti_searching.feature
296
302
  - spec/thinking_sphinx/active_record/delta_spec.rb
297
303
  - spec/thinking_sphinx/active_record/has_many_association_spec.rb
298
304
  - spec/thinking_sphinx/active_record/scopes_spec.rb
@@ -315,6 +321,7 @@ files:
315
321
  - spec/thinking_sphinx/search_methods_spec.rb
316
322
  - spec/thinking_sphinx/search_spec.rb
317
323
  - spec/thinking_sphinx/source_spec.rb
324
+ - spec/thinking_sphinx/test_spec.rb
318
325
  - spec/thinking_sphinx_spec.rb
319
326
  has_rdoc: true
320
327
  homepage: http://ts.freelancing-gods.com
@@ -352,24 +359,6 @@ signing_key:
352
359
  specification_version: 3
353
360
  summary: ActiveRecord/Rails Sphinx library
354
361
  test_files:
355
- - features/abstract_inheritance.feature
356
- - features/alternate_primary_key.feature
357
- - features/attribute_transformation.feature
358
- - features/attribute_updates.feature
359
- - features/deleting_instances.feature
360
- - features/direct_attributes.feature
361
- - features/excerpts.feature
362
- - features/extensible_delta_indexing.feature
363
- - features/facets.feature
364
- - features/facets_across_model.feature
365
- - features/handling_edits.feature
366
- - features/retry_stale_indexes.feature
367
- - features/searching_across_models.feature
368
- - features/searching_by_index.feature
369
- - features/searching_by_model.feature
370
- - features/searching_with_find_arguments.feature
371
- - features/sphinx_detection.feature
372
- - features/sphinx_scopes.feature
373
362
  - features/step_definitions/alpha_steps.rb
374
363
  - features/step_definitions/beta_steps.rb
375
364
  - features/step_definitions/common_steps.rb
@@ -380,11 +369,9 @@ test_files:
380
369
  - features/step_definitions/scope_steps.rb
381
370
  - features/step_definitions/search_steps.rb
382
371
  - features/step_definitions/sphinx_steps.rb
383
- - features/sti_searching.feature
384
372
  - features/support/env.rb
385
373
  - features/support/lib/generic_delta_handler.rb
386
374
  - features/thinking_sphinx/database.example.yml
387
- - features/thinking_sphinx/database.yml
388
375
  - features/thinking_sphinx/db/fixtures/alphas.rb
389
376
  - features/thinking_sphinx/db/fixtures/authors.rb
390
377
  - features/thinking_sphinx/db/fixtures/betas.rb
@@ -441,6 +428,26 @@ test_files:
441
428
  - features/thinking_sphinx/models/robot.rb
442
429
  - features/thinking_sphinx/models/tag.rb
443
430
  - features/thinking_sphinx/models/tagging.rb
431
+ - features/abstract_inheritance.feature
432
+ - features/alternate_primary_key.feature
433
+ - features/attribute_transformation.feature
434
+ - features/attribute_updates.feature
435
+ - features/deleting_instances.feature
436
+ - features/direct_attributes.feature
437
+ - features/excerpts.feature
438
+ - features/extensible_delta_indexing.feature
439
+ - features/facets.feature
440
+ - features/facets_across_model.feature
441
+ - features/handling_edits.feature
442
+ - features/retry_stale_indexes.feature
443
+ - features/searching_across_models.feature
444
+ - features/searching_by_index.feature
445
+ - features/searching_by_model.feature
446
+ - features/searching_with_find_arguments.feature
447
+ - features/sphinx_detection.feature
448
+ - features/sphinx_scopes.feature
449
+ - features/sti_searching.feature
450
+ - features/thinking_sphinx/database.example.yml
444
451
  - spec/thinking_sphinx/active_record/delta_spec.rb
445
452
  - spec/thinking_sphinx/active_record/has_many_association_spec.rb
446
453
  - spec/thinking_sphinx/active_record/scopes_spec.rb
@@ -463,4 +470,5 @@ test_files:
463
470
  - spec/thinking_sphinx/search_methods_spec.rb
464
471
  - spec/thinking_sphinx/search_spec.rb
465
472
  - spec/thinking_sphinx/source_spec.rb
473
+ - spec/thinking_sphinx/test_spec.rb
466
474
  - spec/thinking_sphinx_spec.rb
@@ -1,3 +0,0 @@
1
- username: root
2
- host: localhost
3
- password: