friendlyfashion-thinking-sphinx 2.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. data/HISTORY +244 -0
  2. data/LICENCE +20 -0
  3. data/README.textile +235 -0
  4. data/features/abstract_inheritance.feature +10 -0
  5. data/features/alternate_primary_key.feature +27 -0
  6. data/features/attribute_transformation.feature +22 -0
  7. data/features/attribute_updates.feature +77 -0
  8. data/features/deleting_instances.feature +67 -0
  9. data/features/direct_attributes.feature +11 -0
  10. data/features/excerpts.feature +21 -0
  11. data/features/extensible_delta_indexing.feature +9 -0
  12. data/features/facets.feature +88 -0
  13. data/features/facets_across_model.feature +29 -0
  14. data/features/field_sorting.feature +18 -0
  15. data/features/handling_edits.feature +94 -0
  16. data/features/retry_stale_indexes.feature +24 -0
  17. data/features/searching_across_models.feature +20 -0
  18. data/features/searching_by_index.feature +40 -0
  19. data/features/searching_by_model.feature +175 -0
  20. data/features/searching_with_find_arguments.feature +56 -0
  21. data/features/sphinx_detection.feature +25 -0
  22. data/features/sphinx_scopes.feature +68 -0
  23. data/features/step_definitions/alpha_steps.rb +16 -0
  24. data/features/step_definitions/beta_steps.rb +7 -0
  25. data/features/step_definitions/common_steps.rb +201 -0
  26. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  27. data/features/step_definitions/facet_steps.rb +96 -0
  28. data/features/step_definitions/find_arguments_steps.rb +36 -0
  29. data/features/step_definitions/gamma_steps.rb +15 -0
  30. data/features/step_definitions/scope_steps.rb +19 -0
  31. data/features/step_definitions/search_steps.rb +94 -0
  32. data/features/step_definitions/sphinx_steps.rb +35 -0
  33. data/features/sti_searching.feature +19 -0
  34. data/features/support/env.rb +27 -0
  35. data/features/support/lib/generic_delta_handler.rb +8 -0
  36. data/features/thinking_sphinx/database.example.yml +3 -0
  37. data/features/thinking_sphinx/db/.gitignore +1 -0
  38. data/features/thinking_sphinx/db/fixtures/alphas.rb +8 -0
  39. data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
  40. data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
  41. data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
  42. data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
  43. data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
  44. data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
  45. data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
  46. data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
  47. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
  48. data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
  49. data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
  50. data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
  51. data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
  52. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +1 -0
  53. data/features/thinking_sphinx/db/fixtures/posts.rb +10 -0
  54. data/features/thinking_sphinx/db/fixtures/robots.rb +8 -0
  55. data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
  56. data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
  57. data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
  58. data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
  59. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
  60. data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
  61. data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
  62. data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
  63. data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
  64. data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
  65. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
  66. data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
  67. data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
  68. data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
  69. data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
  70. data/features/thinking_sphinx/db/migrations/create_posts.rb +6 -0
  71. data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
  72. data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
  73. data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
  74. data/features/thinking_sphinx/models/alpha.rb +23 -0
  75. data/features/thinking_sphinx/models/andrew.rb +17 -0
  76. data/features/thinking_sphinx/models/animal.rb +5 -0
  77. data/features/thinking_sphinx/models/author.rb +3 -0
  78. data/features/thinking_sphinx/models/beta.rb +13 -0
  79. data/features/thinking_sphinx/models/box.rb +8 -0
  80. data/features/thinking_sphinx/models/cat.rb +3 -0
  81. data/features/thinking_sphinx/models/category.rb +4 -0
  82. data/features/thinking_sphinx/models/comment.rb +10 -0
  83. data/features/thinking_sphinx/models/developer.rb +21 -0
  84. data/features/thinking_sphinx/models/dog.rb +3 -0
  85. data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
  86. data/features/thinking_sphinx/models/fox.rb +5 -0
  87. data/features/thinking_sphinx/models/gamma.rb +5 -0
  88. data/features/thinking_sphinx/models/genre.rb +3 -0
  89. data/features/thinking_sphinx/models/medium.rb +5 -0
  90. data/features/thinking_sphinx/models/music.rb +10 -0
  91. data/features/thinking_sphinx/models/person.rb +24 -0
  92. data/features/thinking_sphinx/models/post.rb +22 -0
  93. data/features/thinking_sphinx/models/robot.rb +12 -0
  94. data/features/thinking_sphinx/models/tag.rb +3 -0
  95. data/features/thinking_sphinx/models/tagging.rb +4 -0
  96. data/lib/cucumber/thinking_sphinx/external_world.rb +12 -0
  97. data/lib/cucumber/thinking_sphinx/internal_world.rb +137 -0
  98. data/lib/cucumber/thinking_sphinx/sql_logger.rb +28 -0
  99. data/lib/thinking-sphinx.rb +1 -0
  100. data/lib/thinking_sphinx/action_controller.rb +31 -0
  101. data/lib/thinking_sphinx/active_record/attribute_updates.rb +53 -0
  102. data/lib/thinking_sphinx/active_record/collection_proxy.rb +47 -0
  103. data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +27 -0
  104. data/lib/thinking_sphinx/active_record/delta.rb +67 -0
  105. data/lib/thinking_sphinx/active_record/has_many_association.rb +44 -0
  106. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +21 -0
  107. data/lib/thinking_sphinx/active_record/log_subscriber.rb +61 -0
  108. data/lib/thinking_sphinx/active_record/scopes.rb +110 -0
  109. data/lib/thinking_sphinx/active_record.rb +386 -0
  110. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +87 -0
  111. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +62 -0
  112. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +188 -0
  113. data/lib/thinking_sphinx/association.rb +230 -0
  114. data/lib/thinking_sphinx/attribute.rb +405 -0
  115. data/lib/thinking_sphinx/auto_version.rb +40 -0
  116. data/lib/thinking_sphinx/bundled_search.rb +44 -0
  117. data/lib/thinking_sphinx/class_facet.rb +20 -0
  118. data/lib/thinking_sphinx/configuration.rb +375 -0
  119. data/lib/thinking_sphinx/context.rb +76 -0
  120. data/lib/thinking_sphinx/core/string.rb +15 -0
  121. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  122. data/lib/thinking_sphinx/deltas.rb +28 -0
  123. data/lib/thinking_sphinx/deploy/capistrano.rb +99 -0
  124. data/lib/thinking_sphinx/excerpter.rb +23 -0
  125. data/lib/thinking_sphinx/facet.rb +135 -0
  126. data/lib/thinking_sphinx/facet_search.rb +170 -0
  127. data/lib/thinking_sphinx/field.rb +98 -0
  128. data/lib/thinking_sphinx/index/builder.rb +315 -0
  129. data/lib/thinking_sphinx/index/faux_column.rb +118 -0
  130. data/lib/thinking_sphinx/index.rb +159 -0
  131. data/lib/thinking_sphinx/join.rb +37 -0
  132. data/lib/thinking_sphinx/property.rb +187 -0
  133. data/lib/thinking_sphinx/railtie.rb +43 -0
  134. data/lib/thinking_sphinx/search.rb +1061 -0
  135. data/lib/thinking_sphinx/search_methods.rb +439 -0
  136. data/lib/thinking_sphinx/sinatra.rb +7 -0
  137. data/lib/thinking_sphinx/source/internal_properties.rb +51 -0
  138. data/lib/thinking_sphinx/source/sql.rb +174 -0
  139. data/lib/thinking_sphinx/source.rb +194 -0
  140. data/lib/thinking_sphinx/tasks.rb +142 -0
  141. data/lib/thinking_sphinx/test.rb +55 -0
  142. data/lib/thinking_sphinx/version.rb +3 -0
  143. data/lib/thinking_sphinx.rb +297 -0
  144. data/spec/fixtures/data.sql +32 -0
  145. data/spec/fixtures/database.yml.default +3 -0
  146. data/spec/fixtures/models.rb +164 -0
  147. data/spec/fixtures/structure.sql +146 -0
  148. data/spec/spec_helper.rb +61 -0
  149. data/spec/sphinx_helper.rb +60 -0
  150. data/spec/support/rails.rb +25 -0
  151. data/spec/thinking_sphinx/active_record/delta_spec.rb +122 -0
  152. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +173 -0
  153. data/spec/thinking_sphinx/active_record/scopes_spec.rb +176 -0
  154. data/spec/thinking_sphinx/active_record_spec.rb +573 -0
  155. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +145 -0
  156. data/spec/thinking_sphinx/association_spec.rb +250 -0
  157. data/spec/thinking_sphinx/attribute_spec.rb +552 -0
  158. data/spec/thinking_sphinx/auto_version_spec.rb +103 -0
  159. data/spec/thinking_sphinx/configuration_spec.rb +326 -0
  160. data/spec/thinking_sphinx/context_spec.rb +126 -0
  161. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  162. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  163. data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
  164. data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
  165. data/spec/thinking_sphinx/facet_spec.rb +359 -0
  166. data/spec/thinking_sphinx/field_spec.rb +127 -0
  167. data/spec/thinking_sphinx/index/builder_spec.rb +532 -0
  168. data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
  169. data/spec/thinking_sphinx/index_spec.rb +189 -0
  170. data/spec/thinking_sphinx/search_methods_spec.rb +156 -0
  171. data/spec/thinking_sphinx/search_spec.rb +1455 -0
  172. data/spec/thinking_sphinx/source_spec.rb +267 -0
  173. data/spec/thinking_sphinx/test_spec.rb +20 -0
  174. data/spec/thinking_sphinx_spec.rb +204 -0
  175. metadata +524 -0
