thinking-sphinx 1.3.6 → 1.3.7
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.
- data/VERSION +1 -1
- data/features/facets.feature +6 -0
- data/features/facets_across_model.feature +2 -2
- data/features/step_definitions/facet_steps.rb +4 -0
- data/features/sti_searching.feature +5 -0
- data/features/support/db/fixtures/foxes.rb +3 -0
- data/features/support/models/comment.rb +3 -3
- data/features/support/models/fox.rb +5 -0
- data/features/support/models/post.rb +2 -1
- data/lib/thinking_sphinx.rb +9 -3
- data/lib/thinking_sphinx/active_record.rb +67 -18
- data/lib/thinking_sphinx/configuration.rb +7 -37
- data/lib/thinking_sphinx/context.rb +65 -0
- data/lib/thinking_sphinx/facet_search.rb +3 -1
- data/lib/thinking_sphinx/search.rb +2 -0
- data/lib/thinking_sphinx/source.rb +1 -1
- data/lib/thinking_sphinx/source/sql.rb +1 -1
- data/rails/init.rb +0 -2
- data/spec/thinking_sphinx/active_record_spec.rb +123 -48
- data/spec/thinking_sphinx/configuration_spec.rb +0 -56
- data/spec/thinking_sphinx/context_spec.rb +119 -0
- data/spec/thinking_sphinx/source_spec.rb +1 -1
- data/spec/thinking_sphinx_spec.rb +11 -0
- metadata +6 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.7
|
data/features/facets.feature
CHANGED
@@ -74,3 +74,9 @@ Feature: Search and browse models by their defined facets
|
|
74
74
|
Then the Tags facet should have an "Australia" key
|
75
75
|
Then the Tags facet should have an "Melbourne" key
|
76
76
|
Then the Tags facet should have an "Victoria" key
|
77
|
+
|
78
|
+
Scenario: Requesting MVA facets from source queries
|
79
|
+
Given Sphinx is running
|
80
|
+
And I am searching on posts
|
81
|
+
When I am requesting facet results
|
82
|
+
Then the Comment Ids facet should have 9 keys
|
@@ -5,7 +5,7 @@ Feature: Search and browse across models by their defined facets
|
|
5
5
|
When I am requesting facet results
|
6
6
|
And I want all possible attributes
|
7
7
|
Then I should have valid facet results
|
8
|
-
And I should have
|
8
|
+
And I should have 11 facets
|
9
9
|
And I should have the facet Class
|
10
10
|
And the Class facet should have a "Person" key
|
11
11
|
And I should have the facet Gender
|
@@ -19,7 +19,7 @@ Feature: Search and browse across models by their defined facets
|
|
19
19
|
When I am requesting facet results
|
20
20
|
And I want all possible attributes
|
21
21
|
And I don't want classes included
|
22
|
-
Then I should have
|
22
|
+
Then I should have 10 facets
|
23
23
|
And I should not have the facet Class
|
24
24
|
|
25
25
|
Scenario: Requesting facets common to all indexed models
|
@@ -87,6 +87,10 @@ Then /^the ([\w_\s]+) facet should have an? (\d+\.?\d*) key$/ do |name, key|
|
|
87
87
|
results[facet_name(name)].keys.should include(key)
|
88
88
|
end
|
89
89
|
|
90
|
+
Then /^the ([\w\s]+) facet should have (\d+) keys$/ do |name, count|
|
91
|
+
results[facet_name(name)].keys.length.should == count.to_i
|
92
|
+
end
|
93
|
+
|
90
94
|
def facet_name(string)
|
91
95
|
string.gsub(/\s/, '').underscore.to_sym
|
92
96
|
end
|
@@ -12,3 +12,8 @@ Feature: Searching via STI model relationships
|
|
12
12
|
Given Sphinx is running
|
13
13
|
And I am searching on cats
|
14
14
|
Then I should get as many results as there are cats
|
15
|
+
|
16
|
+
Scenario: Searching across super and subclass indexes
|
17
|
+
Given Sphinx is running
|
18
|
+
When I search for "fantastic"
|
19
|
+
Then I should get 1 result
|
@@ -12,7 +12,8 @@ class Post < ActiveRecord::Base
|
|
12
12
|
indexes comments.content, :as => :comments
|
13
13
|
indexes authors.name, :as => :authors
|
14
14
|
|
15
|
-
has comments(:id), :as => :comment_ids, :source => :ranged_query
|
15
|
+
has comments(:id), :as => :comment_ids, :source => :ranged_query,
|
16
|
+
:facet => true
|
16
17
|
has category.name, :facet => true, :as => :category_name, :type => :string
|
17
18
|
has 'COUNT(DISTINCT comments.id)', :as => :comments_count, :type => :integer
|
18
19
|
has comments.created_at, :as => :comments_created_at
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -10,6 +10,7 @@ require 'thinking_sphinx/active_record'
|
|
10
10
|
require 'thinking_sphinx/association'
|
11
11
|
require 'thinking_sphinx/attribute'
|
12
12
|
require 'thinking_sphinx/configuration'
|
13
|
+
require 'thinking_sphinx/context'
|
13
14
|
require 'thinking_sphinx/excerpter'
|
14
15
|
require 'thinking_sphinx/facet'
|
15
16
|
require 'thinking_sphinx/class_facet'
|
@@ -60,12 +61,17 @@ module ThinkingSphinx
|
|
60
61
|
# The collection of indexed models. Keep in mind that Rails lazily loads
|
61
62
|
# its classes, so this may not actually be populated with _all_ the models
|
62
63
|
# that have Sphinx indexes.
|
63
|
-
def self.
|
64
|
-
Thread.current[:
|
64
|
+
def self.context
|
65
|
+
if Thread.current[:thinking_sphinx_context].nil?
|
66
|
+
Thread.current[:thinking_sphinx_context] = ThinkingSphinx::Context.new
|
67
|
+
Thread.current[:thinking_sphinx_context].prepare
|
68
|
+
end
|
69
|
+
|
70
|
+
Thread.current[:thinking_sphinx_context]
|
65
71
|
end
|
66
72
|
|
67
73
|
def self.unique_id_expression(offset = nil)
|
68
|
-
"* #{indexed_models.size} + #{offset || 0}"
|
74
|
+
"* #{context.indexed_models.size} + #{offset || 0}"
|
69
75
|
end
|
70
76
|
|
71
77
|
# Check if index definition is disabled.
|
@@ -16,6 +16,8 @@ module ThinkingSphinx
|
|
16
16
|
extend ThinkingSphinx::ActiveRecord::ClassMethods
|
17
17
|
|
18
18
|
class << self
|
19
|
+
attr_accessor :sphinx_index_blocks
|
20
|
+
|
19
21
|
def set_sphinx_primary_key(attribute)
|
20
22
|
@sphinx_primary_key_attribute = attribute
|
21
23
|
end
|
@@ -53,6 +55,14 @@ module ThinkingSphinx
|
|
53
55
|
|
54
56
|
private
|
55
57
|
|
58
|
+
def defined_indexes?
|
59
|
+
@defined_indexes
|
60
|
+
end
|
61
|
+
|
62
|
+
def defined_indexes=(value)
|
63
|
+
@defined_indexes = value
|
64
|
+
end
|
65
|
+
|
56
66
|
def sphinx_delta?
|
57
67
|
self.sphinx_indexes.any? { |index| index.delta? }
|
58
68
|
end
|
@@ -118,21 +128,37 @@ module ThinkingSphinx
|
|
118
128
|
# at ThinkingSphinx::Index::Builder.
|
119
129
|
#
|
120
130
|
def define_index(name = nil, &block)
|
121
|
-
|
122
|
-
|
123
|
-
self.
|
124
|
-
self.sphinx_facets ||= []
|
131
|
+
self.sphinx_index_blocks ||= []
|
132
|
+
self.sphinx_indexes ||= []
|
133
|
+
self.sphinx_facets ||= []
|
125
134
|
|
126
|
-
|
135
|
+
ThinkingSphinx.context.add_indexed_model self
|
127
136
|
|
128
|
-
|
129
|
-
|
137
|
+
if sphinx_index_blocks.empty?
|
138
|
+
before_validation :define_indexes
|
139
|
+
before_destroy :define_indexes
|
130
140
|
end
|
131
141
|
|
132
|
-
|
133
|
-
|
142
|
+
self.sphinx_index_blocks << lambda {
|
143
|
+
index = ThinkingSphinx::Index::Builder.generate self, name, &block
|
144
|
+
add_sphinx_callbacks_and_extend(index.delta?)
|
145
|
+
add_sphinx_index index
|
146
|
+
}
|
147
|
+
|
148
|
+
include ThinkingSphinx::ActiveRecord::Scopes
|
149
|
+
include ThinkingSphinx::SearchMethods
|
150
|
+
end
|
151
|
+
|
152
|
+
def define_indexes
|
153
|
+
return if sphinx_index_blocks.nil? ||
|
154
|
+
defined_indexes? ||
|
155
|
+
!ThinkingSphinx.define_indexes?
|
156
|
+
|
157
|
+
sphinx_index_blocks.each do |block|
|
158
|
+
block.call
|
159
|
+
end
|
134
160
|
|
135
|
-
|
161
|
+
self.defined_indexes = true
|
136
162
|
|
137
163
|
# We want to make sure that if the database doesn't exist, then Thinking
|
138
164
|
# Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop
|
@@ -146,6 +172,11 @@ module ThinkingSphinx
|
|
146
172
|
end
|
147
173
|
end
|
148
174
|
|
175
|
+
def add_sphinx_index(index)
|
176
|
+
self.sphinx_indexes << index
|
177
|
+
subclasses.each { |klass| klass.add_sphinx_index(index) }
|
178
|
+
end
|
179
|
+
|
149
180
|
def indexed_by_sphinx?
|
150
181
|
sphinx_indexes && sphinx_indexes.length > 0
|
151
182
|
end
|
@@ -155,26 +186,31 @@ module ThinkingSphinx
|
|
155
186
|
end
|
156
187
|
|
157
188
|
def sphinx_index_names
|
189
|
+
define_indexes
|
158
190
|
sphinx_indexes.collect(&:all_names).flatten
|
159
191
|
end
|
160
192
|
|
161
193
|
def core_index_names
|
194
|
+
define_indexes
|
162
195
|
sphinx_indexes.collect(&:core_name)
|
163
196
|
end
|
164
197
|
|
165
198
|
def delta_index_names
|
199
|
+
define_indexes
|
166
200
|
sphinx_indexes.select(&:delta?).collect(&:delta_name)
|
167
201
|
end
|
168
202
|
|
169
|
-
def to_riddle
|
203
|
+
def to_riddle
|
204
|
+
define_indexes
|
170
205
|
sphinx_database_adapter.setup
|
171
206
|
|
172
207
|
local_sphinx_indexes.collect { |index|
|
173
|
-
index.to_riddle(
|
208
|
+
index.to_riddle(sphinx_offset)
|
174
209
|
}.flatten
|
175
210
|
end
|
176
211
|
|
177
212
|
def source_of_sphinx_index
|
213
|
+
define_indexes
|
178
214
|
possible_models = self.sphinx_indexes.collect { |index| index.model }
|
179
215
|
return self if possible_models.include?(self)
|
180
216
|
|
@@ -195,8 +231,13 @@ module ThinkingSphinx
|
|
195
231
|
)
|
196
232
|
end
|
197
233
|
|
198
|
-
|
234
|
+
def sphinx_offset
|
235
|
+
ThinkingSphinx.context.superclass_indexed_models.
|
236
|
+
index eldest_indexed_ancestor
|
237
|
+
end
|
199
238
|
|
239
|
+
private
|
240
|
+
|
200
241
|
def local_sphinx_indexes
|
201
242
|
sphinx_indexes.select { |index|
|
202
243
|
index.model == self
|
@@ -206,10 +247,8 @@ module ThinkingSphinx
|
|
206
247
|
def add_sphinx_callbacks_and_extend(delta = false)
|
207
248
|
unless indexed_by_sphinx?
|
208
249
|
after_destroy :toggle_deleted
|
209
|
-
|
210
|
-
include ThinkingSphinx::SearchMethods
|
250
|
+
|
211
251
|
include ThinkingSphinx::ActiveRecord::AttributeUpdates
|
212
|
-
include ThinkingSphinx::ActiveRecord::Scopes
|
213
252
|
end
|
214
253
|
|
215
254
|
if delta && !delta_indexed_by_sphinx?
|
@@ -219,6 +258,12 @@ module ThinkingSphinx
|
|
219
258
|
after_commit :index_delta
|
220
259
|
end
|
221
260
|
end
|
261
|
+
|
262
|
+
def eldest_indexed_ancestor
|
263
|
+
ancestors.reverse.detect { |ancestor|
|
264
|
+
ThinkingSphinx.context.indexed_models.include?(ancestor.name)
|
265
|
+
}.name
|
266
|
+
end
|
222
267
|
end
|
223
268
|
|
224
269
|
def in_index?(suffix)
|
@@ -262,8 +307,8 @@ module ThinkingSphinx
|
|
262
307
|
end
|
263
308
|
|
264
309
|
def sphinx_document_id
|
265
|
-
primary_key_for_sphinx * ThinkingSphinx.indexed_models.size +
|
266
|
-
|
310
|
+
primary_key_for_sphinx * ThinkingSphinx.context.indexed_models.size +
|
311
|
+
self.class.sphinx_offset
|
267
312
|
end
|
268
313
|
|
269
314
|
private
|
@@ -271,5 +316,9 @@ module ThinkingSphinx
|
|
271
316
|
def sphinx_index_name(suffix)
|
272
317
|
"#{self.class.source_of_sphinx_index.name.underscore.tr(':/\\', '_')}_#{suffix}"
|
273
318
|
end
|
319
|
+
|
320
|
+
def define_indexes
|
321
|
+
self.class.define_indexes
|
322
|
+
end
|
274
323
|
end
|
275
324
|
end
|
@@ -54,8 +54,8 @@ 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 docinfo
|
58
|
-
exceptions html_index_attrs html_remove_elements html_strip
|
57
|
+
IndexOptions = %w( charset_table charset_type charset_dictpath docinfo
|
58
|
+
enable_star exceptions html_index_attrs html_remove_elements html_strip
|
59
59
|
index_exact_words ignore_chars inplace_docinfo_gap inplace_enable
|
60
60
|
inplace_hit_gap inplace_reloc_factor inplace_write_factor min_infix_len
|
61
61
|
min_prefix_len min_stemming_len min_word_len mlock morphology ngram_chars
|
@@ -142,13 +142,14 @@ module ThinkingSphinx
|
|
142
142
|
# indexer and searchd configuration, and sources and indexes details.
|
143
143
|
#
|
144
144
|
def build(file_path=nil)
|
145
|
-
load_models
|
146
145
|
file_path ||= "#{self.config_file}"
|
147
146
|
|
148
147
|
@configuration.indexes.clear
|
149
148
|
|
150
|
-
ThinkingSphinx.indexed_models.
|
151
|
-
|
149
|
+
ThinkingSphinx.context.indexed_models.each do |model|
|
150
|
+
model = model.constantize
|
151
|
+
model.define_indexes
|
152
|
+
@configuration.indexes.concat model.to_riddle
|
152
153
|
end
|
153
154
|
|
154
155
|
open(file_path, "w") do |file|
|
@@ -156,37 +157,6 @@ module ThinkingSphinx
|
|
156
157
|
end
|
157
158
|
end
|
158
159
|
|
159
|
-
# Make sure all models are loaded - without reloading any that
|
160
|
-
# ActiveRecord::Base is already aware of (otherwise we start to hit some
|
161
|
-
# messy dependencies issues).
|
162
|
-
#
|
163
|
-
def load_models
|
164
|
-
return if defined?(Rails) &&
|
165
|
-
Rails::VERSION::STRING.to_f > 2.1 &&
|
166
|
-
Rails.configuration.cache_classes
|
167
|
-
|
168
|
-
self.model_directories.each do |base|
|
169
|
-
Dir["#{base}**/*.rb"].each do |file|
|
170
|
-
model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
|
171
|
-
|
172
|
-
next if model_name.nil?
|
173
|
-
next if ::ActiveRecord::Base.send(:subclasses).detect { |model|
|
174
|
-
model.name == model_name
|
175
|
-
}
|
176
|
-
|
177
|
-
begin
|
178
|
-
model_name.camelize.constantize
|
179
|
-
rescue LoadError
|
180
|
-
model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
|
181
|
-
rescue NameError
|
182
|
-
next
|
183
|
-
rescue StandardError
|
184
|
-
puts "Warning: Error loading #{file}"
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
160
|
def address
|
191
161
|
@configuration.searchd.address
|
192
162
|
end
|
@@ -235,7 +205,7 @@ module ThinkingSphinx
|
|
235
205
|
|
236
206
|
def models_by_crc
|
237
207
|
@models_by_crc ||= begin
|
238
|
-
ThinkingSphinx.indexed_models.inject({}) do |hash, model|
|
208
|
+
ThinkingSphinx.context.indexed_models.inject({}) do |hash, model|
|
239
209
|
hash[model.constantize.to_crc32] = model
|
240
210
|
Object.subclasses_of(model.constantize).each { |subclass|
|
241
211
|
hash[subclass.to_crc32] = subclass.name
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class ThinkingSphinx::Context
|
2
|
+
attr_reader :indexed_models
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@indexed_models = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def prepare
|
9
|
+
load_models
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_indexes
|
13
|
+
indexed_models.each { |model|
|
14
|
+
model.constantize.define_indexes
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_indexed_model(model)
|
19
|
+
model = model.name if model.is_a?(Class)
|
20
|
+
|
21
|
+
indexed_models << model
|
22
|
+
indexed_models.uniq!
|
23
|
+
indexed_models.sort!
|
24
|
+
end
|
25
|
+
|
26
|
+
def superclass_indexed_models
|
27
|
+
klasses = indexed_models.collect { |name| name.constantize }
|
28
|
+
klasses.reject { |klass|
|
29
|
+
klass.superclass.ancestors.any? { |ancestor| klasses.include?(ancestor) }
|
30
|
+
}.collect { |klass| klass.name }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Make sure all models are loaded - without reloading any that
|
36
|
+
# ActiveRecord::Base is already aware of (otherwise we start to hit some
|
37
|
+
# messy dependencies issues).
|
38
|
+
#
|
39
|
+
def load_models
|
40
|
+
return if defined?(Rails) &&
|
41
|
+
Rails::VERSION::STRING.to_f > 2.1 &&
|
42
|
+
Rails.configuration.cache_classes
|
43
|
+
|
44
|
+
ThinkingSphinx::Configuration.instance.model_directories.each do |base|
|
45
|
+
Dir["#{base}**/*.rb"].each do |file|
|
46
|
+
model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
|
47
|
+
|
48
|
+
next if model_name.nil?
|
49
|
+
next if ::ActiveRecord::Base.send(:subclasses).detect { |model|
|
50
|
+
model.name == model_name
|
51
|
+
}
|
52
|
+
|
53
|
+
begin
|
54
|
+
model_name.camelize.constantize
|
55
|
+
rescue LoadError
|
56
|
+
model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
|
57
|
+
rescue NameError
|
58
|
+
next
|
59
|
+
rescue StandardError
|
60
|
+
STDERR.puts "Warning: Error loading #{file}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -3,6 +3,8 @@ module ThinkingSphinx
|
|
3
3
|
attr_accessor :args, :options
|
4
4
|
|
5
5
|
def initialize(*args)
|
6
|
+
ThinkingSphinx.context.define_indexes
|
7
|
+
|
6
8
|
@options = args.extract_options!
|
7
9
|
@args = args
|
8
10
|
|
@@ -64,7 +66,7 @@ module ThinkingSphinx
|
|
64
66
|
|
65
67
|
def facet_classes
|
66
68
|
(
|
67
|
-
options[:classes] || ThinkingSphinx.indexed_models.collect { |model|
|
69
|
+
options[:classes] || ThinkingSphinx.context.indexed_models.collect { |model|
|
68
70
|
model.constantize
|
69
71
|
}
|
70
72
|
).select { |klass| klass.sphinx_facets.any? }
|
@@ -55,7 +55,7 @@ GROUP BY #{ sql_group_clause }
|
|
55
55
|
#
|
56
56
|
def to_sql_query_info(offset)
|
57
57
|
"SELECT * FROM #{@model.quoted_table_name} WHERE " +
|
58
|
-
"#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.indexed_models.size})"
|
58
|
+
"#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.context.indexed_models.size})"
|
59
59
|
end
|
60
60
|
|
61
61
|
def sql_select_clause(offset)
|
data/rails/init.rb
CHANGED
@@ -5,6 +5,9 @@ describe ThinkingSphinx::ActiveRecord do
|
|
5
5
|
@existing_alpha_indexes = Alpha.sphinx_indexes.clone
|
6
6
|
@existing_beta_indexes = Beta.sphinx_indexes.clone
|
7
7
|
|
8
|
+
Alpha.send :defined_indexes=, false
|
9
|
+
Beta.send :defined_indexes=, false
|
10
|
+
|
8
11
|
Alpha.sphinx_indexes.clear
|
9
12
|
Beta.sphinx_indexes.clear
|
10
13
|
end
|
@@ -12,6 +15,9 @@ describe ThinkingSphinx::ActiveRecord do
|
|
12
15
|
after :each do
|
13
16
|
Alpha.sphinx_indexes.replace @existing_alpha_indexes
|
14
17
|
Beta.sphinx_indexes.replace @existing_beta_indexes
|
18
|
+
|
19
|
+
Alpha.sphinx_index_blocks.clear
|
20
|
+
Beta.sphinx_index_blocks.clear
|
15
21
|
end
|
16
22
|
|
17
23
|
describe '.define_index' do
|
@@ -20,62 +26,80 @@ describe ThinkingSphinx::ActiveRecord do
|
|
20
26
|
ThinkingSphinx::Index.should_not_receive(:new)
|
21
27
|
|
22
28
|
Alpha.define_index { }
|
29
|
+
Alpha.define_indexes
|
23
30
|
|
24
31
|
ThinkingSphinx.define_indexes = true
|
25
32
|
end
|
26
33
|
|
27
|
-
it "should
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should add to ThinkingSphinx.indexed_models if the model doesn't already exist in the array" do
|
34
|
-
Alpha.define_index { indexes :name }
|
35
|
-
|
36
|
-
ThinkingSphinx.indexed_models.should include("Alpha")
|
34
|
+
it "should not evaluate the index block automatically" do
|
35
|
+
lambda {
|
36
|
+
Alpha.define_index { raise StandardError }
|
37
|
+
}.should_not raise_error
|
37
38
|
end
|
38
39
|
|
39
|
-
it "
|
40
|
-
Alpha.define_index { indexes :name }
|
40
|
+
it "should add the model to the context collection" do
|
41
41
|
Alpha.define_index { indexes :name }
|
42
42
|
|
43
|
-
ThinkingSphinx.indexed_models.
|
44
|
-
model == "Alpha"
|
45
|
-
}.length.should == 1
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should return the new index" do
|
49
|
-
Alpha.define_index.should be_a(ThinkingSphinx::Index)
|
43
|
+
ThinkingSphinx.context.indexed_models.should include("Alpha")
|
50
44
|
end
|
51
45
|
|
52
46
|
it "should die quietly if there is a database error" do
|
53
47
|
ThinkingSphinx::Index::Builder.stub(:generate) { raise Mysql::Error }
|
48
|
+
Alpha.define_index { indexes :name }
|
54
49
|
|
55
50
|
lambda {
|
56
|
-
Alpha.
|
51
|
+
Alpha.define_indexes
|
57
52
|
}.should_not raise_error
|
58
53
|
end
|
59
54
|
|
60
55
|
it "should die noisily if there is a non-database error" do
|
61
56
|
ThinkingSphinx::Index::Builder.stub(:generate) { raise StandardError }
|
57
|
+
Alpha.define_index { indexes :name }
|
62
58
|
|
63
59
|
lambda {
|
64
|
-
Alpha.
|
60
|
+
Alpha.define_indexes
|
65
61
|
}.should raise_error
|
66
62
|
end
|
67
63
|
|
68
64
|
it "should set the index's name using the parameter if provided" do
|
69
|
-
|
65
|
+
Alpha.define_index('custom') { indexes :name }
|
66
|
+
Alpha.define_indexes
|
70
67
|
|
71
|
-
|
68
|
+
Alpha.sphinx_indexes.first.name.should == 'custom'
|
72
69
|
end
|
73
70
|
|
74
71
|
context 'callbacks' do
|
75
|
-
it "should add a
|
72
|
+
it "should add a before_validation callback to define_indexes" do
|
73
|
+
Alpha.should_receive(:before_validation).with(:define_indexes)
|
74
|
+
|
75
|
+
Alpha.define_index { }
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not add a before_validation callback twice" do
|
79
|
+
Alpha.should_receive(:before_validation).with(:define_indexes).once
|
80
|
+
|
81
|
+
Alpha.define_index { }
|
82
|
+
Alpha.define_index { }
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should add a before_destroy callback to define_indexes" do
|
86
|
+
Alpha.should_receive(:before_destroy).with(:define_indexes)
|
87
|
+
|
88
|
+
Alpha.define_index { }
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should not add a before_destroy callback twice" do
|
92
|
+
Alpha.should_receive(:before_destroy).with(:define_indexes).once
|
93
|
+
|
94
|
+
Alpha.define_index { }
|
95
|
+
Alpha.define_index { }
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should add a toggle_deleted callback when defined" do
|
76
99
|
Alpha.should_receive(:after_destroy).with(:toggle_deleted)
|
77
100
|
|
78
101
|
Alpha.define_index { indexes :name }
|
102
|
+
Alpha.define_indexes
|
79
103
|
end
|
80
104
|
|
81
105
|
it "should not add toggle_deleted callback more than once" do
|
@@ -83,12 +107,14 @@ describe ThinkingSphinx::ActiveRecord do
|
|
83
107
|
|
84
108
|
Alpha.define_index { indexes :name }
|
85
109
|
Alpha.define_index { indexes :name }
|
110
|
+
Alpha.define_indexes
|
86
111
|
end
|
87
112
|
|
88
|
-
it "should add a update_attribute_values callback" do
|
113
|
+
it "should add a update_attribute_values callback when defined" do
|
89
114
|
Alpha.should_receive(:after_commit).with(:update_attribute_values)
|
90
115
|
|
91
116
|
Alpha.define_index { indexes :name }
|
117
|
+
Alpha.define_indexes
|
92
118
|
end
|
93
119
|
|
94
120
|
it "should not add update_attribute_values callback more than once" do
|
@@ -96,6 +122,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
96
122
|
|
97
123
|
Alpha.define_index { indexes :name }
|
98
124
|
Alpha.define_index { indexes :name }
|
125
|
+
Alpha.define_indexes
|
99
126
|
end
|
100
127
|
|
101
128
|
it "should add a toggle_delta callback if deltas are enabled" do
|
@@ -105,12 +132,14 @@ describe ThinkingSphinx::ActiveRecord do
|
|
105
132
|
indexes :name
|
106
133
|
set_property :delta => true
|
107
134
|
}
|
135
|
+
Beta.define_indexes
|
108
136
|
end
|
109
137
|
|
110
138
|
it "should not add a toggle_delta callback if deltas are disabled" do
|
111
139
|
Alpha.should_not_receive(:before_save).with(:toggle_delta)
|
112
140
|
|
113
141
|
Alpha.define_index { indexes :name }
|
142
|
+
Alpha.define_indexes
|
114
143
|
end
|
115
144
|
|
116
145
|
it "should add the toggle_delta callback if deltas are disabled in other indexes" do
|
@@ -121,6 +150,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
121
150
|
indexes :name
|
122
151
|
set_property :delta => true
|
123
152
|
}
|
153
|
+
Beta.define_indexes
|
124
154
|
end
|
125
155
|
|
126
156
|
it "should only add the toggle_delta callback once" do
|
@@ -134,6 +164,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
134
164
|
indexes :name
|
135
165
|
set_property :delta => true
|
136
166
|
}
|
167
|
+
Beta.define_indexes
|
137
168
|
end
|
138
169
|
|
139
170
|
it "should add an index_delta callback if deltas are enabled" do
|
@@ -144,12 +175,14 @@ describe ThinkingSphinx::ActiveRecord do
|
|
144
175
|
indexes :name
|
145
176
|
set_property :delta => true
|
146
177
|
}
|
178
|
+
Beta.define_indexes
|
147
179
|
end
|
148
180
|
|
149
181
|
it "should not add an index_delta callback if deltas are disabled" do
|
150
182
|
Alpha.should_not_receive(:after_commit).with(:index_delta)
|
151
183
|
|
152
184
|
Alpha.define_index { indexes :name }
|
185
|
+
Alpha.define_indexes
|
153
186
|
end
|
154
187
|
|
155
188
|
it "should add the index_delta callback if deltas are disabled in other indexes" do
|
@@ -161,6 +194,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
161
194
|
indexes :name
|
162
195
|
set_property :delta => true
|
163
196
|
}
|
197
|
+
Beta.define_indexes
|
164
198
|
end
|
165
199
|
|
166
200
|
it "should only add the index_delta callback once" do
|
@@ -175,10 +209,29 @@ describe ThinkingSphinx::ActiveRecord do
|
|
175
209
|
indexes :name
|
176
210
|
set_property :delta => true
|
177
211
|
}
|
212
|
+
Beta.define_indexes
|
178
213
|
end
|
179
214
|
end
|
180
215
|
end
|
181
|
-
|
216
|
+
|
217
|
+
describe '.define_indexes' do
|
218
|
+
it "should process define_index blocks" do
|
219
|
+
Beta.define_index { indexes :name }
|
220
|
+
Beta.sphinx_indexes.length.should == 0
|
221
|
+
|
222
|
+
Beta.define_indexes
|
223
|
+
Beta.sphinx_indexes.length.should == 1
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should not re-add indexes" do
|
227
|
+
Beta.define_index { indexes :name }
|
228
|
+
Beta.define_indexes
|
229
|
+
Beta.define_indexes
|
230
|
+
|
231
|
+
Beta.sphinx_indexes.length.should == 1
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
182
235
|
describe "index methods" do
|
183
236
|
before(:all) do
|
184
237
|
@person = Person.find(:first)
|
@@ -364,20 +417,10 @@ describe ThinkingSphinx::ActiveRecord do
|
|
364
417
|
|
365
418
|
it "should return values with the expected offset" do
|
366
419
|
person = Person.find(:first)
|
367
|
-
model_count = ThinkingSphinx.indexed_models.length
|
368
|
-
|
420
|
+
model_count = ThinkingSphinx.context.indexed_models.length
|
421
|
+
Person.stub!(:sphinx_offset => 3)
|
369
422
|
|
370
|
-
(person.id * model_count +
|
371
|
-
|
372
|
-
alpha = Alpha.find(:first)
|
373
|
-
offset = ThinkingSphinx.indexed_models.index("Alpha")
|
374
|
-
|
375
|
-
(alpha.id * model_count + offset).should == alpha.sphinx_document_id
|
376
|
-
|
377
|
-
beta = Beta.find(:first)
|
378
|
-
offset = ThinkingSphinx.indexed_models.index("Beta")
|
379
|
-
|
380
|
-
(beta.id * model_count + offset).should == beta.sphinx_document_id
|
423
|
+
(person.id * model_count + 3).should == person.sphinx_document_id
|
381
424
|
end
|
382
425
|
end
|
383
426
|
|
@@ -409,6 +452,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
409
452
|
describe '.sphinx_index_names' do
|
410
453
|
it "should return the core index" do
|
411
454
|
Alpha.define_index { indexes :name }
|
455
|
+
Alpha.define_indexes
|
412
456
|
Alpha.sphinx_index_names.should == ['alpha_core']
|
413
457
|
end
|
414
458
|
|
@@ -417,6 +461,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
417
461
|
indexes :name
|
418
462
|
set_property :delta => true
|
419
463
|
}
|
464
|
+
Beta.define_indexes
|
420
465
|
|
421
466
|
Beta.sphinx_index_names.should == ['beta_core', 'beta_delta']
|
422
467
|
end
|
@@ -429,6 +474,7 @@ describe ThinkingSphinx::ActiveRecord do
|
|
429
474
|
describe '.indexed_by_sphinx?' do
|
430
475
|
it "should return true if there is at least one index on the model" do
|
431
476
|
Alpha.define_index { indexes :name }
|
477
|
+
Alpha.define_indexes
|
432
478
|
|
433
479
|
Alpha.should be_indexed_by_sphinx
|
434
480
|
end
|
@@ -444,12 +490,14 @@ describe ThinkingSphinx::ActiveRecord do
|
|
444
490
|
indexes :name
|
445
491
|
set_property :delta => true
|
446
492
|
}
|
493
|
+
Beta.define_indexes
|
447
494
|
|
448
495
|
Beta.should be_delta_indexed_by_sphinx
|
449
496
|
end
|
450
497
|
|
451
498
|
it "should return false if there are no delta indexes on the model" do
|
452
499
|
Alpha.define_index { indexes :name }
|
500
|
+
Alpha.define_indexes
|
453
501
|
|
454
502
|
Alpha.should_not be_delta_indexed_by_sphinx
|
455
503
|
end
|
@@ -490,10 +538,11 @@ describe ThinkingSphinx::ActiveRecord do
|
|
490
538
|
|
491
539
|
describe '.core_index_names' do
|
492
540
|
it "should return each index's core name" do
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
541
|
+
Alpha.define_index { indexes :name }
|
542
|
+
Alpha.define_index { indexes :name }
|
543
|
+
Alpha.define_indexes
|
544
|
+
Alpha.sphinx_indexes.first.name = 'foo'
|
545
|
+
Alpha.sphinx_indexes.last.name = 'bar'
|
497
546
|
|
498
547
|
Alpha.core_index_names.should == ['foo_core', 'bar_core']
|
499
548
|
end
|
@@ -501,13 +550,39 @@ describe ThinkingSphinx::ActiveRecord do
|
|
501
550
|
|
502
551
|
describe '.delta_index_names' do
|
503
552
|
it "should return index delta names, for indexes with deltas enabled" do
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
553
|
+
Alpha.define_index { indexes :name }
|
554
|
+
Alpha.define_index { indexes :name }
|
555
|
+
Alpha.define_indexes
|
556
|
+
Alpha.sphinx_indexes.first.name = 'foo'
|
557
|
+
Alpha.sphinx_indexes.first.delta_object = stub('delta')
|
558
|
+
Alpha.sphinx_indexes.last.name = 'bar'
|
509
559
|
|
510
560
|
Alpha.delta_index_names.should == ['foo_delta']
|
511
561
|
end
|
512
562
|
end
|
563
|
+
|
564
|
+
describe '.sphinx_offset' do
|
565
|
+
before :each do
|
566
|
+
@context = ThinkingSphinx.context
|
567
|
+
end
|
568
|
+
|
569
|
+
it "should return the index of the model's name in all known indexed models" do
|
570
|
+
@context.stub!(:indexed_models => ['Alpha', 'Beta'])
|
571
|
+
|
572
|
+
Alpha.sphinx_offset.should == 0
|
573
|
+
Beta.sphinx_offset.should == 1
|
574
|
+
end
|
575
|
+
|
576
|
+
it "should ignore classes that have indexed superclasses" do
|
577
|
+
@context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
|
578
|
+
|
579
|
+
Person.sphinx_offset.should == 1
|
580
|
+
end
|
581
|
+
|
582
|
+
it "should respect first known indexed parents" do
|
583
|
+
@context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
|
584
|
+
|
585
|
+
Parent.sphinx_offset.should == 1
|
586
|
+
end
|
587
|
+
end
|
513
588
|
end
|
@@ -130,62 +130,6 @@ describe ThinkingSphinx::Configuration do
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
describe "#load_models" do
|
134
|
-
before :each do
|
135
|
-
@config = ThinkingSphinx::Configuration.instance
|
136
|
-
@config.model_directories = ['']
|
137
|
-
|
138
|
-
@file_name = 'a.rb'
|
139
|
-
@model_name_lower = 'a'
|
140
|
-
@class_name = 'A'
|
141
|
-
|
142
|
-
@file_name.stub!(:gsub).and_return(@model_name_lower)
|
143
|
-
@model_name_lower.stub!(:camelize).and_return(@class_name)
|
144
|
-
Dir.stub(:[]).and_return([@file_name])
|
145
|
-
end
|
146
|
-
|
147
|
-
it "should load the files by guessing the file name" do
|
148
|
-
@class_name.should_receive(:constantize).and_return(true)
|
149
|
-
|
150
|
-
@config.load_models
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should not raise errors if the model name is nil" do
|
154
|
-
@file_name.stub!(:gsub).and_return(nil)
|
155
|
-
|
156
|
-
lambda {
|
157
|
-
@config.load_models
|
158
|
-
}.should_not raise_error
|
159
|
-
end
|
160
|
-
|
161
|
-
it "should not raise errors if the file name does not represent a class name" do
|
162
|
-
@class_name.should_receive(:constantize).and_raise(NameError)
|
163
|
-
|
164
|
-
lambda {
|
165
|
-
@config.load_models
|
166
|
-
}.should_not raise_error
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should retry if the first pass fails and contains a directory" do
|
170
|
-
@model_name_lower.stub!(:gsub!).and_return(true, nil)
|
171
|
-
@class_name.stub(:constantize).and_raise(LoadError)
|
172
|
-
@model_name_lower.should_receive(:camelize).twice
|
173
|
-
|
174
|
-
lambda {
|
175
|
-
@config.load_models
|
176
|
-
}.should_not raise_error
|
177
|
-
end
|
178
|
-
|
179
|
-
it "should catch database errors with a warning" do
|
180
|
-
@class_name.should_receive(:constantize).and_raise(Mysql::Error)
|
181
|
-
@config.should_receive(:puts).with('Warning: Error loading a.rb')
|
182
|
-
|
183
|
-
lambda {
|
184
|
-
@config.load_models
|
185
|
-
}.should_not raise_error
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
133
|
it "should insert set index options into the configuration file" do
|
190
134
|
config = ThinkingSphinx::Configuration.instance
|
191
135
|
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::Context do
|
4
|
+
before :each do
|
5
|
+
@context = ThinkingSphinx::Context.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#prepare' do
|
9
|
+
before :each do
|
10
|
+
@config = ThinkingSphinx::Configuration.instance
|
11
|
+
@config.model_directories = ['']
|
12
|
+
|
13
|
+
@file_name = 'a.rb'
|
14
|
+
@model_name_lower = 'a'
|
15
|
+
@class_name = 'A'
|
16
|
+
|
17
|
+
@file_name.stub!(:gsub).and_return(@model_name_lower)
|
18
|
+
@model_name_lower.stub!(:camelize).and_return(@class_name)
|
19
|
+
Dir.stub(:[]).and_return([@file_name])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should load the files by guessing the file name" do
|
23
|
+
@class_name.should_receive(:constantize).and_return(true)
|
24
|
+
|
25
|
+
@context.prepare
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not raise errors if the model name is nil" do
|
29
|
+
@file_name.stub!(:gsub).and_return(nil)
|
30
|
+
|
31
|
+
lambda {
|
32
|
+
@context.prepare
|
33
|
+
}.should_not raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not raise errors if the file name does not represent a class name" do
|
37
|
+
@class_name.should_receive(:constantize).and_raise(NameError)
|
38
|
+
|
39
|
+
lambda {
|
40
|
+
@context.prepare
|
41
|
+
}.should_not raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should retry if the first pass fails and contains a directory" do
|
45
|
+
@model_name_lower.stub!(:gsub!).and_return(true, nil)
|
46
|
+
@class_name.stub(:constantize).and_raise(LoadError)
|
47
|
+
@model_name_lower.should_receive(:camelize).twice
|
48
|
+
|
49
|
+
lambda {
|
50
|
+
@context.prepare
|
51
|
+
}.should_not raise_error
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should catch database errors with a warning" do
|
55
|
+
@class_name.should_receive(:constantize).and_raise(Mysql::Error)
|
56
|
+
STDERR.should_receive(:puts).with('Warning: Error loading a.rb')
|
57
|
+
|
58
|
+
lambda {
|
59
|
+
@context.prepare
|
60
|
+
}.should_not raise_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#define_indexes' do
|
65
|
+
it "should call define_indexes on all known indexed models" do
|
66
|
+
@context.stub!(:indexed_models => ['Alpha', 'Beta'])
|
67
|
+
Alpha.should_receive(:define_indexes)
|
68
|
+
Beta.should_receive(:define_indexes)
|
69
|
+
|
70
|
+
@context.define_indexes
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#add_indexed_model' do
|
75
|
+
before :each do
|
76
|
+
@context.indexed_models.clear
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should add the model to the collection" do
|
80
|
+
@context.add_indexed_model 'Alpha'
|
81
|
+
|
82
|
+
@context.indexed_models.should == ['Alpha']
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should not duplicate models in the collection" do
|
86
|
+
@context.add_indexed_model 'Alpha'
|
87
|
+
@context.add_indexed_model 'Alpha'
|
88
|
+
|
89
|
+
@context.indexed_models.should == ['Alpha']
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should keep the collection in alphabetical order" do
|
93
|
+
@context.add_indexed_model 'Beta'
|
94
|
+
@context.add_indexed_model 'Alpha'
|
95
|
+
|
96
|
+
@context.indexed_models.should == ['Alpha', 'Beta']
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should translate classes to their names" do
|
100
|
+
@context.add_indexed_model Alpha
|
101
|
+
|
102
|
+
@context.indexed_models.should == ['Alpha']
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#superclass_indexed_models' do
|
107
|
+
it "should return indexed model names" do
|
108
|
+
@context.stub!(:indexed_models => ['Alpha', 'Beta'])
|
109
|
+
|
110
|
+
@context.superclass_indexed_models.should == ['Alpha', 'Beta']
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not include classes which have indexed superclasses" do
|
114
|
+
@context.stub!(:indexed_models => ['Parent', 'Person'])
|
115
|
+
|
116
|
+
@context.superclass_indexed_models.should == ['Person']
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -161,7 +161,7 @@ describe ThinkingSphinx::Source do
|
|
161
161
|
end
|
162
162
|
|
163
163
|
it "should filter the primary key with the offset" do
|
164
|
-
model_count = ThinkingSphinx.indexed_models.size
|
164
|
+
model_count = ThinkingSphinx.context.indexed_models.size
|
165
165
|
@query.should match(/WHERE `id` = \(\(\$id - 1\) \/ #{model_count}\)/)
|
166
166
|
end
|
167
167
|
end
|
@@ -1,6 +1,17 @@
|
|
1
1
|
require 'spec/spec_helper'
|
2
2
|
|
3
3
|
describe ThinkingSphinx do
|
4
|
+
describe '.context' do
|
5
|
+
it "should return a Context instance" do
|
6
|
+
ThinkingSphinx.context.should be_a(ThinkingSphinx::Context)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should remember changes to the Context instance" do
|
10
|
+
ThinkingSphinx.context.indexed_models.replace([:model])
|
11
|
+
ThinkingSphinx.context.indexed_models.should == [:model]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
describe '.define_indexes?' do
|
5
16
|
it "should define indexes by default" do
|
6
17
|
ThinkingSphinx.define_indexes?.should be_true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-29 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/thinking_sphinx/attribute.rb
|
73
73
|
- lib/thinking_sphinx/class_facet.rb
|
74
74
|
- lib/thinking_sphinx/configuration.rb
|
75
|
+
- lib/thinking_sphinx/context.rb
|
75
76
|
- lib/thinking_sphinx/core/array.rb
|
76
77
|
- lib/thinking_sphinx/core/string.rb
|
77
78
|
- lib/thinking_sphinx/deltas.rb
|
@@ -169,6 +170,7 @@ test_files:
|
|
169
170
|
- features/support/db/fixtures/developers.rb
|
170
171
|
- features/support/db/fixtures/dogs.rb
|
171
172
|
- features/support/db/fixtures/extensible_betas.rb
|
173
|
+
- features/support/db/fixtures/foxes.rb
|
172
174
|
- features/support/db/fixtures/gammas.rb
|
173
175
|
- features/support/db/fixtures/people.rb
|
174
176
|
- features/support/db/fixtures/posts.rb
|
@@ -203,6 +205,7 @@ test_files:
|
|
203
205
|
- features/support/models/developer.rb
|
204
206
|
- features/support/models/dog.rb
|
205
207
|
- features/support/models/extensible_beta.rb
|
208
|
+
- features/support/models/fox.rb
|
206
209
|
- features/support/models/gamma.rb
|
207
210
|
- features/support/models/person.rb
|
208
211
|
- features/support/models/post.rb
|
@@ -216,6 +219,7 @@ test_files:
|
|
216
219
|
- spec/thinking_sphinx/association_spec.rb
|
217
220
|
- spec/thinking_sphinx/attribute_spec.rb
|
218
221
|
- spec/thinking_sphinx/configuration_spec.rb
|
222
|
+
- spec/thinking_sphinx/context_spec.rb
|
219
223
|
- spec/thinking_sphinx/core/array_spec.rb
|
220
224
|
- spec/thinking_sphinx/core/string_spec.rb
|
221
225
|
- spec/thinking_sphinx/excerpter_spec.rb
|