sunspot 2.2.7 → 2.2.8
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.
- 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
|