thinking-sphinx 1.2.13 → 1.4.0

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 (204) hide show
  1. data/README.textile +37 -4
  2. data/VERSION +1 -0
  3. data/features/abstract_inheritance.feature +10 -0
  4. data/features/alternate_primary_key.feature +1 -1
  5. data/features/attribute_updates.feature +49 -5
  6. data/features/deleting_instances.feature +3 -0
  7. data/features/excerpts.feature +8 -0
  8. data/features/facets.feature +15 -1
  9. data/features/facets_across_model.feature +2 -2
  10. data/features/field_sorting.feature +18 -0
  11. data/features/handling_edits.feature +1 -1
  12. data/features/searching_across_models.feature +2 -2
  13. data/features/searching_by_index.feature +40 -0
  14. data/features/searching_by_model.feature +1 -8
  15. data/features/sphinx_scopes.feature +33 -0
  16. data/features/step_definitions/alpha_steps.rb +14 -1
  17. data/features/step_definitions/beta_steps.rb +1 -1
  18. data/features/step_definitions/common_steps.rb +21 -2
  19. data/features/step_definitions/facet_steps.rb +4 -0
  20. data/features/step_definitions/scope_steps.rb +8 -0
  21. data/features/step_definitions/search_steps.rb +5 -0
  22. data/features/step_definitions/sphinx_steps.rb +8 -4
  23. data/features/sti_searching.feature +5 -0
  24. data/features/support/env.rb +7 -6
  25. data/features/{support → thinking_sphinx}/db/fixtures/betas.rb +1 -0
  26. data/features/{support → thinking_sphinx}/db/fixtures/comments.rb +1 -1
  27. data/features/{support → thinking_sphinx}/db/fixtures/developers.rb +2 -0
  28. data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
  29. data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
  30. data/features/{support → thinking_sphinx}/db/fixtures/people.rb +1 -1
  31. data/features/{support → thinking_sphinx}/db/fixtures/tags.rb +1 -1
  32. data/features/{support → thinking_sphinx}/db/migrations/create_alphas.rb +1 -0
  33. data/features/{support → thinking_sphinx}/db/migrations/create_developers.rb +0 -2
  34. data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
  35. data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
  36. data/features/thinking_sphinx/models/alpha.rb +23 -0
  37. data/features/thinking_sphinx/models/andrew.rb +17 -0
  38. data/features/{support → thinking_sphinx}/models/beta.rb +1 -1
  39. data/features/{support → thinking_sphinx}/models/developer.rb +2 -2
  40. data/features/{support → thinking_sphinx}/models/extensible_beta.rb +1 -1
  41. data/features/thinking_sphinx/models/fox.rb +5 -0
  42. data/features/thinking_sphinx/models/genre.rb +3 -0
  43. data/features/thinking_sphinx/models/medium.rb +5 -0
  44. data/features/thinking_sphinx/models/music.rb +8 -0
  45. data/features/{support → thinking_sphinx}/models/person.rb +2 -1
  46. data/features/{support → thinking_sphinx}/models/post.rb +2 -1
  47. data/lib/cucumber/thinking_sphinx/external_world.rb +12 -0
  48. data/lib/cucumber/thinking_sphinx/internal_world.rb +13 -11
  49. data/lib/thinking_sphinx/active_record/attribute_updates.rb +17 -15
  50. data/lib/thinking_sphinx/active_record/delta.rb +0 -26
  51. data/lib/thinking_sphinx/active_record/has_many_association.rb +34 -11
  52. data/lib/thinking_sphinx/active_record/scopes.rb +46 -3
  53. data/lib/thinking_sphinx/active_record.rb +271 -193
  54. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +45 -9
  55. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +5 -1
  56. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +9 -1
  57. data/lib/thinking_sphinx/attribute.rb +67 -23
  58. data/lib/thinking_sphinx/auto_version.rb +24 -0
  59. data/lib/thinking_sphinx/bundled_search.rb +44 -0
  60. data/lib/thinking_sphinx/class_facet.rb +3 -2
  61. data/lib/thinking_sphinx/configuration.rb +78 -64
  62. data/lib/thinking_sphinx/context.rb +76 -0
  63. data/lib/thinking_sphinx/deltas/default_delta.rb +14 -20
  64. data/lib/thinking_sphinx/deltas.rb +0 -2
  65. data/lib/thinking_sphinx/deploy/capistrano.rb +1 -1
  66. data/lib/thinking_sphinx/excerpter.rb +1 -1
  67. data/lib/thinking_sphinx/facet.rb +6 -5
  68. data/lib/thinking_sphinx/facet_search.rb +54 -24
  69. data/lib/thinking_sphinx/field.rb +2 -4
  70. data/lib/thinking_sphinx/index/builder.rb +36 -20
  71. data/lib/thinking_sphinx/index/faux_column.rb +8 -0
  72. data/lib/thinking_sphinx/index.rb +77 -19
  73. data/lib/thinking_sphinx/join.rb +37 -0
  74. data/lib/thinking_sphinx/property.rb +9 -2
  75. data/lib/thinking_sphinx/rails_additions.rb +4 -4
  76. data/lib/thinking_sphinx/search.rb +212 -66
  77. data/lib/thinking_sphinx/search_methods.rb +22 -4
  78. data/lib/thinking_sphinx/source/internal_properties.rb +2 -2
  79. data/lib/thinking_sphinx/source/sql.rb +5 -3
  80. data/lib/thinking_sphinx/source.rb +21 -12
  81. data/lib/thinking_sphinx/tasks.rb +26 -58
  82. data/lib/thinking_sphinx/test.rb +55 -0
  83. data/lib/thinking_sphinx.rb +70 -38
  84. data/rails/init.rb +4 -2
  85. data/spec/{lib/thinking_sphinx → thinking_sphinx}/active_record/delta_spec.rb +6 -8
  86. data/spec/{lib/thinking_sphinx → thinking_sphinx}/active_record/has_many_association_spec.rb +26 -3
  87. data/spec/thinking_sphinx/active_record/scopes_spec.rb +176 -0
  88. data/spec/thinking_sphinx/active_record_spec.rb +618 -0
  89. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +134 -0
  90. data/spec/{lib/thinking_sphinx → thinking_sphinx}/association_spec.rb +1 -1
  91. data/spec/{lib/thinking_sphinx → thinking_sphinx}/attribute_spec.rb +87 -46
  92. data/spec/thinking_sphinx/auto_version_spec.rb +47 -0
  93. data/spec/{lib/thinking_sphinx → thinking_sphinx}/configuration_spec.rb +73 -63
  94. data/spec/thinking_sphinx/context_spec.rb +127 -0
  95. data/spec/{lib/thinking_sphinx → thinking_sphinx}/core/array_spec.rb +1 -1
  96. data/spec/{lib/thinking_sphinx → thinking_sphinx}/core/string_spec.rb +1 -1
  97. data/spec/{lib/thinking_sphinx → thinking_sphinx}/excerpter_spec.rb +1 -9
  98. data/spec/{lib/thinking_sphinx → thinking_sphinx}/facet_search_spec.rb +76 -82
  99. data/spec/{lib/thinking_sphinx → thinking_sphinx}/facet_spec.rb +5 -5
  100. data/spec/{lib/thinking_sphinx → thinking_sphinx}/field_spec.rb +1 -42
  101. data/spec/{lib/thinking_sphinx → thinking_sphinx}/index/builder_spec.rb +71 -31
  102. data/spec/{lib/thinking_sphinx → thinking_sphinx}/index/faux_column_spec.rb +8 -2
  103. data/spec/thinking_sphinx/index_spec.rb +183 -0
  104. data/spec/{lib/thinking_sphinx → thinking_sphinx}/rails_additions_spec.rb +5 -5
  105. data/spec/{lib/thinking_sphinx → thinking_sphinx}/search_methods_spec.rb +5 -1
  106. data/spec/{lib/thinking_sphinx → thinking_sphinx}/search_spec.rb +183 -31
  107. data/spec/{lib/thinking_sphinx → thinking_sphinx}/source_spec.rb +18 -2
  108. data/spec/thinking_sphinx/test_spec.rb +20 -0
  109. data/spec/thinking_sphinx_spec.rb +204 -0
  110. data/tasks/distribution.rb +7 -26
  111. data/tasks/testing.rb +32 -20
  112. metadata +488 -147
  113. data/VERSION.yml +0 -5
  114. data/features/datetime_deltas.feature +0 -66
  115. data/features/delayed_delta_indexing.feature +0 -37
  116. data/features/step_definitions/datetime_delta_steps.rb +0 -15
  117. data/features/step_definitions/delayed_delta_indexing_steps.rb +0 -7
  118. data/features/support/database.yml +0 -5
  119. data/features/support/db/active_record.rb +0 -40
  120. data/features/support/db/database.yml +0 -5
  121. data/features/support/db/fixtures/delayed_betas.rb +0 -10
  122. data/features/support/db/fixtures/thetas.rb +0 -10
  123. data/features/support/db/migrations/create_delayed_betas.rb +0 -17
  124. data/features/support/db/migrations/create_thetas.rb +0 -5
  125. data/features/support/db/mysql.rb +0 -3
  126. data/features/support/db/postgresql.rb +0 -3
  127. data/features/support/models/alpha.rb +0 -10
  128. data/features/support/models/delayed_beta.rb +0 -7
  129. data/features/support/models/theta.rb +0 -7
  130. data/features/support/post_database.rb +0 -43
  131. data/lib/thinking_sphinx/deltas/datetime_delta.rb +0 -50
  132. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +0 -24
  133. data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +0 -27
  134. data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +0 -26
  135. data/lib/thinking_sphinx/deltas/delayed_delta.rb +0 -30
  136. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +0 -96
  137. data/spec/lib/thinking_sphinx/active_record_spec.rb +0 -353
  138. data/spec/lib/thinking_sphinx/deltas/job_spec.rb +0 -32
  139. data/spec/lib/thinking_sphinx/index_spec.rb +0 -45
  140. data/spec/lib/thinking_sphinx_spec.rb +0 -162
  141. data/vendor/after_commit/LICENSE +0 -20
  142. data/vendor/after_commit/README +0 -16
  143. data/vendor/after_commit/Rakefile +0 -22
  144. data/vendor/after_commit/init.rb +0 -8
  145. data/vendor/after_commit/lib/after_commit/active_record.rb +0 -114
  146. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +0 -103
  147. data/vendor/after_commit/lib/after_commit.rb +0 -45
  148. data/vendor/after_commit/test/after_commit_test.rb +0 -53
  149. data/vendor/delayed_job/lib/delayed/job.rb +0 -251
  150. data/vendor/delayed_job/lib/delayed/message_sending.rb +0 -7
  151. data/vendor/delayed_job/lib/delayed/performable_method.rb +0 -55
  152. data/vendor/delayed_job/lib/delayed/worker.rb +0 -54
  153. data/vendor/riddle/lib/riddle/client/filter.rb +0 -53
  154. data/vendor/riddle/lib/riddle/client/message.rb +0 -66
  155. data/vendor/riddle/lib/riddle/client/response.rb +0 -84
  156. data/vendor/riddle/lib/riddle/client.rb +0 -635
  157. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +0 -48
  158. data/vendor/riddle/lib/riddle/configuration/index.rb +0 -142
  159. data/vendor/riddle/lib/riddle/configuration/indexer.rb +0 -19
  160. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +0 -17
  161. data/vendor/riddle/lib/riddle/configuration/searchd.rb +0 -25
  162. data/vendor/riddle/lib/riddle/configuration/section.rb +0 -43
  163. data/vendor/riddle/lib/riddle/configuration/source.rb +0 -23
  164. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +0 -34
  165. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +0 -28
  166. data/vendor/riddle/lib/riddle/configuration.rb +0 -33
  167. data/vendor/riddle/lib/riddle/controller.rb +0 -53
  168. data/vendor/riddle/lib/riddle.rb +0 -30
  169. data/features/{support → thinking_sphinx}/database.example.yml +0 -0
  170. data/features/{support → thinking_sphinx}/db/fixtures/alphas.rb +0 -0
  171. data/features/{support → thinking_sphinx}/db/fixtures/authors.rb +0 -0
  172. data/features/{support → thinking_sphinx}/db/fixtures/boxes.rb +0 -0
  173. data/features/{support → thinking_sphinx}/db/fixtures/categories.rb +0 -0
  174. data/features/{support → thinking_sphinx}/db/fixtures/cats.rb +0 -0
  175. data/features/{support → thinking_sphinx}/db/fixtures/dogs.rb +0 -0
  176. data/features/{support → thinking_sphinx}/db/fixtures/extensible_betas.rb +0 -0
  177. data/features/{support → thinking_sphinx}/db/fixtures/gammas.rb +0 -0
  178. data/features/{support → thinking_sphinx}/db/fixtures/posts.rb +0 -0
  179. data/features/{support → thinking_sphinx}/db/fixtures/robots.rb +0 -0
  180. data/features/{support → thinking_sphinx}/db/migrations/create_animals.rb +0 -0
  181. data/features/{support → thinking_sphinx}/db/migrations/create_authors.rb +0 -0
  182. data/features/{support → thinking_sphinx}/db/migrations/create_authors_posts.rb +0 -0
  183. data/features/{support → thinking_sphinx}/db/migrations/create_betas.rb +0 -0
  184. data/features/{support → thinking_sphinx}/db/migrations/create_boxes.rb +0 -0
  185. data/features/{support → thinking_sphinx}/db/migrations/create_categories.rb +0 -0
  186. data/features/{support → thinking_sphinx}/db/migrations/create_comments.rb +0 -0
  187. data/features/{support → thinking_sphinx}/db/migrations/create_extensible_betas.rb +0 -0
  188. data/features/{support → thinking_sphinx}/db/migrations/create_gammas.rb +0 -0
  189. data/features/{support → thinking_sphinx}/db/migrations/create_people.rb +0 -0
  190. data/features/{support → thinking_sphinx}/db/migrations/create_posts.rb +0 -0
  191. data/features/{support → thinking_sphinx}/db/migrations/create_robots.rb +0 -0
  192. data/features/{support → thinking_sphinx}/db/migrations/create_taggings.rb +0 -0
  193. data/features/{support → thinking_sphinx}/db/migrations/create_tags.rb +0 -0
  194. data/features/{support → thinking_sphinx}/models/animal.rb +0 -0
  195. data/features/{support → thinking_sphinx}/models/author.rb +0 -0
  196. data/features/{support → thinking_sphinx}/models/box.rb +0 -0
  197. data/features/{support → thinking_sphinx}/models/cat.rb +0 -0
  198. data/features/{support → thinking_sphinx}/models/category.rb +0 -0
  199. data/features/{support → thinking_sphinx}/models/comment.rb +3 -3
  200. /data/features/{support → thinking_sphinx}/models/dog.rb +0 -0
  201. /data/features/{support → thinking_sphinx}/models/gamma.rb +0 -0
  202. /data/features/{support → thinking_sphinx}/models/robot.rb +0 -0
  203. /data/features/{support → thinking_sphinx}/models/tag.rb +0 -0
  204. /data/features/{support → thinking_sphinx}/models/tagging.rb +0 -0
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+
3
+ describe ThinkingSphinx::Index do
4
+ describe "prefix_fields method" do
5
+ before :each do
6
+ @index = ThinkingSphinx::Index.new(Person)
7
+
8
+ @field_a = stub('field', :prefixes => true)
9
+ @field_b = stub('field', :prefixes => false)
10
+ @field_c = stub('field', :prefixes => true)
11
+
12
+ @index.stub!(:fields => [@field_a, @field_b, @field_c])
13
+ end
14
+
15
+ it "should return fields that are flagged as prefixed" do
16
+ @index.prefix_fields.should include(@field_a)
17
+ @index.prefix_fields.should include(@field_c)
18
+ end
19
+
20
+ it "should not return fields that aren't flagged as prefixed" do
21
+ @index.prefix_fields.should_not include(@field_b)
22
+ end
23
+ end
24
+
25
+ describe "infix_fields method" do
26
+ before :each do
27
+ @index = ThinkingSphinx::Index.new(Person)
28
+
29
+ @field_a = stub('field', :infixes => true)
30
+ @field_b = stub('field', :infixes => false)
31
+ @field_c = stub('field', :infixes => true)
32
+
33
+ @index.stub!(:fields => [@field_a, @field_b, @field_c])
34
+ end
35
+
36
+ it "should return fields that are flagged as infixed" do
37
+ @index.infix_fields.should include(@field_a)
38
+ @index.infix_fields.should include(@field_c)
39
+ end
40
+
41
+ it "should not return fields that aren't flagged as infixed" do
42
+ @index.infix_fields.should_not include(@field_b)
43
+ end
44
+ end
45
+
46
+ describe '.name_for' do
47
+ it "should return the model's name downcased" do
48
+ ThinkingSphinx::Index.name_for(Alpha).should == 'alpha'
49
+ end
50
+
51
+ it "should separate words by underscores" do
52
+ ThinkingSphinx::Index.name_for(ActiveRecord).should == 'active_record'
53
+ end
54
+
55
+ it "should separate namespaces by underscores" do
56
+ ThinkingSphinx::Index.name_for(ActiveRecord::Base).
57
+ should == 'active_record_base'
58
+ end
59
+ end
60
+
61
+ describe '#name' do
62
+ it "should return the downcased name of the index's model" do
63
+ ThinkingSphinx::Index.new(Alpha).name.should == 'alpha'
64
+ end
65
+
66
+ it "should return a custom name if one is set" do
67
+ index = ThinkingSphinx::Index.new(Alpha)
68
+ index.name = 'custom'
69
+ index.name.should == 'custom'
70
+ end
71
+ end
72
+
73
+ describe '#core_name' do
74
+ it "should take the index's name and append _core" do
75
+ ThinkingSphinx::Index.new(Alpha).core_name.should == 'alpha_core'
76
+ end
77
+ end
78
+
79
+ describe '#delta_name' do
80
+ it "should take the index's name and append _delta" do
81
+ ThinkingSphinx::Index.new(Alpha).delta_name.should == 'alpha_delta'
82
+ end
83
+ end
84
+
85
+ describe '#all_names' do
86
+ it "should return the core index name by default" do
87
+ ThinkingSphinx::Index.new(Alpha).all_names.should == ['alpha_core']
88
+ end
89
+
90
+ it "should return both core and delta names if deltas are enabled" do
91
+ index = ThinkingSphinx::Index.new(Alpha)
92
+ index.delta_object = stub('delta')
93
+
94
+ index.all_names.should == ['alpha_core', 'alpha_delta']
95
+ end
96
+
97
+ it "should respect custom names" do
98
+ index = ThinkingSphinx::Index.new(Alpha)
99
+ index.name = 'custom'
100
+
101
+ index.all_names.should == ['custom_core']
102
+ end
103
+
104
+ it "should respect custom names when deltas are enabled" do
105
+ index = ThinkingSphinx::Index.new(Alpha)
106
+ index.name = 'custom'
107
+ index.delta_object = stub('delta')
108
+
109
+ index.all_names.should == ['custom_core', 'custom_delta']
110
+ end
111
+ end
112
+
113
+ describe '#to_riddle' do
114
+ it "should return two Riddle indexes if deltas are disabled" do
115
+ index = ThinkingSphinx::Index.new(Alpha)
116
+
117
+ index.to_riddle(0).length.should == 2
118
+ end
119
+
120
+ it "should return three Riddle indexes if deltas are enabled" do
121
+ index = ThinkingSphinx::Index.new(Beta)
122
+ index.delta_object = stub('delta')
123
+
124
+ index.to_riddle(0).length.should == 3
125
+ end
126
+
127
+ it "should include a distributed index" do
128
+ index = ThinkingSphinx::Index.new(Alpha)
129
+
130
+ index.to_riddle(0).last.
131
+ should be_a(Riddle::Configuration::DistributedIndex)
132
+ end
133
+
134
+ context 'core index' do
135
+ it "should use the core name" do
136
+ @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
137
+ @index.name.should == 'alpha_core'
138
+ end
139
+
140
+ it "should not try to set disable_range on the index" do
141
+ ThinkingSphinx::Configuration.instance.
142
+ index_options[:disable_range] = true
143
+
144
+ lambda {
145
+ @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
146
+ }.should_not raise_error(NoMethodError)
147
+ end
148
+ end
149
+
150
+ context 'delta index' do
151
+ before :each do
152
+ index = ThinkingSphinx::Index.new(Beta)
153
+ index.delta_object = stub('delta')
154
+ @index = index.to_riddle(0)[1]
155
+ end
156
+
157
+ it "should use the delta name" do
158
+ @index.name.should == 'beta_delta'
159
+ end
160
+ end
161
+
162
+ context 'distributed index' do
163
+ it "should use the index's name" do
164
+ index = ThinkingSphinx::Index.new(Alpha)
165
+
166
+ index.to_riddle(0).last.name.should == 'alpha'
167
+ end
168
+
169
+ it "should add the core index" do
170
+ index = ThinkingSphinx::Index.new(Alpha)
171
+
172
+ index.to_riddle(0).last.local_indexes.should include('alpha_core')
173
+ end
174
+
175
+ it "should add the delta index if there is one" do
176
+ index = ThinkingSphinx::Index.new(Beta)
177
+ index.delta_object = stub('delta')
178
+
179
+ index.to_riddle(0).last.local_indexes.should include('beta_delta')
180
+ end
181
+ end
182
+ end
183
+ end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::HashExcept do
4
4
  before(:each) do
