angelf-thinking-sphinx 1.3.18
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 +170 -0
- data/VERSION +1 -0
- data/features/abstract_inheritance.feature +10 -0
- data/features/alternate_primary_key.feature +27 -0
- data/features/attribute_transformation.feature +22 -0
- data/features/attribute_updates.feature +77 -0
- data/features/deleting_instances.feature +67 -0
- data/features/direct_attributes.feature +11 -0
- data/features/excerpts.feature +13 -0
- data/features/extensible_delta_indexing.feature +9 -0
- data/features/facets.feature +90 -0
- data/features/facets_across_model.feature +29 -0
- data/features/handling_edits.feature +92 -0
- data/features/retry_stale_indexes.feature +24 -0
- data/features/searching_across_models.feature +20 -0
- data/features/searching_by_index.feature +40 -0
- data/features/searching_by_model.feature +175 -0
- data/features/searching_with_find_arguments.feature +56 -0
- data/features/sphinx_detection.feature +25 -0
- data/features/sphinx_scopes.feature +42 -0
- data/features/step_definitions/alpha_steps.rb +16 -0
- data/features/step_definitions/beta_steps.rb +7 -0
- data/features/step_definitions/common_steps.rb +193 -0
- data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
- data/features/step_definitions/facet_steps.rb +96 -0
- data/features/step_definitions/find_arguments_steps.rb +36 -0
- data/features/step_definitions/gamma_steps.rb +15 -0
- data/features/step_definitions/scope_steps.rb +15 -0
- data/features/step_definitions/search_steps.rb +89 -0
- data/features/step_definitions/sphinx_steps.rb +35 -0
- data/features/sti_searching.feature +19 -0
- data/features/support/env.rb +21 -0
- data/features/support/lib/generic_delta_handler.rb +8 -0
- data/features/thinking_sphinx/database.example.yml +3 -0
- data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
- data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
- data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
- data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
- data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
- data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
- data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
- data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
- data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
- data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
- data/features/thinking_sphinx/db/fixtures/posts.rb +6 -0
- data/features/thinking_sphinx/db/fixtures/robots.rb +14 -0
- data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
- data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
- data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
- data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
- data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
- data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
- data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
- data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
- data/features/thinking_sphinx/db/migrations/create_posts.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
- data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
- data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
- data/features/thinking_sphinx/models/alpha.rb +22 -0
- data/features/thinking_sphinx/models/animal.rb +5 -0
- data/features/thinking_sphinx/models/author.rb +3 -0
- data/features/thinking_sphinx/models/beta.rb +8 -0
- data/features/thinking_sphinx/models/box.rb +8 -0
- data/features/thinking_sphinx/models/cat.rb +3 -0
- data/features/thinking_sphinx/models/category.rb +4 -0
- data/features/thinking_sphinx/models/comment.rb +10 -0
- data/features/thinking_sphinx/models/developer.rb +16 -0
- data/features/thinking_sphinx/models/dog.rb +3 -0
- data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
- data/features/thinking_sphinx/models/fox.rb +5 -0
- data/features/thinking_sphinx/models/gamma.rb +5 -0
- data/features/thinking_sphinx/models/genre.rb +3 -0
- data/features/thinking_sphinx/models/medium.rb +5 -0
- data/features/thinking_sphinx/models/music.rb +8 -0
- data/features/thinking_sphinx/models/person.rb +23 -0
- data/features/thinking_sphinx/models/post.rb +21 -0
- data/features/thinking_sphinx/models/robot.rb +12 -0
- data/features/thinking_sphinx/models/tag.rb +3 -0
- data/features/thinking_sphinx/models/tagging.rb +4 -0
- data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
- data/lib/cucumber/thinking_sphinx/internal_world.rb +127 -0
- data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
- data/lib/thinking_sphinx.rb +242 -0
- data/lib/thinking_sphinx/active_record.rb +380 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +50 -0
- data/lib/thinking_sphinx/active_record/delta.rb +61 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +51 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +47 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +58 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +147 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +380 -0
- data/lib/thinking_sphinx/auto_version.rb +22 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/configuration.rb +292 -0
- data/lib/thinking_sphinx/context.rb +74 -0
- data/lib/thinking_sphinx/core/array.rb +7 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +28 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
- data/lib/thinking_sphinx/excerpter.rb +22 -0
- data/lib/thinking_sphinx/facet.rb +125 -0
- data/lib/thinking_sphinx/facet_search.rb +146 -0
- data/lib/thinking_sphinx/field.rb +80 -0
- data/lib/thinking_sphinx/index.rb +157 -0
- data/lib/thinking_sphinx/index/builder.rb +302 -0
- data/lib/thinking_sphinx/index/faux_column.rb +118 -0
- data/lib/thinking_sphinx/join.rb +37 -0
- data/lib/thinking_sphinx/property.rb +168 -0
- data/lib/thinking_sphinx/rails_additions.rb +150 -0
- data/lib/thinking_sphinx/search.rb +785 -0
- data/lib/thinking_sphinx/search_methods.rb +439 -0
- data/lib/thinking_sphinx/source.rb +164 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +130 -0
- data/lib/thinking_sphinx/tasks.rb +121 -0
- data/lib/thinking_sphinx/test.rb +55 -0
- data/rails/init.rb +16 -0
- data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +71 -0
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
- data/spec/thinking_sphinx/active_record_spec.rb +618 -0
- data/spec/thinking_sphinx/association_spec.rb +239 -0
- data/spec/thinking_sphinx/attribute_spec.rb +548 -0
- data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
- data/spec/thinking_sphinx/configuration_spec.rb +271 -0
- data/spec/thinking_sphinx/context_spec.rb +126 -0
- data/spec/thinking_sphinx/core/array_spec.rb +9 -0
- data/spec/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
- data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
- data/spec/thinking_sphinx/facet_spec.rb +333 -0
- data/spec/thinking_sphinx/field_spec.rb +113 -0
- data/spec/thinking_sphinx/index/builder_spec.rb +495 -0
- data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
- data/spec/thinking_sphinx/index_spec.rb +183 -0
- data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
- data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
- data/spec/thinking_sphinx/search_spec.rb +1206 -0
- data/spec/thinking_sphinx/source_spec.rb +243 -0
- data/spec/thinking_sphinx_spec.rb +204 -0
- data/tasks/distribution.rb +46 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +76 -0
- metadata +342 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Field do
|
|
4
|
+
before :each do
|
|
5
|
+
@index = ThinkingSphinx::Index.new(Alpha)
|
|
6
|
+
@source = ThinkingSphinx::Source.new(@index)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#initialize' do
|
|
10
|
+
it 'raises if no columns are provided so that configuration errors are easier to track down' do
|
|
11
|
+
lambda {
|
|
12
|
+
ThinkingSphinx::Field.new(@source, [])
|
|
13
|
+
}.should raise_error(RuntimeError)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do
|
|
17
|
+
lambda {
|
|
18
|
+
ThinkingSphinx::Field.new(@source, [1234])
|
|
19
|
+
}.should raise_error(RuntimeError)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "unique_name method" do
|
|
24
|
+
before :each do
|
|
25
|
+
@field = ThinkingSphinx::Field.new @source, [
|
|
26
|
+
stub('column', :__stack => [], :__name => "col_name")
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should use the alias if there is one" do
|
|
31
|
+
@field.alias = "alias"
|
|
32
|
+
@field.unique_name.should == "alias"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should use the alias if there's multiple columns" do
|
|
36
|
+
@field.columns << stub('column', :__stack => [], :__name => "col_name")
|
|
37
|
+
@field.unique_name.should be_nil
|
|
38
|
+
|
|
39
|
+
@field.alias = "alias"
|
|
40
|
+
@field.unique_name.should == "alias"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should use the column name if there's no alias and just one column" do
|
|
44
|
+
@field.unique_name.should == "col_name"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "prefixes method" do
|
|
49
|
+
it "should default to false" do
|
|
50
|
+
@field = ThinkingSphinx::Field.new(
|
|
51
|
+
@source, [stub('column', :__stack => [])]
|
|
52
|
+
)
|
|
53
|
+
@field.prefixes.should be_false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should be true if the corresponding option is set" do
|
|
57
|
+
@field = ThinkingSphinx::Field.new(
|
|
58
|
+
@source, [stub('column', :__stack => [])], :prefixes => true
|
|
59
|
+
)
|
|
60
|
+
@field.prefixes.should be_true
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "infixes method" do
|
|
65
|
+
it "should default to false" do
|
|
66
|
+
@field = ThinkingSphinx::Field.new(
|
|
67
|
+
@source, [stub('column', :__stack => [])]
|
|
68
|
+
)
|
|
69
|
+
@field.infixes.should be_false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should be true if the corresponding option is set" do
|
|
73
|
+
@field = ThinkingSphinx::Field.new(
|
|
74
|
+
@source, [stub('column', :__stack => [])], :infixes => true
|
|
75
|
+
)
|
|
76
|
+
@field.infixes.should be_true
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "is_many? method" do
|
|
81
|
+
before :each do
|
|
82
|
+
@assoc_a = stub('assoc', :is_many? => true)
|
|
83
|
+
@assoc_b = stub('assoc', :is_many? => true)
|
|
84
|
+
@assoc_c = stub('assoc', :is_many? => true)
|
|
85
|
+
|
|
86
|
+
@field = ThinkingSphinx::Field.new(
|
|
87
|
+
@source, [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
|
|
88
|
+
)
|
|
89
|
+
@field.associations = {
|
|
90
|
+
:a => @assoc_a, :b => @assoc_b, :c => @assoc_c
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should return true if all associations return true to is_many?" do
|
|
95
|
+
@field.send(:is_many?).should be_true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should return true if one association returns true to is_many?" do
|
|
99
|
+
@assoc_b.stub!(:is_many? => false)
|
|
100
|
+
@assoc_c.stub!(:is_many? => false)
|
|
101
|
+
|
|
102
|
+
@field.send(:is_many?).should be_true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should return false if all associations return false to is_many?" do
|
|
106
|
+
@assoc_a.stub!(:is_many? => false)
|
|
107
|
+
@assoc_b.stub!(:is_many? => false)
|
|
108
|
+
@assoc_c.stub!(:is_many? => false)
|
|
109
|
+
|
|
110
|
+
@field.send(:is_many?).should be_false
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ThinkingSphinx::Index::Builder do
|
|
4
|
+
describe ".generate without source scope" do
|
|
5
|
+
before :each do
|
|
6
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
7
|
+
indexes first_name, last_name
|
|
8
|
+
has birthday
|
|
9
|
+
has id, :as => :internal_id
|
|
10
|
+
|
|
11
|
+
set_property :sql_range_step => 1000
|
|
12
|
+
|
|
13
|
+
where "birthday <= NOW()"
|
|
14
|
+
group_by "first_name"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@source = @index.sources.first
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should return an index" do
|
|
21
|
+
@index.should be_a_kind_of(ThinkingSphinx::Index)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should have one source for the index" do
|
|
25
|
+
@index.sources.length.should == 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should have two fields" do
|
|
29
|
+
@source.fields.length.should == 2
|
|
30
|
+
@source.fields[0].unique_name.should == :first_name
|
|
31
|
+
@source.fields[1].unique_name.should == :last_name
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should have two attributes alongside the three internal ones" do
|
|
35
|
+
@source.attributes.length.should == 5
|
|
36
|
+
@source.attributes[3].unique_name.should == :birthday
|
|
37
|
+
@source.attributes[4].unique_name.should == :internal_id
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should have one condition" do
|
|
41
|
+
@source.conditions.length.should == 1
|
|
42
|
+
@source.conditions.first.should == "birthday <= NOW()"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should have one grouping" do
|
|
46
|
+
@source.groupings.length.should == 1
|
|
47
|
+
@source.groupings.first.should == "first_name"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should have one option" do
|
|
51
|
+
@source.options.length.should == 1
|
|
52
|
+
@source.options[:sql_range_step].should == 1000
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe 'aliased field' do
|
|
57
|
+
before :each do
|
|
58
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
59
|
+
indexes first_name, :as => 'name'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@source = @index.sources.first
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should store the alias as a symbol for consistency" do
|
|
66
|
+
@source.fields.last.unique_name.should == :name
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe 'aliased attribute' do
|
|
71
|
+
before :each do
|
|
72
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
73
|
+
indexes first_name
|
|
74
|
+
has :id, :as => 'real_id'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
@source = @index.sources.first
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should store the alias as a symbol for consistency" do
|
|
81
|
+
@source.attributes.last.unique_name.should == :real_id
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "sortable field" do
|
|
86
|
+
before :each do
|
|
87
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
88
|
+
indexes first_name, :sortable => true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
@source = @index.sources.first
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should have one field" do
|
|
95
|
+
@source.fields.length.should == 1
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should have one attribute alongside the three internal ones" do
|
|
99
|
+
@source.attributes.length.should == 4
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should set the attribute name to have the _sort suffix" do
|
|
103
|
+
@source.attributes.last.unique_name.should == :first_name_sort
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should set the attribute column to be the same as the field" do
|
|
107
|
+
@source.attributes.last.columns.length.should == 1
|
|
108
|
+
@source.attributes.last.columns.first.__name.should == :first_name
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe '#join' do
|
|
113
|
+
before :each do
|
|
114
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
115
|
+
indexes first_name
|
|
116
|
+
|
|
117
|
+
join contacts
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
@source = @index.sources.first
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should include the explicit join" do
|
|
124
|
+
@source.joins.length.should == 1
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe "faceted field" do
|
|
129
|
+
before :each do
|
|
130
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
131
|
+
indexes first_name, :facet => true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
@source = @index.sources.first
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
after :each do
|
|
138
|
+
Person.sphinx_facets.delete_at(-1)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should have one field" do
|
|
142
|
+
@source.fields.length.should == 1
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "should have one attribute alongside the three internal ones" do
|
|
146
|
+
@source.attributes.length.should == 4
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "should set the attribute name to have the _facet suffix" do
|
|
150
|
+
@source.attributes.last.unique_name.should == :first_name_facet
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should set the attribute type to integer" do
|
|
154
|
+
@source.attributes.last.type.should == :integer
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should set the attribute column to be the same as the field" do
|
|
158
|
+
@source.attributes.last.columns.length.should == 1
|
|
159
|
+
@source.attributes.last.columns.first.__name.should == :first_name
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
describe "faceted integer attribute" do
|
|
164
|
+
before :each do
|
|
165
|
+
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
|
166
|
+
indexes :name
|
|
167
|
+
has value, :facet => true
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
@source = @index.sources.first
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
after :each do
|
|
174
|
+
Alpha.sphinx_facets.delete_at(-1)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "should have just one attribute alongside the three internal ones" do
|
|
178
|
+
@source.attributes.length.should == 4
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "faceted timestamp attribute" do
|
|
183
|
+
before :each do
|
|
184
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
185
|
+
indexes first_name
|
|
186
|
+
has birthday, :facet => true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
@source = @index.sources.first
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
after :each do
|
|
193
|
+
Person.sphinx_facets.delete_at(-1)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "should have just one attribute alongside the three internal ones" do
|
|
197
|
+
@source.attributes.length.should == 4
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe "faceted boolean attribute" do
|
|
202
|
+
before :each do
|
|
203
|
+
@index = ThinkingSphinx::Index::Builder.generate(Beta) do
|
|
204
|
+
indexes :name
|
|
205
|
+
has delta, :facet => true
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@source = @index.sources.first
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
after :each do
|
|
212
|
+
Beta.sphinx_facets.delete_at(-1)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "should have just one attribute alongside the three internal ones" do
|
|
216
|
+
@source.attributes.length.should == 4
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "faceted float attribute" do
|
|
221
|
+
before :each do
|
|
222
|
+
@index = ThinkingSphinx::Index::Builder.generate(Alpha) do
|
|
223
|
+
indexes :name
|
|
224
|
+
has cost, :facet => true
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
@source = @index.sources.first
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
after :each do
|
|
231
|
+
Alpha.sphinx_facets.delete_at(-1)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "should have just one attribute alongside the three internal ones" do
|
|
235
|
+
@source.attributes.length.should == 4
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
describe "faceted string attribute" do
|
|
240
|
+
before :each do
|
|
241
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
242
|
+
indexes first_name
|
|
243
|
+
has last_name, :facet => true
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
@source = @index.sources.first
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
after :each do
|
|
250
|
+
Person.sphinx_facets.delete_at(-1)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "should have two attributes alongside the three internal ones" do
|
|
254
|
+
@source.attributes.length.should == 5
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it "should set the facet attribute name to have the _facet suffix" do
|
|
258
|
+
@source.attributes.last.unique_name.should == :last_name_facet
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it "should set the attribute type to integer" do
|
|
262
|
+
@source.attributes.last.type.should == :integer
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "should set the attribute column to be the same as the field" do
|
|
266
|
+
@source.attributes.last.columns.length.should == 1
|
|
267
|
+
@source.attributes.last.columns.first.__name.should == :last_name
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
describe 'faceted manual MVA' do
|
|
272
|
+
before :each do
|
|
273
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
274
|
+
indexes first_name
|
|
275
|
+
has 'SQL STATEMENT', :type => :multi, :as => :sql, :facet => true
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
@source = @index.sources.first
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
after :each do
|
|
282
|
+
Person.sphinx_facets.delete_at(-1)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "should have two attributes alongside the three internal ones" do
|
|
286
|
+
@source.attributes.length.should == 5
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it "should set the facet attribute name to have the _facet suffix" do
|
|
290
|
+
@source.attributes.last.unique_name.should == :sql_facet
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "should keep the original attribute's name set as requested" do
|
|
294
|
+
@source.attributes[-2].unique_name.should == :sql
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "should set the attribute type to multi" do
|
|
298
|
+
@source.attributes.last.type.should == :multi
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "should set the attribute column to be the same as the field" do
|
|
302
|
+
@source.attributes.last.columns.length.should == 1
|
|
303
|
+
@source.attributes.last.columns.first.__name.should == 'SQL STATEMENT'
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe 'faceted MVA field' do
|
|
308
|
+
before :each do
|
|
309
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
310
|
+
indexes tags(:name), :as => :tags, :facet => true
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
@source = @index.sources.first
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
after :each do
|
|
317
|
+
Person.sphinx_facets.delete_at(-1)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it "should have one field" do
|
|
321
|
+
@source.fields.length.should == 1
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "should have one attribute alongside the three internal ones" do
|
|
325
|
+
@source.attributes.length.should == 4
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
it "should set the attribute name to have the _facet suffix" do
|
|
329
|
+
@source.attributes.last.unique_name.should == :tags_facet
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it "should set the attribute type to multi" do
|
|
333
|
+
@source.attributes.last.type.should == :multi
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "should set the attribute column to be the same as the field" do
|
|
337
|
+
@source.attributes.last.columns.length.should == 1
|
|
338
|
+
@source.attributes.last.columns.first.__name.should == :name
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe "no fields" do
|
|
343
|
+
it "should raise an exception" do
|
|
344
|
+
lambda {
|
|
345
|
+
ThinkingSphinx::Index::Builder.generate(Person) do
|
|
346
|
+
#
|
|
347
|
+
end
|
|
348
|
+
}.should raise_error
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
describe "explicit source" do
|
|
353
|
+
before :each do
|
|
354
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
355
|
+
define_source do
|
|
356
|
+
indexes first_name, last_name
|
|
357
|
+
has birthday
|
|
358
|
+
has id, :as => :internal_id
|
|
359
|
+
|
|
360
|
+
set_property :delta => true
|
|
361
|
+
|
|
362
|
+
where "birthday <= NOW()"
|
|
363
|
+
group_by "first_name"
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
@source = @index.sources.first
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it "should return an index" do
|
|
371
|
+
@index.should be_a_kind_of(ThinkingSphinx::Index)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "should have one source for the index" do
|
|
375
|
+
@index.sources.length.should == 1
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "should have two fields" do
|
|
379
|
+
@source.fields.length.should == 2
|
|
380
|
+
@source.fields[0].unique_name.should == :first_name
|
|
381
|
+
@source.fields[1].unique_name.should == :last_name
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it "should have two attributes alongside the three internal ones" do
|
|
385
|
+
@source.attributes.length.should == 5
|
|
386
|
+
@source.attributes[3].unique_name.should == :birthday
|
|
387
|
+
@source.attributes[4].unique_name.should == :internal_id
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
describe "multiple sources" do
|
|
392
|
+
before :each do
|
|
393
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
394
|
+
define_source do
|
|
395
|
+
indexes first_name
|
|
396
|
+
has birthday
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
define_source do
|
|
400
|
+
indexes last_name
|
|
401
|
+
has :id, :as => :internal_id
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
it "should have two sources" do
|
|
407
|
+
@index.sources.length.should == 2
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it "should have two fields" do
|
|
411
|
+
@index.fields.length.should == 2
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
it "should have one field in each source" do
|
|
415
|
+
@index.sources.each do |source|
|
|
416
|
+
source.fields.length.should == 1
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
it "should have two attributes alongside the six internal ones" do
|
|
421
|
+
@index.attributes.length.should == 8
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
it "should have one attribute in each source alongside the three internal ones" do
|
|
425
|
+
@index.sources.each do |source|
|
|
426
|
+
source.attributes.length.should == 4
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
describe "index options" do
|
|
432
|
+
before :each do
|
|
433
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
434
|
+
indexes first_name
|
|
435
|
+
|
|
436
|
+
set_property :charset_type => "utf16"
|
|
437
|
+
set_property :group_concat_max_len => 1024
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
it "should store the index setting for the index" do
|
|
442
|
+
@index.local_options[:charset_type].should == "utf16"
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
it "should store non-Sphinx settings for the index" do
|
|
446
|
+
@index.local_options[:group_concat_max_len].should == 1024
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
describe "delta options" do
|
|
451
|
+
before :each do
|
|
452
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
453
|
+
indexes first_name
|
|
454
|
+
|
|
455
|
+
set_property :delta => true
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it "should not keep the delta setting in source options" do
|
|
460
|
+
@index.sources.first.options.should be_empty
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
it "should not keep the delta setting in index options" do
|
|
464
|
+
@index.local_options.should be_empty
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it "should set the index delta object set" do
|
|
468
|
+
@index.delta_object.should be_a_kind_of(ThinkingSphinx::Deltas::DefaultDelta)
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
context 'index options' do
|
|
473
|
+
before :each do
|
|
474
|
+
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
|
475
|
+
indexes first_name
|
|
476
|
+
|
|
477
|
+
set_property :index_exact_words => true
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
it "should track the index_exact_words option to the index" do
|
|
482
|
+
@index.local_options[:index_exact_words].should be_true
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
context 'with an explicit name' do
|
|
487
|
+
it "should set the index's name using the provided value" do
|
|
488
|
+
index = ThinkingSphinx::Index::Builder.generate(Person, 'custom') do
|
|
489
|
+
indexes first_name
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
index.name.should == 'custom'
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
end
|