rsolr 1.1.2 → 2.0.0.pre1

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/lib/rsolr/xml.rb CHANGED
@@ -2,100 +2,11 @@ begin; require 'nokogiri'; rescue LoadError; end
2
2
  require 'time'
3
3
 
4
4
  module RSolr::Xml
5
-
6
- class Document
7
-
8
- # "attrs" is a hash for setting the "doc" xml attributes
9
- # "fields" is an array of Field objects
10
- attr_accessor :attrs, :fields
11
-
12
- # "doc_hash" must be a Hash/Mash object
13
- # If a value in the "doc_hash" is an array,
14
- # a field object is created for each value...
15
- def initialize(doc_hash = {})
16
- @fields = []
17
- doc_hash.each_pair do |field,values|
18
- # create a new field for each value (multi-valued)
19
- wrap(values).each do |v|
20
- v = format_value(v)
21
- next if v.empty?
22
- @fields << RSolr::Xml::Field.new({:name=>field}, v)
23
- end
24
- end
25
- @attrs={}
26
- end
5
+ require 'rsolr/document'
27
6
 
28
- # returns an array of fields that match the "name" arg
29
- def fields_by_name(name)
30
- @fields.select{|f|f.name==name}
31
- end
32
-
33
- # returns the *first* field that matches the "name" arg
34
- def field_by_name(name)
35
- @fields.detect{|f|f.name==name}
36
- end
37
-
38
- #
39
- # Add a field value to the document. Options map directly to
40
- # XML attributes in the Solr <field> node.
41
- # See http://wiki.apache.org/solr/UpdateXmlMessages#head-8315b8028923d028950ff750a57ee22cbf7977c6
42
- #
43
- # === Example:
44
- #
45
- # document.add_field('title', 'A Title', :boost => 2.0)
46
- #
47
- def add_field(name, value, options = {})
48
- @fields << RSolr::Xml::Field.new(options.merge({:name=>name}), value)
49
- end
50
-
51
- private
52
-
53
- def format_value(v)
54
- case v
55
- when Time
56
- v.getutc.iso8601
57
- when DateTime
58
- v.to_time.getutc.iso8601
59
- when Date
60
- Time.utc(v.year, v.mon, v.mday).iso8601
61
- else
62
- v.to_s
63
- end
64
- end
7
+ Document = RSolr::Document
8
+ Field = RSolr::Field
65
9
 
66
- def wrap(object)
67
- if object.nil?
68
- []
69
- elsif object.respond_to?(:to_ary)
70
- object.to_ary || [object]
71
- elsif object.is_a? Enumerable
72
- object
73
- else
74
- [object]
75
- end
76
- end
77
- end
78
-
79
- class Field
80
-
81
- # "attrs" is a hash for setting the "doc" xml attributes
82
- # "value" is the text value for the node
83
- attr_accessor :attrs, :value
84
-
85
- # "attrs" must be a hash
86
- # "value" should be something that responds to #_to_s
87
- def initialize(attrs, value)
88
- @attrs = attrs
89
- @value = value
90
- end
91
-
92
- # the value of the "name" attribute
93
- def name
94
- @attrs[:name]
95
- end
96
-
97
- end
98
-
99
10
  class Generator
100
11
  class << self
101
12
  attr_accessor :use_nokogiri
@@ -162,13 +73,9 @@ module RSolr::Xml
162
73
  build do |xml|
163
74
  xml.add(add_attrs) do |add_node|
164
75
  data.each do |doc|
165
- doc = RSolr::Xml::Document.new(doc) if doc.respond_to?(:each_pair)
76
+ doc = RSolr::Document.new(doc) if doc.respond_to?(:each_pair)
166
77
  yield doc if block_given?
167
- doc_node_builder = lambda do |doc_node|
168
- doc.fields.each do |field_obj|
169
- doc_node.field field_obj.value, field_obj.attrs
170
- end
171
- end
78
+ doc_node_builder = to_xml(doc)
172
79
  self.class.use_nokogiri ? add_node.doc_(doc.attrs,&doc_node_builder) : add_node.doc(doc.attrs,&doc_node_builder)
173
80
  end
174
81
  end
@@ -215,5 +122,24 @@ module RSolr::Xml
215
122
  end
216
123
  end
217
124
  end