@@ -118,14 +118,14 @@ describe ThinkingSphinx::ActiveRecordStoreFullSTIClass do
118
118
  end
119
119
  end
120
120
 
121
- describe ThinkingSphinx::MetaClass do
122
- describe 'metaclass' do
121
+ describe ThinkingSphinx::SingletonClass do
122
+ describe 'singleton_class' do
123
123
  it "should exist as an instance method in Object" do
124
- Object.new.should respond_to('metaclass')
124
+ Object.new.should respond_to('singleton_class')
125
125
  end
126
126
 
127
127
  it "should return the meta/eigen/singleton class" do
128
- Object.new.metaclass.should be_a(Class)
128
+ Object.new.singleton_class.should be_a(Class)
129
129
  end
130
130
  end
131
131
  end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::SearchMethods do
4
4
  it "should be included into models with indexes" do
@@ -135,6 +135,10 @@ describe ThinkingSphinx::SearchMethods do
135
135
  end
136
136
 
137
137
  describe '.facets' do
138
+ before :each do
139
+ ThinkingSphinx::Search.stub!(:bundle_searches => [])
140
+ end
141
+
138
142
  it "should return a FacetSearch instance" do
139
143
  Alpha.facets.should be_a(ThinkingSphinx::FacetSearch)
140
144
  end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
  require 'will_paginate/collection'
