thinking-sphinx 4.3.0 → 5.0.0
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/.travis.yml +16 -21
- data/Appraisals +2 -17
- data/CHANGELOG.markdown +62 -1
- data/README.textile +14 -16
- data/bin/loadsphinx +20 -5
- data/lib/thinking_sphinx/active_record/association_proxy.rb +1 -2
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +1 -1
- data/lib/thinking_sphinx/active_record/base.rb +17 -6
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +1 -1
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +3 -2
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +1 -1
- data/lib/thinking_sphinx/active_record/interpreter.rb +4 -4
- data/lib/thinking_sphinx/active_record/sql_source.rb +12 -0
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +2 -2
- data/lib/thinking_sphinx/callbacks.rb +9 -0
- data/lib/thinking_sphinx/callbacks/appender.rb +47 -0
- data/lib/thinking_sphinx/commands/index_real_time.rb +1 -3
- data/lib/thinking_sphinx/configuration.rb +9 -3
- data/lib/thinking_sphinx/core/index.rb +5 -2
- data/lib/thinking_sphinx/deletion.rb +18 -17
- data/lib/thinking_sphinx/index_set.rb +7 -3
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +1 -1
- data/lib/thinking_sphinx/railtie.rb +9 -1
- data/lib/thinking_sphinx/real_time.rb +17 -0
- data/lib/thinking_sphinx/real_time/index.rb +4 -0
- data/lib/thinking_sphinx/real_time/interpreter.rb +8 -6
- data/lib/thinking_sphinx/real_time/populator.rb +1 -1
- data/lib/thinking_sphinx/real_time/processor.rb +36 -0
- data/lib/thinking_sphinx/real_time/transcriber.rb +35 -19
- data/lib/thinking_sphinx/subscribers/populator_subscriber.rb +0 -4
- data/spec/acceptance/big_integers_spec.rb +1 -1
- data/spec/acceptance/merging_spec.rb +1 -1
- data/spec/acceptance/real_time_updates_spec.rb +2 -2
- data/spec/acceptance/sql_deltas_spec.rb +3 -3
- data/spec/acceptance/suspended_deltas_spec.rb +3 -3
- data/spec/internal/app/models/admin/person.rb +3 -1
- data/spec/internal/app/models/album.rb +3 -1
- data/spec/internal/app/models/animal.rb +1 -0
- data/spec/internal/app/models/article.rb +2 -0
- data/spec/internal/app/models/bird.rb +1 -0
- data/spec/internal/app/models/book.rb +2 -0
- data/spec/internal/app/models/car.rb +1 -1
- data/spec/internal/app/models/city.rb +2 -0
- data/spec/internal/app/models/product.rb +1 -1
- data/spec/internal/app/models/tee.rb +2 -0
- data/spec/internal/app/models/user.rb +2 -0
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +2 -1
- data/spec/thinking_sphinx/active_record/index_spec.rb +0 -12
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +15 -14
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +38 -0
- data/spec/thinking_sphinx/configuration_spec.rb +17 -16
- data/spec/thinking_sphinx/deletion_spec.rb +5 -4
- data/spec/thinking_sphinx/index_set_spec.rb +28 -12
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +2 -1
- data/spec/thinking_sphinx/real_time/index_spec.rb +38 -12
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +14 -14
- data/spec/thinking_sphinx/real_time/transcriber_spec.rb +9 -1
- data/thinking-sphinx.gemspec +3 -5
- metadata +9 -8
@@ -52,7 +52,7 @@ describe '64 bit document ids', :live => true do
|
|
52
52
|
context 'with Real-Time' do
|
53
53
|
it 'handles large 32 bit integers with an offset multiplier' do
|
54
54
|
product = Product.create! :name => "Widget"
|
55
|
-
product.
|
55
|
+
product.update :id => 980190962
|
56
56
|
expect(
|
57
57
|
Product.search('widget', :indices => ['product_core']).to_a
|
58
58
|
).to eq([product])
|
@@ -34,7 +34,7 @@ describe "Merging deltas", :live => true do
|
|
34
34
|
Book.search("Space", :indices => ["book_core"]).to_a
|
35
35
|
).to eq([race])
|
36
36
|
|
37
|
-
race.reload.
|
37
|
+
race.reload.update :title => "The Hate Race"
|
38
38
|
sleep 0.25
|
39
39
|
expect(
|
40
40
|
Book.search("Race", :indices => ["book_delta"]).to_a
|
@@ -11,7 +11,7 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
11
11
|
|
12
12
|
it "handles attributes for sortable fields accordingly" do
|
13
13
|
product = Product.create! :name => 'Red Fish'
|
14
|
-
product.
|
14
|
+
product.update :name => 'Blue Fish'
|
15
15
|
|
16
16
|
expect(Product.search('blue fish', :indices => ['product_core']).to_a).
|
17
17
|
to eq([product])
|
@@ -22,7 +22,7 @@ describe 'Updates to records in real-time indices', :live => true do
|
|
22
22
|
|
23
23
|
expect(Admin::Person.search('Death').to_a).to eq([person])
|
24
24
|
|
25
|
-
person.
|
25
|
+
person.update :name => 'Mort'
|
26
26
|
|
27
27
|
expect(Admin::Person.search('Death').to_a).to be_empty
|
28
28
|
expect(Admin::Person.search('Mort').to_a).to eq([person])
|
@@ -25,7 +25,7 @@ describe 'SQL delta indexing', :live => true do
|
|
25
25
|
|
26
26
|
expect(Book.search('Harry').to_a).to eq([book])
|
27
27
|
|
28
|
-
book.reload.
|
28
|
+
book.reload.update(:author => 'Terry Pratchett')
|
29
29
|
sleep 0.25
|
30
30
|
|
31
31
|
expect(Book.search('Terry').to_a).to eq([book])
|
@@ -37,7 +37,7 @@ describe 'SQL delta indexing', :live => true do
|
|
37
37
|
|
38
38
|
expect(Book.search('Harry').to_a).to eq([book])
|
39
39
|
|
40
|
-
book.reload.
|
40
|
+
book.reload.update(:author => 'Terry Pratchett')
|
41
41
|
sleep 0.25
|
42
42
|
|
43
43
|
expect(Book.search('Harry')).to be_empty
|
@@ -49,7 +49,7 @@ describe 'SQL delta indexing', :live => true do
|
|
49
49
|
|
50
50
|
expect(Album.search('Whitloms').to_a).to eq([album])
|
51
51
|
|
52
|
-
album.reload.
|
52
|
+
album.reload.update(:artist => 'The Whitlams')
|
53
53
|
sleep 0.25
|
54
54
|
|
55
55
|
expect(Book.search('Whitloms')).to be_empty
|
@@ -10,7 +10,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
10
10
|
expect(Book.search('Harry').to_a).to eq([book])
|
11
11
|
|
12
12
|
ThinkingSphinx::Deltas.suspend :book do
|
13
|
-
book.reload.
|
13
|
+
book.reload.update(:author => 'Terry Pratchett')
|
14
14
|
sleep 0.25
|
15
15
|
|
16
16
|
expect(Book.search('Terry').to_a).to eq([])
|
@@ -27,7 +27,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
27
27
|
expect(Book.search('Harry').to_a).to eq([book])
|
28
28
|
|
29
29
|
ThinkingSphinx::Deltas.suspend :book do
|
30
|
-
book.reload.
|
30
|
+
book.reload.update(:author => 'Terry Pratchett')
|
31
31
|
sleep 0.25
|
32
32
|
|
33
33
|
expect(Book.search('Terry').to_a).to eq([])
|
@@ -44,7 +44,7 @@ describe 'Suspend deltas for a given action', :live => true do
|
|
44
44
|
expect(Book.search('Harry').to_a).to eq([book])
|
45
45
|
|
46
46
|
ThinkingSphinx::Deltas.suspend_and_update :book do
|
47
|
-
book.reload.
|
47
|
+
book.reload.update(:author => 'Terry Pratchett')
|
48
48
|
sleep 0.25
|
49
49
|
|
50
50
|
expect(Book.search('Terry').to_a).to eq([])
|
@@ -6,7 +6,9 @@ class Album < ActiveRecord::Base
|
|
6
6
|
before_validation :set_id, :on => :create
|
7
7
|
before_validation :set_integer_id, :on => :create
|
8
8
|
|
9
|
-
|
9
|
+
ThinkingSphinx::Callbacks.append(
|
10
|
+
self, :behaviours => [:sql, :real_time, :deltas]
|
11
|
+
)
|
10
12
|
|
11
13
|
validates :id, :presence => true, :uniqueness => true
|
12
14
|
validates :integer_id, :presence => true, :uniqueness => true
|
@@ -19,12 +19,13 @@ describe ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks do
|
|
19
19
|
let(:klass) { double(:name => 'Article') }
|
20
20
|
let(:configuration) { double('configuration',
|
21
21
|
:settings => {'attribute_updates' => true},
|
22
|
-
:indices_for_references => [index]) }
|
22
|
+
:indices_for_references => [index], :index_set_class => set_class) }
|
23
23
|
let(:connection) { double('connection', :execute => '') }
|
24
24
|
let(:index) { double 'index', :name => 'article_core',
|
25
25
|
:sources => [source], :document_id_for_key => 3, :distributed? => false,
|
26
26
|
:type => 'plain', :primary_key => :id}
|
27
27
|
let(:source) { double('source', :attributes => []) }
|
28
|
+
let(:set_class) { double(:reference_name => :article) }
|
28
29
|
|
29
30
|
before :each do
|
30
31
|
stub_const 'ThinkingSphinx::Configuration',
|
@@ -94,18 +94,6 @@ describe ThinkingSphinx::ActiveRecord::Index do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
describe '#docinfo' do
|
98
|
-
it "defaults to extern" do
|
99
|
-
expect(index.docinfo).to eq(:extern)
|
100
|
-
end
|
101
|
-
|
102
|
-
it "can be disabled" do
|
103
|
-
config.settings["skip_docinfo"] = true
|
104
|
-
|
105
|
-
expect(index.docinfo).to be_nil
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
97
|
describe '#document_id_for_key' do
|
110
98
|
it "calculates the document id based on offset and number of indices" do
|
111
99
|
allow(config).to receive_message_chain(:indices, :count).and_return(5)
|
@@ -15,8 +15,13 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
15
15
|
let(:block) { Proc.new { } }
|
16
16
|
|
17
17
|
before :each do
|
18
|
-
allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages
|
19
|
-
|
18
|
+
allow(ThinkingSphinx::ActiveRecord::SQLSource).to receive_messages(
|
19
|
+
:new => source
|
20
|
+
)
|
21
|
+
|
22
|
+
allow(source).to receive_messages(
|
23
|
+
:model => model, :add_attribute => nil, :add_field => nil
|
24
|
+
)
|
20
25
|
end
|
21
26
|
|
22
27
|
describe '.translate!' do
|
@@ -94,17 +99,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
94
99
|
end
|
95
100
|
|
96
101
|
it "adds an attribute to the source" do
|
97
|
-
|
102
|
+
expect(source).to receive(:add_attribute).with(attribute)
|
98
103
|
|
99
|
-
|
104
|
+
instance.has column
|
100
105
|
end
|
101
106
|
|
102
107
|
it "adds multiple attributes when passed multiple columns" do
|
103
|
-
|
108
|
+
expect(source).to receive(:add_attribute).with(attribute).twice
|
104
109
|
|
105
|
-
|
106
|
-
saved_attribute == attribute
|
107
|
-
}.length).to eq(2)
|
110
|
+
instance.has column, column
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
@@ -144,17 +147,15 @@ describe ThinkingSphinx::ActiveRecord::Interpreter do
|
|
144
147
|
end
|
145
148
|
|
146
149
|
it "adds a field to the source" do
|
147
|
-
|
150
|
+
expect(source).to receive(:add_field).with(field)
|
148
151
|
|
149
|
-
|
152
|
+
instance.indexes column
|
150
153
|
end
|
151
154
|
|
152
155
|
it "adds multiple fields when passed multiple columns" do
|
153
|
-
|
156
|
+
expect(source).to receive(:add_field).with(field).twice
|
154
157
|
|
155
|
-
|
156
|
-
saved_field == field
|
157
|
-
}.length).to eq(2)
|
158
|
+
instance.indexes column, column
|
158
159
|
end
|
159
160
|
end
|
160
161
|
|
@@ -30,6 +30,44 @@ describe ThinkingSphinx::ActiveRecord::SQLSource do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
describe '#add_attribute' do
|
34
|
+
let(:attribute) { double('attribute', name: 'my_attribute') }
|
35
|
+
|
36
|
+
it "appends attributes to the collection" do
|
37
|
+
source.add_attribute attribute
|
38
|
+
|
39
|
+
expect(source.attributes.collect(&:name)).to include('my_attribute')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "replaces attributes with the same name" do
|
43
|
+
source.add_attribute double('attribute', name: 'my_attribute')
|
44
|
+
source.add_attribute attribute
|
45
|
+
|
46
|
+
matching = source.attributes.select { |attr| attr.name == attribute.name }
|
47
|
+
|
48
|
+
expect(matching).to eq([attribute])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#add_field' do
|
53
|
+
let(:field) { double('field', name: 'my_field') }
|
54
|
+
|
55
|
+
it "appends fields to the collection" do
|
56
|
+
source.add_field field
|
57
|
+
|
58
|
+
expect(source.fields.collect(&:name)).to include('my_field')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "replaces fields with the same name" do
|
62
|
+
source.add_field double('field', name: 'my_field')
|
63
|
+
source.add_field field
|
64
|
+
|
65
|
+
matching = source.fields.select { |fld| fld.name == field.name }
|
66
|
+
|
67
|
+
expect(matching).to eq([field])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
33
71
|
describe '#attributes' do
|
34
72
|
it "has the internal id attribute by default" do
|
35
73
|
expect(source.attributes.collect(&:name)).to include('sphinx_internal_id')
|
@@ -4,11 +4,18 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe ThinkingSphinx::Configuration do
|
6
6
|
let(:config) { ThinkingSphinx::Configuration.instance }
|
7
|
+
let(:use_load?) { ActiveRecord::VERSION::MAJOR > 5 }
|
8
|
+
let(:loading_object) { use_load? ? config : ActiveSupport::Dependencies }
|
9
|
+
let(:loading_method) { use_load? ? :load : :require_or_load }
|
7
10
|
|
8
11
|
after :each do
|
9
12
|
ThinkingSphinx::Configuration.reset
|
10
13
|
end
|
11
14
|
|
15
|
+
def expect_loading_of(file)
|
16
|
+
expect(loading_object).to receive(loading_method).with(file).once
|
17
|
+
end
|
18
|
+
|
12
19
|
describe '.instance' do
|
13
20
|
it "returns an instance of ThinkingSphinx::Configuration" do
|
14
21
|
expect(ThinkingSphinx::Configuration.instance).
|
@@ -254,10 +261,8 @@ describe ThinkingSphinx::Configuration do
|
|
254
261
|
'/path/to/indices/bar_index.rb'
|
255
262
|
]
|
256
263
|
|
257
|
-
|
258
|
-
|
259
|
-
expect(ActiveSupport::Dependencies).to receive(:require_or_load).
|
260
|
-
with('/path/to/indices/bar_index.rb').once
|
264
|
+
expect_loading_of('/path/to/indices/foo_index.rb')
|
265
|
+
expect_loading_of('/path/to/indices/bar_index.rb')
|
261
266
|
|
262
267
|
config.preload_indices
|
263
268
|
end
|
@@ -269,10 +274,8 @@ describe ThinkingSphinx::Configuration do
|
|
269
274
|
'/path/to/indices/bar_index.rb'
|
270
275
|
]
|
271
276
|
|
272
|
-
|
273
|
-
|
274
|
-
expect(ActiveSupport::Dependencies).to receive(:require_or_load).
|
275
|
-
with('/path/to/indices/bar_index.rb').once
|
277
|
+
expect_loading_of('/path/to/indices/foo_index.rb')
|
278
|
+
expect_loading_of('/path/to/indices/bar_index.rb')
|
276
279
|
|
277
280
|
config.preload_indices
|
278
281
|
config.preload_indices
|
@@ -316,10 +319,8 @@ describe ThinkingSphinx::Configuration do
|
|
316
319
|
'/path/to/indices/bar_index.rb'
|
317
320
|
]
|
318
321
|
|
319
|
-
|
320
|
-
|
321
|
-
expect(ActiveSupport::Dependencies).to receive(:require_or_load).
|
322
|
-
with('/path/to/indices/bar_index.rb').once
|
322
|
+
expect_loading_of('/path/to/indices/foo_index.rb')
|
323
|
+
expect_loading_of('/path/to/indices/bar_index.rb')
|
323
324
|
|
324
325
|
config.render
|
325
326
|
end
|
@@ -331,10 +332,8 @@ describe ThinkingSphinx::Configuration do
|
|
331
332
|
'/path/to/indices/bar_index.rb'
|
332
333
|
]
|
333
334
|
|
334
|
-
|
335
|
-
|
336
|
-
expect(ActiveSupport::Dependencies).to receive(:require_or_load).
|
337
|
-
with('/path/to/indices/bar_index.rb').once
|
335
|
+
expect_loading_of('/path/to/indices/foo_index.rb')
|
336
|
+
expect_loading_of('/path/to/indices/bar_index.rb')
|
338
337
|
|
339
338
|
config.preload_indices
|
340
339
|
config.preload_indices
|
@@ -372,6 +371,8 @@ describe ThinkingSphinx::Configuration do
|
|
372
371
|
end
|
373
372
|
|
374
373
|
it "skips creating a directory when the binlog_path is blank" do
|
374
|
+
allow(loading_object).to receive(loading_method)
|
375
|
+
|
375
376
|
allow(FileUtils).to receive_messages :mkdir_p => true
|
376
377
|
allow(config).to receive_messages :searchd => double(:binlog_path => '')
|
377
378
|
|
@@ -6,7 +6,7 @@ describe ThinkingSphinx::Deletion do
|
|
6
6
|
describe '.perform' do
|
7
7
|
let(:connection) { double('connection', :execute => nil) }
|
8
8
|
let(:index) { double('index', :name => 'foo_core',
|
9
|
-
:
|
9
|
+
:type => 'plain', :distributed? => false) }
|
10
10
|
|
11
11
|
before :each do
|
12
12
|
allow(ThinkingSphinx::Connection).to receive(:take).and_yield(connection)
|
@@ -15,8 +15,9 @@ describe ThinkingSphinx::Deletion do
|
|
15
15
|
|
16
16
|
context 'index is SQL-backed' do
|
17
17
|
it "updates the deleted flag to false" do
|
18
|
-
expect(connection).to receive(:execute).
|
19
|
-
|
18
|
+
expect(connection).to receive(:execute).with(
|
19
|
+
'UPDATE foo_core SET sphinx_deleted = 1 WHERE sphinx_internal_id IN (7)'
|
20
|
+
)
|
20
21
|
|
21
22
|
ThinkingSphinx::Deletion.perform index, 7
|
22
23
|
end
|
@@ -38,7 +39,7 @@ describe ThinkingSphinx::Deletion do
|
|
38
39
|
|
39
40
|
it "deletes the record to false" do
|
40
41
|
expect(connection).to receive(:execute).
|
41
|
-
with('DELETE FROM foo_core WHERE
|
42
|
+
with('DELETE FROM foo_core WHERE sphinx_internal_id IN (7)')
|
42
43
|
|
43
44
|
ThinkingSphinx::Deletion.perform index, 7
|
44
45
|
end
|
@@ -30,6 +30,16 @@ describe ThinkingSphinx::IndexSet do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
describe '#to_a' do
|
33
|
+
let(:article_index) do
|
34
|
+
double(:reference => :article, :distributed? => false)
|
35
|
+
end
|
36
|
+
let(:opinion_article_index) do
|
37
|
+
double(:reference => :opinion_article, :distributed? => false)
|
38
|
+
end
|
39
|
+
let(:page_index) do
|
40
|
+
double(:reference => :page, :distributed? => false)
|
41
|
+
end
|
42
|
+
|
33
43
|
it "ensures the indices are loaded" do
|
34
44
|
expect(configuration).to receive(:preload_indices)
|
35
45
|
|
@@ -50,21 +60,29 @@ describe ThinkingSphinx::IndexSet do
|
|
50
60
|
|
51
61
|
it "uses indices for the given classes" do
|
52
62
|
configuration.indices.replace [
|
53
|
-
|
54
|
-
double(:reference => :opinion_article, :distributed? => false),
|
55
|
-
double(:reference => :page, :distributed? => false)
|
63
|
+
article_index, opinion_article_index, page_index
|
56
64
|
]
|
57
65
|
|
58
66
|
options[:classes] = [class_double('Article', :column_names => [])]
|
59
67
|
|
60
|
-
expect(set.to_a
|
68
|
+
expect(set.to_a).to eq([article_index])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "uses indices for the given instance's class" do
|
72
|
+
configuration.indices.replace [
|
73
|
+
article_index, opinion_article_index, page_index
|
74
|
+
]
|
75
|
+
|
76
|
+
instance_class = class_double('Article', :column_names => [])
|
77
|
+
|
78
|
+
options[:instances] = [double(:instance, :class => instance_class)]
|
79
|
+
|
80
|
+
expect(set.to_a).to eq([article_index])
|
61
81
|
end
|
62
82
|
|
63
83
|
it "requests indices for any STI superclasses" do
|
64
84
|
configuration.indices.replace [
|
65
|
-
|
66
|
-
double(:reference => :opinion_article, :distributed? => false),
|
67
|
-
double(:reference => :page, :distributed? => false)
|
85
|
+
article_index, opinion_article_index, page_index
|
68
86
|
]
|
69
87
|
|
70
88
|
article = class_double('Article', :column_names => [:type])
|
@@ -73,14 +91,12 @@ describe ThinkingSphinx::IndexSet do
|
|
73
91
|
|
74
92
|
options[:classes] = [opinion]
|
75
93
|
|
76
|
-
expect(set.to_a
|
94
|
+
expect(set.to_a).to eq([article_index, opinion_article_index])
|
77
95
|
end
|
78
96
|
|
79
97
|
it "does not use MTI superclasses" do
|
80
98
|
configuration.indices.replace [
|
81
|
-
|
82
|
-
double(:reference => :opinion_article, :distributed? => false),
|
83
|
-
double(:reference => :page, :distributed? => false)
|
99
|
+
article_index, opinion_article_index, page_index
|
84
100
|
]
|
85
101
|
|
86
102
|
article = class_double('Article', :column_names => [])
|
@@ -88,7 +104,7 @@ describe ThinkingSphinx::IndexSet do
|
|
88
104
|
|
89
105
|
options[:classes] = [opinion]
|
90
106
|
|
91
|
-
expect(set.to_a
|
107
|
+
expect(set.to_a).to eq([opinion_article_index])
|
92
108
|
end
|
93
109
|
|
94
110
|
it "uses named indices if names are provided" do
|