thinking-sphinx 1.4.6 → 1.4.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/README.textile +6 -1
  2. data/features/searching_by_model.feature +24 -30
  3. data/features/thinking_sphinx/db/.gitignore +1 -0
  4. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +1 -0
  5. data/lib/cucumber/thinking_sphinx/internal_world.rb +26 -26
  6. data/lib/thinking_sphinx.rb +17 -26
  7. data/lib/thinking_sphinx/active_record.rb +69 -74
  8. data/lib/thinking_sphinx/active_record/attribute_updates.rb +11 -10
  9. data/lib/thinking_sphinx/active_record/has_many_association.rb +2 -1
  10. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +11 -11
  11. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +34 -20
  12. data/lib/thinking_sphinx/association.rb +12 -7
  13. data/lib/thinking_sphinx/attribute.rb +64 -61
  14. data/lib/thinking_sphinx/configuration.rb +32 -36
  15. data/lib/thinking_sphinx/context.rb +3 -2
  16. data/lib/thinking_sphinx/deploy/capistrano.rb +7 -9
  17. data/lib/thinking_sphinx/search.rb +201 -178
  18. data/lib/thinking_sphinx/source/sql.rb +1 -1
  19. data/lib/thinking_sphinx/tasks.rb +21 -19
  20. data/lib/thinking_sphinx/version.rb +3 -0
  21. data/spec/fixtures/data.sql +32 -0
  22. data/spec/fixtures/database.yml.default +3 -0
  23. data/spec/fixtures/models.rb +161 -0
  24. data/spec/fixtures/structure.sql +146 -0
  25. data/spec/spec_helper.rb +57 -0
  26. data/spec/sphinx_helper.rb +61 -0
  27. data/spec/thinking_sphinx/active_record/delta_spec.rb +24 -24
  28. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +22 -0
  29. data/spec/thinking_sphinx/active_record/scopes_spec.rb +25 -25
  30. data/spec/thinking_sphinx/active_record_spec.rb +110 -109
  31. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +38 -38
  32. data/spec/thinking_sphinx/association_spec.rb +20 -2
  33. data/spec/thinking_sphinx/context_spec.rb +61 -64
  34. data/spec/thinking_sphinx/search_spec.rb +7 -0
  35. data/spec/thinking_sphinx_spec.rb +47 -46
  36. metadata +50 -98
  37. data/VERSION +0 -1
  38. data/tasks/distribution.rb +0 -34
  39. data/tasks/testing.rb +0 -80
@@ -0,0 +1,57 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+ Dir[File.join(File.dirname(__FILE__), '../vendor/*/lib')].each do |path|
3
+ $:.unshift path
4
+ end
5
+
6
+ require 'rubygems'
7
+ require 'fileutils'
8
+ require 'bundler'
9
+
10
+ Bundler.require :default, :development
11
+
12
+ require "#{File.dirname(__FILE__)}/sphinx_helper"
13
+
14
+ ActiveRecord::Base.logger = Logger.new(StringIO.new)
15
+
16
+ RSpec.configure do |config|
17
+ %w( tmp tmp/config tmp/log tmp/db ).each do |path|
18
+ FileUtils.mkdir_p "#{Dir.pwd}/#{path}"
19
+ end
20
+
21
+ Kernel.const_set :RAILS_ROOT, "#{Dir.pwd}/tmp" unless defined?(RAILS_ROOT)
22
+
23
+ sphinx = SphinxHelper.new
24
+ sphinx.setup_mysql
25
+
26
+ require "#{File.dirname(__FILE__)}/fixtures/models"
27
+ ThinkingSphinx.context.define_indexes
28
+
29
+ config.before :each do
30
+ %w( tmp tmp/config tmp/log tmp/db ).each do |path|
31
+ FileUtils.mkdir_p "#{Dir.pwd}/#{path}"
32
+ end
33
+
34
+ ThinkingSphinx.updates_enabled = true
35
+ ThinkingSphinx.deltas_enabled = true
36
+ ThinkingSphinx.suppress_delta_output = true
37
+
38
+ ThinkingSphinx::Configuration.instance.reset
39
+ end
40
+
41
+ config.after :all do
42
+ FileUtils.rm_r "#{Dir.pwd}/tmp" rescue nil
43
+ end
44
+ end
45
+
46
+ def minimal_result_hashes(*instances)
47
+ instances.collect do |instance|
48
+ {
49
+ :weight => 21,
50
+ :attributes => {
51
+ 'sphinx_internal_id' => instance.id,
52
+ 'sphinx_internal_class' => instance.class.name,
53
+ 'class_crc' => instance.class.name.to_crc32
54
+ }
55
+ }
56
+ end
57
+ end
@@ -0,0 +1,61 @@
1
+ require 'active_record'
2
+ prefix = defined?(JRUBY_VERSION) ? "jdbc" : ""
3
+ require "active_record/connection_adapters/#{prefix}mysql_adapter"
4
+ require "active_record/connection_adapters/mysql2_adapter"
5
+
6
+ begin
7
+ require "active_record/connection_adapters/#{prefix}postgresql_adapter"
8
+ rescue LoadError
9
+ # No postgres? no prob...
10
+ end
11
+ require 'yaml'
12
+
13
+ class SphinxHelper
14
+ attr_accessor :host, :username, :password, :socket
15
+ attr_reader :path
16
+
17
+ def initialize
18
+ @host = 'localhost'
19
+ @username = 'root'
20
+ @password = ''
21
+
22
+ if File.exist?('spec/fixtures/database.yml')
23
+ config = YAML.load(File.open('spec/fixtures/database.yml'))
24
+ @host = config['host']
25
+ @username = config['username']
26
+ @password = config['password']
27
+ @socket = config['socket']
28
+ end
29
+
30
+ @path = File.expand_path(File.dirname(__FILE__))
31
+ end
32
+
33
+ def setup_mysql
34
+ ActiveRecord::Base.establish_connection(
35
+ :adapter => mysql_adapter,
36
+ :database => 'thinking_sphinx',
37
+ :username => @username,
38
+ :password => @password,
39
+ :host => @host,
40
+ :socket => @socket
41
+ )
42
+ ActiveRecord::Base.logger = Logger.new(File.open('tmp/activerecord.log', 'a'))
43
+
44
+ structure = File.open('spec/fixtures/structure.sql') { |f| f.read.chomp }
45
+ structure.split(';').each { |table|
46
+ ActiveRecord::Base.connection.execute table
47
+ }
48
+
49
+ File.open('spec/fixtures/data.sql') { |f|
50
+ while line = f.gets
51
+ ActiveRecord::Base.connection.execute line unless line.blank?
52
+ end
53
+ }
54
+ end
55
+
56
+ private
57
+
58
+ def mysql_adapter
59
+ defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'
60
+ end
61
+ end
@@ -3,18 +3,18 @@ require 'spec_helper'
3
3
  describe "ThinkingSphinx::ActiveRecord::Delta" do
