thinking-sphinx 1.5.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/README.textile +15 -48
  2. data/VERSION +1 -0
  3. data/features/attribute_transformation.feature +7 -7
  4. data/features/attribute_updates.feature +16 -18
  5. data/features/deleting_instances.feature +13 -16
  6. data/features/excerpts.feature +0 -8
  7. data/features/facets.feature +19 -25
  8. data/features/handling_edits.feature +20 -25
  9. data/features/searching_across_models.feature +1 -1
  10. data/features/searching_by_index.feature +5 -6
  11. data/features/searching_by_model.feature +29 -29
  12. data/features/sphinx_scopes.feature +0 -26
  13. data/features/step_definitions/common_steps.rb +6 -18
  14. data/features/step_definitions/scope_steps.rb +0 -4
  15. data/features/step_definitions/search_steps.rb +4 -9
  16. data/features/support/env.rb +10 -3
  17. data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -8
  18. data/features/thinking_sphinx/db/fixtures/cats.rb +1 -1
  19. data/features/thinking_sphinx/db/fixtures/dogs.rb +1 -1
  20. data/features/thinking_sphinx/db/fixtures/foxes.rb +1 -1
  21. data/features/thinking_sphinx/db/fixtures/people.rb +1 -1
  22. data/features/thinking_sphinx/db/fixtures/posts.rb +1 -5
  23. data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -1
  24. data/features/thinking_sphinx/models/alpha.rb +0 -1
  25. data/features/thinking_sphinx/models/beta.rb +0 -5
  26. data/features/thinking_sphinx/models/developer.rb +1 -6
  27. data/features/thinking_sphinx/models/music.rb +1 -3
  28. data/features/thinking_sphinx/models/person.rb +1 -2
  29. data/features/thinking_sphinx/models/post.rb +0 -1
  30. data/lib/cucumber/thinking_sphinx/external_world.rb +4 -8
  31. data/lib/cucumber/thinking_sphinx/internal_world.rb +27 -36
  32. data/lib/thinking_sphinx.rb +60 -132
  33. data/lib/thinking_sphinx/active_record.rb +98 -124
  34. data/lib/thinking_sphinx/active_record/attribute_updates.rb +13 -17
  35. data/lib/thinking_sphinx/active_record/delta.rb +15 -21
  36. data/lib/thinking_sphinx/active_record/has_many_association.rb +23 -16
  37. data/lib/thinking_sphinx/active_record/scopes.rb +0 -18
  38. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +15 -63
  39. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -4
  40. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +24 -65
  41. data/lib/thinking_sphinx/association.rb +11 -36
  42. data/lib/thinking_sphinx/attribute.rb +85 -92
  43. data/lib/thinking_sphinx/auto_version.rb +3 -21
  44. data/lib/thinking_sphinx/class_facet.rb +3 -8
  45. data/lib/thinking_sphinx/configuration.rb +58 -114
  46. data/lib/thinking_sphinx/context.rb +20 -22
  47. data/lib/thinking_sphinx/core/array.rb +13 -0
  48. data/lib/thinking_sphinx/deltas.rb +0 -2
  49. data/lib/thinking_sphinx/deltas/default_delta.rb +22 -18
  50. data/lib/thinking_sphinx/deploy/capistrano.rb +31 -30
  51. data/lib/thinking_sphinx/excerpter.rb +1 -2
  52. data/lib/thinking_sphinx/facet.rb +35 -45
  53. data/lib/thinking_sphinx/facet_search.rb +24 -58
  54. data/lib/thinking_sphinx/field.rb +0 -18
  55. data/lib/thinking_sphinx/index.rb +36 -38
  56. data/lib/thinking_sphinx/index/builder.rb +59 -74
  57. data/lib/thinking_sphinx/property.rb +45 -66
  58. data/lib/thinking_sphinx/railtie.rb +35 -0
  59. data/lib/thinking_sphinx/search.rb +250 -506
  60. data/lib/thinking_sphinx/source.rb +31 -50
  61. data/lib/thinking_sphinx/source/internal_properties.rb +3 -8
  62. data/lib/thinking_sphinx/source/sql.rb +31 -71
  63. data/lib/thinking_sphinx/tasks.rb +27 -48
  64. data/spec/thinking_sphinx/active_record/delta_spec.rb +41 -36
  65. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -96
  66. data/spec/thinking_sphinx/active_record/scopes_spec.rb +29 -29
  67. data/spec/thinking_sphinx/active_record_spec.rb +169 -140
  68. data/spec/thinking_sphinx/association_spec.rb +2 -20
  69. data/spec/thinking_sphinx/attribute_spec.rb +97 -101
  70. data/spec/thinking_sphinx/auto_version_spec.rb +11 -75
  71. data/spec/thinking_sphinx/configuration_spec.rb +62 -63
  72. data/spec/thinking_sphinx/context_spec.rb +66 -66
  73. data/spec/thinking_sphinx/facet_search_spec.rb +99 -99
  74. data/spec/thinking_sphinx/facet_spec.rb +4 -30
  75. data/spec/thinking_sphinx/field_spec.rb +3 -17
  76. data/spec/thinking_sphinx/index/builder_spec.rb +132 -169
  77. data/spec/thinking_sphinx/index_spec.rb +39 -45
  78. data/spec/thinking_sphinx/search_methods_spec.rb +33 -37
  79. data/spec/thinking_sphinx/search_spec.rb +269 -491
  80. data/spec/thinking_sphinx/source_spec.rb +48 -62
  81. data/spec/thinking_sphinx_spec.rb +49 -49
  82. data/tasks/distribution.rb +46 -0
  83. data/tasks/testing.rb +74 -0
  84. metadata +123 -199
  85. data/features/field_sorting.feature +0 -18
  86. data/features/thinking_sphinx/db/.gitignore +0 -1
  87. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
  88. data/features/thinking_sphinx/models/andrew.rb +0 -17
  89. data/lib/thinking-sphinx.rb +0 -1
  90. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
  91. data/lib/thinking_sphinx/bundled_search.rb +0 -40
  92. data/lib/thinking_sphinx/connection.rb +0 -71
  93. data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
  94. data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
  95. data/lib/thinking_sphinx/rails_additions.rb +0 -181
  96. data/spec/fixtures/data.sql +0 -32
  97. data/spec/fixtures/database.yml.default +0 -3
  98. data/spec/fixtures/models.rb +0 -161
  99. data/spec/fixtures/structure.sql +0 -146
  100. data/spec/spec_helper.rb +0 -54
  101. data/spec/sphinx_helper.rb +0 -67
  102. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
  103. data/spec/thinking_sphinx/connection_spec.rb +0 -77
  104. data/spec/thinking_sphinx/rails_additions_spec.rb +0 -203
@@ -4,185 +4,179 @@ describe ThinkingSphinx::Index do
4
4
  describe "prefix_fields method" do
5
5
  before :each do
6
6
  @index = ThinkingSphinx::Index.new(Person)
7
-
7
+
8
8
  @field_a = stub('field', :prefixes => true)
9
9
  @field_b = stub('field', :prefixes => false)
10
10
  @field_c = stub('field', :prefixes => true)
11
-
11
+
12
12
  @index.stub!(:fields => [@field_a, @field_b, @field_c])
13
13
  end
14
-
14
+
15
15
  it "should return fields that are flagged as prefixed" do
16
16
  @index.prefix_fields.should include(@field_a)
17
17
  @index.prefix_fields.should include(@field_c)
18
18
  end
19
-
19
+
20
20
  it "should not return fields that aren't flagged as prefixed" do
21
21
  @index.prefix_fields.should_not include(@field_b)
22
22
  end
23
23
  end
24
-
24
+
25
25
  describe "infix_fields method" do
26
26
  before :each do
27
27
  @index = ThinkingSphinx::Index.new(Person)
28
-
28
+
29
29
  @field_a = stub('field', :infixes => true)
30
30
  @field_b = stub('field', :infixes => false)
31
31
  @field_c = stub('field', :infixes => true)
32
-
32
+
33
33
  @index.stub!(:fields => [@field_a, @field_b, @field_c])
34
34
  end
35
-
35
+
36
36
  it "should return fields that are flagged as infixed" do
37
37
  @index.infix_fields.should include(@field_a)
38
38
  @index.infix_fields.should include(@field_c)
39
39
  end
40
-
40
+
41
41
  it "should not return fields that aren't flagged as infixed" do
42
42
  @index.infix_fields.should_not include(@field_b)
43
43
  end
44
44
  end
45
-
45
+
46
46
  describe '.name_for' do
47
47
  it "should return the model's name downcased" do
48
48
  ThinkingSphinx::Index.name_for(Alpha).should == 'alpha'
49
49
  end
50
-
50
+
51
51
  it "should separate words by underscores" do
52
52
  ThinkingSphinx::Index.name_for(ActiveRecord).should == 'active_record'
53
53
  end
54
-
54
+
55
55
  it "should separate namespaces by underscores" do
56
56
  ThinkingSphinx::Index.name_for(ActiveRecord::Base).
57
57
  should == 'active_record_base'
58
58
  end
59
59
  end
60
-
60
+
61
61
  describe '#name' do
62
62
  it "should return the downcased name of the index's model" do
63
63
  ThinkingSphinx::Index.new(Alpha).name.should == 'alpha'
64
64
  end
65
-
65
+
66
66
  it "should return a custom name if one is set" do
67
67
  index = ThinkingSphinx::Index.new(Alpha)
68
68
  index.name = 'custom'
69
69
  index.name.should == 'custom'
70
70
  end
71
71
  end
72
-
72
+
73
73
  describe '#core_name' do
74
74
  it "should take the index's name and append _core" do
75
75
  ThinkingSphinx::Index.new(Alpha).core_name.should == 'alpha_core'
76
76
  end
77
77
  end