3
3
 
4
4
  describe ThinkingSphinx::Search do
@@ -43,7 +43,12 @@ describe ThinkingSphinx::Search do
43
43
 
44
44
  it "should be true once the client request has been made" do
45
45
  @search.first
46
- @search.populated?.should be_true
46
+ @search.should be_populated
47
+ end
48
+
49
+ it "should be populated if :populate is set to true" do
50
+ search = ThinkingSphinx::Search.new(:populate => true)
51
+ search.should be_populated
47
52
  end
48
53
  end
49
54
 
@@ -153,6 +158,17 @@ describe ThinkingSphinx::Search do
153
158
  end
154
159
  end
155
160
 
161
+ describe '.matching_fields' do
162
+ it "should return objects with indexes matching 1's in the bitmask" do
163
+ fields = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta']
164
+ ThinkingSphinx::Search.matching_fields(fields, 85).
165
+ should == ['alpha', 'gamma', 'epsilon', 'eta']
166
+
167
+ ThinkingSphinx::Search.matching_fields(fields, 42).
168
+ should == ['beta', 'delta', 'zeta']
169
+ end
170
+ end
171
+
156
172
  describe '#populate' do
157
173
  before :each do
158
174
  @alpha_a, @alpha_b = Alpha.new, Alpha.new