4
4
  it "should call the toggle_delta method after a save" do
5
5
  @beta = Beta.new(:name => 'beta')
6
- @beta.should_receive(:toggle_delta).and_return(true)
7
-
6
+ @beta.should_receive(:toggle_delta).at_least(1).times.and_return(true)
7
+
8
8
  @beta.save
9
9
  end
10
-
10
+
11
11
  it "should call the toggle_delta method after a save!" do
12
12
  @beta = Beta.new(:name => 'beta')
13
- @beta.should_receive(:toggle_delta).and_return(true)
14
-
13
+ @beta.should_receive(:toggle_delta).at_least(1).times.and_return(true)
14
+
15
15
  @beta.save!
16
16
  end
17
-
17
+
18
18
  describe "suspended_delta method" do
19
19
  before :each do
20
20
  ThinkingSphinx.deltas_suspended = false
@@ -47,23 +47,23 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
47
47
  Person.should_receive(:index_delta)
48
48
  Person.suspended_delta { 'no-op' }
49
49
  end
50
-
50
+
51
51
  it "should not reindex after the code block if false is passed in" do
52
52
  Person.should_not_receive(:index_delta)
53
53
  Person.suspended_delta(false) { 'no-op' }
54
54
  end
55
55
  end
56
-
56
+
57
57
  describe "toggle_delta method" do
58
58
  it "should set the delta value to true" do
59
59
  @person = Person.new
60
-
60
+
61
61
  @person.delta.should be_false
62
62
  @person.send(:toggle_delta)
63
63
  @person.delta.should be_true
64
64
  end
65
65
  end
66
-
66
+
67
67
  describe "index_delta method" do
68
68
  before :each do
69
69
  ThinkingSphinx::Configuration.stub!(:environment => "spec")
@@ -71,57 +71,57 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
71
71
  ThinkingSphinx.updates_enabled = true
72
72
  ThinkingSphinx.stub!(:sphinx_running? => true)