125
+
126
+ private
127
+
128
+ def to_xml(doc)
129
+ lambda do |doc_node|
130
+ doc.fields.each do |field_obj|
131
+ value = field_obj.value
132
+ if field_obj.name.to_s == RSolr::Document::CHILD_DOCUMENT_KEY
133
+ child_node_builder = to_xml(field_obj.value)
134
+ self.class.use_nokogiri ? doc_node.doc_(&child_node_builder) : doc_node.doc(&child_node_builder)
135
+ elsif value.is_a?(Hash) && value.length == 1 && field_obj.attrs[:update].nil?
136
+ update_attr, real_value = value.first
137
+ doc_node.field real_value, field_obj.attrs.merge(update: update_attr)
138
+ else
139
+ doc_node.field field_obj.value, field_obj.attrs
140
+ end
141
+ end
142
+ end
143
+ end
218
144
  end
219
145
  end
data/lib/rsolr.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  module RSolr
2
-
3
2
  Dir.glob(File.expand_path("../rsolr/*.rb", __FILE__)).each{|rb_file| require(rb_file)}
4
-
3
+
5
4
  def self.connect *args
6
- driver = Class === args[0] ? args[0] : RSolr::Connection
7
- opts = Hash === args[-1] ? args[-1] : {}
8
- Client.new driver.new, opts
5
+ opts = args.pop if args.last.is_a?(::Hash)
6
+ opts ||= {}
7
+
8
+ connection = args.first
9
+
10
+ Client.new connection, opts
9
11
  end
10
-
11
- # RSolr.escape, which is deprecated as of 2015-02
12
- extend Char
13
-
12
+
14
13
  # backslash escape characters that have special meaning to Solr query parser
15
14
  # per http://lucene.apache.org/core/4_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Escaping_Special_Characters
16
15
  # + - & | ! ( ) { } [ ] ^ " ~ * ? : \ /
data/rsolr.gemspec CHANGED
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
32
32
  s.required_ruby_version = '>= 1.9.3'
33
33
 
34
34
  s.add_dependency 'builder', '>= 2.1.2'
35
+ s.add_dependency 'faraday'
36
+
35
37
  s.add_development_dependency 'activesupport'
36
38
  s.add_development_dependency 'nokogiri', '>= 1.4.0'
37
39
  s.add_development_dependency 'rake', '~> 10.0'
@@ -1,20 +1,15 @@
1
1
  require 'spec_helper'
2
- describe "RSolr::Client" do
3
2
 
4
- module ClientHelper
5
- def client
6
- @client ||= (
7
- connection = RSolr::Connection.new
8
- RSolr::Client.new connection, :url => "http://localhost:9999/solr", :read_timeout => 42, :open_timeout=>43
9
- )
10
- end
3
+ RSpec.describe RSolr::Client do
4
+ let(:connection) { nil }
5
+ let(:connection_options) { { url: "http://localhost:9999/solr", read_timeout: 42, open_timeout: 43, update_format: :xml } }
11
6
 
12
- def client_with_proxy
13
- @client_with_proxy ||= (
14
- connection = RSolr::Connection.new
15
- RSolr::Client.new connection, :url => "http://localhost:9999/solr", :proxy => 'http://localhost:8080', :read_timeout => 42, :open_timeout=>43
16
- )
17
- end
7
+ let(:client) do
8
+ RSolr::Client.new connection, connection_options
9
+ end
10
+
11
+ let(:client_with_proxy) do
12
+ RSolr::Client.new connection, connection_options.merge(proxy: 'http://localhost:8080')
18
13
  end
19
14
 
20
15
  context "initialize" do
@@ -49,61 +44,20 @@ describe "RSolr::Client" do
49
44
  end
50
45
 
51
46
  context "send_and_receive" do
52
- include ClientHelper
53
47
  it "should forward these method calls the #connection object" do
54
48
  [:get, :post, :head].each do |meth|
55
- expect(client.connection).to receive(:execute).
49
+ expect(client).to receive(:execute).
56
50
  and_return({:status => 200, :body => "{}", :headers => {}})
57
51
  client.send_and_receive '', :method => meth, :params => {}, :data => nil, :headers => {}
58
52
  end
59
53
  end