@@ -164,7 +180,8 @@ describe ThinkingSphinx::Search do
164
180
  @beta_b.stub! :id => 2, :read_attribute => 2
165
181
 
166
182
  @client.stub! :query => {
167
- :matches => minimal_result_hashes(@alpha_a, @beta_b, @alpha_b, @beta_a)
183
+ :matches => minimal_result_hashes(@alpha_a, @beta_b, @alpha_b, @beta_a),
184
+ :fields => ["one", "two", "three", "four", "five"]
168
185
  }
169
186
  Alpha.stub! :find => [@alpha_a, @alpha_b]
170
187
  Beta.stub! :find => [@beta_a, @beta_b]
@@ -201,6 +218,34 @@ describe ThinkingSphinx::Search do
201
218
  ThinkingSphinx::Search.new(:classes => [Alpha, Beta]).first
202
219
  end
203
220
 
221
+ it "should restrict includes to the relevant classes" do
222
+ Alpha.should_receive(:find) do |type, options|
223
+ options[:include].should == [:betas]
224
+ [@alpha_a, @alpha_b]
225
+ end
226
+
227
+ Beta.should_receive(:find) do |type, options|
228
+ options[:include].should == [:gammas]
229
+ [@beta_a, @beta_b]
230
+ end
231
+
232
+ ThinkingSphinx::Search.new(:include => [:betas, :gammas]).first
233
+ end
234
+
235
+ it "should restrict single includes to the relevant classes" do
236
+ Alpha.should_receive(:find) do |type, options|
237
+ options[:include].should == :betas
238
+ [@alpha_a, @alpha_b]
239
+ end
240
+
241
+ Beta.should_receive(:find) do |type, options|
242
+ options[:include].should be_nil
243
+ [@beta_a, @beta_b]
244
+ end
245
+
246
+ ThinkingSphinx::Search.new(:include => :betas).first
247
+ end
248
+
204
249
  describe 'query' do