73
73
  Person.delta_objects.first.stub!(:` => "", :toggled => true)
74
-
74
+
75
75
  @person = Person.new
76
76
  Person.stub!(:search_for_id => false)
77
77
  @person.stub!(:sphinx_document_id => 1)
78
-
78
+
79
79
  @client = Riddle::Client.new
80
80
  @client.stub!(:update => true)
81
81
  ThinkingSphinx::Configuration.instance.stub!(:client => @client)
82
82
  end
83
-
83
+
84
84
  it "shouldn't index if delta indexing is disabled" do
85
85
  ThinkingSphinx.deltas_enabled = false
86
86
  Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
87
87
  @client.should_not_receive(:update)
88
-
88
+
89
89
  @person.send(:index_delta)
90
90
  end
91
-
91
+
92
92
  it "shouldn't index if index updating is disabled" do
93
93
  ThinkingSphinx.updates_enabled = false
94
94
  Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
95
-
95
+
96
96
  @person.send(:index_delta)
97
97
  end
98
-
98
+
99
99
  it "shouldn't index if the environment is 'test'" do
100
100
  ThinkingSphinx.deltas_enabled = nil
101
101
  ThinkingSphinx::Configuration.stub!(:environment => "test")
102
102
  Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
103
-
103
+
104
104
  @person.send(:index_delta)
105
105
  end
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
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)
113
113
  end
114
-
114
+
115
115
  it "shouldn't update the deleted attribute if not in the index" do
116
116
  @client.should_not_receive(:update)
117
-
117
+
118
118
  @person.send(:index_delta)
119
119
  end
120
-
120
+
121
121
  it "should update the deleted attribute if in the core index" do
122
122
  Person.stub!(:search_for_id => true)
123
123
  @client.should_receive(:update)
124
-
124
+
125
125
  @person.send(:index_delta)
126
126
  end
127
127
  end
@@ -23,6 +23,17 @@ describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
23
23
  @person.friendships.search "test"
24
24
  end
25
25
 
26
+ it "should add a filter for an aliased attribute into a normal search call" do
27
+ @team = CricketTeam.new
28
+ @team.stub!(:id => 1)
29
+
30
+ Person.should_receive(:search).with do |query, options|
31
+ options[:with][:team_id].should == @team.id
32
+ end
33
+
34
+ @team.people.search "test"
35
+ end
36
+
26
37
  it "should define indexes for the reflection class" do
27
38
  Friendship.should_receive(:define_indexes)
28
39
 
@@ -51,6 +62,17 @@ describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
51
62
 
52
63
  @person.friends.search "test"
53
64
  end
65
+
66
+ it "should add a filter for an aliased attribute into a normal search call" do
67
+ @team = FootballTeam.new
68
+ @team.stub!(:id => 1)
69
+
70
+ Person.should_receive(:search).with do |query, options|
71
+ options[:with][:football_team_id].should == @team.id
72
+ end
73
+
74
+ @team.people.search "test"
75
+ end
54
76
  end
55
77
 
56
78
  describe 'filtering sphinx scopes' do
@@ -4,32 +4,32 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
4
4
  after :each do
5
5
  Alpha.remove_sphinx_scopes
6
6
  end
7
-
7
+
8
8
  it "should be included into models with indexes" do
9
9
  Alpha.included_modules.should include(ThinkingSphinx::ActiveRecord::Scopes)
10
10
  end
11
-
11
+
12
12
  it "should not be included into models without indexes" do
13
13
  Gamma.included_modules.should_not include(
14
14
  ThinkingSphinx::ActiveRecord::Scopes
15
15
  )
16
16
  end
17
-
17
+
18
18
  describe '.sphinx_scope' do
19
19
  before :each do
20
20
  Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
21
21
  end
22
-
22
+
23
23
  it "should define a method on the model" do
24
24
  Alpha.should respond_to(:by_name)
25
25
  end
26
26
  end
27
-
27
+
28
28
  describe '.sphinx_scopes' do
29
29
  before :each do
30
30
  Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
31
31
  end
32
-
32
+
33
33
  it "should return an array of defined scope names as symbols" do
34
34
  Alpha.sphinx_scopes.should == [:by_name]
35
35
  end
@@ -40,11 +40,11 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
40
40
  Alpha.sphinx_scope(:scope_used_as_default_scope) { {:conditions => {:name => 'name'}} }
41
41
  Alpha.default_sphinx_scope :scope_used_as_default_scope
42
42
  end
43
-
43
+
44
44
  it "should return an array of defined scope names as symbols" do
45
45
  Alpha.sphinx_scopes.should == [:scope_used_as_default_scope]
46
46
  end
47
-
47
+
48
48
  it "should have a default_sphinx_scope" do
49
49
  Alpha.has_default_sphinx_scope?.should be_true
50
50
  end
@@ -55,11 +55,11 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
55
55
  Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
56
56
  Alpha.remove_sphinx_scopes
57
57
  end
58
-
58
+
59
59
  it "should remove sphinx scope methods" do
60
60
  Alpha.should_not respond_to(:by_name)
61
61
  end
62
-
62
+
63
63
  it "should empty the list of sphinx scopes" do
64
64
  Alpha.sphinx_scopes.should be_empty
65
65
  end
@@ -99,44 +99,44 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
99
99
  Alpha.sphinx_scope(:by_foo) { |foo| {:conditions => {:foo => foo}} }
100
100
  Alpha.sphinx_scope(:with_betas) { {:classes => [Beta]} }
101
101
  end
102
-
102
+
103
103
  it "should return a ThinkingSphinx::Search object" do
104
104
  Alpha.by_name('foo').should be_a(ThinkingSphinx::Search)
105
105
  end
106
-
106
+
107
107
  it "should set the classes option" do
108
108
  Alpha.by_name('foo').options[:classes].should == [Alpha]
109
109
  end
110
-
110
+
111
111
  it "should be able to be called on a ThinkingSphinx::Search object" do
112
112
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
113
113
  lambda {
114
114
  search.by_name('foo')
115
115
  }.should_not raise_error
116
116
  end
117
-
117
+
118
118
  it "should return the search object it gets called upon" do
119
119
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
120
- search.by_name('foo').should == search
120
+ search.by_name('foo').object_id.should == search.object_id
121
121
  end
122
-
122
+
123
123
  it "should apply the scope options to the underlying search object" do
124
124
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
125
125
  search.by_name('foo').options[:conditions].should == {:name => 'foo'}
126
126
  end
127
-
127
+
128
128
  it "should combine hash option scopes such as :conditions" do
129
129
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
130
130
  search.by_name('foo').by_foo('bar').options[:conditions].
131
131
  should == {:name => 'foo', :foo => 'bar'}
132
132
  end
133
-
133
+
134
134
  it "should combine array option scopes such as :classes" do
135
135
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
136
136
  search.with_betas.options[:classes].should == [Alpha, Beta]
137
137
  end
138
138
  end
139
-
139
+
140
140
  describe '.search_count_with_scope' do
141
141
  before :each do
142
142
  @config = ThinkingSphinx::Configuration.instance
@@ -147,24 +147,24 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
147
147
  Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
148
148
  Alpha.sphinx_scope(:ids_only) { {:ids_only => true} }
149
149
  end
150
-
150
+
151
151
  it "should return the total number of results" do
152
152
  Alpha.by_name('foo').search_count.should == 43
153
153
  end
154
-
154
+
155
155
  it "should not make any calls to the database" do
156
156
  Alpha.should_not_receive(:find)
157
-
157
+
158
158
  Alpha.by_name('foo').search_count
159
159
  end
160
-
160
+
161
161
  it "should not leave the :ids_only option set and the results populated if it was not set before" do
162
162
  stored_scope = Alpha.by_name('foo')
163
163
  stored_scope.search_count
164
164
  stored_scope.options[:ids_only].should be_false
165
165
  stored_scope.populated?.should be_false
166
166
  end
167
-
167
+
168
168
  it "should leave the :ids_only option set and the results populated if it was set before" do
169
169
  stored_scope = Alpha.by_name('foo').ids_only
170
170
  stored_scope.search_count
@@ -172,5 +172,5 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
172
172
  stored_scope.populated?.should be_true
173
173
  end
174
174
  end
175
-
175
+
176
176
  end
@@ -4,80 +4,81 @@ describe ThinkingSphinx::ActiveRecord do
4
4
  before :each do
5
5
  @existing_alpha_indexes = Alpha.sphinx_indexes.clone
6
6
  @existing_beta_indexes = Beta.sphinx_indexes.clone
7
-
7
+
8
8
  Alpha.send :defined_indexes=, false
9
9
  Beta.send :defined_indexes=, false
10
-
10
+
11
11
  Alpha.sphinx_indexes.clear
12
12
  Beta.sphinx_indexes.clear
13
13
  end
14
-
14
+
15
15
  after :each do
16
16
  Alpha.sphinx_indexes.replace @existing_alpha_indexes
17
17
  Beta.sphinx_indexes.replace @existing_beta_indexes
18
-
18
+
19
19
  Alpha.send :defined_indexes=, true
20
20
  Beta.send :defined_indexes=, true
21
-
21
+
22
22
  Alpha.sphinx_index_blocks.clear
23
23
  Beta.sphinx_index_blocks.clear
24
24
  end
25
-
25
+
26
26
  describe '.define_index' do
27
27
  it "should do nothing if indexes are disabled" do
28
28
  ThinkingSphinx.define_indexes = false
29
29
  ThinkingSphinx::Index.should_not_receive(:new)
30
-
30
+
31
31
  Alpha.define_index { }
32
32
  Alpha.define_indexes
33
-
33
+
34
34
  ThinkingSphinx.define_indexes = true
35
35
  end
36
-
36
+
37
37
  it "should not evaluate the index block automatically" do
38
38
  lambda {
39
39
  Alpha.define_index { raise StandardError }
40
40
  }.should_not raise_error
41
41
  end
42
-
42
+
43
43
  it "should add the model to the context collection" do
44
44
  Alpha.define_index { indexes :name }
45
-
45
+
46
46
  ThinkingSphinx.context.indexed_models.should include("Alpha")
47
47
  end
48
-
48
+
49
49
  it "should die quietly if there is a database error" do
50
- ThinkingSphinx::Index::Builder.stub(:generate) { raise Mysql::Error }
50
+ ThinkingSphinx::Index::Builder.stub(:generate).
51
+ and_raise(Mysql2::Error.new(''))
51
52
  Alpha.define_index { indexes :name }
52
-
53
+
53
54
  lambda {
54
55
  Alpha.define_indexes
55
56
  }.should_not raise_error
56
- end
57
-
57
+ end unless RUBY_PLATFORM == 'java'
58
+
58
59
  it "should die noisily if there is a non-database error" do
59
60
  ThinkingSphinx::Index::Builder.stub(:generate) { raise StandardError }
60
61
  Alpha.define_index { indexes :name }
61
-
62
+
62
63
  lambda {
63
64
  Alpha.define_indexes
64
65
  }.should raise_error
65
66
  end
66
-
67
+
67
68
  it "should set the index's name using the parameter if provided" do
68
69
  Alpha.define_index('custom') { indexes :name }
69
70
  Alpha.define_indexes
70
-
71
+
71
72
  Alpha.sphinx_indexes.first.name.should == 'custom'
72
73
  end
73
-
74
+
74
75
  context 'callbacks' do
75
76
  it "should add a before_validation callback to define_indexes" do
76
77
  Alpha.should_receive(:before_validation).with(:define_indexes)
77
78
 
78
79
  Alpha.define_index { }
79
80
  end
80
-
81
+
81
82
  it "should not add a before_validation callback twice" do
82
83
  Alpha.should_receive(:before_validation).with(:define_indexes).once
83
84
 
@@ -90,44 +91,44 @@ describe ThinkingSphinx::ActiveRecord do
90
91
 
91
92
  Alpha.define_index { }
92
93
  end
93
-
94
+
94
95
  it "should not add a before_destroy callback twice" do
95
96
  Alpha.should_receive(:before_destroy).with(:define_indexes).once
96
97
 
97
98
  Alpha.define_index { }
98
99
  Alpha.define_index { }
99
100
  end
100
-
101
+
101
102
  it "should add a toggle_deleted callback when defined" do
102
103
  Alpha.should_receive(:after_destroy).with(:toggle_deleted)
103
-
104
+
104
105
  Alpha.define_index { indexes :name }
105
106
  Alpha.define_indexes
106
107
  end
107
-
108
+
108
109
  it "should not add toggle_deleted callback more than once" do
109
110
  Alpha.should_receive(:after_destroy).with(:toggle_deleted).once
110
-
111
+
111
112
  Alpha.define_index { indexes :name }
112
113
  Alpha.define_index { indexes :name }
113
114
  Alpha.define_indexes
114
115
  end
115
-
116
+
116
117
  it "should add a update_attribute_values callback when defined" do
117
118
  Alpha.should_receive(:after_commit).with(:update_attribute_values)
118
-
119
+
119
120
  Alpha.define_index { indexes :name }
120
121
  Alpha.define_indexes
121
122
  end
122
-
123
+
123
124
  it "should not add update_attribute_values callback more than once" do
124
125
  Alpha.should_receive(:after_commit).with(:update_attribute_values).once
125
-
126
+
126
127
  Alpha.define_index { indexes :name }
127
128
  Alpha.define_index { indexes :name }
128
129
  Alpha.define_indexes
129
130
  end
130
-
131
+
131
132
  it "should add a toggle_delta callback if deltas are enabled" do
132
133
  Beta.should_receive(:before_save).with(:toggle_delta)
133
134
 
@@ -137,14 +138,14 @@ describe ThinkingSphinx::ActiveRecord do
137
138
  }
138
139
  Beta.define_indexes
139
140
  end
140
-
141
+
141
142
  it "should not add a toggle_delta callback if deltas are disabled" do
142
143
  Alpha.should_not_receive(:before_save).with(:toggle_delta)
143
144
 
144
145
  Alpha.define_index { indexes :name }
145
146
  Alpha.define_indexes
146
147
  end
147
-
148
+
148
149
  it "should add the toggle_delta callback if deltas are disabled in other indexes" do
149
150
  Beta.should_receive(:before_save).with(:toggle_delta).once
150
151
 
@@ -155,7 +156,7 @@ describe ThinkingSphinx::ActiveRecord do
155
156
  }
156
157
  Beta.define_indexes
157
158
  end
158
-
159
+
159
160
  it "should only add the toggle_delta callback once" do
160
161
  Beta.should_receive(:before_save).with(:toggle_delta).once
161
162
 
@@ -169,7 +170,7 @@ describe ThinkingSphinx::ActiveRecord do
169
170
  }
170
171
  Beta.define_indexes
171
172
  end
172
-
173
+
173
174
  it "should add an index_delta callback if deltas are enabled" do
174
175
  Beta.stub!(:after_commit => true)
175
176
  Beta.should_receive(:after_commit).with(:index_delta)
@@ -180,14 +181,14 @@ describe ThinkingSphinx::ActiveRecord do
180
181
  }
181
182
  Beta.define_indexes
182
183
  end
183
-
184
+
184
185
  it "should not add an index_delta callback if deltas are disabled" do
185
186
  Alpha.should_not_receive(:after_commit).with(:index_delta)
186
187
 
187
188
  Alpha.define_index { indexes :name }
188
189
  Alpha.define_indexes
189
190
  end
190
-
191
+
191
192
  it "should add the index_delta callback if deltas are disabled in other indexes" do
192
193
  Beta.stub!(:after_commit => true)
193
194
  Beta.should_receive(:after_commit).with(:index_delta).once
@@ -199,7 +200,7 @@ describe ThinkingSphinx::ActiveRecord do
199
200
  }
200
201
  Beta.define_indexes
201
202
  end
202
-
203
+
203
204
  it "should only add the index_delta callback once" do
204
205
  Beta.stub!(:after_commit => true)
205
206
  Beta.should_receive(:after_commit).with(:index_delta).once
@@ -214,23 +215,23 @@ describe ThinkingSphinx::ActiveRecord do
214
215
  }
215
216
  Beta.define_indexes
216
217
  end
217
- end
218
+ end
218
219
  end
219
-
220
+
220
221
  describe '.define_indexes' do
221
222
  it "should process define_index blocks" do
222
223
  Beta.define_index { indexes :name }
223
224
  Beta.sphinx_indexes.length.should == 0
224
-
225
+
225
226
  Beta.define_indexes
226
227
  Beta.sphinx_indexes.length.should == 1
227
228
  end
228
-
229
+
229
230
  it "should not re-add indexes" do
230
231
  Beta.define_index { indexes :name }
231
232
  Beta.define_indexes
232
233
  Beta.define_indexes
233
-
234
+
234
235
  Beta.sphinx_indexes.length.should == 1
235
236
  end
236
237
  end
@@ -244,23 +245,23 @@ describe ThinkingSphinx::ActiveRecord do
244
245
  Admin::Person.source_of_sphinx_index.should == Person
245
246
  end
246
247
  end
247
-
248
+
248
249
  describe '.to_crc32' do
249
250
  it "should return an integer" do
250
251
  Person.to_crc32.should be_a_kind_of(Integer)
251
252
  end
252
253
  end
253
-
254
+
254
255
  describe '.to_crc32s' do
255
256
  it "should return an array" do
256
257
  Person.to_crc32s.should be_a_kind_of(Array)
257
258
  end
258
259
  end
259
-
260
+
260
261
  describe "toggle_deleted method" do
261
262
  before :each do
262
263
  ThinkingSphinx.stub!(:sphinx_running? => true)
263
-
264
+
264
265
  @configuration = ThinkingSphinx::Configuration.instance
265
266
  @configuration.stub!(
266
267
  :address => "an address",
@@ -269,37 +270,37 @@ describe ThinkingSphinx::ActiveRecord do
269
270
  @client = Riddle::Client.new
270
271
  @client.stub!(:update => true)
271
272
  @person = Person.find(:first)
272
-
273
+
273
274
  @configuration.stub!(:client => @client)
274
275
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => false) }
275
276
  Person.stub!(:search_for_id => true)
276
277
  end
277
-
278
+
278
279
  it "should update the core index's deleted flag if in core index" do
279
280
  @client.should_receive(:update).with(
280
281
  "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
281
282
  )
282
-
283
+
283
284
  @person.toggle_deleted
284
285
  end
285
-
286
+
286
287
  it "shouldn't update the core index's deleted flag if the record isn't in it" do
287
288
  Person.stub!(:search_for_id => false)
288
289
  @client.should_not_receive(:update).with(
289
290
  "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
290
291
  )
291
-
292
+
292
293
  @person.toggle_deleted
293
294
  end
294
-
295
+
295
296
  it "shouldn't attempt to update the deleted flag if sphinx isn't running" do
296
297
  ThinkingSphinx.stub!(:sphinx_running? => false)
297
298
  @client.should_not_receive(:update)
298
299
  Person.should_not_receive(:search_for_id)
299
-
300
+
300
301
  @person.toggle_deleted
301
302
  end
302
-
303
+
303
304
  it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do
304
305
  ThinkingSphinx.deltas_enabled = true
305
306
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
@@ -307,10 +308,10 @@ describe ThinkingSphinx::ActiveRecord do
307
308
  @client.should_receive(:update).with(
308
309
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
309
310
  )
310
-
311
+
311
312
  @person.toggle_deleted
312
313
  end
313
-
314
+
314
315
  it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do
315
316
  ThinkingSphinx.deltas_enabled = true
316
317
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
@@ -318,10 +319,10 @@ describe ThinkingSphinx::ActiveRecord do
318
319
  @client.should_not_receive(:update).with(
319
320
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
320
321
  )
321
-
322
+
322
323
  @person.toggle_deleted
323
324
  end
324
-
325
+
325
326
  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
326
327
  ThinkingSphinx.deltas_enabled = true
327
328
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
@@ -338,17 +339,17 @@ describe ThinkingSphinx::ActiveRecord do
338
339
  @client.should_not_receive(:update).with(
339
340
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => [1]}
340
341
  )
341
-
342
+
342
343
  @person.toggle_deleted
343
344
  end
344
-
345
+
345
346
  it "should not update either index if updates are disabled" do
346
347
  ThinkingSphinx.updates_enabled = false
347
348
  ThinkingSphinx.deltas_enabled = true
348
349
  Person.sphinx_indexes.each { |index| index.stub!(:delta? => true) }
349
350
  @person.delta = true
350
351
  @client.should_not_receive(:update)
351
-
352
+
352
353
  @person.toggle_deleted
353
354
  end
354
355
  end
@@ -367,92 +368,92 @@ describe ThinkingSphinx::ActiveRecord do
367
368
  }.should_not raise_error(ActiveRecord::StatementInvalid)
368
369
  end
369
370
  end
370
-
371
+
371
372
  describe '#sphinx_document_id' do
372
373
  before :each do
373
374
  Alpha.define_index { indexes :name }
374
375
  Beta.define_index { indexes :name }
375
376
  end
376
-
377
+
377
378
  it "should return values with the expected offset" do
378
379
  person = Person.find(:first)
379
380
  model_count = ThinkingSphinx.context.indexed_models.length
380
381
  Person.stub!(:sphinx_offset => 3)
381
-
382
+
382
383
  (person.id * model_count + 3).should == person.sphinx_document_id
383
384
  end
384
385
  end
385
-
386
+
386
387
  describe '#primary_key_for_sphinx' do
387
388
  before :each do
388
389
  @person = Person.find(:first)
389
390
  end
390
-
391
+
391
392
  after :each do
392
393
  Person.clear_primary_key_for_sphinx
393
394
  end
394
-
395
+
395
396
  after :each do
396
397
  Person.set_sphinx_primary_key nil
397
398
  end
398
-
399
+
399
400
  it "should return the id by default" do
400
401
  @person.primary_key_for_sphinx.should == @person.id
401
402
  end
402
-
403
+
403
404
  it "should use the sphinx primary key to determine the value" do
404
405
  Person.set_sphinx_primary_key :first_name
405
406
  @person.primary_key_for_sphinx.should == @person.first_name
406
407
  end
407
-
408
+
408
409
  it "should not use accessor methods but the attributes hash" do
409
410
  id = @person.id
410
411
  @person.stub!(:id => 'unique_hash')
411
412
  @person.primary_key_for_sphinx.should == id
412
413
  end
413
-
414
+
414
415
  it "should be inherited by subclasses" do
415
416
  Person.set_sphinx_primary_key :first_name
416
417
  Parent.superclass.custom_primary_key_for_sphinx?
417
418
  Parent.primary_key_for_sphinx.should == Person.primary_key_for_sphinx
418
419
  end
419
420
  end
420
-
421
+
421
422
  describe '.sphinx_index_names' do
422
423
  it "should return the core index" do
423
424
  Alpha.define_index { indexes :name }
424
425
  Alpha.define_indexes
425
426
  Alpha.sphinx_index_names.should == ['alpha_core']
426
427
  end
427
-
428
+
428
429
  it "should return the delta index if enabled" do
429
430
  Beta.define_index {
430
431
  indexes :name
431
432
  set_property :delta => true
432
433
  }
433
434
  Beta.define_indexes
434
-
435
+
435
436
  Beta.sphinx_index_names.should == ['beta_core', 'beta_delta']
436
437
  end
437
-
438
+
438
439
  it "should return the superclass with an index definition" do
439
440
  Parent.sphinx_index_names.should == ['person_core', 'person_delta']
440
441
  end
441
442
  end
442
-
443
+
443
444
  describe '.indexed_by_sphinx?' do
444
445
  it "should return true if there is at least one index on the model" do
445
446
  Alpha.define_index { indexes :name }
446
447
  Alpha.define_indexes
447
-
448
+
448
449
  Alpha.should be_indexed_by_sphinx
449
450
  end
450
-
451
+
451
452
  it "should return false if there are no indexes on the model" do
452
453
  Gamma.should_not be_indexed_by_sphinx
453
454
  end
454
455
  end
455
-
456
+
456
457
  describe '.delta_indexed_by_sphinx?' do
457
458
  it "should return true if there is at least one delta index on the model" do
458
459
  Beta.define_index {
@@ -460,18 +461,18 @@ describe ThinkingSphinx::ActiveRecord do
460
461
  set_property :delta => true
461
462
  }
462
463
  Beta.define_indexes
463
-
464
+
464
465
  Beta.should be_delta_indexed_by_sphinx
465
466
  end
466
-
467
+
467
468
  it "should return false if there are no delta indexes on the model" do
468
469
  Alpha.define_index { indexes :name }
469
470
  Alpha.define_indexes
470
-
471
+
471
472
  Alpha.should_not be_delta_indexed_by_sphinx
472
473
  end
473
474
  end
474
-
475
+
475
476
  describe '.delete_in_index' do
476
477
  before :each do
477
478
  @client = stub('client')
@@ -479,105 +480,105 @@ describe ThinkingSphinx::ActiveRecord do
479
480
  ThinkingSphinx::Configuration.instance.stub!(:client => @client)
480
481
  Alpha.stub!(:search_for_id => true)
481
482
  end
482
-
483
+
483
484
  it "should not update if the document isn't in the given index" do
484
485
  Alpha.stub!(:search_for_id => false)
485
486
  @client.should_not_receive(:update)
486
-
487
+
487
488
  Alpha.delete_in_index('alpha_core', 42)
488
489
  end
489
-
490
+
490
491
  it "should direct the update to the supplied index" do
491
492
  @client.should_receive(:update) do |index, attributes, values|
492
493
  index.should == 'custom_index_core'
493
494
  end
494
-
495
+
495
496
  Alpha.delete_in_index('custom_index_core', 42)
496
497
  end
497
-
498
+
498
499
  it "should set the sphinx_deleted flag to true" do
499
500
  @client.should_receive(:update) do |index, attributes, values|
500
501
  attributes.should == ['sphinx_deleted']
501
502
  values.should == {42 => [1]}
502
503
  end
503
-
504
+
504
505
  Alpha.delete_in_index('alpha_core', 42)
505
506
  end
506
507
  end
507
-
508
+
508
509
  describe '.core_index_names' do
509
510
  it "should return each index's core name" do
510
511
  Alpha.define_index('foo') { indexes :name }
511
512
  Alpha.define_index('bar') { indexes :name }
512
513
  Alpha.define_indexes
513
-
514
+
514
515
  Alpha.core_index_names.should == ['foo_core', 'bar_core']
515
516
  end
516
517
  end
517
-
518
+
518
519
  describe '.delta_index_names' do
519
520
  it "should return index delta names, for indexes with deltas enabled" do
520
521
  Alpha.define_index('foo') { indexes :name }
521
522
  Alpha.define_index('bar') { indexes :name }
522
523
  Alpha.define_indexes
523
524
  Alpha.sphinx_indexes.first.delta_object = stub('delta')
524
-
525
+
525
526
  Alpha.delta_index_names.should == ['foo_delta']
526
527
  end
527
528
  end
528
-
529
+
529
530
  describe '.sphinx_offset' do
530
531
  before :each do
531
532
  @context = ThinkingSphinx.context
532
533
  end
533
-
534
+
534
535
  it "should return the index of the model's name in all known indexed models" do
535
536
  @context.stub!(:indexed_models => ['Alpha', 'Beta'])
536
-
537
+
537
538
  Alpha.sphinx_offset.should == 0
538
539
  Beta.sphinx_offset.should == 1
539
540
  end
540
-
541
+
541
542
  it "should ignore classes that have indexed superclasses" do
542
543
  @context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
543
-
544
+
544
545
  Person.sphinx_offset.should == 1
545
546
  end
546
-
547
+
547
548
  it "should respect first known indexed parents" do
548
549
  @context.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])
549
-
550
+
550
551
  Parent.sphinx_offset.should == 1
551
552
  end
552
553
  end
553
-
554
+
554
555
  describe '.has_sphinx_indexes?' do
555
556
  it "should return true if there are sphinx indexes defined" do
556
557
  Alpha.sphinx_indexes.replace [stub('index')]
557
558
  Alpha.sphinx_index_blocks.replace []
558
-
559
+
559
560
  Alpha.should have_sphinx_indexes
560
561
  end
561
-
562
+
562
563
  it "should return true if there are sphinx index blocks defined" do
563
564
  Alpha.sphinx_indexes.replace []
564
565
  Alpha.sphinx_index_blocks.replace [stub('lambda')]
565
-
566
+
566
567
  Alpha.should have_sphinx_indexes
567
568
  end
568
-
569
+
569
570
  it "should return false if there are no sphinx indexes or blocks" do
570
571
  Alpha.sphinx_indexes.clear
571
572
  Alpha.sphinx_index_blocks.clear
572
-
573
+
573
574
  Alpha.should_not have_sphinx_indexes
574
575
  end
575
576
  end
576
-
577
+
577
578
  describe '.reset_subclasses' do
578
579
  it "should reset the stored context" do
579
580
  ThinkingSphinx.should_receive(:reset_context!)
580
-
581
+
581
582
  ActiveRecord::Base.reset_subclasses
582
583
  end
583
584
  end