@@ -0,0 +1,267 @@
1
+ require 'spec_helper'
2
+
3
+ describe ThinkingSphinx::Source do
4
+ before :each do
5
+ @index = ThinkingSphinx::Index.new(Person)
6
+ @source = ThinkingSphinx::Source.new(@index, :sql_range_step => 1000)
7
+ end
8
+
9
+ describe '#initialize' do
10
+ it "should store the current connection details" do
11
+ config = Person.connection.instance_variable_get(:@config)
12
+ @source.database_configuration.should == config
13
+ end
14
+ end
15
+
16
+ it "should generate the name from the model" do
17
+ @source.name.should == "person"
18
+ end
19
+
20
+ it "should handle namespaced models for name generation" do
21
+ index = ThinkingSphinx::Index.new(Admin::Person)
22
+ source = ThinkingSphinx::Source.new(index)
23
+ source.name.should == "admin_person"
24
+ end
25
+
26
+ describe "#to_riddle_for_core" do
27
+ before :each do
28
+ config = ThinkingSphinx::Configuration.instance
29
+ config.source_options[:sql_ranged_throttle] = 100
30
+
31
+ ThinkingSphinx::Field.new(
32
+ @source, ThinkingSphinx::Index::FauxColumn.new(:first_name)
33
+ )
34
+ ThinkingSphinx::Field.new(
35
+ @source, ThinkingSphinx::Index::FauxColumn.new(:last_name)
36
+ )
37
+
38
+ ThinkingSphinx::Attribute.new(
39
+ @source, ThinkingSphinx::Index::FauxColumn.new(:id), :as => :internal_id
40
+ )
41
+ ThinkingSphinx::Attribute.new(
42
+ @source, ThinkingSphinx::Index::FauxColumn.new(:birthday)
43
+ )
44
+ ThinkingSphinx::Attribute.new(
45
+ @source, ThinkingSphinx::Index::FauxColumn.new(:tags, :id), :as => :tag_ids
46
+ )
47
+ ThinkingSphinx::Attribute.new(
48
+ @source, ThinkingSphinx::Index::FauxColumn.new(:contacts, :id),
49
+ :as => :contact_ids, :source => :query
50
+ )
51
+ ThinkingSphinx::Attribute.new(
52
+ @source, ThinkingSphinx::Index::FauxColumn.new(:source, :id),
53
+ :as => :source_id, :type => :integer
54
+ )
55
+
56
+ ThinkingSphinx::Join.new(
57
+ @source, ThinkingSphinx::Index::FauxColumn.new(:links)
58
+ )
59
+
60
+ @source.conditions << "`birthday` <= NOW()"
61
+ @source.groupings << "`first_name`"
62
+
63
+ @index.local_options[:group_concat_max_len] = 1024
64
+
65
+ @riddle = @source.to_riddle_for_core(1, 0)
66
+ end
67
+
68
+ it "should generate a Riddle Source object" do
69
+ @riddle.should be_a_kind_of(Riddle::Configuration::SQLSource)
70
+ end
71
+
72
+ it "should use the index and name its own name" do
73
+ @riddle.name.should == "person_core_0"
74
+ end
75
+
76
+ it "should use the model's database connection to determine type" do
77
+ @riddle.type.should == "mysql"
78
+ end
79
+
80
+ it "should match the model's database settings" do
81
+ config = Person.connection.instance_variable_get(:@config)
82
+ @riddle.sql_db.should == config[:database]
83
+ @riddle.sql_user.should == config[:username]
84
+ @riddle.sql_pass.should == config[:password].to_s
85
+ @riddle.sql_host.should == config[:host]
86
+ @riddle.sql_port.should == config[:port]
87
+ @riddle.sql_sock.should == config[:socket]
88
+
89
+ @riddle.mysql_ssl_ca.should == config[:sslca]
90
+ @riddle.mysql_ssl_cert.should == config[:sslcert]
91
+ @riddle.mysql_ssl_key.should == config[:sslkey]
92
+ end
93
+
94
+ it "should use a environment user if nothing else is provided" do
95
+ Person.connection.stub!(:instance_variable_get => {
96
+ :user => nil,
97
+ :username => nil
98
+ })
99
+ @source = ThinkingSphinx::Source.new(@index)
100
+
101
+ riddle = @source.to_riddle_for_core(1, 0)
102
+ riddle.sql_user.should == ENV['USER']
103
+ end
104
+
105
+ it "should assign attributes" do
106
+ # 3 internal attributes plus the one requested
107
+ @riddle.sql_attr_uint.length.should == 4
108
+ @riddle.sql_attr_uint.last.should == :internal_id
109
+
110
+ @riddle.sql_attr_timestamp.length.should == 1
111
+ @riddle.sql_attr_timestamp.first.should == :birthday
112
+ end
113
+
114
+ it "should not include an attribute definition for polymorphic references without data" do
115
+ @riddle.sql_attr_uint.select { |uint|
116
+ uint == :source_id
117
+ }.should be_empty
118
+ end
119
+
120
+ it "should set Sphinx Source options" do
121
+ @riddle.sql_range_step.should == 1000
122
+ @riddle.sql_ranged_throttle.should == 100
123
+ end
124
+
125
+ describe "#sql_query" do
126
+ before :each do
127
+ @query = @riddle.sql_query
128
+ end
129
+
130
+ it "should select data from the model table" do
131
+ @query.should match(/FROM\s+`people`/)
132
+ end
133
+
134
+ it "should select each of the fields" do
135
+ @query.should match(/`first_name`.+FROM/)
136
+ @query.should match(/`last_name`.+FROM/)
137
+ end
138
+
139
+ it "should select each of the attributes" do
140
+ @query.should match(/`id` AS `internal_id`.+FROM/)
141
+ @query.should match(/`birthday`.+FROM/)
142
+ @query.should match(/`tags`.`id`.+ AS `tag_ids`.+FROM/)
143
+ end
144
+
145
+ it "should not match the sourced MVA attribute" do
146
+ @query.should_not match(/contact_ids/)
147
+ end
148
+
149
+ it "should include joins for required associations" do
150
+ @query.should match(/LEFT OUTER JOIN `tags`/)
151
+ end
152
+
153
+ it "should not include joins for the sourced MVA attribute" do
154
+ @query.should_not match(/LEFT OUTER JOIN `contacts`/)
155
+ end
156
+
157
+ it "should include explicitly requested joins" do
158
+ @query.should match(/LEFT OUTER JOIN `links`/)
159
+ end
160
+
161
+ it "should include any defined conditions" do
162
+ @query.should match(/WHERE.+`birthday` <= NOW()/)
163
+ end
164
+
165
+ it "should include any defined groupings" do
166
+ @query.should match(/GROUP BY.+`first_name`/)
167
+ end
168
+
169
+ it "should include descendants" do
170
+ index = ThinkingSphinx::Index.new(Child)
171
+ source = ThinkingSphinx::Source.new(index, :sql_range_step => 1000)
172
+ riddle = source.to_riddle_for_core(1, 0)
173
+ query = riddle.sql_query
174
+
175
+ query.should match(/WHERE.+`people`\.`type`.+'Child'.+ 'Teenager'\)/)
176
+ query.should_not match(/WHERE.+"users"."type" = 'Employee'/)
177
+ end
178
+ end
179
+
180
+ describe "#sql_query_range" do
181
+ before :each do
182
+ @query = @riddle.sql_query_range
183
+ end
184
+
185
+ it "should select data from the model table" do
186
+ @query.should match(/FROM `people`/)
187
+ end
188
+
189
+ it "should select the minimum and the maximum ids" do
190
+ @query.should match(/SELECT.+MIN.+MAX.+FROM/)
191
+ end
192
+ end
193
+
194
+ describe "#sql_query_info" do
195
+ before :each do
196
+ @query = @riddle.sql_query_info
197
+ end
198
+
199
+ it "should select all fields from the model table" do
200
+ @query.should match(/SELECT \* FROM `people`/)
201
+ end
202
+
203
+ it "should filter the primary key with the offset" do
204
+ model_count = ThinkingSphinx.context.indexed_models.size
205
+ @query.should match(/WHERE `id` = \(\(\$id - 1\) \/ #{model_count}\)/)
206
+ end
207
+ end
208
+
209
+ describe "#sql_query_pre" do
210
+ before :each do
211
+ @queries = @riddle.sql_query_pre
212
+ end
213
+
214
+ it "should default to just the UTF8 statement" do
215
+ @queries.detect { |query|
216
+ query == "SET NAMES utf8"
217
+ }.should_not be_nil
218
+ end
219
+
220
+ it "should set the group_concat_max_len session value for MySQL if requested" do
221
+ @queries.detect { |query|
222
+ query == "SET SESSION group_concat_max_len = 1024"
223
+ }.should_not be_nil
224
+ end
225
+ end
226
+ end
227
+
228
+ describe "#to_riddle_for_core with range disabled" do
229
+ before :each do
230
+ ThinkingSphinx::Field.new(
231
+ @source, ThinkingSphinx::Index::FauxColumn.new(:first_name)
232
+ )
233
+ end
234
+
235
+ describe "set per-index" do
236
+ before :each do
237
+ @index.local_options[:disable_range] = true
238
+ @riddle = @source.to_riddle_for_core(1, 0)
239
+ end
240
+
241
+ it "should not have the range in the sql_query" do
242
+ @riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
243
+ @riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
244
+ end
245
+
246
+ it "should not have a sql_query_range" do
247
+ @riddle.sql_query_range.should be_nil
248
+ end
249
+ end
250
+
251
+ describe "set globally" do
252
+ before :each do
253
+ ThinkingSphinx::Configuration.instance.index_options[:disable_range] = true
254
+ @riddle = @source.to_riddle_for_core(1, 0)
255
+ end
256
+
257
+ it "should not have the range in the sql_query" do
258
+ @riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
259
+ @riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
260
+ end
261
+
262
+ it "should not have a sql_query_range" do
263
+ @riddle.sql_query_range.should be_nil
264
+ end
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require "#{File.dirname(__FILE__)}/../../lib/thinking_sphinx/test"
3
+
4
+ describe ThinkingSphinx::Test do
5
+ describe ".run" do
6
+ before :each do
7
+ ThinkingSphinx::Test.stub!(:start)
8
+ end
9
+
10
+ it "should call stop when an exception is raised by passed block" do
11
+ ThinkingSphinx::Test.should_receive(:stop)
12
+
13
+ begin
14
+ ThinkingSphinx::Test.run { raise FakeError }
15
+ rescue => FakeError
16
+ # we raised it manually ourselves!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+
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
+ models = ThinkingSphinx.context.indexed_models.clone
11
+
12
+ ThinkingSphinx.context.indexed_models.replace([:model])
13
+ ThinkingSphinx.context.indexed_models.should == [:model]
14
+
15
+ ThinkingSphinx.context.indexed_models.replace(models)
16
+ end
17
+ end
18
+
19
+ describe '.reset_context!' do
20
+ it "should remove the existing Context instance" do
21
+ existing = ThinkingSphinx.context
22
+
23
+ ThinkingSphinx.reset_context!
24
+ ThinkingSphinx.context.should_not == existing
25
+
26
+ ThinkingSphinx.reset_context! existing
27
+ end
28
+ end
29
+
30
+ describe '.define_indexes?' do
31
+ it "should define indexes by default" do
32
+ ThinkingSphinx.define_indexes?.should be_true
33
+ end
34
+ end
35
+
36
+ describe '.define_indexes=' do
37
+ it "should disable index definition" do
38
+ ThinkingSphinx.define_indexes = false
39
+ ThinkingSphinx.define_indexes?.should be_false
40
+ end
41
+
42
+ it "should enable index definition" do
43
+ ThinkingSphinx.define_indexes = false
44
+ ThinkingSphinx.define_indexes?.should be_false
45
+ ThinkingSphinx.define_indexes = true
46
+ ThinkingSphinx.define_indexes?.should be_true
47
+ end
48
+ end
49
+
50
+ describe '.deltas_enabled?' do
51
+ it "should index deltas by default" do
52
+ ThinkingSphinx.deltas_enabled?.should be_true
53
+ end
54
+ end
55
+
56
+ describe '.deltas_enabled=' do
57
+ it "should disable delta indexing" do
58
+ ThinkingSphinx.deltas_enabled = false
59
+ ThinkingSphinx.deltas_enabled?.should be_false
60
+ end
61
+
62
+ it "should enable delta indexing" do
63
+ ThinkingSphinx.deltas_enabled = false
64
+ ThinkingSphinx.deltas_enabled?.should be_false
65
+ ThinkingSphinx.deltas_enabled = true
66
+ ThinkingSphinx.deltas_enabled?.should be_true
67
+ end
68
+ end
69
+
70
+ describe '.updates_enabled?' do
71
+ it "should update indexes by default" do
72
+ ThinkingSphinx::Configuration.stub! :environment => 'development'
73
+
74
+ ThinkingSphinx.updates_enabled = nil
75
+ ThinkingSphinx.updates_enabled?.should be_true
76
+ end
77
+ end
78
+
79
+ describe '.updates_enabled=' do
80
+ it "should disable index updating" do
81
+ ThinkingSphinx.updates_enabled = false
82
+ ThinkingSphinx.updates_enabled?.should be_false
83
+ end
84
+
85
+ it "should enable index updating" do
86
+ ThinkingSphinx.updates_enabled = false
87
+ ThinkingSphinx.updates_enabled?.should be_false
88
+ ThinkingSphinx.updates_enabled = true
89
+ ThinkingSphinx.updates_enabled?.should be_true
90
+ end
91
+ end
92
+
93
+ describe '.sphinx_running?' do
94
+ it "should always say Sphinx is running if flagged as being on a remote machine" do
95
+ ThinkingSphinx.remote_sphinx = true
96
+ ThinkingSphinx.stub!(:sphinx_running_by_pid? => false)
97
+
98
+ ThinkingSphinx.sphinx_running?.should be_true
99
+ end
100
+
101
+ it "should actually pay attention to Sphinx if not on a remote machine" do
102
+ ThinkingSphinx.remote_sphinx = false
103
+ ThinkingSphinx.stub!(:sphinx_running_by_pid? => false)
104
+ ThinkingSphinx.sphinx_running?.should be_false
105
+
106
+ ThinkingSphinx.stub!(:sphinx_running_by_pid? => true)
107
+ ThinkingSphinx.sphinx_running?.should be_true
108
+ end
109
+ end
110
+
111
+ describe "use_group_by_shortcut? method" do
112
+ before :each do
113
+ adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :Mysql2Adapter
114
+ unless ::ActiveRecord::ConnectionAdapters.const_defined?(adapter)
115
+ pending "No MySQL"
116
+ return
117
+ end
118
+
119
+ @connection = stub('adapter',
120
+ :select_all => true,
121
+ :class => ActiveRecord::ConnectionAdapters::Mysql2Adapter,
122
+ :config => {:adapter => defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql2'}
123
+ )
124
+ ::ActiveRecord::Base.stub!(
125
+ :connection => @connection
126
+ )
127
+
128
+ ThinkingSphinx.reset_use_group_by_shortcut
129
+ end
130
+
131
+ it "should return true if no ONLY_FULL_GROUP_BY" do
132
+ @connection.stub!(
133
+ :select_all => {:a => "OTHER SETTINGS"}
134
+ )
135
+
136
+ ThinkingSphinx.use_group_by_shortcut?.should be_true
137
+ end
138
+
139
+ it "should return true if NULL value" do
140
+ @connection.stub!(
141
+ :select_all => {:a => nil}
142
+ )
143
+
144
+ ThinkingSphinx.use_group_by_shortcut?.should be_true
145
+ end
146
+
147
+ it "should return true if using mysql2 gem" do
148
+ @connection.stub!(
149
+ :class => ActiveRecord::ConnectionAdapters::Mysql2Adapter,
150
+ :select_all => {:a => ""}
151
+ )
152
+
153
+ ThinkingSphinx.use_group_by_shortcut?.should be_true
154
+ end unless RUBY_PLATFORM == 'java'
155
+
156
+ it "should return false if ONLY_FULL_GROUP_BY is set" do
157
+ @connection.stub!(
158
+ :select_all => {:a => "OTHER SETTINGS,ONLY_FULL_GROUP_BY,blah"}
159
+ )
160
+
161
+ ThinkingSphinx.use_group_by_shortcut?.should be_false
162
+ end
163
+
164
+ it "should return false if ONLY_FULL_GROUP_BY is set in any of the values" do
165
+ @connection.stub!(
166
+ :select_all => {
167
+ :a => "OTHER SETTINGS",
168
+ :b => "ONLY_FULL_GROUP_BY"
169
+ }
170
+ )
171
+
172
+ ThinkingSphinx.use_group_by_shortcut?.should be_false
173
+ end
174
+
175
+ describe "if not using MySQL" do
176
+ before :each do
177
+ adapter = defined?(JRUBY_VERSION) ? 'JdbcAdapter' : 'PostgreSQLAdapter'
178
+ unless ::ActiveRecord::ConnectionAdapters.const_defined?(adapter)
179
+ pending "No PostgreSQL"
180
+ return
181
+ end
182
+
183
+ @connection = stub(adapter).as_null_object
184
+ @connection.stub!(
185
+ :select_all => true,
186
+ :config => {:adapter => defined?(JRUBY_VERSION) ? 'jdbcpostgresql' : 'postgresql'}
187
+ )
188
+ ::ActiveRecord::Base.stub!(
189
+ :connection => @connection
190
+ )
191
+ end
192
+
193
+ it "should return false" do
194
+ ThinkingSphinx.use_group_by_shortcut?.should be_false
195
+ end
196
+
197
+ it "should not call select_all" do
198
+ @connection.should_not_receive(:select_all)
199
+
200
+ ThinkingSphinx.use_group_by_shortcut?
201
+ end
202
+ end
203
+ end
204
+ end