205
250
  it "should concatenate arguments with spaces" do
206
251
  @client.should_receive(:query) do |query, index, comment|
@@ -259,6 +304,32 @@ describe ThinkingSphinx::Search do
259
304
  'foo@bar.com -foo-bar', :star => /[\w@.-]+/u
260
305
  ).first
261
306
  end
307
+
308
+ it "should ignore multi-field limitations" do
309
+ @client.should_receive(:query) do |query, index, comment|
310
+ query.should == '@(foo,bar) *baz*'
311
+ end
312
+
313
+ ThinkingSphinx::Search.new('@(foo,bar) baz', :star => true).first
314
+ end
315
+
316
+ it "should ignore multi-field limitations with spaces" do
317
+ @client.should_receive(:query) do |query, index, comment|
318
+ query.should == '@(foo bar) *baz*'
319
+ end
320
+
321
+ ThinkingSphinx::Search.new('@(foo bar) baz', :star => true).first
322
+ end
323
+
324
+ it "should ignore multi-field limitations in the middle of queries" do
325
+ @client.should_receive(:query) do |query, index, comment|
326
+ query.should == '*baz* @foo *bar* @(foo,bar) *baz*'
327
+ end
328
+
329
+ ThinkingSphinx::Search.new(
330
+ 'baz @foo bar @(foo,bar) baz', :star => true
331
+ ).first
332
+ end
262
333
  end