78
-
78
+
79
79
  describe '#delta_name' do
80
80
  it "should take the index's name and append _delta" do
81
81
  ThinkingSphinx::Index.new(Alpha).delta_name.should == 'alpha_delta'
82
82
  end
83
83
  end
84
-
84
+
85
85
  describe '#all_names' do
86
86
  it "should return the core index name by default" do
87
87
  ThinkingSphinx::Index.new(Alpha).all_names.should == ['alpha_core']
88
88
  end
89
-
89
+
90
90
  it "should return both core and delta names if deltas are enabled" do
91
91
  index = ThinkingSphinx::Index.new(Alpha)
92
92
  index.delta_object = stub('delta')
93
-
93
+
94
94
  index.all_names.should == ['alpha_core', 'alpha_delta']
95
95
  end
96
-
96
+
97
97
  it "should respect custom names" do
98
98
  index = ThinkingSphinx::Index.new(Alpha)
99
99
  index.name = 'custom'
100
-
100
+
101
101
  index.all_names.should == ['custom_core']
102
102
  end
103
-
103
+
104
104
  it "should respect custom names when deltas are enabled" do
105
105
  index = ThinkingSphinx::Index.new(Alpha)
106
106
  index.name = 'custom'
107
107
  index.delta_object = stub('delta')
108
-
108
+
109
109
  index.all_names.should == ['custom_core', 'custom_delta']
110
110
  end
111
111
  end
112
-
112
+
113
113
  describe '#to_riddle' do
114
114
  it "should return two Riddle indexes if deltas are disabled" do
115
115
  index = ThinkingSphinx::Index.new(Alpha)
116
-
116
+
117
117
  index.to_riddle(0).length.should == 2
118
118
  end
119
-
119
+
120
120
  it "should return three Riddle indexes if deltas are enabled" do
121
121
  index = ThinkingSphinx::Index.new(Beta)
122
122
  index.delta_object = stub('delta')
123
-
123
+
124
124
  index.to_riddle(0).length.should == 3
125
125
  end
126
-
126
+
127
127
  it "should include a distributed index" do
128
128
  index = ThinkingSphinx::Index.new(Alpha)
129
-
129
+
130
130
  index.to_riddle(0).last.
131
131
  should be_a(Riddle::Configuration::DistributedIndex)
132
132
  end
133
-
133
+
134
134
  context 'core index' do
135
135
  it "should use the core name" do
136
136
  @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
137
137
  @index.name.should == 'alpha_core'
138
138
  end
139
-
139
+
140
140
  it "should not try to set disable_range on the index" do
141
141
  ThinkingSphinx::Configuration.instance.
142
142
  index_options[:disable_range] = true
143
-
143
+
144
144
  lambda {
145
145
  @index = ThinkingSphinx::Index.new(Alpha).to_riddle(0).first
146
146
  }.should_not raise_error(NoMethodError)
147
147
  end
148
148
  end
149
-
149
+
150
150
  context 'delta index' do
151
151
  before :each do
152
152
  index = ThinkingSphinx::Index.new(Beta)
153
153
  index.delta_object = stub('delta')
154
154
  @index = index.to_riddle(0)[1]
155
155
  end
156
-
156
+
157
157
  it "should use the delta name" do
158
158
  @index.name.should == 'beta_delta'
159
159
  end
160
160
  end
161
-
161
+
162
162
  context 'distributed index' do
163
163
  it "should use the index's name" do
164
164
  index = ThinkingSphinx::Index.new(Alpha)
165
165
 
166
166
  index.to_riddle(0).last.name.should == 'alpha'
167
167
  end
168
-
168
+
169
169
  it "should add the core index" do
170
170
  index = ThinkingSphinx::Index.new(Alpha)
171
171
 
172
- index.to_riddle(0).last.local_indices.should include('alpha_core')
172
+ index.to_riddle(0).last.local_indexes.should include('alpha_core')
173
173
  end
174
-
174
+
175
175
  it "should add the delta index if there is one" do
176
176
  index = ThinkingSphinx::Index.new(Beta)
177
177
  index.delta_object = stub('delta')
178
178
 
179
- index.to_riddle(0).last.local_indices.should include('beta_delta')
180
- end
181
-
182
- it "should add additional local indexes if there are any" do
183
- index = ThinkingSphinx::Index.new(Alpha)
184
- index.additional_indices << "other_index_core"
185
- index.to_riddle(0).last.local_indices.should include('other_index_core')
179
+ index.to_riddle(0).last.local_indexes.should include('beta_delta')
186
180
  end
187
181
  end
188
182
  end
@@ -4,150 +4,146 @@ describe ThinkingSphinx::SearchMethods do
4
4
  it "should be included into models with indexes" do
5
5
  Alpha.included_modules.should include(ThinkingSphinx::SearchMethods)
6
6
  end
7
-
7
+
8
8
  it "should not be included into models that don't have indexes" do
9
9
  Gamma.included_modules.should_not include(ThinkingSphinx::SearchMethods)
10
10
  end
11
-
11
+
12
12
  describe '.search_context' do
13
13
  it "should return nil if not within a model" do
14
14
  ThinkingSphinx.search_context.should be_nil
15
15
  end
16
-
16
+
17
17
  it "should return the model if within one" do
18
18
  Alpha.search_context.should == Alpha
19
19
  end
20
20
  end
21
-
21
+
22
22
  describe '.search' do
23
23
  it "should return an instance of ThinkingSphinx::Search" do
24
24
  Alpha.search.class.should == ThinkingSphinx::Search
25
25
  end
26
-
26
+
27
27
  it "should set the classes option if not already set" do
28
28
  search = Alpha.search
29
29
  search.options[:classes].should == [Alpha]
30
30
  end
31
-
31
+
32
32
  it "shouldn't set the classes option if already defined" do
33
33
  search = Alpha.search :classes => [Beta]
34
34
  search.options[:classes].should == [Beta]
35
35
  end
36
-
36
+
37
37
  it "should default to nil for the classes options" do
38
38
  ThinkingSphinx.search.options[:classes].should be_nil
39
39
  end
40
40
  end
41
-
41
+
42
42
  describe '.search_for_ids' do
43
43
  it "should return an instance of ThinkingSphinx::Search" do
44
44
  Alpha.search.class.should == ThinkingSphinx::Search
45
45
  end
46
-
46
+
47
47
  it "should set the classes option if not already set" do
48
48
  search = Alpha.search_for_ids
49
49
  search.options[:classes].should == [Alpha]
50
50
  end
51
-
51
+
52
52
  it "shouldn't set the classes option if already defined" do
53
53
  search = Alpha.search_for_ids :classes => [Beta]
54
54
  search.options[:classes].should == [Beta]
55
55
  end
56
-
56
+
57
57
  it "should set ids_only to true" do
58
58
  search = Alpha.search_for_ids
59
59
  search.options[:ids_only].should be_true
60
60
  end
61
61
  end
62
-
62
+
63
63
  describe '.search_for_id' do
64
64
  before :each do
65
65
  @config = ThinkingSphinx::Configuration.instance
66
66
  @client = Riddle::Client.new
67
67
 
68
- ThinkingSphinx::Connection.stub!(:take).and_yield(@client)
68
+ @config.stub!(:client => @client)
69
69
  @client.stub!(:query => {:matches => [], :total_found => 0})
70
70
  end
71
-
71
+
72
72
  it "should set the id range to the given id value" do
73
73
  ThinkingSphinx.search_for_id(101, 'alpha_core')
74
-
74
+
75
75
  @client.id_range.should == (101..101)
76
76
  end
77
-
77
+
78
78
  it "should not make any calls to the database" do
79
79
  Alpha.should_not_receive(:find)
80
-
80
+
81
81
  ThinkingSphinx.search_for_id(101, 'alpha_core', :classes => [Alpha])
82
82
  end
83
-
83
+
84
84
  it "should return true if there is a record" do
85
85
  @client.stub!(:query => {:matches => [
86
86
  {:attributes => {'sphinx_internal_id' => 100}}
87
87
  ], :total_found => 1})
88
-
88
+
89
89
  ThinkingSphinx.search_for_id(101, 'alpha_core').should be_true
90
90
  end
91
-
91
+
92
92
  it "should return false if there isn't a record" do
93
93
  ThinkingSphinx.search_for_id(101, 'alpha_core').should be_false
94
94
  end
95
95
  end
96
-
96
+
97
97
  describe '.count' do
98
98
  before :each do
99
99
  @config = ThinkingSphinx::Configuration.instance
100
100
  @client = Riddle::Client.new
101
101
 
102
- ThinkingSphinx::Connection.stub!(:take).and_yield(@client)
102
+ @config.stub!(:client => @client)
103
103
  @client.stub!(:query => {:matches => [], :total_found => 42})
104
104
  end
105
-
105
+
106
106
  it "should fall through to ActiveRecord if called on a class" do
107
107
  @client.should_not_receive(:query)
108
-
108
+
109
109
  Alpha.count
110
110
  end
111
-
111
+
112
112
  it "should return the total number of results if called globally" do
113
113
  ThinkingSphinx.count.should == 42
114
114
  end
115
115
  end
116
-
116
+
117
117
  describe '.search_count' do
118
118
  before :each do
119
119
  @config = ThinkingSphinx::Configuration.instance
120
120
  @client = Riddle::Client.new
121
121
 
122
- ThinkingSphinx::Connection.stub!(:take).and_yield(@client)
122
+ @config.stub!(:client => @client)
123
123
  @client.stub!(:query => {:matches => [], :total_found => 42})
124
124
  end
125
-
125
+
126
126
  it "should return the total number of results" do
127
127
  Alpha.search_count.should == 42
128
128
  end
129
-
129
+
130
130
  it "should not make any calls to the database" do
131
131
  Alpha.should_not_receive(:find)