60
-
61
- it "should be timeout aware" do
62
- [:get, :post, :head].each do |meth|
63
- expect(client.connection).to receive(:execute).with(client, hash_including(:read_timeout => 42, :open_timeout=>43))
64
- client.send_and_receive '', :method => meth, :params => {}, :data => nil, :headers => {}
65
- end
66
- end
67
- end
68
-
69
- context "execute" do
70
- include ClientHelper
71
- let :request_context do
72
- {
73
- :method => :post,
74
- :params => {},
75
- :data => nil,
76
- :headers => {},
77
- :path => '',
78
- :uri => client.base_uri,
79
- :retry_503 => 1
80
- }
81
- end
82
- it "should retry 503s if requested" do
83
- expect(client.connection).to receive(:execute).exactly(2).times.and_return(
84
- {:status => 503, :body => "{}", :headers => {'Retry-After' => 0}},
85
- {:status => 200, :body => "{}", :headers => {}}
86
- )
87
- client.execute request_context
88
- end
89
- it "should not retry a 503 if the retry-after is too large" do
90
- expect(client.connection).to receive(:execute).exactly(1).times.and_return(
91
- {:status => 503, :body => "{}", :headers => {'Retry-After' => 10}}
92
- )
93
- expect {
94
- Timeout.timeout(0.5) do
95
- client.execute({:retry_after_limit => 0}.merge(request_context))
96
- end
97
- }.to raise_error(RSolr::Error::Http)
98
- end
99
54
  end
100
55
 
101
56
  context "post" do
102
- include ClientHelper
103
57
  it "should pass the expected params to the connection's #execute method" do
104
58
  request_opts = {:data => "the data", :method=>:post, :headers => {"Content-Type" => "text/plain"}}
