sunspot 2.2.7 → 2.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Appraisals +7 -0
- data/Gemfile +0 -8
- data/gemfiles/.gitkeep +0 -0
- data/lib/sunspot/dsl/scope.rb +6 -1
- data/lib/sunspot/field.rb +11 -0
- data/lib/sunspot/field_factory.rb +6 -2
- data/lib/sunspot/query/bbox.rb +5 -1
- data/lib/sunspot/query/restriction.rb +11 -0
- data/lib/sunspot/search/hit_enumerable.rb +4 -1
- data/lib/sunspot/search/standard_search.rb +2 -3
- data/lib/sunspot/version.rb +1 -1
- data/spec/api/adapters_spec.rb +19 -19
- data/spec/api/batcher_spec.rb +15 -15
- data/spec/api/binding_spec.rb +3 -3
- data/spec/api/class_set_spec.rb +3 -3
- data/spec/api/hit_enumerable_spec.rb +32 -9
- data/spec/api/indexer/attributes_spec.rb +31 -31
- data/spec/api/indexer/batch_spec.rb +8 -7
- data/spec/api/indexer/dynamic_fields_spec.rb +8 -8
- data/spec/api/indexer/fixed_fields_spec.rb +12 -12
- data/spec/api/indexer/fulltext_spec.rb +8 -8
- data/spec/api/indexer/removal_spec.rb +14 -14
- data/spec/api/indexer_spec.rb +2 -2
- data/spec/api/query/advanced_manipulation_examples.rb +3 -3
- data/spec/api/query/connectives_examples.rb +26 -14
- data/spec/api/query/dsl_spec.rb +17 -9
- data/spec/api/query/dynamic_fields_examples.rb +18 -18
- data/spec/api/query/faceting_examples.rb +62 -62
- data/spec/api/query/fulltext_examples.rb +56 -55
- data/spec/api/query/function_spec.rb +26 -26
- data/spec/api/query/geo_examples.rb +6 -6
- data/spec/api/query/group_spec.rb +6 -6
- data/spec/api/query/highlighting_examples.rb +26 -26
- data/spec/api/query/join_spec.rb +2 -2
- data/spec/api/query/more_like_this_spec.rb +29 -29
- data/spec/api/query/ordering_pagination_examples.rb +25 -25
- data/spec/api/query/scope_examples.rb +39 -39
- data/spec/api/query/spatial_examples.rb +3 -3
- data/spec/api/query/spellcheck_examples.rb +3 -3
- data/spec/api/query/standard_spec.rb +1 -1
- data/spec/api/query/stats_examples.rb +8 -8
- data/spec/api/query/text_field_scoping_examples.rb +5 -5
- data/spec/api/query/types_spec.rb +4 -4
- data/spec/api/search/cursor_paginated_collection_spec.rb +12 -12
- data/spec/api/search/dynamic_fields_spec.rb +4 -4
- data/spec/api/search/faceting_spec.rb +55 -52
- data/spec/api/search/highlighting_spec.rb +7 -7
- data/spec/api/search/hits_spec.rb +29 -29
- data/spec/api/search/paginated_collection_spec.rb +18 -18
- data/spec/api/search/results_spec.rb +13 -13
- data/spec/api/search/search_spec.rb +3 -3
- data/spec/api/search/stats_spec.rb +10 -10
- data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +19 -18
- data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +9 -9
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +10 -6
- data/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +10 -10
- data/spec/api/session_proxy/sharding_session_proxy_spec.rb +14 -13
- data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +2 -2
- data/spec/api/session_proxy/spec_helper.rb +1 -1
- data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +9 -5
- data/spec/api/session_spec.rb +42 -42
- data/spec/api/sunspot_spec.rb +4 -4
- data/spec/integration/atomic_updates_spec.rb +25 -11
- data/spec/integration/dynamic_fields_spec.rb +10 -10
- data/spec/integration/faceting_spec.rb +39 -39
- data/spec/integration/field_grouping_spec.rb +16 -16
- data/spec/integration/field_lists_spec.rb +41 -0
- data/spec/integration/geospatial_spec.rb +19 -8
- data/spec/integration/highlighting_spec.rb +5 -5
- data/spec/integration/indexing_spec.rb +5 -5
- data/spec/integration/keyword_search_spec.rb +47 -45
- data/spec/integration/local_search_spec.rb +4 -4
- data/spec/integration/more_like_this_spec.rb +7 -7
- data/spec/integration/scoped_search_spec.rb +107 -107
- data/spec/integration/spellcheck_spec.rb +52 -7
- data/spec/integration/stats_spec.rb +10 -10
- data/spec/integration/stored_fields_spec.rb +1 -1
- data/spec/integration/test_pagination.rb +4 -4
- data/spec/integration/unicode_spec.rb +1 -1
- data/spec/mocks/post.rb +5 -1
- data/spec/spec_helper.rb +11 -6
- data/sunspot.gemspec +3 -1
- metadata +40 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97232f93d9d1c5ce704e6249cd1afcec04f7f231
|
4
|
+
data.tar.gz: 9eb35de3e65284cdec3eb299d6085cc32e662590
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bd0d81960ded04f07fdfa72811ddf959c5c97b0339e58246761469d3f9b4d9a82bf71ec69e8ee222b05ff9c07b5ff406f2702ef1ab8caeacbb1d219415b0044
|
7
|
+
data.tar.gz: b8adf8fc509ea65e460139687084832f8353e81e6ad1fd50f976db0a721545934761894ca42281962b19ce64b179a69b607dd3bb05b735b5fc53603aff0685a5
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/gemfiles/.gitkeep
ADDED
File without changes
|
data/lib/sunspot/dsl/scope.rb
CHANGED
@@ -14,7 +14,12 @@ module Sunspot
|
|
14
14
|
|
15
15
|
# Build a restriction to return only fields of the type in the results.
|
16
16
|
def field_list(*args)
|
17
|
-
@
|
17
|
+
list = args.flatten.map { |field| @setup.field(field.to_sym).indexed_name.to_sym }
|
18
|
+
@query.add_field_list(Sunspot::Query::FieldList.new([:id] + list)) unless list.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def without_stored_fields
|
22
|
+
@query.add_field_list(Sunspot::Query::FieldList.new([:id]))
|
18
23
|
end
|
19
24
|
|
20
25
|
#
|
data/lib/sunspot/field.rb
CHANGED
@@ -93,6 +93,17 @@ module Sunspot
|
|
93
93
|
!!@joined
|
94
94
|
end
|
95
95
|
|
96
|
+
#
|
97
|
+
# Whether the field is stored or not.
|
98
|
+
#
|
99
|
+
# ==== Returns
|
100
|
+
#
|
101
|
+
# Boolean:: True if this field is a stored field
|
102
|
+
#
|
103
|
+
def stored?
|
104
|
+
!!@stored
|
105
|
+
end
|
106
|
+
|
96
107
|
def hash
|
97
108
|
indexed_name.hash
|
98
109
|
end
|
@@ -72,11 +72,15 @@ module Sunspot
|
|
72
72
|
# into the Solr document for indexing.
|
73
73
|
#
|
74
74
|
def populate_document(document, model, options = {}) #:nodoc:
|
75
|
+
atomic_operation = options[:update] == :set
|
75
76
|
value = extract_value(model, options)
|
76
|
-
|
77
|
-
Util.Array(@field.to_indexed(value))
|
77
|
+
if value != nil || atomic_operation
|
78
|
+
indexed_values = Util.Array(@field.to_indexed(value))
|
79
|
+
indexed_values = [nil] if indexed_values.empty? && atomic_operation
|
80
|
+
indexed_values.each do |scalar_value|
|
78
81
|
field_options = {}
|
79
82
|
field_options[:boost] = @field.boost if @field.boost
|
83
|
+
field_options[:null] = true if scalar_value.nil? && atomic_operation
|
80
84
|
document.add_field(
|
81
85
|
@field.indexed_name.to_sym,
|
82
86
|
scalar_value,
|
data/lib/sunspot/query/bbox.rb
CHANGED
@@ -5,8 +5,12 @@ module Sunspot
|
|
5
5
|
@field, @first_corner, @second_corner = field, first_corner, second_corner
|
6
6
|
end
|
7
7
|
|
8
|
+
def to_solr_conditional
|
9
|
+
"[#{@first_corner.join(",")} TO #{@second_corner.join(",")}]"
|
10
|
+
end
|
11
|
+
|
8
12
|
def to_params
|
9
|
-
filter = "#{@field.indexed_name}
|
13
|
+
filter = "#{@field.indexed_name}:#{to_solr_conditional}"
|
10
14
|
|
11
15
|
{:fq => filter}
|
12
16
|
end
|
@@ -169,6 +169,17 @@ module Sunspot
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
+
class InBoundingBox < Base
|
173
|
+
def initialize(negated, field, first_corner, second_corner)
|
174
|
+
@bbox = Sunspot::Query::Bbox.new(field, first_corner, second_corner)
|
175
|
+
super negated, field, [first_corner, second_corner]
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_solr_conditional
|
179
|
+
@bbox.to_solr_conditional
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
172
183
|
#
|
173
184
|
# Results must have field with value equal to given value. If the value
|
174
185
|
# is nil, results must have no value for the given field.
|
@@ -11,6 +11,9 @@ module Sunspot
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
#
|
15
|
+
# Returns all of the hits that have a result
|
16
|
+
#
|
14
17
|
def verified_hits
|
15
18
|
hits.select { |h| h.result }
|
16
19
|
end
|
@@ -31,7 +34,7 @@ module Sunspot
|
|
31
34
|
hits_for_class = id_hit_hash[class_name]
|
32
35
|
data_accessor.load_all(ids).each do |result|
|
33
36
|
hit = hits_for_class.delete(Adapters::InstanceAdapter.adapt(result).id.to_s)
|
34
|
-
hit.result = result
|
37
|
+
hit.result = result if hit
|
35
38
|
end
|
36
39
|
hits_for_class.values.each { |hit| hit.result = nil }
|
37
40
|
end
|
@@ -49,12 +49,11 @@ module Sunspot
|
|
49
49
|
# the index. Otherwise return Solr's suggested collation.
|
50
50
|
#
|
51
51
|
# Solr's suggested collation is more liberal, replacing even terms that
|
52
|
-
# are present in the index.
|
53
|
-
# misspelled and preventing useful results.
|
52
|
+
# are present in the index.
|
54
53
|
#
|
55
54
|
# Mix and match in your views for a blend of strict and liberal collations.
|
56
55
|
def spellcheck_collation(*terms)
|
57
|
-
if solr_spellcheck['suggestions'] && solr_spellcheck['suggestions'].length >
|
56
|
+
if solr_spellcheck['suggestions'] && solr_spellcheck['suggestions'].length > 0
|
58
57
|
collation = terms.join(" ").dup if terms
|
59
58
|
|
60
59
|
# If we are given a query string, tokenize it and strictly replace
|
data/lib/sunspot/version.rb
CHANGED
data/spec/api/adapters_spec.rb
CHANGED
@@ -2,45 +2,45 @@ require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
describe Sunspot::Adapters::InstanceAdapter do
|
4
4
|
it "finds adapter by superclass" do
|
5
|
-
Sunspot::Adapters::InstanceAdapter::for(Model).
|
5
|
+
expect(Sunspot::Adapters::InstanceAdapter::for(Model)).to be(AbstractModelInstanceAdapter)
|
6
6
|
end
|
7
7
|
|
8
8
|
it "finds adapter by mixin" do
|
9
|
-
Sunspot::Adapters::InstanceAdapter::for(MixModel).
|
9
|
+
expect(Sunspot::Adapters::InstanceAdapter::for(MixModel)).to be(MixInModelInstanceAdapter)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'throws NoAdapterError if anonymous module passed in' do
|
13
|
-
|
13
|
+
expect do
|
14
14
|
Sunspot::Adapters::InstanceAdapter::for(Module.new)
|
15
|
-
end.
|
15
|
+
end.to raise_error(Sunspot::NoAdapterError)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "registers adapters found by ancestor lookup with the descendant class" do
|
19
|
-
Sunspot::Adapters::InstanceAdapter::registered_adapter_for(UnseenModel).
|
19
|
+
expect(Sunspot::Adapters::InstanceAdapter::registered_adapter_for(UnseenModel)).to be(nil)
|
20
20
|
Sunspot::Adapters::InstanceAdapter::for(UnseenModel)
|
21
|
-
Sunspot::Adapters::InstanceAdapter::registered_adapter_for(UnseenModel).
|
21
|
+
expect(Sunspot::Adapters::InstanceAdapter::registered_adapter_for(UnseenModel)).to be(AbstractModelInstanceAdapter)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe Sunspot::Adapters::DataAccessor do
|
26
26
|
it "finds adapter by superclass" do
|
27
|
-
Sunspot::Adapters::DataAccessor::for(Model).
|
27
|
+
expect(Sunspot::Adapters::DataAccessor::for(Model)).to be(AbstractModelDataAccessor)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "finds adapter by mixin" do
|
31
|
-
Sunspot::Adapters::DataAccessor::for(MixModel).
|
31
|
+
expect(Sunspot::Adapters::DataAccessor::for(MixModel)).to be(MixInModelDataAccessor)
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'throws NoAdapterError if anonymous module passed in' do
|
35
|
-
|
35
|
+
expect do
|
36
36
|
Sunspot::Adapters::DataAccessor::for(Module.new)
|
37
|
-
end.
|
37
|
+
end.to raise_error(Sunspot::NoAdapterError)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "registers adapters found by ancestor lookup with the descendant class" do
|
41
|
-
Sunspot::Adapters::DataAccessor::registered_accessor_for(UnseenModel).
|
41
|
+
expect(Sunspot::Adapters::DataAccessor::registered_accessor_for(UnseenModel)).to be(nil)
|
42
42
|
Sunspot::Adapters::DataAccessor::for(UnseenModel)
|
43
|
-
Sunspot::Adapters::DataAccessor::registered_accessor_for(UnseenModel).
|
43
|
+
expect(Sunspot::Adapters::DataAccessor::registered_accessor_for(UnseenModel)).to be(AbstractModelDataAccessor)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -51,30 +51,30 @@ describe Sunspot::Adapters::Registry do
|
|
51
51
|
let(:mixin_accessor){ Sunspot::Adapters::DataAccessor::for(MixModel) }
|
52
52
|
|
53
53
|
it "registers and retrieves a data accessor for abstractclass" do
|
54
|
-
registry.retrieve(AbstractModel).
|
54
|
+
expect(registry.retrieve(AbstractModel)).to be_a(abstractclass_accessor)
|
55
55
|
end
|
56
56
|
|
57
57
|
it "registers and retrieves a data accessor for superclass" do
|
58
|
-
registry.retrieve(Model).
|
58
|
+
expect(registry.retrieve(Model)).to be_a(superclass_accessor)
|
59
59
|
end
|
60
60
|
|
61
61
|
it "registers and retrieves a data accessor for mixin" do
|
62
|
-
registry.retrieve(MixModel).
|
62
|
+
expect(registry.retrieve(MixModel)).to be_a(mixin_accessor)
|
63
63
|
end
|
64
64
|
|
65
65
|
it "injects inherited attributes" do
|
66
|
-
AbstractModelDataAccessor.
|
66
|
+
allow_any_instance_of(AbstractModelDataAccessor).to receive(:inherited_attributes).and_return([:to_be_injected])
|
67
67
|
in_registry_data_accessor = registry.retrieve(AbstractModel)
|
68
68
|
in_registry_data_accessor.to_be_injected = "value"
|
69
|
-
registry.retrieve(Model).to_be_injected.
|
69
|
+
expect(registry.retrieve(Model).to_be_injected).to eq("value")
|
70
70
|
end
|
71
71
|
|
72
72
|
it "not overrides inherited attributes" do
|
73
|
-
AbstractModelDataAccessor.
|
73
|
+
allow_any_instance_of(AbstractModelDataAccessor).to receive(:inherited_attributes).and_return([:to_be_injected])
|
74
74
|
parent_data_accessor = registry.retrieve(AbstractModel)
|
75
75
|
current_data_accessor = registry.retrieve(Model)
|
76
76
|
parent_data_accessor.to_be_injected = "value"
|
77
77
|
current_data_accessor.to_be_injected = "safe-value"
|
78
|
-
registry.retrieve(Model).to_be_injected.
|
78
|
+
expect(registry.retrieve(Model).to_be_injected).to eq("safe-value")
|
79
79
|
end
|
80
80
|
end
|
data/spec/api/batcher_spec.rb
CHANGED
@@ -2,12 +2,12 @@ require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
describe Sunspot::Batcher do
|
4
4
|
it "includes Enumerable" do
|
5
|
-
described_class.
|
5
|
+
expect(described_class).to include Enumerable
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#each" do
|
9
9
|
let(:current) { [:foo, :bar] }
|
10
|
-
before { subject.
|
10
|
+
before { allow(subject).to receive(:current).and_return current }
|
11
11
|
|
12
12
|
it "iterates over current" do
|
13
13
|
yielded_values = []
|
@@ -16,25 +16,25 @@ describe Sunspot::Batcher do
|
|
16
16
|
yielded_values << value
|
17
17
|
end
|
18
18
|
|
19
|
-
yielded_values.
|
19
|
+
expect(yielded_values).to eq current
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "adding to current batch" do
|
24
24
|
it "#push pushes to current" do
|
25
25
|
subject.push :foo
|
26
|
-
subject.current.
|
26
|
+
expect(subject.current).to include :foo
|
27
27
|
end
|
28
28
|
|
29
29
|
it "#<< pushes to current" do
|
30
30
|
subject.push :foo
|
31
|
-
subject.current.
|
31
|
+
expect(subject.current).to include :foo
|
32
32
|
end
|
33
33
|
|
34
34
|
it "#concat concatinates on current batch" do
|
35
35
|
subject << :foo
|
36
36
|
subject.concat [:bar, :mix]
|
37
|
-
|
37
|
+
is_expected.to include :foo, :bar, :mix
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -46,7 +46,7 @@ describe Sunspot::Batcher do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "is empty by default" do
|
49
|
-
subject.current.
|
49
|
+
expect(subject.current).to be_empty
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -58,7 +58,7 @@ describe Sunspot::Batcher do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "returns the same as last time" do
|
61
|
-
subject.current.
|
61
|
+
expect(subject.current).to eq subject.current
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -71,7 +71,7 @@ describe Sunspot::Batcher do
|
|
71
71
|
it "changes current" do
|
72
72
|
subject << :foo
|
73
73
|
subject.start_new
|
74
|
-
|
74
|
+
is_expected.not_to include :foo
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -88,25 +88,25 @@ describe Sunspot::Batcher do
|
|
88
88
|
it "changes current" do
|
89
89
|
subject << :foo
|
90
90
|
subject.end_current
|
91
|
-
|
91
|
+
is_expected.not_to include :foo
|
92
92
|
end
|
93
93
|
|
94
94
|
it "returns current" do
|
95
95
|
subject << :foo
|
96
|
-
subject.end_current.
|
96
|
+
expect(subject.end_current).to include :foo
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
describe "#batching?" do
|
102
102
|
it "is false when depth is 0" do
|
103
|
-
subject.
|
104
|
-
|
103
|
+
expect(subject).to receive(:depth).and_return 0
|
104
|
+
is_expected.not_to be_batching
|
105
105
|
end
|
106
106
|
|
107
107
|
it "is true when depth is more than 0" do
|
108
|
-
subject.
|
109
|
-
|
108
|
+
expect(subject).to receive(:depth).and_return 1
|
109
|
+
is_expected.to be_batching
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
data/spec/api/binding_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe "DSL bindings" do
|
|
6
6
|
session.search(Post) do
|
7
7
|
value = test_method
|
8
8
|
end
|
9
|
-
value.
|
9
|
+
expect(value).to eq('value')
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'should give access to calling context\'s id method in search DSL' do
|
@@ -14,7 +14,7 @@ describe "DSL bindings" do
|
|
14
14
|
session.search(Post) do
|
15
15
|
value = id
|
16
16
|
end
|
17
|
-
value.
|
17
|
+
expect(value).to eq(16)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should give access to calling context\'s methods in nested DSL block' do
|
@@ -24,7 +24,7 @@ describe "DSL bindings" do
|
|
24
24
|
value = test_method
|
25
25
|
end
|
26
26
|
end
|
27
|
-
value.
|
27
|
+
expect(value).to eq('value')
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'should give access to calling context\'s methods in double-nested DSL block' do
|
data/spec/api/class_set_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Sunspot::ClassSet do
|
|
7
7
|
set = described_class.new
|
8
8
|
set << class1 << class2
|
9
9
|
|
10
|
-
set.to_a.
|
10
|
+
expect(set.to_a).to match_array([class1, class2])
|
11
11
|
end
|
12
12
|
|
13
13
|
it "replaces classes with the same name" do
|
@@ -15,10 +15,10 @@ describe Sunspot::ClassSet do
|
|
15
15
|
|
16
16
|
class1 = double(:name => "Class1")
|
17
17
|
set << class1
|
18
|
-
set.to_a.
|
18
|
+
expect(set.to_a).to eq([class1])
|
19
19
|
|
20
20
|
class1_dup = double(:name => "Class1")
|
21
21
|
set << class1_dup
|
22
|
-
set.to_a.
|
22
|
+
expect(set.to_a).to eq([class1_dup])
|
23
23
|
end
|
24
24
|
end
|
@@ -9,37 +9,60 @@ describe Sunspot::Search::HitEnumerable do
|
|
9
9
|
|
10
10
|
describe "#hits" do
|
11
11
|
before do
|
12
|
-
subject.
|
13
|
-
subject.
|
12
|
+
allow(subject).to receive(:solr_docs).and_return([{"id" => "Post 1", "score" => 3.14}])
|
13
|
+
allow(subject).to receive(:highlights_for)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "retrieves the raw Solr response from #solr_docs and constructs Hit objects" do
|
17
|
-
Sunspot::Search::Hit.
|
17
|
+
expect(Sunspot::Search::Hit).to receive(:new).
|
18
18
|
with({"id" => "Post 1", "score" => 3.14}, anything, anything)
|
19
19
|
|
20
20
|
subject.hits
|
21
21
|
end
|
22
22
|
|
23
23
|
it "constructs Hit objects with highlights" do
|
24
|
-
subject.
|
24
|
+
expect(subject).to receive(:highlights_for).with({"id" => "Post 1", "score" => 3.14})
|
25
25
|
|
26
26
|
subject.hits
|
27
27
|
end
|
28
28
|
|
29
29
|
it "returns only verified hits if :verify => true is passed" do
|
30
|
-
Sunspot::Search::Hit.
|
30
|
+
allow_any_instance_of(Sunspot::Search::Hit).to receive(:result).and_return(nil)
|
31
31
|
|
32
|
-
subject.hits(:verify => true).
|
32
|
+
expect(subject.hits(:verify => true)).to be_empty
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns an empty array if no results are available from Solr" do
|
36
|
-
subject.
|
36
|
+
allow(subject).to receive(:solr_docs).and_return(nil)
|
37
37
|
|
38
|
-
subject.hits.
|
38
|
+
expect(subject.hits).to eq([])
|
39
39
|
end
|
40
40
|
|
41
41
|
it "provides #populate_hits so that querying for one hit result will eager load the rest" do
|
42
|
-
Sunspot::Search::Hit.
|
42
|
+
expect_any_instance_of(Sunspot::Search::Hit).to receive(:result=)
|
43
|
+
|
44
|
+
subject.populate_hits
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#populate_hits" do
|
49
|
+
let(:post_1) { Post.new(id: "1", title: "Title 1") }
|
50
|
+
|
51
|
+
before do
|
52
|
+
allow(subject).to receive(:solr_docs).and_return([{ "id" => "Post 1", "score" => 3.14 }])
|
53
|
+
allow(subject).to receive(:highlights_for)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "populates the hit object with the result from the data accessor" do
|
57
|
+
allow_any_instance_of(MockAdapter::DataAccessor).to receive(:load_all).and_return([post_1])
|
58
|
+
expect_any_instance_of(Sunspot::Search::Hit).to receive(:result=).with(post_1)
|
59
|
+
|
60
|
+
subject.populate_hits
|
61
|
+
end
|
62
|
+
|
63
|
+
it "populates the hit object only once if there are duplicate entries in the database (ex: db missing unique constraints)" do
|
64
|
+
allow_any_instance_of(MockAdapter::DataAccessor).to receive(:load_all).and_return([post_1, post_1])
|
65
|
+
expect_any_instance_of(Sunspot::Search::Hit).to receive(:result=).with(post_1)
|
43
66
|
|
44
67
|
subject.populate_hits
|
45
68
|
end
|