263
334
 
264
335
  describe 'comment' do
@@ -302,6 +373,23 @@ describe ThinkingSphinx::Search do
302
373
  @client.match_mode.should == :extended2
303
374
  end
304
375
  end
376
+
377
+ describe 'sphinx_select' do
378
+ it "should default to *" do
379
+ ThinkingSphinx::Search.new.first
380
+
381
+ @client.select.should == "*"
382
+ end
383
+
384
+ it "should get set on the client if specified" do
385
+ ThinkingSphinx::Search.new('general',
386
+ :sphinx_select => "*, foo as bar"
387
+ ).first
388
+
389
+ @client.select.should == "*, foo as bar"
390
+ end
391
+
392
+ end
305
393
 
306
394
  describe 'pagination' do
307
395
  it "should set the limit using per_page" do
@@ -476,31 +564,6 @@ describe ThinkingSphinx::Search do
476
564
  filter.attribute.should == 'sphinx_internal_id'
477
565
  filter.exclude?.should be_true
478
566
  end
479
-
480
- describe 'in :conditions' do
481
- it "should add as filters for known attributes in :conditions option" do
482
- ThinkingSphinx::Search.new('general',
483
- :conditions => {:word => 'specific', :lat => 1.5},
484
- :classes => [Alpha]
485
- ).first
486
-
487
- filter = @client.filters.last
488
- filter.values.should == [1.5]
489
- filter.attribute.should == 'lat'
490
- filter.exclude?.should be_false
491
- end
492
-
493
- it "should not add the filter to the query string" do
494
- @client.should_receive(:query) do |query, index, comment|
495
- query.should == 'general @word specific'
496
- end
497
-
498
- ThinkingSphinx::Search.new('general',
499
- :conditions => {:word => 'specific', :lat => 1.5},
500
- :classes => [Alpha]
501
- ).first
502
- end
503
- end
504
567
  end