105
- expect(client.connection).to receive(:execute).
106
- with(client, hash_including(request_opts)).
59
+ expect(client).to receive(:execute).
60
+ with(hash_including(request_opts)).
107
61
  and_return(
108
62
  :body => "",
109
63
  :status => 200,
@@ -114,18 +68,22 @@ describe "RSolr::Client" do
114
68
  end
115
69
 
116
70
  context "xml" do
117
- include ClientHelper
118
71
  it "should return an instance of RSolr::Xml::Generator" do
119
72
  expect(client.xml).to be_a RSolr::Xml::Generator
120
73
  end
121
74
  end
122
75
 
76
+ context "json" do
77
+ it "should return an instance of RSolr::JSON::Generator" do
78
+ expect(client.json).to be_a RSolr::JSON::Generator
79
+ end
80
+ end
81
+
123
82
  context "add" do
124
- include ClientHelper
125
83
  it "should send xml to the connection's #post method" do
126
- expect(client.connection).to receive(:execute).
84
+ expect(client).to receive(:execute).
127
85
  with(
128
- client, hash_including({
86
+ hash_including({
129
87
  :path => "update",
130
88
  :headers => {"Content-Type"=>"text/xml"},
131
89
  :method => :post,
@@ -142,14 +100,54 @@ describe "RSolr::Client" do
142
100
  and_return("<xml/>")
143
101
  client.add({:id=>1}, :add_attributes => {:commitWith=>10})
144
102
  end
103
+
104
+ context 'when the client is configured for json updates' do
105
+ let(:client) do
106
+ RSolr::Client.new nil, :url => "http://localhost:9999/solr", :read_timeout => 42, :open_timeout=>43, :update_format => :json
107
+ end
108
+ it "should send json to the connection's #post method" do
109
+ expect(client).to receive(:execute).
110
+ with(hash_including({
111
+ :path => 'update',
112
+ :headers => {"Content-Type" => 'application/json'},
113
+ :method => :post,
114
+ :data => '{"hello":"this is json"}'
115
+ })
116
+ ).
117
+ and_return(
118
+ :body => "",
119
+ :status => 200,
120
+ :headers => {"Content-Type"=>"text/xml"}
121
+ )
122
+ expect(client.json).to receive(:add).
123
+ with({:id => 1}, {:commitWith=>10}).
124
+ and_return('{"hello":"this is json"}')
125
+ client.add({:id=>1}, :add_attributes => {:commitWith=>10})
126
+ end
127
+
128
+ it "should send json to the connection's #post method" do
129
+ expect(client).to receive(:execute).
130
+ with(hash_including({
131
+ :path => 'update',
132
+ :headers => {'Content-Type'=>'application/json'},
133
+ :method => :post,
134
+ :data => '{"optimise" : {}}'
135
+ })
136
+ ).
137
+ and_return(
138
+ :body => "",
139
+ :status => 200,
140
+ :headers => {"Content-Type"=>"text/xml"}
141
+ )
142
+ client.update(:data => '{"optimise" : {}}')
143
+ end
144
+ end
145
145
  end
146
146
 
147
147
  context "update" do
148
- include ClientHelper
149
148
  it "should send data to the connection's #post method" do
150
- expect(client.connection).to receive(:execute).
151
- with(
152
- client, hash_including({
149
+ expect(client).to receive(:execute).
150
+ with(hash_including({
153
151
  :path => "update",
154
152
  :headers => {"Content-Type"=>"text/xml"},
155
153
  :method => :post,
@@ -178,12 +176,10 @@ describe "RSolr::Client" do
178
176
  end
179
177
 
180
178
  context "post based helper methods:" do
181
- include ClientHelper
182
179
  [:commit, :optimize, :rollback].each do |meth|
183
180
  it "should send a #{meth} message to the connection's #post method" do
184
- expect(client.connection).to receive(:execute).
185
- with(
186
- client, hash_including({
181
+ expect(client).to receive(:execute).
182
+ with(hash_including({
187
183
  :path => "update",
188
184
  :headers => {"Content-Type"=>"text/xml"},
189
185
  :method => :post,
@@ -201,11 +197,10 @@ describe "RSolr::Client" do
201
197
  end
202
198
 
203
199
  context "delete_by_id" do
204
- include ClientHelper
205
200
  it "should send data to the connection's #post method" do
206
- expect(client.connection).to receive(:execute).
201
+ expect(client).to receive(:execute).
207
202
  with(
208
- client, hash_including({
203
+ hash_including({
209
204
  :path => "update",
210
205
  :headers => {"Content-Type"=>"text/xml"},
211
206
  :method => :post,
@@ -222,11 +217,10 @@ describe "RSolr::Client" do
222
217
  end
223
218
 
224
219
  context "delete_by_query" do
225
- include ClientHelper
226
220
  it "should send data to the connection's #post method" do
227
- expect(client.connection).to receive(:execute).
221
+ expect(client).to receive(:execute).
228
222
  with(
229
- client, hash_including({
223
+ hash_including({
230
224
  :path => "update",
231
225
  :headers => {"Content-Type"=>"text/xml"},
232
226
  :method => :post,
@@ -243,7 +237,6 @@ describe "RSolr::Client" do
243
237
  end
244
238
 
245
239
  context "adapt_response" do
246
- include ClientHelper
247
240
  it 'should not try to evaluate ruby when the :qt is not :ruby' do
248
241
  body = '{"time"=>"NOW"}'
249
242
  result = client.adapt_response({:params=>{}}, {:status => 200, :body => body, :headers => {}})
@@ -281,9 +274,9 @@ describe "RSolr::Client" do
281
274
  end
282
275
 
283
276
  context "indifferent access" do
284
- include ClientHelper
285
277
  it "should raise a RuntimeError if the #with_indifferent_access extension isn't loaded" do
286
- hide_const("HashWithIndifferentAccess")
278
+ hide_const("::RSolr::HashWithIndifferentAccessWithResponse")
279
+ hide_const("ActiveSupport::HashWithIndifferentAccess")
287
280
  body = "{'foo'=>'bar'}"
288
281
  result = client.adapt_response({:params=>{:wt=>:ruby}}, {:status => 200, :body => body, :headers => {}})
289
282
  expect { result.with_indifferent_access }.to raise_error RuntimeError
@@ -306,7 +299,6 @@ describe "RSolr::Client" do
306
299
  end
307
300
 
308
301
  context "build_request" do
309
- include ClientHelper
310
302
  let(:data) { 'data' }
311
303
  let(:params) { { q: 'test', fq: [0,1] } }
312
304
  let(:options) { { method: :post, params: params, data: data, headers: {} } }
@@ -314,7 +306,7 @@ describe "RSolr::Client" do
314
306
 
315
307
  context "when params are symbols" do
316
308
  it 'should return a request context array' do
317
- [/fq=0/, /fq=1/, /q=test/, /wt=ruby/].each do |pattern|
309
+ [/fq=0/, /fq=1/, /q=test/, /wt=json/].each do |pattern|
318
310
  expect(subject[:query]).to match pattern
319
311
  end
320
312
  expect(subject[:data]).to eq("data")
@@ -336,11 +328,11 @@ describe "RSolr::Client" do
336
328
  let(:options) { { method: :post, data: data, headers: {} } }
337
329
 
338
330
  it "sets the Content-Type header to application/x-www-form-urlencoded; charset=UTF-8" do
339
- expect(subject[:query]).to eq("wt=ruby")
331
+ expect(subject[:query]).to eq("wt=json")
340
332
  [/fq=0/, /fq=1/, /q=test/].each do |pattern|
341
333
  expect(subject[:data]).to match pattern
342
334
  end
343
- expect(subject[:data]).not_to match /wt=ruby/
335
+ expect(subject[:data]).not_to match(/wt=json/)
344
336
  expect(subject[:headers]).to eq({"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8"})
345
337
  end
346
338
  end
@@ -351,7 +343,7 @@ describe "RSolr::Client" do
351
343
  :data => {:q=>'test', :fq=>[0,1]},
352
344
  :headers => {}
353
345
  )
354
- expect(result[:uri].to_s).to match /^http:\/\/localhost:9999\/solr\//
355
- end
346
+ expect(result[:uri].to_s).to match %r{^http://localhost:9999/solr/}
347
+ end
356
348
  end
357
349
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RSolr::Document do
4
+ describe RSolr::Field do
5
+ describe ".instance" do
6
+ subject { RSolr::Field }
7
+
8
+ it "uses the class name of the field value" do
9
+ expect(subject.instance({}, Time.new)).to be_a_kind_of(RSolr::TimeField)
10
+ end
11
+
12
+ it "uses the provided type option when it is a class" do
13
+ expect(subject.instance({:type => RSolr::TimeField}, nil)).to be_a_kind_of(RSolr::TimeField)
14
+ end
15
+
16
+ it "uses the provided type option when it is a string" do
17
+ expect(subject.instance({:type => 'Time'}, nil)).to be_a_kind_of(RSolr::TimeField)
18
+ end
19
+
20
+ it "falls back to the base Field class" do
21
+ expect(subject.instance({:type => 'UndefinedType'}, nil)).to be_a_kind_of(RSolr::Field)
22
+ end
23
+
24
+ it "defaults to the base Field class" do
25
+ expect(subject.instance({}, nil)).to be_a_kind_of(RSolr::Field)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe RSolr::TimeField do
31
+ it "convert value to string" do
32
+ time_value = Time.utc(2013, 9, 11, 18, 10, 0)
33
+ expect(RSolr::Field.instance({}, time_value).value).to eq '2013-09-11T18:10:00Z'
34
+ end
35
+
36
+ it "convert time to UTC" do
37
+ time_value = Time.new(2013, 9, 11, 18, 10, 0, '+02:00')
38
+ expect(RSolr::Field.instance({}, time_value).value).to eq '2013-09-11T16:10:00Z'
39
+ end
40
+ end
41
+
42
+ describe RSolr::DateField do
43
+ it "convert value to string" do
44
+ date_value = Date.new(2013, 9, 11)
45
+ expect(RSolr::Field.instance({}, date_value).value).to eq '2013-09-11T00:00:00Z'
46
+ end
47
+ end
48
+ end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
- describe "RSolr::Error" do
2
+
3
+ RSpec.describe RSolr::Error do
3
4
  def generate_error_with_backtrace(request, response)
4
5
  raise RSolr::Error::Http.new request, response
5
6
  rescue RSolr::Error::Http => exception
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RSolr::JSON do
4
+
5
+ let(:generator){ RSolr::JSON::Generator.new }
6
+
7
+ context :add do
8
+ # add a single hash ("doc")
9
+ it 'should create an add from a hash' do
10
+ data = {
11
+ :id=>"1",
12
+ :name=>'matt'
13
+ }
14
+ message = JSON.parse(generator.add(data), symbolize_names: true)
15
+ expect(message.length).to eq 1
16
+ expect(message.first).to eq data
17
+ end
18
+
19
+ # add an array of hashes
20
+ it 'should create many adds from an array of hashes' do
21
+ data = [
22
+ {
23
+ :id=>"1",
24
+ :name=>'matt'
25
+ },
26
+ {
27
+ :id=>"2",
28
+ :name=>'sam'
29
+ }
30
+ ]
31
+ message = JSON.parse(generator.add(data), symbolize_names: true)
32
+ expect(message).to eq data
33
+ end
34
+
35
+ it 'should yield a Document object when #add is called with a block' do
36
+ documents = [{:id=>1, :name=>'sam', :cat=>['cat 1', 'cat 2']}]
37
+ result = generator.add(documents) do |doc|
38
+ doc.field_by_name(:name).attrs[:boost] = 10
39
+ end
40
+
41
+ message = JSON.parse(result, symbolize_names: true)
42
+
43
+ expect(message.length).to eq 1
44
+ expect(message.first).to include name: { boost: 10, value: 'sam' }
45
+ end
46
+
47
+ context 'with add_attr' do
48
+ it 'should create an add command with the attributes from a hash' do
49
+ data = {
50
+ :id=>"1",
51
+ :name=>'matt'
52
+ }
53
+ message = JSON.parse(generator.add(data, boost: 1), symbolize_names: true)
54
+ expect(message).to include :add
55
+ expect(message[:add][:doc]).to eq data
56
+ expect(message[:add][:boost]).to eq 1
57
+ end
58
+
59
+ it 'should create multiple add command with the attributes from a hash' do
60
+ data = [
61
+ {
62
+ :id=>"1",
63
+ :name=>'matt'
64
+ },
65
+ {
66
+ :id=>"2",
67
+ :name=>'sam'
68
+ },
69
+ ]
70
+
71
+ # custom JSON object class to handle Solr's non-standard JSON command format
72
+ tmp = Class.new do
73
+ def initialize
74
+ @source ||= {}
75
+ end
76
+
77
+ def []=(k, v)
78
+ if k == :add
79
+ @source[k] ||= []
80
+ @source[k] << v.to_h
81
+ elsif v.class == self.class
82
+ @source[k] = v.to_h
83
+ else
84
+ @source[k] = v
85
+ end
86
+ end
87
+
88
+ def to_h
89
+ @source
90
+ end
91
+ end
92
+
93
+ request = generator.add(data, boost: 1)
94
+ message = JSON.parse(request, object_class: tmp, symbolize_names: true).to_h
95
+ expect(message[:add].length).to eq 2
96
+ expect(message[:add].map { |x| x[:doc] }).to eq data
97
+ end
98
+ end
99
+
100
+ it 'allows for atomic updates' do
101
+ data = {
102
+ foo: { set: 'Bar' }
103
+ }
104
+
105
+ message = JSON.parse(generator.add(data), symbolize_names: true)
106
+ expect(message.length).to eq 1
107
+ expect(message.first).to eq data
108
+ end
109
+
110
+ it 'supports nested child documents' do
111
+ data = {
112
+ _childDocuments_: [
113
+ {
114
+ id: 1
115
+ },
116
+ {
117
+ id: 2
118
+ }
119
+ ]
120
+ }
121
+
122
+ message = JSON.parse(generator.add(data), symbolize_names: true)
123
+ expect(message.length).to eq 1
124
+ expect(message.first).to eq data
125
+ end
126
+ end
127
+
128
+ it 'should create multiple fields from array values' do
129
+ data = {
130
+ :id => "1",
131
+ :name => ['matt1', 'matt2']
132
+ }
133
+ message = JSON.parse(generator.add(data), symbolize_names: true)
134
+ expect(message.length).to eq 1
135
+ expect(message.first).to eq data
136
+ end
137
+
138
+ describe '#commit' do
139
+ it 'generates a commit command' do
140
+ expect(JSON.parse(generator.commit, symbolize_names: true)).to eq(commit: {})
141
+ end
142
+ end
143
+
144
+ describe '#optimize' do
145
+ it 'generates a optimize command' do
146
+ expect(JSON.parse(generator.optimize, symbolize_names: true)).to eq(optimize: {})
147
+ end
148
+ end
149
+
150
+ describe '#rollback' do
151
+ it 'generates a rollback command' do
152
+ expect(JSON.parse(generator.rollback, symbolize_names: true)).to eq(rollback: {})
153
+ end
154
+ end
155
+
156
+ describe '#delete_by_id' do
157
+ it 'generates a delete_by_id command for single documents' do
158
+ expect(JSON.parse(generator.delete_by_id('x'), symbolize_names: true)).to eq(delete: 'x')
159
+ end
160
+
161
+ it 'generates a delete_by_id command for an array of documents' do
162
+ expect(JSON.parse(generator.delete_by_id(%w(a b c)), symbolize_names: true)).to eq(delete: %w(a b c))
163
+ end
164
+ end
165
+
166
+ describe '#delete_by_query' do
167
+ it 'generates a delete_by_id command for single documents' do
168
+ expect(JSON.parse(generator.delete_by_query('id:x'), symbolize_names: true)).to eq(delete: { query: 'id:x'})
169
+ end
170
+
171
+ it 'generates a delete_by_id command for an array of documents' do
172
+ expect(JSON.parse(generator.delete_by_id(%w(a b c)), symbolize_names: true)).to eq(delete: %w(a b c))
173
+ end
174
+ end
175
+ end