132
-
132
+
133
133
  Alpha.search_count
134
134
  end
135
135
  end
136
-
136
+
137
137
  describe '.facets' do
138
- before :each do
139
- ThinkingSphinx::Search.stub!(:bundle_searches => [])
140
- end
141
-
142
138
  it "should return a FacetSearch instance" do
143
139
  Alpha.facets.should be_a(ThinkingSphinx::FacetSearch)
144
140
  end
145
-
141
+
146
142
  it "should set the classes option if not already set" do
147
143
  facets = Alpha.facets
148
144
  facets.options[:classes].should == [Alpha]
149
145
  end
150
-
146
+
151
147
  it "shouldn't set the classes option if already defined" do
152
148
  facets = Alpha.facets :classes => [Beta]
153
149
  facets.options[:classes].should == [Beta]
@@ -5,105 +5,63 @@ describe ThinkingSphinx::Search do
5
5
  before :each do
6
6
  @config = ThinkingSphinx::Configuration.instance
7
7
  @client = Riddle::Client.new
8
-
9
- ThinkingSphinx::Connection.stub(:take).and_yield(@client)
10
-
8
+
9
+ @config.stub!(:client => @client)
11
10
  @client.stub!(:query => {:matches => [], :total_found => 41, :total => 41})
12
11
  end
13
-
12
+
14
13
  it "not request results from the client if not accessing items" do
15
- ThinkingSphinx::Connection.should_not_receive(:take)
16
-
14
+ @config.should_not_receive(:client)
15
+
17
16
  ThinkingSphinx::Search.new.class
18
17
  end
19
-
18
+
20
19
  it "should request results if access is required" do
21
- ThinkingSphinx::Connection.should_receive(:take).and_yield(@client)
22
-
20
+ @config.should_receive(:client)
21
+
23
22
  ThinkingSphinx::Search.new.first
24
23
  end
25
-
24
+
26
25
  describe '#respond_to?' do
27
26
  it "should respond to Array methods" do
28
27
  ThinkingSphinx::Search.new.respond_to?(:each).should be_true
29
28
  end
30
-
29
+
31
30
  it "should respond to Search methods" do
32
31
  ThinkingSphinx::Search.new.respond_to?(:per_page).should be_true
33
32
  end
34
33
  end
35
-
36
- describe '#==' do
37
- it "populates the search results when checking equality" do
38
- search = ThinkingSphinx::Search.new
39
- search == []
40
-
41
- search.should be_populated
42
- end
43
- end
44
-
34
+
45
35
  describe '#populated?' do
46
36
  before :each do
47
37
  @search = ThinkingSphinx::Search.new
48
38
  end
49
-
39
+
50
40
  it "should be false if the client request has not been made" do
51
41
  @search.populated?.should be_false
52
42
  end
53
-
43
+
54
44
  it "should be true once the client request has been made" do
55
45
  @search.first
56
46
  @search.should be_populated
57
47
  end
58
-
48
+
59
49
  it "should be populated if :populate is set to true" do
60
50
  search = ThinkingSphinx::Search.new(:populate => true)
61
51
  search.should be_populated
62
52
  end
63
53
  end
64
-
65
- describe '#error?' do
66
- before :each do
67
- @search = ThinkingSphinx::Search.new
68
- end
69
-
70
- it "should be false if client requests have not resulted in an error" do
71
- @search.should_receive(:error).and_return(nil)
72
- @search.error?.should_not be_true
73
- end
74
-
75
- it "should be true when client requests result in an error" do
76
- @search.should_receive(:error).and_return("error message")
77
- @search.error?.should be_true
78
- end
79
- end
80
-
81
- describe '#warning?' do
82
- before :each do
83
- @search = ThinkingSphinx::Search.new
84
- end
85
-
86
- it "should be false if client requests have not resulted in a warning" do
87
- @search.should_receive(:warning).and_return(nil)
88
- @search.warning?.should_not be_true
89
- end
90
-
91
- it "should be true when client requests result in an error" do
92
- @search.should_receive(:warning).and_return("warning message")
93
- @search.warning?.should be_true
94
- end
95
- end
96
-
54
+
97
55
  describe '#results' do
98
56
  it "should populate search results before returning" do
99
57
  @search = ThinkingSphinx::Search.new
100
58
  @search.populated?.should be_false
101
-
59
+
102
60
  @search.results
103
61
  @search.populated?.should be_true
104
62
  end
105
63
  end
106
-
64
+
107
65
  describe '#method_missing' do
108
66
  before :each do
109
67
  Alpha.sphinx_scope(:by_name) { |name|
@@ -111,116 +69,116 @@ describe ThinkingSphinx::Search do
111
69
  }
112
70
  Alpha.sphinx_scope(:ids_only) { {:ids_only => true} }
113
71
  end
114
-
72
+
115
73
  after :each do
116
74
  Alpha.remove_sphinx_scopes
117
75
  end
118
-
76
+
119
77
  it "should handle Array methods" do
120
78
  ThinkingSphinx::Search.new.private_methods.should be_an(Array)
121
79
  end
122
-
80
+
123
81
  it "should raise a NoMethodError exception if unknown method" do
124
82
  lambda {
125
83
  ThinkingSphinx::Search.new.foo
126
84
  }.should raise_error(NoMethodError)
127
85
  end
128
-
86
+
129
87
  it "should not request results from client if method does not exist" do
130
88
  @client.should_not_receive(:query)
131
-
89
+
132
90
  lambda {
133
91
  ThinkingSphinx::Search.new.foo
134
92
  }.should raise_error(NoMethodError)
135
93
  end
136
-
94
+
137
95
  it "should accept sphinx scopes" do
138
96
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
139
-
97
+
140
98
  lambda {
141
99
  search.by_name('Pat')
142
100
  }.should_not raise_error(NoMethodError)
143
101
  end
144
-
102
+
145
103
  it "should return itself when using a sphinx scope" do
146
104
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
147
105
  search.by_name('Pat').object_id.should == search.object_id
148
106
  end
149
-
107
+
150
108
  it "should keep the same search object when chaining multiple scopes" do
151
109
  search = ThinkingSphinx::Search.new(:classes => [Alpha])
152
110
  search.by_name('Pat').ids_only.object_id.should == search.object_id
153
111
  end
154
112
  end
155
-
113
+
156
114
  describe '.search' do
157
115
  it "return the output of ThinkingSphinx.search" do
158
116
  @results = [] # to confirm same object
159
117
  ThinkingSphinx.stub!(:search => @results)
160
-
161
- ThinkingSphinx.search.object_id.should == @results.object_id
118
+
119
+ ThinkingSphinx::Search.search.object_id.should == @results.object_id
162
120
  end
163
121
  end
164
-
122
+
165
123
  describe '.search_for_ids' do
166
124
  it "return the output of ThinkingSphinx.search_for_ids" do
167
125
  @results = [] # to confirm same object
168
126
  ThinkingSphinx.stub!(:search_for_ids => @results)
169
-
170
- ThinkingSphinx.search_for_ids.object_id.
127
+
128
+ ThinkingSphinx::Search.search_for_ids.object_id.
171
129
  should == @results.object_id
172
130
  end
173
131
  end
174
-
132
+
175
133
  describe '.search_for_id' do
176
134
  it "return the output of ThinkingSphinx.search_for_ids" do
177
135
  @results = [] # to confirm same object
178
136
  ThinkingSphinx.stub!(:search_for_id => @results)
179
-
180
- ThinkingSphinx.search_for_id.object_id.
137
+
138
+ ThinkingSphinx::Search.search_for_id.object_id.
181
139
  should == @results.object_id
182
140
  end
183
141
  end
184
-
142
+
185
143
  describe '.count' do
186
144
  it "return the output of ThinkingSphinx.search" do
187
145
  @results = [] # to confirm same object
188
146
  ThinkingSphinx.stub!(:count => @results)
189
-
190
- ThinkingSphinx.count.object_id.should == @results.object_id
147
+
148
+ ThinkingSphinx::Search.count.object_id.should == @results.object_id
191
149
  end
192
150
  end
193
-
151
+
194
152
  describe '.facets' do
195
153
  it "return the output of ThinkingSphinx.facets" do
196
154
  @results = [] # to confirm same object
197
155
  ThinkingSphinx.stub!(:facets => @results)
198
-
199
- ThinkingSphinx.facets.object_id.should == @results.object_id
156
+
157
+ ThinkingSphinx::Search.facets.object_id.should == @results.object_id
200
158
  end
201
159
  end
202
-
160
+
203
161
  describe '.matching_fields' do
204
162
  it "should return objects with indexes matching 1's in the bitmask" do
205
163
  fields = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta']
206
164
  ThinkingSphinx::Search.matching_fields(fields, 85).
207
165
  should == ['alpha', 'gamma', 'epsilon', 'eta']
208
-
166
+
209
167
  ThinkingSphinx::Search.matching_fields(fields, 42).
210
168
  should == ['beta', 'delta', 'zeta']
211
169
  end
212
170
  end
213
-
171
+
214
172
  describe '#populate' do
215
173
  before :each do
216
174
  @alpha_a, @alpha_b = Alpha.new, Alpha.new
217
175
  @beta_a, @beta_b = Beta.new, Beta.new
218
-
176
+
219
177
  @alpha_a.stub! :id => 1, :read_attribute => 1
220
178
  @alpha_b.stub! :id => 2, :read_attribute => 2
221
179
  @beta_a.stub! :id => 1, :read_attribute => 1
222
180
  @beta_b.stub! :id => 2, :read_attribute => 2