505
568
 
506
569
  describe 'sort mode' do
@@ -751,9 +814,10 @@ describe ThinkingSphinx::Search do
751
814
  end
752
815
 
753
816
  it "should set up the excerpter with the instances and search" do
754
- ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_a)
755
- ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_b)
756
-
817
+ [@alpha_a, @beta_b, @alpha_b, @beta_a].each do |object|
818
+ ThinkingSphinx::Excerpter.should_receive(:new).with(@search, object)
819
+ end
820
+
757
821
  @search.first
758
822
  end
759
823
  end
@@ -781,6 +845,28 @@ describe ThinkingSphinx::Search do
781
845
  hash['class_crc'].should == @search.last.class.to_crc32
782
846
  end
783
847
  end
848
+
849
+ describe '#matching_fields' do
850
+ it "should add matching_fields method if using fieldmask ranking mode" do
851
+ search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
852
+ search.first.should respond_to(:matching_fields)
853
+ end
854
+
855
+ it "should not add matching_fields method if object already have one" do
856
+ search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
857
+ search.last.matching_fields.should_not be_an(Array)
858
+ end
859
+
860
+ it "should return an array" do
861
+ search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
862
+ search.first.matching_fields.should be_an(Array)
863
+ end
864
+
865
+ it "should return the fields that the bitmask match" do
866
+ search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
867
+ search.first.matching_fields.should == ['one', 'three', 'five']
868
+ end
869
+ end
784
870
  end
785
871
  end
786
872
 
@@ -816,6 +902,10 @@ describe ThinkingSphinx::Search do
816
902
  :per_page => 30, :limit => 40
817
903
  ).per_page.should == 40
818
904
  end
905
+
906
+ it "should allow for string arguments" do
907
+ ThinkingSphinx::Search.new(:per_page => '10').per_page.should == 10
908
+ end
819
909
  end
820
910
 
821
911
  describe '#total_pages' do
@@ -834,6 +924,14 @@ describe ThinkingSphinx::Search do
834
924
 
835
925
  ThinkingSphinx::Search.new.total_pages.should == 2
836
926
  end
927
+
928
+ it "should return 0 if there is no index and therefore no results" do
929
+ @client.stub!(:query => {
930
+ :matches => [], :total_found => nil, :total => nil
931
+ })
932
+
933
+ ThinkingSphinx::Search.new.total_pages.should == 0
934
+ end
837
935
  end
838
936
 
839
937
  describe '#next_page' do
@@ -860,6 +958,14 @@ describe ThinkingSphinx::Search do
860
958
  it "should return the total number of results, not just the amount on the page" do
861
959
  ThinkingSphinx::Search.new.total_entries.should == 41
862
960
  end
961
+
962
+ it "should return 0 if there is no index and therefore no results" do
963
+ @client.stub!(:query => {
964
+ :matches => [], :total_found => nil
965
+ })
966
+
967
+ ThinkingSphinx::Search.new.total_entries.should == 0
968
+ end
863
969
  end
864
970
 
865
971
  describe '#offset' do
