initforthe-thinking-sphinx 1.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENCE +20 -0
- data/README.textile +141 -0
- data/lib/thinking_sphinx.rb +215 -0
- data/lib/thinking_sphinx/active_record.rb +278 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
- data/lib/thinking_sphinx/active_record/delta.rb +87 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
- data/lib/thinking_sphinx/active_record/search.rb +57 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +135 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +268 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/collection.rb +148 -0
- data/lib/thinking_sphinx/configuration.rb +262 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +30 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +82 -0
- data/lib/thinking_sphinx/facet.rb +108 -0
- data/lib/thinking_sphinx/facet_collection.rb +59 -0
- data/lib/thinking_sphinx/field.rb +82 -0
- data/lib/thinking_sphinx/index.rb +99 -0
- data/lib/thinking_sphinx/index/builder.rb +287 -0
- data/lib/thinking_sphinx/index/faux_column.rb +110 -0
- data/lib/thinking_sphinx/property.rb +160 -0
- data/lib/thinking_sphinx/rails_additions.rb +136 -0
- data/lib/thinking_sphinx/search.rb +727 -0
- data/lib/thinking_sphinx/search/facets.rb +104 -0
- data/lib/thinking_sphinx/source.rb +150 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +126 -0
- data/lib/thinking_sphinx/tasks.rb +162 -0
- data/rails/init.rb +14 -0
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +136 -0
- data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
- data/spec/unit/thinking_sphinx/active_record/search_spec.rb +107 -0
- data/spec/unit/thinking_sphinx/active_record_spec.rb +329 -0
- data/spec/unit/thinking_sphinx/association_spec.rb +246 -0
- data/spec/unit/thinking_sphinx/attribute_spec.rb +338 -0
- data/spec/unit/thinking_sphinx/collection_spec.rb +15 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +222 -0
- data/spec/unit/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/unit/thinking_sphinx/facet_collection_spec.rb +64 -0
- data/spec/unit/thinking_sphinx/facet_spec.rb +302 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +154 -0
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +355 -0
- data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +30 -0
- data/spec/unit/thinking_sphinx/index_spec.rb +45 -0
- data/spec/unit/thinking_sphinx/rails_additions_spec.rb +191 -0
- data/spec/unit/thinking_sphinx/search_spec.rb +228 -0
- data/spec/unit/thinking_sphinx/source_spec.rb +217 -0
- data/spec/unit/thinking_sphinx_spec.rb +151 -0
- data/tasks/distribution.rb +67 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +78 -0
- data/vendor/after_commit/LICENSE +20 -0
- data/vendor/after_commit/README +16 -0
- data/vendor/after_commit/Rakefile +22 -0
- data/vendor/after_commit/init.rb +8 -0
- data/vendor/after_commit/lib/after_commit.rb +45 -0
- data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
- data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
- data/vendor/after_commit/test/after_commit_test.rb +53 -0
- data/vendor/delayed_job/lib/delayed/job.rb +251 -0
- data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
- data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
- data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
- data/vendor/riddle/lib/riddle.rb +30 -0
- data/vendor/riddle/lib/riddle/client.rb +619 -0
- data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
- data/vendor/riddle/lib/riddle/client/message.rb +65 -0
- data/vendor/riddle/lib/riddle/client/response.rb +84 -0
- data/vendor/riddle/lib/riddle/configuration.rb +33 -0
- data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
- data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
- data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
- data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
- data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
- data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
- data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
- data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
- data/vendor/riddle/lib/riddle/controller.rb +44 -0
- metadata +190 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Collection do
|
|
4
|
+
it "should behave like WillPaginate::Collection" do
|
|
5
|
+
instance_methods = ThinkingSphinx::Collection.instance_methods.collect { |m| m.to_s }
|
|
6
|
+
instance_methods.should include("previous_page")
|
|
7
|
+
instance_methods.should include("next_page")
|
|
8
|
+
instance_methods.should include("current_page")
|
|
9
|
+
instance_methods.should include("total_pages")
|
|
10
|
+
instance_methods.should include("total_entries")
|
|
11
|
+
instance_methods.should include("offset")
|
|
12
|
+
|
|
13
|
+
ThinkingSphinx::Collection.ancestors.should include(Array)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Configuration do
|
|
4
|
+
describe "environment class method" do
|
|
5
|
+
before :each do
|
|
6
|
+
ThinkingSphinx::Configuration.send(:class_variable_set, :@@environment, nil)
|
|
7
|
+
|
|
8
|
+
ENV["RAILS_ENV"] = nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should use the Merb environment value if set" do
|
|
12
|
+
unless defined?(Merb)
|
|
13
|
+
module ::Merb; end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ThinkingSphinx::Configuration.stub_method(:defined? => true)
|
|
17
|
+
Merb.stub!(:environment => "merb_production")
|
|
18
|
+
ThinkingSphinx::Configuration.environment.should == "merb_production"
|
|
19
|
+
|
|
20
|
+
Object.send(:remove_const, :Merb)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should use the Rails environment value if set" do
|
|
24
|
+
ENV["RAILS_ENV"] = "rails_production"
|
|
25
|
+
ThinkingSphinx::Configuration.environment.should == "rails_production"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should default to development" do
|
|
29
|
+
ThinkingSphinx::Configuration.environment.should == "development"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "parse_config method" do
|
|
34
|
+
before :each do
|
|
35
|
+
@settings = {
|
|
36
|
+
"development" => {
|
|
37
|
+
"config_file" => "tmp/config/development.sphinx.conf",
|
|
38
|
+
"searchd_log_file" => "searchd_log_file.log",
|
|
39
|
+
"query_log_file" => "query_log_file.log",
|
|
40
|
+
"pid_file" => "pid_file.pid",
|
|
41
|
+
"searchd_file_path" => "searchd/file/path",
|
|
42
|
+
"address" => "127.0.0.1",
|
|
43
|
+
"port" => 3333,
|
|
44
|
+
"min_prefix_len" => 2,
|
|
45
|
+
"min_infix_len" => 3,
|
|
46
|
+
"mem_limit" => "128M",
|
|
47
|
+
"max_matches" => 1001,
|
|
48
|
+
"morphology" => "stem_ru",
|
|
49
|
+
"charset_type" => "latin1",
|
|
50
|
+
"charset_table" => "table",
|
|
51
|
+
"ignore_chars" => "e",
|
|
52
|
+
"searchd_binary_name" => "searchd",
|
|
53
|
+
"indexer_binary_name" => "indexer"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
|
|
58
|
+
f.write YAML.dump(@settings)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should use the accessors to set the configuration values" do
|
|
63
|
+
config = ThinkingSphinx::Configuration.instance
|
|
64
|
+
config.send(:parse_config)
|
|
65
|
+
|
|
66
|
+
%w(config_file searchd_log_file query_log_file pid_file searchd_file_path
|
|
67
|
+
address port searchd_binary_name indexer_binary_name).each do |key|
|
|
68
|
+
config.send(key).should == @settings["development"][key]
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
after :each do
|
|
73
|
+
FileUtils.rm "#{RAILS_ROOT}/config/sphinx.yml"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "block configuration" do
|
|
78
|
+
it "should let the user set-up a custom app_root" do
|
|
79
|
+
ThinkingSphinx::Configuration.configure do |config|
|
|
80
|
+
config.app_root = "/here/somewhere"
|
|
81
|
+
end
|
|
82
|
+
ThinkingSphinx::Configuration.instance.app_root.should == "/here/somewhere"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe "initialisation" do
|
|
87
|
+
it "should have a default bin_path of nothing" do
|
|
88
|
+
ThinkingSphinx::Configuration.instance.bin_path.should == ""
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should append a / to bin_path if one is supplied" do
|
|
92
|
+
@settings = {
|
|
93
|
+
"development" => {
|
|
94
|
+
"bin_path" => "path/to/somewhere"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
|
|
99
|
+
f.write YAML.dump(@settings)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
ThinkingSphinx::Configuration.instance.send(:parse_config)
|
|
103
|
+
ThinkingSphinx::Configuration.instance.bin_path.should match(/\/$/)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "index options" do
|
|
108
|
+
before :each do
|
|
109
|
+
@settings = {
|
|
110
|
+
"development" => {"disable_range" => true}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
|
|
114
|
+
f.write YAML.dump(@settings)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
@config = ThinkingSphinx::Configuration.instance
|
|
118
|
+
@config.send(:parse_config)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should collect disable_range" do
|
|
122
|
+
@config.index_options[:disable_range].should be_true
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "#load_models" do
|
|
127
|
+
before :each do
|
|
128
|
+
@config = ThinkingSphinx::Configuration.instance
|
|
129
|
+
@config.model_directories = ['']
|
|
130
|
+
|
|
131
|
+
@file_name = 'a.rb'
|
|
132
|
+
@model_name_lower = 'a'
|
|
133
|
+
@class_name = 'A'
|
|
134
|
+
|
|
135
|
+
@file_name.stub!(:gsub).and_return(@model_name_lower)
|
|
136
|
+
@model_name_lower.stub!(:camelize).and_return(@class_name)
|
|
137
|
+
Dir.stub(:[]).and_return([@file_name])
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should load the files by guessing the file name" do
|
|
141
|
+
@class_name.should_receive(:constantize).and_return(true)
|
|
142
|
+
|
|
143
|
+
@config.load_models
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "should not raise errors if the model name is nil" do
|
|
147
|
+
@file_name.stub!(:gsub).and_return(nil)
|
|
148
|
+
|
|
149
|
+
lambda {
|
|
150
|
+
@config.load_models
|
|
151
|
+
}.should_not raise_error
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "should not raise errors if the file name does not represent a class name" do
|
|
155
|
+
@class_name.should_receive(:constantize).and_raise(NameError)
|
|
156
|
+
|
|
157
|
+
lambda {
|
|
158
|
+
@config.load_models
|
|
159
|
+
}.should_not raise_error
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should retry if the first pass fails and contains a directory" do
|
|
163
|
+
@model_name_lower.stub!(:gsub!).and_return(true, nil)
|
|
164
|
+
@class_name.stub(:constantize).and_raise(LoadError)
|
|
165
|
+
@model_name_lower.should_receive(:camelize).twice
|
|
166
|
+
|
|
167
|
+
lambda {
|
|
168
|
+
@config.load_models
|
|
169
|
+
}.should_not raise_error
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should catch database errors with a warning" do
|
|
173
|
+
@class_name.should_receive(:constantize).and_raise(Mysql::Error)
|
|
174
|
+
@config.should_receive(:puts).with('Warning: Error loading a.rb')
|
|
175
|
+
|
|
176
|
+
lambda {
|
|
177
|
+
@config.load_models
|
|
178
|
+
}.should_not raise_error
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should insert set index options into the configuration file" do
|
|
183
|
+
config = ThinkingSphinx::Configuration.instance
|
|
184
|
+
ThinkingSphinx::Configuration::IndexOptions.each do |option|
|
|
185
|
+
config.index_options[option.to_sym] = "something"
|
|
186
|
+
config.build
|
|
187
|
+
|
|
188
|
+
file = open(config.config_file) { |f| f.read }
|
|
189
|
+
file.should match(/#{option}\s+= something/)
|
|
190
|
+
|
|
191
|
+
config.index_options[option.to_sym] = nil
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should insert set source options into the configuration file" do
|
|
196
|
+
config = ThinkingSphinx::Configuration.instance
|
|
197
|
+
ThinkingSphinx::Configuration::SourceOptions.each do |option|
|
|
198
|
+
config.source_options[option.to_sym] = "something"
|
|
199
|
+
config.build
|
|
200
|
+
|
|
201
|
+
file = open(config.config_file) { |f| f.read }
|
|
202
|
+
file.should match(/#{option}\s+= something/)
|
|
203
|
+
|
|
204
|
+
config.source_options[option.to_sym] = nil
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should set any explicit prefixed or infixed fields" do
|
|
209
|
+
file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
|
|
210
|
+
f.read
|
|
211
|
+
}
|
|
212
|
+
file.should match(/prefix_fields\s+= city/)
|
|
213
|
+
file.should match(/infix_fields\s+= state/)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "should not have prefix fields in indexes where nothing is set" do
|
|
217
|
+
file = open(ThinkingSphinx::Configuration.instance.config_file) { |f|
|
|
218
|
+
f.read
|
|
219
|
+
}
|
|
220
|
+
file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::FacetCollection do
|
|
4
|
+
before do
|
|
5
|
+
@facet_collection = ThinkingSphinx::FacetCollection.new([])
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# TODO fix nasty hack when we have internet!
|
|
9
|
+
def mock_results
|
|
10
|
+
return @results if defined? @results
|
|
11
|
+
@result = Person.find(:first)
|
|
12
|
+
@results = [@result]
|
|
13
|
+
@results.stub!(:each_with_groupby_and_count).and_yield(@result, @result.city.to_crc32, 1)
|
|
14
|
+
@results
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "#add_from_results" do
|
|
18
|
+
describe "with empty result set" do
|
|
19
|
+
before do
|
|
20
|
+
@facet_collection.add_from_results('attribute_facet', [])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should add key as attribute" do
|
|
24
|
+
@facet_collection.should have_key(:attribute)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should return an empty hash for the facet results" do
|
|
28
|
+
@facet_collection[:attribute].should be_empty
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "with non-empty result set" do
|
|
33
|
+
before do
|
|
34
|
+
@facet_collection.add_from_results('city_facet', mock_results)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should return a hash" do
|
|
38
|
+
@facet_collection.should be_a_kind_of(Hash)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should add key as attribute" do
|
|
42
|
+
@facet_collection.keys.should include(:city)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should return a hash" do
|
|
46
|
+
@facet_collection[:city].should == {@result.city => 1}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "#for" do
|
|
52
|
+
before do
|
|
53
|
+
@facet_collection.add_from_results('city_facet', mock_results)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should return the search results for the attribute and key pair" do
|
|
57
|
+
ThinkingSphinx::Search.should_receive(:search) do |options|
|
|
58
|
+
options[:with].should have_key('city_facet')
|
|
59
|
+
options[:with]['city_facet'].should == @result.city.to_crc32
|
|
60
|
+
end
|
|
61
|
+
@facet_collection.for(:city => @result.city)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Facet do
|
|
4
|
+
describe ".name_for" do
|
|
5
|
+
it "should remove '_facet' from provided string and return a symbol" do
|
|
6
|
+
ThinkingSphinx::Facet.name_for('attribute_facet').should == :attribute
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should remove '_facet' from provided symbol" do
|
|
10
|
+
ThinkingSphinx::Facet.name_for(:attribute_facet).should == :attribute
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should return the name of the facet if a Facet is passed" do
|
|
14
|
+
facet = ThinkingSphinx::Facet.new(
|
|
15
|
+
ThinkingSphinx::Attribute.stub_instance(:unique_name => :attribute, :columns => ['attribute'])
|
|
16
|
+
)
|
|
17
|
+
ThinkingSphinx::Facet.name_for(facet).should == :attribute
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should return 'class' for special case name 'class_crc'" do
|
|
21
|
+
ThinkingSphinx::Facet.name_for(:class_crc).should == :class
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should cycle" do
|
|
25
|
+
ThinkingSphinx::Facet.name_for(ThinkingSphinx::Facet.attribute_name_for(:attribute)).should == :attribute
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe ".attribute_name_for" do
|
|
30
|
+
it "should append '_facet' to provided string" do
|
|
31
|
+
ThinkingSphinx::Facet.attribute_name_for('attribute').should == 'attribute_facet'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should append '_facet' to provided symbol and return a string" do
|
|
35
|
+
ThinkingSphinx::Facet.attribute_name_for(:attribute).should == 'attribute_facet'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should return 'class_crc' for special case attribute 'class'" do
|
|
39
|
+
ThinkingSphinx::Facet.attribute_name_for(:class).should == 'class_crc'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should cycle" do
|
|
43
|
+
ThinkingSphinx::Facet.attribute_name_for(ThinkingSphinx::Facet.name_for('attribute_facet')).should == 'attribute_facet'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe ".attribute_name_from_value" do
|
|
48
|
+
it "should append _facet if the value is a string" do
|
|
49
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', 'string').
|
|
50
|
+
should == 'attribute_facet'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should not append _facet if the value isn't a string" do
|
|
54
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', 1).
|
|
55
|
+
should == 'attribute'
|
|
56
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', Time.now).
|
|
57
|
+
should == 'attribute'
|
|
58
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', true).
|
|
59
|
+
should == 'attribute'
|
|
60
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', 1.23).
|
|
61
|
+
should == 'attribute'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should append _facet is the value is an array of strings" do
|
|
65
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', ['a', 'b']).
|
|
66
|
+
should == 'attribute_facet'
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should not append _facet if the value is an array of integers" do
|
|
70
|
+
ThinkingSphinx::Facet.attribute_name_from_value('attribute', [1, 2]).
|
|
71
|
+
should == 'attribute'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe ".translate?" do
|
|
76
|
+
before :each do
|
|
77
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
78
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
79
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
|
80
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should return true if the property is a field" do
|
|
85
|
+
field = ThinkingSphinx::Field.new(
|
|
86
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
ThinkingSphinx::Facet.translate?(field).should be_true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should return true if the property is a string attribute" do
|
|
93
|
+
@attribute.stub_method(:type => :string)
|
|
94
|
+
|
|
95
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should return false if the property is an integer attribute" do
|
|
99
|
+
@attribute.stub_method(:type => :integer)
|
|
100
|
+
|
|
101
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_false
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should return false if the property is a boolean attribute" do
|
|
105
|
+
@attribute.stub_method(:type => :boolean)
|
|
106
|
+
|
|
107
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_false
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should return false if the property is a timestamp attribute" do
|
|
111
|
+
@attribute.stub_method(:type => :datetime)
|
|
112
|
+
|
|
113
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_false
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should return false if the property is a float attribute" do
|
|
117
|
+
@attribute.stub_method(:type => :float)
|
|
118
|
+
|
|
119
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_false
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "should return false if the property is an MVA of integer values" do
|
|
123
|
+
@attribute.stub_method(:type => :multi, :all_ints? => true)
|
|
124
|
+
|
|
125
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_false
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should return true if the property is an MVA of string values" do
|
|
129
|
+
@attribute.stub_method(:type => :multi, :all_ints? => false)
|
|
130
|
+
|
|
131
|
+
ThinkingSphinx::Facet.translate?(@attribute).should be_true
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
describe "#translate?" do
|
|
136
|
+
before :each do
|
|
137
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
138
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
139
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
|
140
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should return true if the property is a field" do
|
|
145
|
+
field = ThinkingSphinx::Field.new(
|
|
146
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
ThinkingSphinx::Facet.new(field).translate?.should be_true
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should return true if the property is a string attribute" do
|
|
153
|
+
@attribute.stub_method(:type => :string)
|
|
154
|
+
|
|
155
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_true
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should return false if the property is an integer attribute" do
|
|
159
|
+
@attribute.stub_method(:type => :integer)
|
|
160
|
+
|
|
161
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "should return false if the property is a boolean attribute" do
|
|
165
|
+
@attribute.stub_method(:type => :boolean)
|
|
166
|
+
|
|
167
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "should return false if the property is a timestamp attribute" do
|
|
171
|
+
@attribute.stub_method(:type => :datetime)
|
|
172
|
+
|
|
173
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "should return false if the property is a float attribute" do
|
|
177
|
+
@attribute.stub_method(:type => :float)
|
|
178
|
+
|
|
179
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should return false if the property is an MVA of integer values" do
|
|
183
|
+
@attribute.stub_method(:type => :multi, :all_ints? => true)
|
|
184
|
+
|
|
185
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_false
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should return true if the property is an MVA of string values" do
|
|
189
|
+
@attribute.stub_method(:type => :multi, :all_ints? => false)
|
|
190
|
+
|
|
191
|
+
ThinkingSphinx::Facet.new(@attribute).translate?.should be_true
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe "#attribute_name" do
|
|
196
|
+
before :each do
|
|
197
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
198
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
199
|
+
@attribute = ThinkingSphinx::Attribute.new(
|
|
200
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
201
|
+
)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should return the attribute name if built off an integer attribute" do
|
|
205
|
+
@attribute.stub_method(:type => :integer)
|
|
206
|
+
|
|
207
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "should return the attribute name if built off a boolean attribute" do
|
|
211
|
+
@attribute.stub_method(:type => :boolean)
|
|
212
|
+
|
|
213
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "should return the attribute name if built off a float attribute" do
|
|
217
|
+
@attribute.stub_method(:type => :float)
|
|
218
|
+
|
|
219
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "should return the attribute name if built off a timestamp attribute" do
|
|
223
|
+
@attribute.stub_method(:type => :datetime)
|
|
224
|
+
|
|
225
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "should return the attribute name with _facet suffix if built off a string attribute" do
|
|
229
|
+
@attribute.stub_method(:type => :string)
|
|
230
|
+
|
|
231
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name_facet"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "should return the attribute name with _facet suffix if built off a field" do
|
|
235
|
+
field = ThinkingSphinx::Field.new(
|
|
236
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
ThinkingSphinx::Facet.new(field).attribute_name.should == "name_facet"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should return the attribute name if build off an integer MVA" do
|
|
243
|
+
@attribute.stub_method(:type => :multi, :all_ints? => true)
|
|
244
|
+
|
|
245
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name"
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should return the attribute name with the _facet suffix if build off an non-integer MVA" do
|
|
249
|
+
@attribute.stub_method(:type => :multi, :all_ints? => false)
|
|
250
|
+
|
|
251
|
+
ThinkingSphinx::Facet.new(@attribute).attribute_name.should == "name_facet"
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
describe "#type" do
|
|
256
|
+
before :each do
|
|
257
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
258
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it "should return :string if the property is a field" do
|
|
262
|
+
field = ThinkingSphinx::Field.new(
|
|
263
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
ThinkingSphinx::Facet.new(field).type.should == :string
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it "should return the attribute type if the property is an attribute" do
|
|
270
|
+
attribute = ThinkingSphinx::Attribute.new(
|
|
271
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:name)
|
|
272
|
+
)
|
|
273
|
+
attribute.stub_method(:type => :anything)
|
|
274
|
+
|
|
275
|
+
ThinkingSphinx::Facet.new(attribute).type.should == :anything
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
describe "#value" do
|
|
280
|
+
before :each do
|
|
281
|
+
@index = ThinkingSphinx::Index.new(Friendship)
|
|
282
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
283
|
+
@field = ThinkingSphinx::Field.new(
|
|
284
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:person, :first_name)
|
|
285
|
+
)
|
|
286
|
+
@facet = ThinkingSphinx::Facet.new(@field)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it "should return association values" do
|
|
290
|
+
person = Person.find(:first)
|
|
291
|
+
friendship = Friendship.new(:person => person)
|
|
292
|
+
|
|
293
|
+
@facet.value(friendship, 1).should == person.first_name
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "should return nil if the association is nil" do
|
|
297
|
+
friendship = Friendship.new(:person => nil)
|
|
298
|
+
|
|
299
|
+
@facet.value(friendship, 1).should be_nil
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|