223
-
181
+
224
182
  @client.stub! :query => {
225
183
  :matches => minimal_result_hashes(@alpha_a, @beta_b, @alpha_b, @beta_a),
226
184
  :fields => ["one", "two", "three", "four", "five"]
@@ -228,14 +186,14 @@ describe ThinkingSphinx::Search do
228
186
  Alpha.stub! :find => [@alpha_a, @alpha_b]
229
187
  Beta.stub! :find => [@beta_a, @beta_b]
230
188
  end
231
-
189
+
232
190
  it "should issue only one select per model" do
233
191
  Alpha.should_receive(:find).once.and_return([@alpha_a, @alpha_b])
234
192
  Beta.should_receive(:find).once.and_return([@beta_a, @beta_b])
235
-
193
+
236
194
  ThinkingSphinx::Search.new.first
237
195
  end
238
-
196
+
239
197
  it "should mix the results from different models" do
240
198
  search = ThinkingSphinx::Search.new
241
199
  search[0].should be_a(Alpha)
@@ -243,7 +201,7 @@ describe ThinkingSphinx::Search do
243
201
  search[2].should be_a(Alpha)
244
202
  search[3].should be_a(Beta)
245
203
  end
246
-
204
+
247
205
  it "should maintain the Xoopit ordering for results" do
248
206
  search = ThinkingSphinx::Search.new
249
207
  search[0].id.should == 1
@@ -251,121 +209,53 @@ describe ThinkingSphinx::Search do
251
209
  search[2].id.should == 2
252
210
  search[3].id.should == 1
253
211
  end
254
-
212
+
255
213
  it "should use the requested classes to generate the index argument" do
256
214
  @client.should_receive(:query) do |query, index, comment|
257
215
  index.should == 'alpha_core,beta_core,beta_delta'
258
216
  end
259
-
217
+
260
218
  ThinkingSphinx::Search.new(:classes => [Alpha, Beta]).first
261
219
  end
262
-
263
- it "should restrict includes to the relevant classes" do
264
- Alpha.should_receive(:find) do |type, options|
265
- options[:include].should == [:betas]
266
- [@alpha_a, @alpha_b]
267
- end
268
-
269
- Beta.should_receive(:find) do |type, options|
270
- options[:include].should == [:gammas]
271
- [@beta_a, @beta_b]
272
- end
273
-
274
- ThinkingSphinx::Search.new(:include => [:betas, :gammas]).first
275
- end
276
-
277
- it "should restrict single includes to the relevant classes" do
278
- Alpha.should_receive(:find) do |type, options|
279
- options[:include].should == :betas
280
- [@alpha_a, @alpha_b]
281
- end
282
-
283
- Beta.should_receive(:find) do |type, options|
284
- options[:include].should be_nil
285
- [@beta_a, @beta_b]
286
- end
287
-
288
- ThinkingSphinx::Search.new(:include => :betas).first
289
- end
290
-
291
- it "should respect complex includes" do
292
- Alpha.should_receive(:find) do |type, options|
293
- options[:include].should == [:thetas, {:betas => :gammas}]
294
- [@alpha_a, @alpha_b]
295
- end
296
-
297
- Beta.should_receive(:find) do |type, options|
298
- options[:include].should be_nil
299
- [@beta_a, @beta_b]
300
- end
301
-
302
- ThinkingSphinx::Search.new(:include => [:thetas, {:betas => :gammas}]).first
303
- end
304
-
305
- it "should respect hash includes" do
306
- Alpha.should_receive(:find) do |type, options|
307
- options[:include].should == {:betas => :gammas}
308
- [@alpha_a, @alpha_b]
309
- end
310
-
311
- Beta.should_receive(:find) do |type, options|
312
- options[:include].should be_nil
313
- [@beta_a, @beta_b]
314
- end
315
-
316
- ThinkingSphinx::Search.new(:include => {:betas => :gammas}).first
317
- end
318
-
319
- it "should respect includes for single class searches" do
320
- Alpha.should_receive(:find) do |type, options|
321
- options[:include].should == {:betas => :gammas}
322
- [@alpha_a, @alpha_b]
323
- end
324
-
325
- ThinkingSphinx::Search.new(
326
- :include => {:betas => :gammas},
327
- :classes => [Alpha]
328
- ).first
329
- end
330
-
220
+
331
221
  describe 'query' do
332
222
  it "should concatenate arguments with spaces" do
333
223
  @client.should_receive(:query) do |query, index, comment|
334
224
  query.should == 'two words'
335
225
  end
336
-
226
+
337
227
  ThinkingSphinx::Search.new('two', 'words').first
338
228
  end
339
-
229
+
340
230
  it "should append conditions to the query" do
341
231
  @client.should_receive(:query) do |query, index, comment|
342
232
  query.should == 'general @focused specific'
343
233
  end
344
-
234
+
345
235
  ThinkingSphinx::Search.new('general', :conditions => {
346
236
  :focused => 'specific'
347
237
  }).first
348
238
  end
349
-
239
+
350
240
  it "append multiple conditions together" do
351
241
  @client.should_receive(:query) do |query, index, comment|
352
242
  query.should match(/general.+@foo word/)
353
243
  query.should match(/general.+@bar word/)
354
244
  end
355
-
245
+
356
246
  ThinkingSphinx::Search.new('general', :conditions => {
357
247
  :foo => 'word', :bar => 'word'
358
248
  }).first
359
249
  end
360
-
250
+
361
251
  it "should apply stars if requested, and handle full extended syntax" do
362
252
  input = %{a b* c (d | e) 123 5&6 (f_f g) !h "i j" "k l"~10 "m n"/3 @o p -(q|r)}
363
253
  expected = %{*a* b* *c* (*d* | *e*) *123* *5*&*6* (*f_f* *g*) !*h* "i j" "k l"~10 "m n"/3 @o *p* -(*q*|*r*)}
364
-
254
+
365
255
  @client.should_receive(:query) do |query, index, comment|
366
256
  query.should == expected
367
257
  end
368
-
258
+
369
259
  ThinkingSphinx::Search.new(input, :star => true).first
370
260
  end
371
261
 
@@ -373,7 +263,7 @@ describe ThinkingSphinx::Search do
373
263
  @client.should_receive(:query) do |query, index, comment|
374
264
  query.should == '*foo*@*bar*.*com*'
375
265
  end
376
-
266
+
377
267
  ThinkingSphinx::Search.new('foo@bar.com', :star => true).first
378
268
  end
379
269
 
@@ -381,109 +271,51 @@ describe ThinkingSphinx::Search do
381
271
  @client.should_receive(:query) do |query, index, comment|
382
272
  query.should == '*foo@bar.com* -*foo-bar*'
383
273
  end
384
-
274
+
385
275
  ThinkingSphinx::Search.new(
386
276
  'foo@bar.com -foo-bar', :star => /[\w@.-]+/u
387
277
  ).first
388
278
  end
389
-
390
- it "should ignore multi-field limitations" do
391
- @client.should_receive(:query) do |query, index, comment|
392
- query.should == '@(foo,bar) *baz*'
393
- end
394
-
395
- ThinkingSphinx::Search.new('@(foo,bar) baz', :star => true).first
396
- end
397
-
398
- it "should ignore multi-field limitations with spaces" do
399
- @client.should_receive(:query) do |query, index, comment|
400
- query.should == '@(foo bar) *baz*'
401
- end
402
-
403
- ThinkingSphinx::Search.new('@(foo bar) baz', :star => true).first
404
- end
405
-
406
- it "should ignore multi-field limitations in the middle of queries" do
407
- @client.should_receive(:query) do |query, index, comment|
408
- query.should == '*baz* @foo *bar* @(foo,bar) *baz*'
409
- end
410
-
411
- ThinkingSphinx::Search.new(
412
- 'baz @foo bar @(foo,bar) baz', :star => true
413
- ).first
414
- end
415
-
416
- it "should try retry query up to the hard_retry_count option times if it catches an exception" do
417
- @client.should_receive(:query).exactly(4).and_raise("Test Exception")
418
-
419
- expect { ThinkingSphinx::Search.new(:hard_retry_count => 3).first }.
420
- to raise_error("Test Exception")
421
- end
422
-
423
- it "should not retry query if hard_retry_count option is not set" do
424
- @client.should_receive(:query).exactly(1).and_raise("Test Exception")
425
-
426
- expect { ThinkingSphinx::Search.new.first }.
427
- to raise_error("Test Exception")
428
- end
429
-
430
- it "should allow the hard_retry_count to be globally set as a configuration option" do
431
- @config.hard_retry_count = 2
432
-
433
- @client.should_receive(:query).exactly(3).and_raise("Test Exception")
434
-
435
- expect { ThinkingSphinx::Search.new.first }.
436
- to raise_error("Test Exception")
437
- end
438
-
439
- it "should give priority to the hard_retry_count search option over the globally configured option" do
440
- @config.hard_retry_count = 4
441
-
442
- @client.should_receive(:query).exactly(2).and_raise("Test Exception")
443
-
444
- expect { ThinkingSphinx::Search.new(:hard_retry_count => 1).first }.
445
- to raise_error("Test Exception")
446
- end
447
279
  end
448
-
280
+
449
281
  describe 'comment' do
450
282
  it "should add comment if explicitly provided" do
451
283
  @client.should_receive(:query) do |query, index, comment|
452
284
  comment.should == 'custom log'
453
285
  end
454
-
286
+
455
287
  ThinkingSphinx::Search.new(:comment => 'custom log').first
456
288
  end
457
-
289
+
458
290
  it "should default to a blank comment" do
459
291
  @client.should_receive(:query) do |query, index, comment|
460
292
  comment.should == ''
461
293
  end
462
-
294
+
463
295
  ThinkingSphinx::Search.new.first
464
296
  end
465
297
  end
466
-
298
+
467
299
  describe 'match mode' do
468
300
  it "should default to :all" do
469
301
  ThinkingSphinx::Search.new.first
470
-
302
+
471
303
  @client.match_mode.should == :all
472
304
  end
473
-
305
+
474
306
  it "should default to :extended if conditions are supplied" do
475
307
  ThinkingSphinx::Search.new('general', :conditions => {
476
308
  :foo => 'word', :bar => 'word'
477
309
  }).first
478
-
310
+
479
311
  @client.match_mode.should == :extended
480
312
  end
481
-
313
+
482
314
  it "should use explicit match modes" do
483
315
  ThinkingSphinx::Search.new('general', :conditions => {
484
316
  :foo => 'word', :bar => 'word'
485
317
  }, :match_mode => :extended2).first
486
-
318
+
487
319
  @client.match_mode.should == :extended2
488
320
  end
489
321
  end
@@ -491,59 +323,59 @@ describe ThinkingSphinx::Search do
491
323
  describe 'sphinx_select' do
492
324
  it "should default to *" do
493
325
  ThinkingSphinx::Search.new.first
494
-
326
+
495
327
  @client.select.should == "*"
496
328
  end
497
-
329
+
498
330
  it "should get set on the client if specified" do
499
331
  ThinkingSphinx::Search.new('general',
500
332
  :sphinx_select => "*, foo as bar"
501
333
  ).first
502
-
334
+
503
335
  @client.select.should == "*, foo as bar"
504
336
  end
505
337
 
506
338
  end
507
-
339
+
508
340
  describe 'pagination' do
509
341
  it "should set the limit using per_page" do
510
342
  ThinkingSphinx::Search.new(:per_page => 30).first
511
343
  @client.limit.should == 30
512
344
  end
513
-
345
+
514
346
  it "should set the offset if pagination is requested" do
515
347
  ThinkingSphinx::Search.new(:page => 3).first
516
348
  @client.offset.should == 40
517
349
  end
518
-
350
+
519
351
  it "should set the offset by the per_page value" do
520
352
  ThinkingSphinx::Search.new(:page => 3, :per_page => 30).first
521
353
  @client.offset.should == 60
522
354
  end
523
355
  end
524
-
356
+
525
357
  describe 'filters' do
526
358
  it "should filter out deleted values by default" do
527
359
  ThinkingSphinx::Search.new.first
528
-
360
+
529
361
  filter = @client.filters.last
530
362
  filter.values.should == [0]
531
363
  filter.attribute.should == 'sphinx_deleted'
532
364
  filter.exclude?.should be_false
533
365
  end
534
-
366
+
535
367
  it "should add class filters for explicit classes" do
536
368
  ThinkingSphinx::Search.new(:classes => [Alpha, Beta]).first
537
-
369
+
538
370
  filter = @client.filters.last
539
371
  filter.values.should == [Alpha.to_crc32, Beta.to_crc32]
540
372
  filter.attribute.should == 'class_crc'
541
373
  filter.exclude?.should be_false
542
374
  end
543
-
375
+
544
376
  it "should add class filters for subclasses of requested classes" do
545
377
  ThinkingSphinx::Search.new(:classes => [Person]).first
546
-
378
+
547
379
  filter = @client.filters.last
548
380
  filter.values.should == [
549
381
  Parent.to_crc32, Admin::Person.to_crc32,
@@ -552,141 +384,159 @@ describe ThinkingSphinx::Search do
552
384
  filter.attribute.should == 'class_crc'
553
385
  filter.exclude?.should be_false
554
386
  end
555
-
387
+
556
388
  it "should append inclusive filters of integers" do
557
389
  ThinkingSphinx::Search.new(:with => {:int => 1}).first
558
-
390
+
559
391
  filter = @client.filters.last
560
392
  filter.values.should == [1]
561
393
  filter.attribute.should == 'int'
562
394
  filter.exclude?.should be_false
563
395
  end
564
-
396
+
565
397
  it "should append inclusive filters of floats" do
566
398
  ThinkingSphinx::Search.new(:with => {:float => 1.5}).first
567
-
399
+
568
400
  filter = @client.filters.last
569
401
  filter.values.should == [1.5]
570
402
  filter.attribute.should == 'float'
571
403
  filter.exclude?.should be_false
572
404
  end
573
-
405
+
574
406
  it "should append inclusive filters of booleans" do
575
407
  ThinkingSphinx::Search.new(:with => {:boolean => true}).first
576
-
408
+
577
409
  filter = @client.filters.last
578
410
  filter.values.should == [true]
579
411
  filter.attribute.should == 'boolean'
580
412
  filter.exclude?.should be_false
581
413
  end
582
-
414
+
583
415
  it "should append inclusive filters of arrays" do
584
416
  ThinkingSphinx::Search.new(:with => {:ints => [1, 2, 3]}).first
585
-
417
+
586
418
  filter = @client.filters.last
587
419
  filter.values.should == [1, 2, 3]
588
420
  filter.attribute.should == 'ints'
589
421
  filter.exclude?.should be_false
590
422
  end
591
-
423
+
592
424
  it "should treat nils in arrays as 0" do
593
425
  ThinkingSphinx::Search.new(:with => {:ints => [nil, 1, 2, 3]}).first
594
-
426
+
595
427
  filter = @client.filters.last
596
428
  filter.values.should == [0, 1, 2, 3]
597
429
  end
598
-
430
+
599
431
  it "should append inclusive filters of time ranges" do
600
432
  first, last = 1.week.ago, Time.now
601
433
  ThinkingSphinx::Search.new(:with => {
602
434
  :time => first..last
603
435
  }).first
604
-
436
+
605
437
  filter = @client.filters.last
606
438
  filter.values.should == (first.to_i..last.to_i)
607
439
  filter.attribute.should == 'time'
608
440
  filter.exclude?.should be_false
609
441
  end
610
-
442
+
611
443
  it "should append exclusive filters of integers" do
612
444
  ThinkingSphinx::Search.new(:without => {:int => 1}).first
613
-
445
+
614
446
  filter = @client.filters.last
615
447
  filter.values.should == [1]
616
448
  filter.attribute.should == 'int'
617
449
  filter.exclude?.should be_true
618
450
  end
619
-
451
+
620
452
  it "should append exclusive filters of floats" do
621
453
  ThinkingSphinx::Search.new(:without => {:float => 1.5}).first
622
-
454
+
623
455
  filter = @client.filters.last
624
456
  filter.values.should == [1.5]
625
457
  filter.attribute.should == 'float'
626
458
  filter.exclude?.should be_true
627
459
  end
628
-
460
+
629
461
  it "should append exclusive filters of booleans" do
630
462
  ThinkingSphinx::Search.new(:without => {:boolean => true}).first
631
-
463
+
632
464
  filter = @client.filters.last
633
465
  filter.values.should == [true]
634
466
  filter.attribute.should == 'boolean'
635
467
  filter.exclude?.should be_true
636
468
  end
637
-
469
+
638
470
  it "should append exclusive filters of arrays" do
639
471
  ThinkingSphinx::Search.new(:without => {:ints => [1, 2, 3]}).first
640
-
472
+
641
473
  filter = @client.filters.last
642
474
  filter.values.should == [1, 2, 3]
643
475
  filter.attribute.should == 'ints'
644
476
  filter.exclude?.should be_true
645
477
  end
646
-
478
+
647
479
  it "should append exclusive filters of time ranges" do
648
480
  first, last = 1.week.ago, Time.now
649
481
  ThinkingSphinx::Search.new(:without => {
650
482
  :time => first..last
651
483
  }).first
652
-
484
+
653
485
  filter = @client.filters.last
654
486
  filter.values.should == (first.to_i..last.to_i)
655
487
  filter.attribute.should == 'time'
656
488
  filter.exclude?.should be_true
657
489
  end
658
-
490
+
659
491
  it "should add separate filters for each item in a with_all value" do
660
492
  ThinkingSphinx::Search.new(:with_all => {:ints => [1, 2, 3]}).first
661
-
493
+
662
494
  filters = @client.filters[-3, 3]
663
495
  filters.each do |filter|
664
496
  filter.attribute.should == 'ints'
665
497
  filter.exclude?.should be_false
666
498
  end
667
-
499
+
668
500
  filters[0].values.should == [1]
669
501
  filters[1].values.should == [2]
670
502
  filters[2].values.should == [3]
671
503
  end
672
-
504
+
673
505
  it "should filter out specific ids using :without_ids" do
674
506
  ThinkingSphinx::Search.new(:without_ids => [4, 5, 6]).first
675
-
507
+
676
508
  filter = @client.filters.last
677
509
  filter.values.should == [4, 5, 6]
678
510
  filter.attribute.should == 'sphinx_internal_id'
679
511
  filter.exclude?.should be_true
680
512
  end
681
-
682
- it "should not filter out any ids if :without_ids is an empty array" do
683
- ThinkingSphinx::Search.new(:without_ids => []).first
684
-
685
- filter = @client.filters.last
686
- filter.attribute.should_not == 'sphinx_internal_id'
513
+
514
+ describe 'in :conditions' do
515
+ it "should add as filters for known attributes in :conditions option" do
516
+ ThinkingSphinx::Search.new('general',
517
+ :conditions => {:word => 'specific', :lat => 1.5},
518
+ :classes => [Alpha]
519
+ ).first
520
+
521
+ filter = @client.filters.last
522
+ filter.values.should == [1.5]
523
+ filter.attribute.should == 'lat'
524
+ filter.exclude?.should be_false
525
+ end
526
+
527
+ it "should not add the filter to the query string" do
528
+ @client.should_receive(:query) do |query, index, comment|
529
+ query.should == 'general @word specific'
530
+ end
531
+
532
+ ThinkingSphinx::Search.new('general',
533
+ :conditions => {:word => 'specific', :lat => 1.5},
534
+ :classes => [Alpha]
535
+ ).first
536
+ end
687
537
  end
688
538
  end
689
-
539
+
690
540
  describe 'sort mode' do
691
541
  it "should use :relevance as a default" do
692
542
  ThinkingSphinx::Search.new.first
@@ -724,18 +574,18 @@ describe ThinkingSphinx::Search do
724
574
  @client.sort_mode.should == :attr_desc
725
575
  end
726
576
  end
727
-
577
+
728
578
  describe 'sort by' do
729
579
  it "should presume order symbols are attributes" do
730
580
  ThinkingSphinx::Search.new(:order => :created_at).first
731
581
  @client.sort_by.should == 'created_at'
732
582
  end
733
-
583
+
734
584
  it "replace field names with their sortable attributes" do
735
585
  ThinkingSphinx::Search.new(:order => :name, :classes => [Alpha]).first
736
586
  @client.sort_by.should == 'name_sort'
737
587
  end
738
-
588
+
739
589
  it "should replace field names in strings" do
740
590
  ThinkingSphinx::Search.new(
741
591
  :order => "created_at ASC, name DESC", :classes => [Alpha]
@@ -743,43 +593,43 @@ describe ThinkingSphinx::Search do
743
593
  @client.sort_by.should == 'created_at ASC, name_sort DESC'
744
594
  end
745
595
  end
746
-
596
+
747
597
  describe 'max matches' do
748
598
  it "should use the global setting by default" do
749
599
  ThinkingSphinx::Search.new.first
750
600
  @client.max_matches.should == 1000
751
601
  end
752
-
602
+
753
603
  it "should use explicit setting" do
754
604
  ThinkingSphinx::Search.new(:max_matches => 2000).first
755
605
  @client.max_matches.should == 2000
756
606
  end
757
607
  end
758
-
608
+
759
609
  describe 'field weights' do
760
610
  it "should set field weights as provided" do
761
611
  ThinkingSphinx::Search.new(
762
612
  :field_weights => {'foo' => 10, 'bar' => 5}
763
613
  ).first
764
-
614
+
765
615
  @client.field_weights.should == {
766
616
  'foo' => 10, 'bar' => 5
767
617
  }
768
618
  end
769
-
619
+
770
620
  it "should use field weights set in the index" do
771
621
  ThinkingSphinx::Search.new(:classes => [Alpha]).first
772
-
622
+
773
623
  @client.field_weights.should == {'name' => 10}
774
624
  end
775
625
  end
776
-
626
+
777
627
  describe 'index weights' do
778
628
  it "should send index weights through to the client" do
779
629
  ThinkingSphinx::Search.new(:index_weights => {'foo' => 100}).first
780
630
  @client.index_weights.should == {'foo' => 100}
781
631
  end
782
-
632
+
783
633
  it "should convert classes to their core and delta index names" do
784
634
  ThinkingSphinx::Search.new(:index_weights => {Alpha => 100}).first
785
635
  @client.index_weights.should == {
@@ -788,15 +638,15 @@ describe ThinkingSphinx::Search do
788
638
  }
789
639
  end
790
640
  end
791
-
641
+
792
642
  describe 'grouping' do
793
643
  it "should convert group into group_by and group_function" do
794
644
  ThinkingSphinx::Search.new(:group => :edition).first
795
-
645
+
796
646
  @client.group_function.should == :attr
797
647
  @client.group_by.should == "edition"
798
648
  end
799
-
649
+
800
650
  it "should pass on explicit grouping arguments" do
801
651
  ThinkingSphinx::Search.new(
802
652
  :group_by => 'created_at',
@@ -804,45 +654,45 @@ describe ThinkingSphinx::Search do
804
654
  :group_clause => 'clause',
805
655
  :group_distinct => 'distinct'
806
656
  ).first
807
-
657
+
808
658
  @client.group_by.should == 'created_at'
809
659
  @client.group_function.should == :attr
810
660
  @client.group_clause.should == 'clause'
811
661
  @client.group_distinct.should == 'distinct'
812
662
  end
813
663
  end
814
-
664
+
815
665
  describe 'anchor' do
816
666
  it "should detect lat and lng attributes on the given model" do
817
667
  ThinkingSphinx::Search.new(
818
668
  :geo => [1.0, -1.0],
819
669
  :classes => [Alpha]
820
670
  ).first
821
-
671
+
822
672
  @client.anchor[:latitude_attribute].should == 'lat'
823
673
  @client.anchor[:longitude_attribute].should == 'lng'
824
674
  end
825
-
675
+
826
676
  it "should detect lat and lon attributes on the given model" do
827
677
  ThinkingSphinx::Search.new(
828
678
  :geo => [1.0, -1.0],
829
679
  :classes => [Beta]
830
680
  ).first
831
-
681
+
832
682
  @client.anchor[:latitude_attribute].should == 'lat'
833
683
  @client.anchor[:longitude_attribute].should == 'lon'
834
684
  end
835
-
685
+
836
686
  it "should detect latitude and longitude attributes on the given model" do
837
687
  ThinkingSphinx::Search.new(
838
688
  :geo => [1.0, -1.0],
839
689
  :classes => [Person]
840
690
  ).first
841
-
691
+
842
692
  @client.anchor[:latitude_attribute].should == 'latitude'
843
693
  @client.anchor[:longitude_attribute].should == 'longitude'
844
694
  end
845
-
695
+
846
696
  it "should accept manually defined latitude and longitude attributes" do
847
697
  ThinkingSphinx::Search.new(
848
698
  :geo => [1.0, -1.0],
@@ -850,43 +700,43 @@ describe ThinkingSphinx::Search do
850
700
  :latitude_attr => :updown,
851
701
  :longitude_attr => :leftright
852
702
  ).first
853
-
703
+
854
704
  @client.anchor[:latitude_attribute].should == 'updown'
855
705
  @client.anchor[:longitude_attribute].should == 'leftright'
856
706
  end
857
-
707
+
858
708
  it "should accept manually defined latitude and longitude attributes in the given model" do
859
709
  ThinkingSphinx::Search.new(
860
710
  :geo => [1.0, -1.0],
861
711
  :classes => [Friendship]
862
712
  ).first
863
-
713
+
864
714
  @client.anchor[:latitude_attribute].should == 'person_id'
865
715
  @client.anchor[:longitude_attribute].should == 'person_id'
866
716
  end
867
-
717
+
868
718
  it "should accept geo array for geo-position values" do
869
719
  ThinkingSphinx::Search.new(
870
720
  :geo => [1.0, -1.0],
871
721
  :classes => [Alpha]
872
722
  ).first
873
-
723
+
874
724
  @client.anchor[:latitude].should == 1.0
875
725
  @client.anchor[:longitude].should == -1.0
876
726
  end
877
-
727
+
878
728
  it "should accept lat and lng options for geo-position values" do
879
729
  ThinkingSphinx::Search.new(
880
730
  :lat => 1.0,
881
731
  :lng => -1.0,
882
732
  :classes => [Alpha]
883
733
  ).first
884
-
734
+
885
735
  @client.anchor[:latitude].should == 1.0
886
736
  @client.anchor[:longitude].should == -1.0
887
737
  end
888
738
  end
889
-
739
+
890
740
  describe 'sql ordering' do
891
741
  before :each do
892
742
  @client.stub! :query => {
@@ -894,7 +744,7 @@ describe ThinkingSphinx::Search do
894
744
  }
895
745
  Alpha.stub! :find => [@alpha_a, @alpha_b]
896
746
  end
897
-
747
+
898
748
  it "shouldn't re-sort SQL results based on Sphinx information" do
899
749
  search = ThinkingSphinx::Search.new(
900
750
  :classes => [Alpha],
@@ -903,261 +753,201 @@ describe ThinkingSphinx::Search do
903
753
  search.first.should == @alpha_a
904
754
  search.last.should == @alpha_b
905
755
  end
906
-
756
+
907
757
  it "should use the option for the ActiveRecord::Base#find calls" do
908
758
  Alpha.should_receive(:find) do |mode, options|
909
759
  options[:order].should == 'id'
910
760
  end
911
-
761
+
912
762
  ThinkingSphinx::Search.new(
913
763
  :classes => [Alpha],
914
764
  :sql_order => 'id'
915
765
  ).first
916
766
  end
917
767
  end
918
-
919
- describe ':only option' do
920
- it "returns the requested attribute as an array" do
921
- ThinkingSphinx::Search.new(:only => :class_crc).first.
922
- should == Alpha.to_crc32
923
- end
924
-
925
- it "returns multiple attributes as hashes with values" do
926
- ThinkingSphinx::Search.new(
927
- :only => [:class_crc, :sphinx_internal_id]
928
- ).first.should == {
929
- :class_crc => Alpha.to_crc32,
930
- :sphinx_internal_id => @alpha_a.id
931
- }
932
- end
933
-
934
- it "handles strings for a single attribute name" do
935
- ThinkingSphinx::Search.new(:only => 'class_crc').first.
936
- should == Alpha.to_crc32
937
- end
938
-
939
- it "handles strings for multiple attribute names" do
940
- ThinkingSphinx::Search.new(
941
- :only => ['class_crc', 'sphinx_internal_id']
942
- ).first.should == {
943
- :class_crc => Alpha.to_crc32,
944
- :sphinx_internal_id => @alpha_a.id
945
- }
946
- end
947
- end
948
-
949
- describe ':attributes_only option' do
950
- it "returns the attributes as hashes with values" do
951
- ThinkingSphinx::Search.new(
952
- :attributes_only => true
953
- ).first.should == {
954
- :sphinx_internal_class => "Alpha",
955
- :class_crc => Alpha.to_crc32,
956
- :sphinx_internal_id => 1
957
- }
958
- end
959
- end
960
-
768
+
961
769
  context 'result objects' do
962
770
  describe '#excerpts' do
963
771
  before :each do
964
772
  @search = ThinkingSphinx::Search.new
965
773
  end
966
-
774
+
967
775
  it "should add excerpts method if objects don't already have one" do
968
776
  @search.first.should respond_to(:excerpts)
969
777
  end
970
-
778
+
971
779
  it "should return an instance of ThinkingSphinx::Excerpter" do
972
780
  @search.first.excerpts.should be_a(ThinkingSphinx::Excerpter)
973
781
  end
974
-
782
+
975
783
  it "should not add excerpts method if objects already have one" do
976
784
  @search.last.excerpts.should_not be_a(ThinkingSphinx::Excerpter)
977
785
  end
978
-
979
- # Fails in Ruby 1.9 (or maybe it's an RSpec update). Not sure why.
786
+
980
787
  it "should set up the excerpter with the instances and search" do
981
- [@alpha_a, @beta_b, @alpha_b, @beta_a].each do |object|
982
- ThinkingSphinx::Excerpter.should_receive(:new).with(@search, object)
983
- end
984
-
788
+ ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_a)
789
+ ThinkingSphinx::Excerpter.should_receive(:new).with(@search, @alpha_b)
790
+
985
791
  @search.first
986
792
  end
987
793
  end
988
-
794
+
989
795
  describe '#sphinx_attributes' do
990
796
  before :each do
991
797
  @search = ThinkingSphinx::Search.new
992
798
  end
993
-
799
+
994
800
  it "should add sphinx_attributes method if objects don't already have one" do
995
801
  @search.last.should respond_to(:sphinx_attributes)
996
802
  end
997
-
803
+
998
804
  it "should return a hash" do
999
805
  @search.last.sphinx_attributes.should be_a(Hash)
1000
806
  end
1001
-
807
+
1002
808
  it "should not add sphinx_attributes if objects have a method of that name already" do
1003
809
  @search.first.sphinx_attributes.should_not be_a(Hash)
1004
810
  end
1005
-
811
+
1006
812
  it "should pair sphinx_attributes with the correct hash" do
1007
813
  hash = @search.last.sphinx_attributes
1008
814
  hash['sphinx_internal_id'].should == @search.last.id
1009
815
  hash['class_crc'].should == @search.last.class.to_crc32
1010
816
  end
1011
817
  end
1012
-
818
+
1013
819
  describe '#matching_fields' do
1014
820
  it "should add matching_fields method if using fieldmask ranking mode" do
1015
821
  search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
1016
822
  search.first.should respond_to(:matching_fields)
1017
823
  end
1018
-
824
+
825
+ it "should not add matching_fields method if using a different ranking mode" do
826
+ search = ThinkingSphinx::Search.new :rank_mode => :bm25
827
+ search.first.should_not respond_to(:matching_fields)
828
+ end
829
+
1019
830
  it "should not add matching_fields method if object already have one" do
1020
831
  search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
1021
832
  search.last.matching_fields.should_not be_an(Array)
1022
833
  end
1023
-
834
+
1024
835
  it "should return an array" do
1025
836
  search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
1026
837
  search.first.matching_fields.should be_an(Array)
1027
838
  end
1028
-
839
+
1029
840
  it "should return the fields that the bitmask match" do
1030
841
  search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
1031
842
  search.first.matching_fields.should == ['one', 'three', 'five']
1032
843
  end
1033
844
  end
1034
845
  end
1035
-
1036
- context 'Sphinx errors' do
1037
- describe '#error?' do
1038
- before :each do
1039
- @client.stub! :query => {
1040
- :error => @warning = "Not good"
1041
- }
1042
- # @search.should_receive(:error).and_return(nil)
1043
- end
1044
- it "should raise an error" do
1045
- lambda{
1046
- ThinkingSphinx::Search.new.first
1047
- }.should raise_error(ThinkingSphinx::SphinxError)
1048
- end
1049
- it "should not raise an error when ignore_errors is true" do
1050
- lambda{
1051
- ThinkingSphinx::Search.new(:ignore_errors => true).first
1052
- }.should_not raise_error(ThinkingSphinx::SphinxError)
1053
- end
1054
- end
1055
- end
1056
846
  end
1057
-
847
+
1058
848
  describe '#current_page' do
1059
849
  it "should return 1 by default" do
1060
850
  ThinkingSphinx::Search.new.current_page.should == 1
1061
851
  end
1062
-
852
+
1063
853
  it "should handle string page values" do
1064
854
  ThinkingSphinx::Search.new(:page => '2').current_page.should == 2
1065
855
  end
1066
-
856
+
1067
857
  it "should handle empty string page values" do
1068
858
  ThinkingSphinx::Search.new(:page => '').current_page.should == 1
1069
859
  end
1070
-
860
+
1071
861
  it "should return the requested page" do
1072
862
  ThinkingSphinx::Search.new(:page => 10).current_page.should == 10
1073
863
  end
1074
864
  end
1075
-
865
+
1076
866
  describe '#per_page' do
1077
867
  it "should return 20 by default" do
1078
868
  ThinkingSphinx::Search.new.per_page.should == 20
1079
869
  end
1080
-
870
+
1081
871
  it "should allow for custom values" do
1082
872
  ThinkingSphinx::Search.new(:per_page => 30).per_page.should == 30
1083
873
  end
1084
-
874
+
1085
875
  it "should prioritise :limit over :per_page if given" do
1086
876
  ThinkingSphinx::Search.new(
1087
877
  :per_page => 30, :limit => 40
1088
878
  ).per_page.should == 40
1089
879
  end
1090
-
880
+
1091
881
  it "should allow for string arguments" do
1092
882
  ThinkingSphinx::Search.new(:per_page => '10').per_page.should == 10
1093
883
  end
1094
884
  end
1095
-
885
+
1096
886
  describe '#total_pages' do
1097
887
  it "should calculate the total pages depending on per_page and total_entries" do
1098
888
  ThinkingSphinx::Search.new.total_pages.should == 3
1099
889
  end
1100
-
890
+
1101
891
  it "should allow for custom per_page values" do
1102
892
  ThinkingSphinx::Search.new(:per_page => 30).total_pages.should == 2
1103
893
  end
1104
-
894
+
1105
895
  it "should not overstep the max_matches implied limit" do
1106
896
  @client.stub!(:query => {
1107
897
  :matches => [], :total_found => 41, :total => 40
1108
898
  })
1109
-
899
+
1110
900
  ThinkingSphinx::Search.new.total_pages.should == 2
1111
901
  end
1112
-
902
+
1113
903
  it "should return 0 if there is no index and therefore no results" do
1114
904
  @client.stub!(:query => {
1115
905
  :matches => [], :total_found => nil, :total => nil
1116
906
  })
1117
-
907
+
1118
908
  ThinkingSphinx::Search.new.total_pages.should == 0
1119
909
  end
1120
910
  end
1121
-
911
+
1122
912
  describe '#next_page' do
1123
913
  it "should return one more than the current page" do
1124
914
  ThinkingSphinx::Search.new.next_page.should == 2
1125
915
  end
1126
-
916
+
1127
917
  it "should return nil if on the last page" do
1128
918
  ThinkingSphinx::Search.new(:page => 3).next_page.should be_nil
1129
919
  end
1130
920
  end
1131
-
921
+
1132
922
  describe '#previous_page' do
1133
923
  it "should return one less than the current page" do
1134
924
  ThinkingSphinx::Search.new(:page => 2).previous_page.should == 1
1135
925
  end
1136
-
926
+
1137
927
  it "should return nil if on the first page" do
1138
928
  ThinkingSphinx::Search.new.previous_page.should be_nil
1139
929
  end
1140
930
  end
1141
-
931
+
1142
932
  describe '#total_entries' do
1143
933
  it "should return the total number of results, not just the amount on the page" do
1144
934
  ThinkingSphinx::Search.new.total_entries.should == 41
1145
935
  end
1146
-
936
+
1147
937
  it "should return 0 if there is no index and therefore no results" do
1148
938
  @client.stub!(:query => {
1149
939
  :matches => [], :total_found => nil
1150
940
  })
1151
-
941
+
1152
942
  ThinkingSphinx::Search.new.total_entries.should == 0
1153
943
  end
1154
944
  end
1155
-
945
+
1156
946
  describe '#offset' do
1157
947
  it "should default to 0" do
1158
948
  ThinkingSphinx::Search.new.offset.should == 0
1159
949
  end
1160
-
950
+
1161
951
  it "should increase by the per_page value for each page in" do
1162
952
  ThinkingSphinx::Search.new(:per_page => 25, :page => 2).offset.should == 25
1163
953
  end
@@ -1166,47 +956,46 @@ describe ThinkingSphinx::Search do
1166
956
  ThinkingSphinx::Search.new(:offset => 5).offset.should == 5
1167
957
  end
1168
958
  end
1169
-
959
+
1170
960
  describe '#indexes' do
1171
961
  it "should default to '*'" do
1172
962
  ThinkingSphinx::Search.new.indexes.should == '*'
1173
963
  end
1174
-
964
+
1175
965
  it "should use given class to determine index name" do
1176
966
  ThinkingSphinx::Search.new(:classes => [Alpha]).indexes.
1177
967
  should == 'alpha_core'
1178
968
  end
1179
-
969
+
1180
970
  it "should add both core and delta indexes for given classes" do
1181
971
  ThinkingSphinx::Search.new(:classes => [Alpha, Beta]).indexes.
1182
972
  should == 'alpha_core,beta_core,beta_delta'
1183
973
  end
1184
-
974
+
1185
975
  it "should respect the :index option" do
1186
976
  ThinkingSphinx::Search.new(:classes => [Alpha], :index => '*').indexes.
1187
977
  should == '*'
1188
978
  end
1189
979
  end
1190
-
980
+
1191
981
  describe '.each_with_groupby_and_count' do
1192
982
  before :each do
1193
983
  @alpha = Alpha.new
1194
984
  @alpha.stub!(:id => 1, :read_attribute => 1)
1195
-
985
+
1196
986
  @client.stub! :query => {
1197
987
  :matches => [{
1198
988
  :attributes => {
1199
- 'sphinx_internal_id' => @alpha.id,
1200
- 'sphinx_internal_class' => 'Alpha',
1201
- 'class_crc' => Alpha.to_crc32,
1202
- '@groupby' => 101,
1203
- '@count' => 5
989
+ 'sphinx_internal_id' => @alpha.id,
990
+ 'class_crc' => Alpha.to_crc32,
991
+ '@groupby' => 101,
992
+ '@count' => 5
1204
993
  }
1205
994
  }]
1206
995
  }
1207
996
  Alpha.stub!(:find => [@alpha])
1208
997
  end
1209
-
998
+
1210
999
  it "should yield the match, group and count" do
1211
1000
  search = ThinkingSphinx::Search.new
1212
1001
  search.each_with_groupby_and_count do |obj, group, count|
@@ -1215,7 +1004,7 @@ describe ThinkingSphinx::Search do
1215
1004
  count.should == 5
1216
1005
  end
1217
1006
  end
1218
-
1007
+
1219
1008
  it "should be aliased to each_with_group_and_count" do
1220
1009
  search = ThinkingSphinx::Search.new
1221
1010
  search.each_with_group_and_count do |obj, group, count|
@@ -1225,24 +1014,23 @@ describe ThinkingSphinx::Search do
1225
1014
  end
1226
1015
  end
1227
1016
  end
1228
-
1017
+
1229
1018
  describe '.each_with_weighting' do
1230
1019
  before :each do
1231
1020
  @alpha = Alpha.new
1232
1021
  @alpha.stub!(:id => 1, :read_attribute => 1)
1233
-
1022
+
1234
1023
  @client.stub! :query => {
1235
1024
  :matches => [{
1236
1025
  :attributes => {
1237
- 'sphinx_internal_id' => @alpha.id,
1238
- 'sphinx_internal_class' => 'Alpha',
1239
- 'class_crc' => Alpha.to_crc32
1026
+ 'sphinx_internal_id' => @alpha.id,
1027
+ 'class_crc' => Alpha.to_crc32
1240
1028
  }, :weight => 12
1241
1029
  }]
1242
1030
  }
1243
1031
  Alpha.stub!(:find => [@alpha])
1244
1032
  end
1245
-
1033
+
1246
1034
  it "should yield the match and weight" do
1247
1035
  search = ThinkingSphinx::Search.new
1248
1036
  search.each_with_weighting do |obj, weight|
@@ -1251,50 +1039,49 @@ describe ThinkingSphinx::Search do
1251
1039
  end
1252
1040
  end
1253
1041
  end
1254
-
1042
+
1255
1043
  describe '.each_with_*' do
1256
1044
  before :each do
1257
1045
  @alpha = Alpha.new
1258
1046
  @alpha.stub!(:id => 1, :read_attribute => 1)
1259
-
1047
+
1260
1048
  @client.stub! :query => {
1261
1049
  :matches => [{
1262
1050
  :attributes => {
1263
- 'sphinx_internal_id' => @alpha.id,
1264
- 'sphinx_internal_class' => 'Alpha',
1265
- 'class_crc' => Alpha.to_crc32,
1266
- '@geodist' => 101,
1267
- '@groupby' => 102,
1268
- '@count' => 103
1051
+ 'sphinx_internal_id' => @alpha.id,
1052
+ 'class_crc' => Alpha.to_crc32,
1053
+ '@geodist' => 101,
1054
+ '@groupby' => 102,
1055
+ '@count' => 103
1269
1056
  }, :weight => 12
1270
1057
  }]
1271
1058
  }
1272
1059
  Alpha.stub!(:find => [@alpha])
1273
-
1060
+
1274
1061
  @search = ThinkingSphinx::Search.new
1275
1062
  end
1276
-
1063
+
1277
1064
  it "should yield geodist if requested" do
1278
1065
  @search.each_with_geodist do |obj, distance|
1279
1066
  obj.should == @alpha
1280
1067
  distance.should == 101
1281
1068
  end
1282
1069
  end
1283
-
1070
+
1284
1071
  it "should yield count if requested" do
1285
1072
  @search.each_with_count do |obj, count|
1286
1073
  obj.should == @alpha
1287
1074
  count.should == 103
1288
1075
  end
1289
1076
  end
1290
-
1077
+
1291
1078
  it "should yield groupby if requested" do
1292
1079
  @search.each_with_groupby do |obj, group|
1293
1080
  obj.should == @alpha
1294
1081
  group.should == 102
1295
1082
  end
1296
1083
  end
1297
-
1084
+
1298
1085
  it "should still use the array's each_with_index" do
1299
1086
  @search.each_with_index do |obj, index|
1300
1087
  obj.should == @alpha
@@ -1302,7 +1089,7 @@ describe ThinkingSphinx::Search do
1302
1089
  end
1303
1090
  end
1304
1091
  end
1305
-
1092
+
1306
1093
  describe '#excerpt_for' do
1307
1094
  before :each do
1308
1095
  @client.stub!(:excerpts => ['excerpted string'])
@@ -1310,55 +1097,46 @@ describe ThinkingSphinx::Search do
1310
1097
  :matches => [],
1311
1098
  :words => {'one' => {}, 'two' => {}}
1312
1099
  })
1313
- @search = ThinkingSphinx::Search.new('reading comprehension', :classes => [Alpha])
1100
+ @search = ThinkingSphinx::Search.new(:classes => [Alpha])
1314
1101
  end
1315
-
1102
+
1316
1103
  it "should return the Sphinx excerpt value" do
1317
1104
  @search.excerpt_for('string').should == 'excerpted string'
1318
1105
  end
1319
-
1106
+
1320
1107
  it "should use the given model's core index" do
1321
1108
  @client.should_receive(:excerpts) do |options|
1322
1109
  options[:index].should == 'alpha_core'
1323
1110
  end
1324
-
1325
- @search.excerpt_for('string')
1326
- end
1327
-
1328
- it "should respect the provided index option" do
1329
- @search = ThinkingSphinx::Search.new(:classes => [Alpha], :index => 'foo')
1330
- @client.should_receive(:excerpts) do |options|
1331
- options[:index].should == 'foo'
1332
- end
1333
-
1111
+
1334
1112
  @search.excerpt_for('string')
1335
1113
  end
1336
-
1114
+
1337
1115
  it "should optionally take a second argument to allow for multi-model searches" do
1338
1116
  @client.should_receive(:excerpts) do |options|
1339
1117
  options[:index].should == 'beta_core'
1340
1118
  end
1341
-
1119
+
1342
1120
  @search.excerpt_for('string', Beta)
1343
1121
  end
1344
-
1345
- it "should use the query string" do
1122
+
1123
+ it "should join the words together" do
1346
1124
  @client.should_receive(:excerpts) do |options|
1347
- options[:words].should == 'reading comprehension'
1125
+ options[:words].should == @search.results[:words].keys.join(' ')
1348
1126
  end
1349
-
1127
+
1350
1128
  @search.excerpt_for('string', Beta)
1351
1129
  end
1352
-
1130
+
1353
1131
  it "should use the correct index in STI situations" do
1354
1132
  @client.should_receive(:excerpts) do |options|
1355
1133
  options[:index].should == 'person_core'
1356
1134
  end
1357
-
1135
+
1358
1136
  @search.excerpt_for('string', Parent)
1359
1137
  end
1360
1138
  end
1361
-
1139
+
1362
1140
  describe '#search' do
1363
1141
  before :each do
1364
1142
  @search = ThinkingSphinx::Search.new('word',
@@ -1366,31 +1144,31 @@ describe ThinkingSphinx::Search do
1366
1144
  :with => {:int => 5}
1367
1145
  )
1368
1146
  end
1369
-
1147
+
1370
1148
  it "should return itself" do
1371
1149
  @search.search.object_id.should == @search.object_id
1372
1150
  end
1373
-
1151
+
1374
1152
  it "should merge in arguments" do
1375
1153
  @client.should_receive(:query) do |query, index, comments|
1376
1154
  query.should == 'word more @field field'
1377
1155
  end
1378
-
1156
+
1379
1157
  @search.search('more').first
1380
1158
  end
1381
-
1159
+
1382
1160
  it "should merge conditions" do
1383
1161
  @client.should_receive(:query) do |query, index, comments|
1384
1162
  query.should match(/@name plato/)
1385
1163
  query.should match(/@field field/)
1386
1164
  end
1387
-
1165
+
1388
1166
  @search.search(:conditions => {:name => 'plato'}).first
1389
1167
  end
1390
-
1168
+
1391
1169
  it "should merge filters" do
1392
1170
  @search.search(:with => {:float => 1.5}).first
1393
-
1171
+
1394
1172
  @client.filters.detect { |filter|
1395
1173
  filter.attribute == 'float'
1396
1174
  }.should_not be_nil
@@ -1399,22 +1177,22 @@ describe ThinkingSphinx::Search do
1399
1177
  }.should_not be_nil
1400
1178
  end
1401
1179
  end
1402
-
1180
+
1403
1181
  describe '#freeze' do
1404
1182
  before :each do
1405
1183
  @search = ThinkingSphinx::Search.new
1406
1184
  end
1407
-
1185
+
1408
1186
  it "should populate the result set" do
1409
1187
  @search.freeze
1410
1188
  @search.should be_populated
1411
1189
  end
1412
-
1190
+
1413
1191
  it "should freeze the underlying array" do
1414
1192
  @search.freeze
1415
1193
  @search.to_a.should be_frozen
1416
1194
  end
1417
-
1195
+
1418
1196
  it "should return the Search object" do
1419
1197
  @search.freeze.should be_a(ThinkingSphinx::Search)
1420
1198
  end