@@ -870,6 +976,10 @@ describe ThinkingSphinx::Search do
870
976
  it "should increase by the per_page value for each page in" do
871
977
  ThinkingSphinx::Search.new(:per_page => 25, :page => 2).offset.should == 25
872
978
  end
979
+
980
+ it "should prioritise explicit :offset over calculated if given" do
981
+ ThinkingSphinx::Search.new(:offset => 5).offset.should == 5
982
+ end
873
983
  end
874
984
 
875
985
  describe '#indexes' do
@@ -1027,6 +1137,15 @@ describe ThinkingSphinx::Search do
1027
1137
  @search.excerpt_for('string')
1028
1138
  end
1029
1139
 
1140
+ it "should respect the provided index option" do
1141
+ @search = ThinkingSphinx::Search.new(:classes => [Alpha], :index => 'foo')
1142
+ @client.should_receive(:excerpts) do |options|
1143
+ options[:index].should == 'foo'
1144
+ end
1145
+
1146
+ @search.excerpt_for('string')
1147
+ end
1148
+
1030
1149
  it "should optionally take a second argument to allow for multi-model searches" do
1031
1150
  @client.should_receive(:excerpts) do |options|
1032
1151
  options[:index].should == 'beta_core'
@@ -1092,6 +1211,39 @@ describe ThinkingSphinx::Search do
1092
1211
  }.should_not be_nil
1093
1212
  end
1094
1213
  end
1214
+
1215
+ describe '#freeze' do
1216
+ before :each do
1217
+ @search = ThinkingSphinx::Search.new
1218
+ end
1219
+
1220
+ it "should populate the result set" do
1221
+ @search.freeze
1222
+ @search.should be_populated
1223
+ end
1224
+
1225
+ it "should freeze the underlying array" do
1226
+ @search.freeze
1227
+ @search.to_a.should be_frozen
1228
+ end
1229
+
1230
+ it "should return the Search object" do
1231
+ @search.freeze.should be_a(ThinkingSphinx::Search)
1232
+ end
1233
+ end
1234
+
1235
+ describe '#client' do
1236
+ let(:client) { Riddle::Client.new }
1237
+ it "should respect the client in options" do
1238
+ search = ThinkingSphinx::Search.new :client => client
1239
+ search.client.should == client
1240
+ end
1241
+
1242
+ it "should get a new client from the configuration singleton by default" do
1243
+ ThinkingSphinx::Configuration.instance.stub!(:client => client)
1244
+ ThinkingSphinx::Search.new.client.should == client
1245
+ end
1246
+ end
1095
1247
  end
1096
1248
 
1097
1249
  describe ThinkingSphinx::Search, "playing nice with Search model" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Source do
4
4
  before :each do
@@ -6,6 +6,13 @@ describe ThinkingSphinx::Source do
6
6
  @source = ThinkingSphinx::Source.new(@index, :sql_range_step => 1000)
7
7
  end
8
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
+
9
16
  it "should generate the name from the model" do
10
17
  @source.name.should == "person"
11
18
  end
@@ -42,6 +49,10 @@ describe ThinkingSphinx::Source do
42
49
  :as => :contact_ids, :source => :query
43
50
  )
44
51
 
52
+ ThinkingSphinx::Join.new(
53
+ @source, ThinkingSphinx::Index::FauxColumn.new(:links)
54
+ )
55
+
45
56
  @source.conditions << "`birthday` <= NOW()"
46
57
  @source.groupings << "`first_name`"
47
58
 
@@ -77,6 +88,7 @@ describe ThinkingSphinx::Source do
77
88
  :user => nil,
78
89
  :username => nil
79
90
  })
91
+ @source = ThinkingSphinx::Source.new(@index)
80
92
 
81
93
  riddle = @source.to_riddle_for_core(1, 0)
82
94
  riddle.sql_user.should == 'root'
@@ -128,6 +140,10 @@ describe ThinkingSphinx::Source do
128
140
  @query.should_not match(/LEFT OUTER JOIN `contacts`/)
129
141
  end
130
142
 
143
+ it "should include explicitly requested joins" do
144
+ @query.should match(/LEFT OUTER JOIN `links`/)
145
+ end
146
+
131
147
  it "should include any defined conditions" do
132
148
  @query.should match(/WHERE.+`birthday` <= NOW()/)
133
149
  end
@@ -161,7 +177,7 @@ describe ThinkingSphinx::Source do
161
177
  end
162
178
 
163
179
  it "should filter the primary key with the offset" do
164
- model_count = ThinkingSphinx.indexed_models.size
180
+ model_count = ThinkingSphinx.context.indexed_models.size
165
181
  @query.should match(/WHERE `id` = \(\(\$id - 1\) \/ #{model_count}\)/)
166
182
  end
167
183
  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