angelf-thinking-sphinx 1.3.18
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/LICENCE +20 -0
- data/README.textile +170 -0
- data/VERSION +1 -0
- data/features/abstract_inheritance.feature +10 -0
- data/features/alternate_primary_key.feature +27 -0
- data/features/attribute_transformation.feature +22 -0
- data/features/attribute_updates.feature +77 -0
- data/features/deleting_instances.feature +67 -0
- data/features/direct_attributes.feature +11 -0
- data/features/excerpts.feature +13 -0
- data/features/extensible_delta_indexing.feature +9 -0
- data/features/facets.feature +90 -0
- data/features/facets_across_model.feature +29 -0
- data/features/handling_edits.feature +92 -0
- data/features/retry_stale_indexes.feature +24 -0
- data/features/searching_across_models.feature +20 -0
- data/features/searching_by_index.feature +40 -0
- data/features/searching_by_model.feature +175 -0
- data/features/searching_with_find_arguments.feature +56 -0
- data/features/sphinx_detection.feature +25 -0
- data/features/sphinx_scopes.feature +42 -0
- data/features/step_definitions/alpha_steps.rb +16 -0
- data/features/step_definitions/beta_steps.rb +7 -0
- data/features/step_definitions/common_steps.rb +193 -0
- data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
- data/features/step_definitions/facet_steps.rb +96 -0
- data/features/step_definitions/find_arguments_steps.rb +36 -0
- data/features/step_definitions/gamma_steps.rb +15 -0
- data/features/step_definitions/scope_steps.rb +15 -0
- data/features/step_definitions/search_steps.rb +89 -0
- data/features/step_definitions/sphinx_steps.rb +35 -0
- data/features/sti_searching.feature +19 -0
- data/features/support/env.rb +21 -0
- data/features/support/lib/generic_delta_handler.rb +8 -0
- data/features/thinking_sphinx/database.example.yml +3 -0
- data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
- data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
- data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
- data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
- data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
- data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
- data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
- data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
- data/features/thinking_sphinx/db/fixtures/posts.rb +6 -0
- data/features/thinking_sphinx/db/fixtures/robots.rb +14 -0
- data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
- data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
- data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
- data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
- data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
- data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
- data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
- data/features/thinking_sphinx/db/migrations/create_posts.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
- data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
- data/features/thinking_sphinx/models/alpha.rb +22 -0
- data/features/thinking_sphinx/models/animal.rb +5 -0
- data/features/thinking_sphinx/models/author.rb +3 -0
- data/features/thinking_sphinx/models/beta.rb +8 -0
- data/features/thinking_sphinx/models/box.rb +8 -0
- data/features/thinking_sphinx/models/cat.rb +3 -0
- data/features/thinking_sphinx/models/category.rb +4 -0
- data/features/thinking_sphinx/models/comment.rb +10 -0
- data/features/thinking_sphinx/models/developer.rb +16 -0
- data/features/thinking_sphinx/models/dog.rb +3 -0
- data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
- data/features/thinking_sphinx/models/fox.rb +5 -0
- data/features/thinking_sphinx/models/gamma.rb +5 -0
- data/features/thinking_sphinx/models/genre.rb +3 -0
- data/features/thinking_sphinx/models/medium.rb +5 -0
- data/features/thinking_sphinx/models/music.rb +8 -0
- data/features/thinking_sphinx/models/person.rb +23 -0
- data/features/thinking_sphinx/models/post.rb +21 -0
- data/features/thinking_sphinx/models/robot.rb +12 -0
- data/features/thinking_sphinx/models/tag.rb +3 -0
- data/features/thinking_sphinx/models/tagging.rb +4 -0
- data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
- data/lib/cucumber/thinking_sphinx/internal_world.rb +127 -0
- data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
- data/lib/thinking_sphinx.rb +242 -0
- data/lib/thinking_sphinx/active_record.rb +380 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +50 -0
- data/lib/thinking_sphinx/active_record/delta.rb +61 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +51 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +47 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +58 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +147 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +380 -0
- data/lib/thinking_sphinx/auto_version.rb +22 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/configuration.rb +292 -0
- data/lib/thinking_sphinx/context.rb +74 -0
- data/lib/thinking_sphinx/core/array.rb +7 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +28 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
- data/lib/thinking_sphinx/excerpter.rb +22 -0
- data/lib/thinking_sphinx/facet.rb +125 -0
- data/lib/thinking_sphinx/facet_search.rb +146 -0
- data/lib/thinking_sphinx/field.rb +80 -0
- data/lib/thinking_sphinx/index.rb +157 -0
- data/lib/thinking_sphinx/index/builder.rb +302 -0
- data/lib/thinking_sphinx/index/faux_column.rb +118 -0
- data/lib/thinking_sphinx/join.rb +37 -0
- data/lib/thinking_sphinx/property.rb +168 -0
- data/lib/thinking_sphinx/rails_additions.rb +150 -0
- data/lib/thinking_sphinx/search.rb +785 -0
- data/lib/thinking_sphinx/search_methods.rb +439 -0
- data/lib/thinking_sphinx/source.rb +164 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +130 -0
- data/lib/thinking_sphinx/tasks.rb +121 -0
- data/lib/thinking_sphinx/test.rb +55 -0
- data/rails/init.rb +16 -0
- data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +71 -0
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
- data/spec/thinking_sphinx/active_record_spec.rb +618 -0
- data/spec/thinking_sphinx/association_spec.rb +239 -0
- data/spec/thinking_sphinx/attribute_spec.rb +548 -0
- data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
- data/spec/thinking_sphinx/configuration_spec.rb +271 -0
- data/spec/thinking_sphinx/context_spec.rb +126 -0
- data/spec/thinking_sphinx/core/array_spec.rb +9 -0
- data/spec/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
- data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
- data/spec/thinking_sphinx/facet_spec.rb +333 -0
- data/spec/thinking_sphinx/field_spec.rb +113 -0
- data/spec/thinking_sphinx/index/builder_spec.rb +495 -0
- data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
- data/spec/thinking_sphinx/index_spec.rb +183 -0
- data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
- data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
- data/spec/thinking_sphinx/search_spec.rb +1206 -0
- data/spec/thinking_sphinx/source_spec.rb +243 -0
- data/spec/thinking_sphinx_spec.rb +204 -0
- data/tasks/distribution.rb +46 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +76 -0
- metadata +342 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
|
|
4
|
+
describe "search method" do
|
|
5
|
+
before :each do
|
|
6
|
+
Friendship.stub!(:search => true)
|
|
7
|
+
|
|
8
|
+
@person = Person.find(:first)
|
|
9
|
+
@index = Friendship.sphinx_indexes.first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should raise an error if the required attribute doesn't exist" do
|
|
13
|
+
@index.stub!(:attributes => [])
|
|
14
|
+
|
|
15
|
+
lambda { @person.friendships.search "test" }.should raise_error(RuntimeError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should add a filter for the attribute into a normal search call" do
|
|
19
|
+
Friendship.should_receive(:search) do |query, options|
|
|
20
|
+
options[:with][:person_id].should == @person.id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
@person.friendships.search "test"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should define indexes for the reflection class" do
|
|
27
|
+
Friendship.should_receive(:define_indexes)
|
|
28
|
+
|
|
29
|
+
@person.friendships.search 'test'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "search method for has_many :through" do
|
|
34
|
+
before :each do
|
|
35
|
+
Person.stub!(:search => true)
|
|
36
|
+
|
|
37
|
+
@person = Person.find(:first)
|
|
38
|
+
@index = Person.sphinx_indexes.first
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should raise an error if the required attribute doesn't exist" do
|
|
42
|
+
@index.stub!(:attributes => [])
|
|
43
|
+
|
|
44
|
+
lambda { @person.friends.search "test" }.should raise_error(RuntimeError)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should add a filter for the attribute into a normal search call" do
|
|
48
|
+
Person.should_receive(:search).with do |query, options|
|
|
49
|
+
options[:with][:friendly_ids].should == @person.id
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
@person.friends.search "test"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe 'filtering sphinx scopes' do
|
|
57
|
+
before :each do
|
|
58
|
+
Friendship.stub!(:search => Friendship)
|
|
59
|
+
|
|
60
|
+
@person = Person.find(:first)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should add a filter for the attribute in a sphinx scope call" do
|
|
64
|
+
Friendship.should_receive(:search).with do |options|
|
|
65
|
+
options[:with][:person_id].should == @person.id
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@person.friendships.reverse
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::ActiveRecord::Scopes do
|
|
4
|
+
after :each do
|
|
5
|
+
Alpha.remove_sphinx_scopes
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should be included into models with indexes" do
|
|
9
|
+
Alpha.included_modules.should include(ThinkingSphinx::ActiveRecord::Scopes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should not be included into models without indexes" do
|
|
13
|
+
Gamma.included_modules.should_not include(
|
|
14
|
+
ThinkingSphinx::ActiveRecord::Scopes
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '.sphinx_scope' do
|
|
19
|
+
before :each do
|
|
20
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should define a method on the model" do
|
|
24
|
+
Alpha.should respond_to(:by_name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '.sphinx_scopes' do
|
|
29
|
+
before :each do
|
|
30
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should return an array of defined scope names as symbols" do
|
|
34
|
+
Alpha.sphinx_scopes.should == [:by_name]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '.default_sphinx_scope' do
|
|
39
|
+
before :each do
|
|
40
|
+
Alpha.sphinx_scope(:scope_used_as_default_scope) { {:conditions => {:name => 'name'}} }
|
|
41
|
+
Alpha.default_sphinx_scope :scope_used_as_default_scope
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should return an array of defined scope names as symbols" do
|
|
45
|
+
Alpha.sphinx_scopes.should == [:scope_used_as_default_scope]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should have a default_sphinx_scope" do
|
|
49
|
+
Alpha.has_default_sphinx_scope?.should be_true
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '.remove_sphinx_scopes' do
|
|
54
|
+
before :each do
|
|
55
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
56
|
+
Alpha.remove_sphinx_scopes
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should remove sphinx scope methods" do
|
|
60
|
+
Alpha.should_not respond_to(:by_name)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should empty the list of sphinx scopes" do
|
|
64
|
+
Alpha.sphinx_scopes.should be_empty
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe '.example_default_scope' do
|
|
69
|
+
before :each do
|
|
70
|
+
Alpha.sphinx_scope(:foo_scope){ {:conditions => {:name => 'foo'}} }
|
|
71
|
+
Alpha.default_sphinx_scope :foo_scope
|
|
72
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
73
|
+
Alpha.sphinx_scope(:by_foo) { |foo| {:conditions => {:foo => foo}} }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should return a ThinkingSphinx::Search object" do
|
|
77
|
+
Alpha.search.should be_a(ThinkingSphinx::Search)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should apply the default scope options to the underlying search object" do
|
|
81
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
82
|
+
search.search.options[:conditions].should == {:name => 'foo'}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should apply the default scope options and scope options to the underlying search object" do
|
|
86
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
87
|
+
search.by_foo('foo').search.options[:conditions].should == {:foo => 'foo', :name => 'foo'}
|
|
88
|
+
end
|
|
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
|
|
92
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
93
|
+
search.by_name('bar').search.options[:conditions].should == {:name => 'foo'}
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe '.example_scope' do
|
|
98
|
+
before :each do
|
|
99
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
100
|
+
Alpha.sphinx_scope(:by_foo) { |foo| {:conditions => {:foo => foo}} }
|
|
101
|
+
Alpha.sphinx_scope(:with_betas) { {:classes => [Beta]} }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should return a ThinkingSphinx::Search object" do
|
|
105
|
+
Alpha.by_name('foo').should be_a(ThinkingSphinx::Search)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should set the classes option" do
|
|
109
|
+
Alpha.by_name('foo').options[:classes].should == [Alpha]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "should be able to be called on a ThinkingSphinx::Search object" do
|
|
113
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
114
|
+
lambda {
|
|
115
|
+
search.by_name('foo')
|
|
116
|
+
}.should_not raise_error
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should return the search object it gets called upon" do
|
|
120
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
121
|
+
search.by_name('foo').should == search
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should apply the scope options to the underlying search object" do
|
|
125
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
126
|
+
search.by_name('foo').options[:conditions].should == {:name => 'foo'}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should combine hash option scopes such as :conditions" do
|
|
130
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
131
|
+
search.by_name('foo').by_foo('bar').options[:conditions].
|
|
132
|
+
should == {:name => 'foo', :foo => 'bar'}
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should combine array option scopes such as :classes" do
|
|
136
|
+
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
|
137
|
+
search.with_betas.options[:classes].should == [Alpha, Beta]
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe '.search_count_with_scope' do
|
|
142
|
+
before :each do
|
|
143
|
+
@config = ThinkingSphinx::Configuration.instance
|
|
144
|
+
@client = Riddle::Client.new
|
|
145
|
+
|
|
146
|
+
@config.stub!(:client => @client)
|
|
147
|
+
@client.stub!(:query => {:matches => [], :total_found => 43})
|
|
148
|
+
Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
|
|
149
|
+
Alpha.sphinx_scope(:ids_only) { {:ids_only => true} }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should return the total number of results" do
|
|
153
|
+
Alpha.by_name('foo').search_count.should == 43
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "should not make any calls to the database" do
|
|
157
|
+
Alpha.should_not_receive(:find)
|
|
158
|
+
|
|
159
|
+
Alpha.by_name('foo').search_count
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should not leave the :ids_only option set and the results populated if it was not set before" do
|
|
163
|
+
stored_scope = Alpha.by_name('foo')
|
|
164
|
+
stored_scope.search_count
|
|
165
|
+
stored_scope.options[:ids_only].should be_false
|
|
166
|
+
stored_scope.populated?.should be_false
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should leave the :ids_only option set and the results populated if it was set before" do
|
|
170
|
+
stored_scope = Alpha.by_name('foo').ids_only
|
|
171
|
+
stored_scope.search_count
|
|
172
|
+
stored_scope.options[:ids_only].should be_true
|
|
173
|
+
stored_scope.populated?.should be_true
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
end
|
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::ActiveRecord do
|
|
4
|
+
before :each do
|
|
5
|
+
@existing_alpha_indexes = Alpha.sphinx_indexes.clone
|
|
6
|
+
@existing_beta_indexes = Beta.sphinx_indexes.clone
|
|
7
|
+
|
|
8
|
+
Alpha.send :defined_indexes=, false
|
|
9
|
+
Beta.send :defined_indexes=, false
|
|
10
|
+
|
|
11
|
+
Alpha.sphinx_indexes.clear
|
|
12
|
+
Beta.sphinx_indexes.clear
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
after :each do
|
|
16
|
+
Alpha.sphinx_indexes.replace @existing_alpha_indexes
|
|
17
|
+
Beta.sphinx_indexes.replace @existing_beta_indexes
|
|
18
|
+
|
|
19
|
+
Alpha.send :defined_indexes=, true
|
|
20
|
+
Beta.send :defined_indexes=, true
|
|
21
|
+
|
|
22
|
+
Alpha.sphinx_index_blocks.clear
|
|
23
|
+
Beta.sphinx_index_blocks.clear
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '.define_index' do
|
|
27
|
+
it "should do nothing if indexes are disabled" do
|
|
28
|
+
ThinkingSphinx.define_indexes = false
|
|
29
|
+
ThinkingSphinx::Index.should_not_receive(:new)
|
|
30
|
+
|
|
31
|
+
Alpha.define_index { }
|
|
32
|
+
Alpha.define_indexes
|
|
33
|
+
|
|
34
|
+
ThinkingSphinx.define_indexes = true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should not evaluate the index block automatically" do
|
|
38
|
+
lambda {
|
|
39
|
+
Alpha.define_index { raise StandardError }
|
|
40
|
+
}.should_not raise_error
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should add the model to the context collection" do
|
|
44
|
+
Alpha.define_index { indexes :name }
|
|
45
|
+
|
|
46
|
+
ThinkingSphinx.context.indexed_models.should include("Alpha")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should die quietly if there is a database error" do
|
|
50
|
+
ThinkingSphinx::Index::Builder.stub(:generate) { raise Mysql::Error }
|
|
51
|
+
Alpha.define_index { indexes :name }
|
|
52
|
+
|
|
53
|
+
lambda {
|
|
54
|
+
Alpha.define_indexes
|
|
55
|
+
}.should_not raise_error
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should die noisily if there is a non-database error" do
|
|
59
|
+
ThinkingSphinx::Index::Builder.stub(:generate) { raise StandardError }
|
|
60
|
+
Alpha.define_index { indexes :name }
|
|
61
|
+
|
|
62
|
+
lambda {
|
|
63
|
+
Alpha.define_indexes
|
|
64
|
+
}.should raise_error
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should set the index's name using the parameter if provided" do
|
|
68
|
+
Alpha.define_index('custom') { indexes :name }
|
|
69
|
+
Alpha.define_indexes
|
|
70
|
+
|
|
71
|
+
Alpha.sphinx_indexes.first.name.should == 'custom'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'callbacks' do
|
|
75
|
+
it "should add a before_validation callback to define_indexes" do
|
|
76
|
+
Alpha.should_receive(:before_validation).with(:define_indexes)
|
|
77
|
+
|
|
78
|
+
Alpha.define_index { }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should not add a before_validation callback twice" do
|
|
82
|
+
Alpha.should_receive(:before_validation).with(:define_indexes).once
|
|
83
|
+
|
|
84
|
+
Alpha.define_index { }
|
|
85
|
+
Alpha.define_index { }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should add a before_destroy callback to define_indexes" do
|
|
89
|
+
Alpha.should_receive(:before_destroy).with(:define_indexes)
|
|
90
|
+
|
|
91
|
+
Alpha.define_index { }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should not add a before_destroy callback twice" do
|
|
95
|
+
Alpha.should_receive(:before_destroy).with(:define_indexes).once
|
|
96
|
+
|
|
97
|
+
Alpha.define_index { }
|
|
98
|
+
Alpha.define_index { }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should add a toggle_deleted callback when defined" do
|
|
102
|
+
Alpha.should_receive(:after_destroy).with(:toggle_deleted)
|
|
103
|
+
|
|
104
|
+
Alpha.define_index { indexes :name }
|
|
105
|
+
Alpha.define_indexes
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should not add toggle_deleted callback more than once" do
|
|
109
|
+
Alpha.should_receive(:after_destroy).with(:toggle_deleted).once
|
|
110
|
+
|
|
111
|
+
Alpha.define_index { indexes :name }
|
|
112
|
+
Alpha.define_index { indexes :name }
|
|
113
|
+
Alpha.define_indexes
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should add a update_attribute_values callback when defined" do
|
|
117
|
+
Alpha.should_receive(:after_commit).with(:update_attribute_values)
|
|
118
|
+
|
|
119
|
+
Alpha.define_index { indexes :name }
|
|
120
|
+
Alpha.define_indexes
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should not add update_attribute_values callback more than once" do
|
|
124
|
+
Alpha.should_receive(:after_commit).with(:update_attribute_values).once
|
|
125
|
+
|
|
126
|
+
Alpha.define_index { indexes :name }
|
|
127
|
+
Alpha.define_index { indexes :name }
|
|
128
|
+
Alpha.define_indexes
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should add a toggle_delta callback if deltas are enabled" do
|
|
132
|
+
Beta.should_receive(:before_save).with(:toggle_delta)
|
|
133
|
+
|
|
134
|
+
Beta.define_index {
|
|
135
|
+
indexes :name
|
|
136
|
+
set_property :delta => true
|
|
137
|
+
}
|
|
138
|
+
Beta.define_indexes
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should not add a toggle_delta callback if deltas are disabled" do
|
|
142
|
+
Alpha.should_not_receive(:before_save).with(:toggle_delta)
|
|
143
|
+
|
|
144
|
+
Alpha.define_index { indexes :name }
|
|
145
|
+
Alpha.define_indexes
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should add the toggle_delta callback if deltas are disabled in other indexes" do
|
|
149
|
+
Beta.should_receive(:before_save).with(:toggle_delta).once
|
|
150
|
+
|
|
151
|
+
Beta.define_index { indexes :name }
|
|
152
|
+
Beta.define_index('foo') {
|
|
153
|
+
indexes :name
|
|
154
|
+
set_property :delta => true
|
|
155
|
+
}
|
|
156
|
+
Beta.define_indexes
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should only add the toggle_delta callback once" do
|
|
160
|
+
Beta.should_receive(:before_save).with(:toggle_delta).once
|
|
161
|
+
|
|
162
|
+
Beta.define_index {
|
|
163
|
+
indexes :name
|
|
164
|
+
set_property :delta => true
|
|
165
|
+
}
|
|
166
|
+
Beta.define_index {
|
|
167
|
+
indexes :name
|
|
168
|
+
set_property :delta => true
|
|
169
|
+
}
|
|
170
|
+
Beta.define_indexes
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "should add an index_delta callback if deltas are enabled" do
|
|
174
|
+
Beta.stub!(:after_commit => true)
|
|
175
|
+
Beta.should_receive(:after_commit).with(:index_delta)
|
|
176
|
+
|
|
177
|
+
Beta.define_index {
|
|
178
|
+
indexes :name
|
|
179
|
+
set_property :delta => true
|
|
180
|
+
}
|
|
181
|
+
Beta.define_indexes
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should not add an index_delta callback if deltas are disabled" do
|
|
185
|
+
Alpha.should_not_receive(:after_commit).with(:index_delta)
|
|
186
|
+
|
|
187
|
+
Alpha.define_index { indexes :name }
|
|
188
|
+
Alpha.define_indexes
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should add the index_delta callback if deltas are disabled in other indexes" do
|
|
192
|
+
Beta.stub!(:after_commit => true)
|
|
193
|
+
Beta.should_receive(:after_commit).with(:index_delta).once
|
|
194
|
+
|
|
195
|
+
Beta.define_index { indexes :name }
|
|
196
|
+
Beta.define_index('foo') {
|
|
197
|
+
indexes :name
|
|
198
|
+
set_property :delta => true
|
|
199
|
+
}
|
|
200
|
+
Beta.define_indexes
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "should only add the index_delta callback once" do
|
|
204
|
+
Beta.stub!(:after_commit => true)
|
|
205
|
+
Beta.should_receive(:after_commit).with(:index_delta).once
|
|
206
|
+
|
|
207
|
+
Beta.define_index {
|
|
208
|
+
indexes :name
|
|
209
|
+
set_property :delta => true
|
|
210
|
+
}
|
|
211
|
+
Beta.define_index {
|
|
212
|
+
indexes :name
|
|
213
|
+
set_property :delta => true
|
|
214
|
+
}
|
|
215
|
+
Beta.define_indexes
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe '.define_indexes' do
|
|
221
|
+
it "should process define_index blocks" do
|
|
222
|
+
Beta.define_index { indexes :name }
|
|
223
|
+
Beta.sphinx_indexes.length.should == 0
|
|
224
|
+
|
|
225
|
+
Beta.define_indexes
|
|
226
|
+
Beta.sphinx_indexes.length.should == 1
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it "should not re-add indexes" do
|
|
230
|
+
Beta.define_index { indexes :name }
|
|
231
|
+
Beta.define_indexes
|
|
232
|
+
Beta.define_indexes
|
|
233
|
+
|
|
234
|
+
Beta.sphinx_indexes.length.should == 1
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
describe "index methods" do
|
|
239
|
+
before(:all) do
|
|
240
|
+
@person = Person.find(:first)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
describe "in_both_indexes?" do
|
|
244
|
+
it "should return true if in core and delta indexes" do
|
|
245
|
+
@person.should_receive(:in_core_index?).and_return(true)
|
|
246
|
+
@person.should_receive(:in_delta_index?).and_return(true)
|
|
247
|
+
@person.in_both_indexes?.should be_true
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should return false if in one index and not the other" do
|
|
251
|
+
@person.should_receive(:in_core_index?).and_return(true)
|
|
252
|
+
@person.should_receive(:in_delta_index?).and_return(false)
|
|
253
|
+
@person.in_both_indexes?.should be_false
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe "in_core_index?" do
|
|
258
|
+
it "should call in_index? with core" do
|
|
259
|
+
@person.should_receive(:in_index?).with('core')
|
|
260
|
+
@person.in_core_index?
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
describe "in_delta_index?" do
|
|
265
|
+
it "should call in_index? with delta" do
|
|
266
|
+
@person.should_receive(:in_index?).with('delta')
|
|
267
|
+
@person.in_delta_index?
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
describe "in_index?" do
|
|
272
|
+
it "should return true if in the specified index" do
|
|
273
|
+
@person.should_receive(:sphinx_document_id).and_return(1)
|
|
274
|
+
@person.should_receive(:sphinx_index_name).and_return('person_core')
|
|
275
|
+
Person.should_receive(:search_for_id).with(1, 'person_core').and_return(true)
|
|
276
|
+
|
|
277
|
+
@person.in_index?('core').should be_true
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe '.source_of_sphinx_index' do
|
|
283
|
+
it "should return self if model defines an index" do
|
|
284
|
+
Person.source_of_sphinx_index.should == Person
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "should return the parent if model inherits an index" do
|
|
288
|
+
Admin::Person.source_of_sphinx_index.should == Person
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
describe '.to_crc32' do
|
|
293
|
+
it "should return an integer" do
|
|
294
|
+
Person.to_crc32.should be_a_kind_of(Integer)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
describe '.to_crc32s' do
|
|
299
|
+
it "should return an array" do
|
|
300
|
+
Person.to_crc32s.should be_a_kind_of(Array)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
describe "toggle_deleted method" do
|
|
305
|
+
before :each do
|
|
306
|
+
ThinkingSphinx.stub!(:sphinx_running? => true)
|
|
307
|
+
|
|
308
|
+
@configuration = ThinkingSphinx::Configuration.instance
|
|
309
|
+
@configuration.stub!(
|
|
310
|
+
:address => "an address",
|
|
311
|
+
:port => 123
|
|
312
|
+
)
|
|
313
|
+
@client = Riddle::Client.new
|
|
314
|
+
@client.stub!(:update => true)
|
|
315
|
+
@person = Person.find(:first)
|
|
316
|
+
|
|
317
|
+
@configuration.stub!(:client => @client)
|
|
318
|
+
Person.sphinx_indexes.each { |index| index.stub!(:delta? => false) }
|
|
319
|
+
Person.stub!(:search_for_id => true)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "should update the core index's deleted flag if in core index" do
|
|
323
|
+
@client.should_receive(:update).with(
|
|
324
|
+
"person_core", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
@person.toggle_deleted
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "shouldn't update the core index's deleted flag if the record isn't in it" do
|
|
331
|
+
Person.stub!(:search_for_id => false)
|
|
332
|
+
@client.should_not_receive(:update).with(
|
|
333
|
+
"person_core", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
@person.toggle_deleted
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
it "shouldn't attempt to update the deleted flag if sphinx isn't running" do
|
|
340
|
+
ThinkingSphinx.stub!(:sphinx_running? => false)
|
|
341
|
+
@client.should_not_receive(:update)
|
|
342
|
+
Person.should_not_receive(:search_for_id)
|
|
343
|
+
|
|
344
|
+
@person.toggle_deleted
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do
|
|
348
|
+
ThinkingSphinx.deltas_enabled = true
|
|
349
|
+
Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
|
|
350
|
+
@person.delta = true
|
|
351
|
+
@client.should_receive(:update).with(
|
|
352
|
+
"person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
@person.toggle_deleted
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do
|
|
359
|
+
ThinkingSphinx.deltas_enabled = true
|
|
360
|
+
Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
|
|
361
|
+
@person.delta = false
|
|
362
|
+
@client.should_not_receive(:update).with(
|
|
363
|
+
"person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
@person.toggle_deleted
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is equivalent to false" do
|
|
370
|
+
ThinkingSphinx.deltas_enabled = true
|
|
371
|
+
Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
|
|
372
|
+
@person.delta = 0
|
|
373
|
+
@client.should_not_receive(:update).with(
|
|
374
|
+
"person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
@person.toggle_deleted
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
it "shouldn't update the delta index if delta indexes are disabled" do
|
|
381
|
+
ThinkingSphinx.deltas_enabled = true
|
|
382
|
+
@client.should_not_receive(:update).with(
|
|
383
|
+
"person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
@person.toggle_deleted
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it "should not update either index if updates are disabled" do
|
|
390
|
+
ThinkingSphinx.updates_enabled = false
|
|
391
|
+
ThinkingSphinx.deltas_enabled = true
|
|
392
|
+
Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
|
|
393
|
+
@person.delta = true
|
|
394
|
+
@client.should_not_receive(:update)
|
|
395
|
+
|
|
396
|
+
@person.toggle_deleted
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe "sphinx_indexes in the inheritance chain (STI)" do
|
|
401
|
+
it "should hand defined indexes on a class down to its child classes" do
|
|
402
|
+
Child.sphinx_indexes.should include(*Person.sphinx_indexes)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "should allow associations to other STI models" do
|
|
406
|
+
source = Child.sphinx_indexes.last.sources.first
|
|
407
|
+
sql = source.to_riddle_for_core(0, 0).sql_query
|
|
408
|
+
sql.gsub!('$start', '0').gsub!('$end', '100')
|
|
409
|
+
lambda {
|
|
410
|
+
Child.connection.execute(sql)
|
|
411
|
+
}.should_not raise_error(ActiveRecord::StatementInvalid)
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
describe '#sphinx_document_id' do
|
|
416
|
+
before :each do
|
|
417
|
+
Alpha.define_index { indexes :name }
|
|
418
|
+
Beta.define_index { indexes :name }
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
it "should return values with the expected offset" do
|
|
422
|
+
person = Person.find(:first)
|
|
423
|
+
model_count = ThinkingSphinx.context.indexed_models.length
|
|
424
|
+
Person.stub!(:sphinx_offset => 3)
|
|
425
|
+
|
|
426
|
+
(person.id * model_count + 3).should == person.sphinx_document_id
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
describe '#primary_key_for_sphinx' do
|
|
431
|
+
before :each do
|
|
432
|
+
@person = Person.find(:first)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
after :each do
|
|
436
|
+
Person.set_sphinx_primary_key nil
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
it "should return the id by default" do
|
|
440
|
+
@person.primary_key_for_sphinx.should == @person.id
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
it "should use the sphinx primary key to determine the value" do
|
|
444
|
+
Person.set_sphinx_primary_key :first_name
|
|
445
|
+
@person.primary_key_for_sphinx.should == @person.first_name
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
it "should not use accessor methods but the attributes hash" do
|
|
449
|
+
id = @person.id
|
|
450
|
+
@person.stub!(:id => 'unique_hash')
|
|
451
|
+
@person.primary_key_for_sphinx.should == id
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
describe '.sphinx_index_names' do
|
|
456
|
+
it "should return the core index" do
|
|
457
|
+
Alpha.define_index { indexes :name }
|
|
458
|
+
Alpha.define_indexes
|
|
459
|
+
Alpha.sphinx_index_names.should == ['alpha_core']
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
it "should return the delta index if enabled" do
|
|
463
|
+
Beta.define_index {
|
|
464
|
+
indexes :name
|
|
465
|
+
set_property :delta => true
|
|
466
|
+
}
|
|
467
|
+
Beta.define_indexes
|
|
468
|
+
|
|
469
|
+
Beta.sphinx_index_names.should == ['beta_core', 'beta_delta']
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "should return the superclass with an index definition" do
|
|
473
|
+
Parent.sphinx_index_names.should == ['person_core', 'person_delta']
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
describe '.indexed_by_sphinx?' do
|
|
478
|
+
it "should return true if there is at least one index on the model" do
|
|
479
|
+
Alpha.define_index { indexes :name }
|
|
480
|
+
Alpha.define_indexes
|
|
481
|
+
|
|
482
|
+
Alpha.should be_indexed_by_sphinx
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
it "should return false if there are no indexes on the model" do
|
|
486
|
+
Gamma.should_not be_indexed_by_sphinx
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
describe '.delta_indexed_by_sphinx?' do
|
|
491
|
+
it "should return true if there is at least one delta index on the model" do
|
|
492
|
+
Beta.define_index {
|
|
493
|
+
indexes :name
|
|
494
|
+
set_property :delta => true
|
|
495
|
+
}
|
|
496
|
+
Beta.define_indexes
|
|
497
|
+
|
|
498
|
+
Beta.should be_delta_indexed_by_sphinx
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
it "should return false if there are no delta indexes on the model" do
|
|
502
|
+
Alpha.define_index { indexes :name }
|
|
503
|
+
Alpha.define_indexes
|
|
504
|
+
|
|
505
|
+
Alpha.should_not be_delta_indexed_by_sphinx
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
describe '.delete_in_index' do
|
|
510
|
+
before :each do
|
|
511
|
+
@client = stub('client')
|
|
512
|
+
ThinkingSphinx.stub!(:sphinx_running? => true)
|
|
513
|
+
ThinkingSphinx::Configuration.instance.stub!(:client => @client)
|
|
514
|
+
Alpha.stub!(:search_for_id => true)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it "should not update if the document isn't in the given index" do
|
|
518
|
+
Alpha.stub!(:search_for_id => false)
|
|
519
|
+
@client.should_not_receive(:update)
|
|
520
|
+
|
|
521
|
+
Alpha.delete_in_index('alpha_core', 42)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
it "should direct the update to the supplied index" do
|
|
525
|
+
@client.should_receive(:update) do |index, attributes, values|
|
|
526
|
+
index.should == 'custom_index_core'
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
Alpha.delete_in_index('custom_index_core', 42)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
it "should set the sphinx_deleted flag to true" do
|
|
533
|
+
@client.should_receive(:update) do |index, attributes, values|
|
|
534
|
+
attributes.should == ['sphinx_deleted']
|
|
535
|
+
values.should == {42 => [1]}
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
Alpha.delete_in_index('alpha_core', 42)
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
describe '.core_index_names' do
|
|
543
|
+
it "should return each index's core name" do
|
|
544
|
+
Alpha.define_index('foo') { indexes :name }
|
|
545
|
+
Alpha.define_index('bar') { indexes :name }
|
|
546
|
+
Alpha.define_indexes
|
|
547
|
+
|
|
548
|
+
Alpha.core_index_names.should == ['foo_core', 'bar_core']
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
describe '.delta_index_names' do
|
|
553
|
+
it "should return index delta names, for indexes with deltas enabled" do
|
|
554
|
+
Alpha.define_index('foo') { indexes :name }
|
|
555
|
+
Alpha.define_index('bar') { indexes :name }
|
|
556
|
+
Alpha.define_indexes
|
|
557
|
+
Alpha.sphinx_indexes.first.delta_object = stub('delta')
|
|
558
|
+
|
|
559
|
+
Alpha.delta_index_names.should == ['foo_delta']
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
describe '.sphinx_offset' do
|
|
564
|
+
before :each do
|
|
565
|
+
@context = ThinkingSphinx.context
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
it "should return the index of the model's name in all known indexed models" do
|
|
569
|
+
@context.stub!(:indexed_models => ['Alpha', 'Beta'])
|
|
570
|
+
|
|
571
|
+
Alpha.sphinx_offset.should == 0
|
|
572
|
+
Beta.sphinx_offset.should == 1
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it "should ignore classes that have indexed superclasses" do
|
|
576
|
+
@context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
|
|
577
|
+
|
|
578
|
+
Person.sphinx_offset.should == 1
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
it "should respect first known indexed parents" do
|
|
582
|
+
@context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
|
|
583
|
+
|
|
584
|
+
Parent.sphinx_offset.should == 1
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
describe '.has_sphinx_indexes?' do
|
|
589
|
+
it "should return true if there are sphinx indexes defined" do
|
|
590
|
+
Alpha.sphinx_indexes.replace [stub('index')]
|
|
591
|
+
Alpha.sphinx_index_blocks.replace []
|
|
592
|
+
|
|
593
|
+
Alpha.should have_sphinx_indexes
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
it "should return true if there are sphinx index blocks defined" do
|
|
597
|
+
Alpha.sphinx_indexes.replace []
|
|
598
|
+
Alpha.sphinx_index_blocks.replace [stub('lambda')]
|
|
599
|
+
|
|
600
|
+
Alpha.should have_sphinx_indexes
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
it "should return false if there are no sphinx indexes or blocks" do
|
|
604
|
+
Alpha.sphinx_indexes.clear
|
|
605
|
+
Alpha.sphinx_index_blocks.clear
|
|
606
|
+
|
|
607
|
+
Alpha.should_not have_sphinx_indexes
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
describe '.reset_subclasses' do
|
|
612
|
+
it "should reset the stored context" do
|
|
613
|
+
ThinkingSphinx.should_receive(:reset_context!)
|
|
614
|
+
|
|
615
|
+
ActiveRecord::Base.reset_subclasses
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
end
|