rsolr 1.0.10 → 1.0.11
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 +1 -0
- data/CHANGES.txt +14 -0
- data/Gemfile +1 -11
- data/README.rdoc +18 -15
- data/Rakefile +1 -10
- data/lib/rsolr/char.rb +3 -0
- data/lib/rsolr/client.rb +9 -12
- data/lib/rsolr/error.rb +2 -2
- data/lib/rsolr/response.rb +45 -15
- data/lib/rsolr/uri.rb +44 -27
- data/lib/rsolr/version.rb +1 -1
- data/lib/rsolr.rb +15 -8
- data/rsolr.gemspec +6 -4
- data/spec/api/char_spec.rb +8 -3
- data/spec/api/client_spec.rb +37 -38
- data/spec/api/connection_spec.rb +32 -30
- data/spec/api/error_spec.rb +6 -6
- data/spec/api/pagination_spec.rb +5 -5
- data/spec/api/rsolr_spec.rb +28 -8
- data/spec/api/uri_spec.rb +108 -50
- data/spec/api/xml_spec.rb +33 -34
- data/spec/spec_helper.rb +6 -1
- data/tasks/spec.rake +1 -38
- metadata +13 -13
- data/tasks/rcov.rake +0 -25
data/spec/api/client_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe "RSolr::Client" do
|
|
12
12
|
|
13
13
|
context "initialize" do
|
14
14
|
it "should accept whatevs and set it as the @connection" do
|
15
|
-
RSolr::Client.new(:whatevs).connection.
|
15
|
+
expect(RSolr::Client.new(:whatevs).connection).to eq(:whatevs)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -20,7 +20,7 @@ describe "RSolr::Client" do
|
|
20
20
|
include ClientHelper
|
21
21
|
it "should forward these method calls the #connection object" do
|
22
22
|
[:get, :post, :head].each do |meth|
|
23
|
-
client.connection.
|
23
|
+
expect(client.connection).to receive(:execute).
|
24
24
|
and_return({:status => 200, :body => "{}", :headers => {}})
|
25
25
|
client.send_and_receive '', :method => meth, :params => {}, :data => nil, :headers => {}
|
26
26
|
end
|
@@ -28,7 +28,7 @@ describe "RSolr::Client" do
|
|
28
28
|
|
29
29
|
it "should be timeout aware" do
|
30
30
|
[:get, :post, :head].each do |meth|
|
31
|
-
client.connection.
|
31
|
+
expect(client.connection).to receive(:execute).with(client, hash_including(:read_timeout => 42, :open_timeout=>43))
|
32
32
|
client.send_and_receive '', :method => meth, :params => {}, :data => nil, :headers => {}
|
33
33
|
end
|
34
34
|
end
|
@@ -48,21 +48,21 @@ describe "RSolr::Client" do
|
|
48
48
|
}
|
49
49
|
end
|
50
50
|
it "should retry 503s if requested" do
|
51
|
-
client.connection.
|
51
|
+
expect(client.connection).to receive(:execute).exactly(2).times.and_return(
|
52
52
|
{:status => 503, :body => "{}", :headers => {'Retry-After' => 0}},
|
53
53
|
{:status => 200, :body => "{}", :headers => {}}
|
54
54
|
)
|
55
55
|
client.execute request_context
|
56
56
|
end
|
57
57
|
it "should not retry a 503 if the retry-after is too large" do
|
58
|
-
client.connection.
|
58
|
+
expect(client.connection).to receive(:execute).exactly(1).times.and_return(
|
59
59
|
{:status => 503, :body => "{}", :headers => {'Retry-After' => 10}}
|
60
60
|
)
|
61
|
-
|
61
|
+
expect {
|
62
62
|
Timeout.timeout(0.5) do
|
63
63
|
client.execute({:retry_after_limit => 0}.merge(request_context))
|
64
64
|
end
|
65
|
-
}.
|
65
|
+
}.to raise_error(RSolr::Error::Http)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -70,7 +70,7 @@ describe "RSolr::Client" do
|
|
70
70
|
include ClientHelper
|
71
71
|
it "should pass the expected params to the connection's #execute method" do
|
72
72
|
request_opts = {:data => "the data", :method=>:post, :headers => {"Content-Type" => "text/plain"}}
|
73
|
-
client.connection.
|
73
|
+
expect(client.connection).to receive(:execute).
|
74
74
|
with(client, hash_including(request_opts)).
|
75
75
|
and_return(
|
76
76
|
:body => "",
|
@@ -84,14 +84,14 @@ describe "RSolr::Client" do
|
|
84
84
|
context "xml" do
|
85
85
|
include ClientHelper
|
86
86
|
it "should return an instance of RSolr::Xml::Generator" do
|
87
|
-
client.xml.
|
87
|
+
expect(client.xml).to be_a RSolr::Xml::Generator
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
context "add" do
|
92
92
|
include ClientHelper
|
93
93
|
it "should send xml to the connection's #post method" do
|
94
|
-
client.connection.
|
94
|
+
expect(client.connection).to receive(:execute).
|
95
95
|
with(
|
96
96
|
client, hash_including({
|
97
97
|
:path => "update",
|
@@ -105,7 +105,7 @@ describe "RSolr::Client" do
|
|
105
105
|
:status => 200,
|
106
106
|
:headers => {"Content-Type"=>"text/xml"}
|
107
107
|
)
|
108
|
-
client.xml.
|
108
|
+
expect(client.xml).to receive(:add).
|
109
109
|
with({:id=>1}, {:commitWith=>10}).
|
110
110
|
and_return("<xml/>")
|
111
111
|
client.add({:id=>1}, :add_attributes => {:commitWith=>10})
|
@@ -115,7 +115,7 @@ describe "RSolr::Client" do
|
|
115
115
|
context "update" do
|
116
116
|
include ClientHelper
|
117
117
|
it "should send data to the connection's #post method" do
|
118
|
-
client.connection.
|
118
|
+
expect(client.connection).to receive(:execute).
|
119
119
|
with(
|
120
120
|
client, hash_including({
|
121
121
|
:path => "update",
|
@@ -137,7 +137,7 @@ describe "RSolr::Client" do
|
|
137
137
|
include ClientHelper
|
138
138
|
[:commit, :optimize, :rollback].each do |meth|
|
139
139
|
it "should send a #{meth} message to the connection's #post method" do
|
140
|
-
client.connection.
|
140
|
+
expect(client.connection).to receive(:execute).
|
141
141
|
with(
|
142
142
|
client, hash_including({
|
143
143
|
:path => "update",
|
@@ -159,7 +159,7 @@ describe "RSolr::Client" do
|
|
159
159
|
context "delete_by_id" do
|
160
160
|
include ClientHelper
|
161
161
|
it "should send data to the connection's #post method" do
|
162
|
-
client.connection.
|
162
|
+
expect(client.connection).to receive(:execute).
|
163
163
|
with(
|
164
164
|
client, hash_including({
|
165
165
|
:path => "update",
|
@@ -180,7 +180,7 @@ describe "RSolr::Client" do
|
|
180
180
|
context "delete_by_query" do
|
181
181
|
include ClientHelper
|
182
182
|
it "should send data to the connection's #post method" do
|
183
|
-
client.connection.
|
183
|
+
expect(client.connection).to receive(:execute).
|
184
184
|
with(
|
185
185
|
client, hash_including({
|
186
186
|
:path => "update",
|
@@ -203,42 +203,41 @@ describe "RSolr::Client" do
|
|
203
203
|
it 'should not try to evaluate ruby when the :qt is not :ruby' do
|
204
204
|
body = '{:time=>"NOW"}'
|
205
205
|
result = client.adapt_response({:params=>{}}, {:status => 200, :body => body, :headers => {}})
|
206
|
-
result.
|
206
|
+
expect(result).to eq(body)
|
207
207
|
end
|
208
208
|
|
209
209
|
it 'should evaluate ruby responses when the :wt is :ruby' do
|
210
210
|
body = '{:time=>"NOW"}'
|
211
211
|
result = client.adapt_response({:params=>{:wt=>:ruby}}, {:status => 200, :body => body, :headers => {}})
|
212
|
-
result.
|
212
|
+
expect(result).to eq({:time=>"NOW"})
|
213
213
|
end
|
214
214
|
|
215
215
|
it 'should evaluate json responses when the :wt is :json' do
|
216
216
|
body = '{"time": "NOW"}'
|
217
217
|
result = client.adapt_response({:params=>{:wt=>:json}}, {:status => 200, :body => body, :headers => {}})
|
218
218
|
if defined? JSON
|
219
|
-
result.
|
219
|
+
expect(result).to eq({:time=>"NOW"})
|
220
220
|
else
|
221
221
|
# ruby 1.8 without the JSON gem
|
222
|
-
result.
|
222
|
+
expect(result).to eq('{"time": "NOW"}')
|
223
223
|
end
|
224
224
|
end
|
225
225
|
|
226
226
|
it "ought raise a RSolr::Error::InvalidRubyResponse when the ruby is indeed frugged, or even fruggified" do
|
227
|
-
|
227
|
+
expect {
|
228
228
|
client.adapt_response({:params=>{:wt => :ruby}}, {:status => 200, :body => "<woops/>", :headers => {}})
|
229
|
-
}.
|
229
|
+
}.to raise_error RSolr::Error::InvalidRubyResponse
|
230
230
|
end
|
231
231
|
|
232
232
|
end
|
233
233
|
|
234
234
|
context "indifferent access" do
|
235
235
|
include ClientHelper
|
236
|
-
it "should raise a
|
237
|
-
|
238
|
-
Hash.any_instance.should_receive(:respond_to?).with(:with_indifferent_access).and_return(false)
|
236
|
+
it "should raise a RuntimeError if the #with_indifferent_access extension isn't loaded" do
|
237
|
+
hide_const("HashWithIndifferentAccess")
|
239
238
|
body = "{'foo'=>'bar'}"
|
240
239
|
result = client.adapt_response({:params=>{:wt=>:ruby}}, {:status => 200, :body => body, :headers => {}})
|
241
|
-
|
240
|
+
expect { result.with_indifferent_access }.to raise_error RuntimeError
|
242
241
|
end
|
243
242
|
|
244
243
|
it "should provide indifferent access" do
|
@@ -247,13 +246,13 @@ describe "RSolr::Client" do
|
|
247
246
|
result = client.adapt_response({:params=>{:wt=>:ruby}}, {:status => 200, :body => body, :headers => {}})
|
248
247
|
indifferent_result = result.with_indifferent_access
|
249
248
|
|
250
|
-
result.
|
251
|
-
result['foo'].
|
252
|
-
result[:foo].
|
249
|
+
expect(result).to be_a(RSolr::Response)
|
250
|
+
expect(result['foo']).to eq('bar')
|
251
|
+
expect(result[:foo]).to be_nil
|
253
252
|
|
254
|
-
indifferent_result.
|
255
|
-
indifferent_result['foo'].
|
256
|
-
indifferent_result[:foo].
|
253
|
+
expect(indifferent_result).to be_a(RSolr::Response)
|
254
|
+
expect(indifferent_result['foo']).to eq('bar')
|
255
|
+
expect(indifferent_result[:foo]).to eq('bar')
|
257
256
|
end
|
258
257
|
end
|
259
258
|
|
@@ -267,10 +266,10 @@ describe "RSolr::Client" do
|
|
267
266
|
:headers => {}
|
268
267
|
)
|
269
268
|
[/fq=0/, /fq=1/, /q=test/, /wt=ruby/].each do |pattern|
|
270
|
-
result[:query].
|
269
|
+
expect(result[:query]).to match pattern
|
271
270
|
end
|
272
|
-
result[:data].
|
273
|
-
result[:headers].
|
271
|
+
expect(result[:data]).to eq("data")
|
272
|
+
expect(result[:headers]).to eq({})
|
274
273
|
end
|
275
274
|
|
276
275
|
it "should set the Content-Type header to application/x-www-form-urlencoded; charset=UTF-8 if a hash is passed in to the data arg" do
|
@@ -279,12 +278,12 @@ describe "RSolr::Client" do
|
|
279
278
|
:data => {:q=>'test', :fq=>[0,1]},
|
280
279
|
:headers => {}
|
281
280
|
)
|
282
|
-
result[:query].
|
281
|
+
expect(result[:query]).to eq("wt=ruby")
|
283
282
|
[/fq=0/, /fq=1/, /q=test/].each do |pattern|
|
284
|
-
result[:data].
|
283
|
+
expect(result[:data]).to match pattern
|
285
284
|
end
|
286
|
-
result[:data].
|
287
|
-
result[:headers].
|
285
|
+
expect(result[:data]).not_to match /wt=ruby/
|
286
|
+
expect(result[:headers]).to eq({"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8"})
|
288
287
|
end
|
289
288
|
|
290
289
|
end
|
data/spec/api/connection_spec.rb
CHANGED
@@ -4,93 +4,95 @@ require 'base64'
|
|
4
4
|
describe "RSolr::Connection" do
|
5
5
|
|
6
6
|
context "setup_raw_request" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
it "should set the correct request parameters" do
|
8
|
+
c = RSolr::Connection.new
|
9
|
+
base_url = "http://localhost:8983/solr"
|
10
|
+
client = RSolr::Client.new c, :url => base_url
|
11
|
+
req = c.send :setup_raw_request, {:headers => {"content-type" => "text/xml"}, :method => :get, :uri => URI.parse(base_url + "/select?q=*:*")}
|
12
|
+
expect(req.path).to eq("/solr/select?q=*:*")
|
13
|
+
headers = {}
|
14
|
+
req.each_header{|k,v| headers[k] = v}
|
15
|
+
expect(headers).to eq({"content-type"=>"text/xml"})
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
context "read timeout configuration" do
|
18
|
-
let(:client) {
|
20
|
+
let(:client) { double.as_null_object }
|
19
21
|
|
20
|
-
let(:http) {
|
22
|
+
let(:http) { double(Net::HTTP).as_null_object }
|
21
23
|
|
22
24
|
subject { RSolr::Connection.new }
|
23
25
|
|
24
26
|
before do
|
25
|
-
Net::HTTP.
|
27
|
+
allow(Net::HTTP).to receive(:new) { http }
|
26
28
|
end
|
27
29
|
|
28
30
|
it "should configure Net:HTTP read_timeout" do
|
29
|
-
http.
|
31
|
+
expect(http).to receive(:read_timeout=).with(42)
|
30
32
|
subject.execute client, {:uri => URI.parse("http://localhost/some_uri"), :method => :get, :read_timeout => 42}
|
31
33
|
end
|
32
34
|
|
33
35
|
it "should use Net:HTTP default read_timeout if not specified" do
|
34
|
-
http.
|
36
|
+
expect(http).not_to receive(:read_timeout=)
|
35
37
|
subject.execute client, {:uri => URI.parse("http://localhost/some_uri"), :method => :get}
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
41
|
context "open timeout configuration" do
|
40
|
-
let(:client) {
|
42
|
+
let(:client) { double.as_null_object }
|
41
43
|
|
42
|
-
let(:http) {
|
44
|
+
let(:http) { double(Net::HTTP).as_null_object }
|
43
45
|
|
44
46
|
subject { RSolr::Connection.new }
|
45
47
|
|
46
48
|
before do
|
47
|
-
Net::HTTP.
|
49
|
+
allow(Net::HTTP).to receive(:new) { http }
|
48
50
|
end
|
49
51
|
|
50
52
|
it "should configure Net:HTTP open_timeout" do
|
51
|
-
http.
|
53
|
+
expect(http).to receive(:open_timeout=).with(42)
|
52
54
|
subject.execute client, {:uri => URI.parse("http://localhost/some_uri"), :method => :get, :open_timeout => 42}
|
53
55
|
end
|
54
56
|
|
55
57
|
it "should use Net:HTTP default open_timeout if not specified" do
|
56
|
-
http.
|
58
|
+
expect(http).not_to receive(:open_timeout=)
|
57
59
|
subject.execute client, {:uri => URI.parse("http://localhost/some_uri"), :method => :get}
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
63
|
context "connection refused" do
|
62
|
-
let(:client) {
|
64
|
+
let(:client) { double.as_null_object }
|
63
65
|
|
64
|
-
let(:http) {
|
66
|
+
let(:http) { double(Net::HTTP).as_null_object }
|
65
67
|
let(:request_context) {
|
66
68
|
{:uri => URI.parse("http://localhost/some_uri"), :method => :get, :open_timeout => 42}
|
67
69
|
}
|
68
70
|
subject { RSolr::Connection.new }
|
69
71
|
|
70
72
|
before do
|
71
|
-
Net::HTTP.
|
73
|
+
allow(Net::HTTP).to receive(:new) { http }
|
72
74
|
end
|
73
75
|
|
74
76
|
it "should configure Net:HTTP open_timeout" do
|
75
|
-
|
76
|
-
http.
|
77
|
-
|
77
|
+
skip "doesn't work with ruby 1.8" if RUBY_VERSION < "1.9"
|
78
|
+
expect(http).to receive(:request).and_raise(Errno::ECONNREFUSED)
|
79
|
+
expect {
|
78
80
|
subject.execute client, request_context
|
79
|
-
}.
|
81
|
+
}.to raise_error(Errno::ECONNREFUSED, /#{request_context}/)
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
83
85
|
describe "basic auth support" do
|
84
|
-
let(:http) {
|
86
|
+
let(:http) { double(Net::HTTP).as_null_object }
|
85
87
|
|
86
88
|
before do
|
87
|
-
Net::HTTP.
|
89
|
+
allow(Net::HTTP).to receive(:new) { http }
|
88
90
|
end
|
89
91
|
|
90
92
|
it "sets the authorization header" do
|
91
|
-
http.
|
92
|
-
request.fetch('authorization').
|
93
|
-
|
93
|
+
expect(http).to receive(:request) do |request|
|
94
|
+
expect(request.fetch('authorization')).to eq("Basic #{Base64.encode64("joe:pass")}".strip)
|
95
|
+
double(Net::HTTPResponse).as_null_object
|
94
96
|
end
|
95
97
|
RSolr::Connection.new.execute nil, :uri => URI.parse("http://joe:pass@localhost:8983/solr"), :method => :get
|
96
98
|
end
|
data/spec/api/error_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe "RSolr::Error" do
|
|
10
10
|
before do
|
11
11
|
response_lines = (1..15).to_a.map { |i| "line #{i}" }
|
12
12
|
|
13
|
-
@request =
|
13
|
+
@request = double :[] => "mocked"
|
14
14
|
@response = {
|
15
15
|
:body => "<pre>" + response_lines.join("\n") + "</pre>",
|
16
16
|
:status => 400
|
@@ -19,14 +19,14 @@ describe "RSolr::Error" do
|
|
19
19
|
|
20
20
|
it "only shows the first eleven lines of the response" do
|
21
21
|
error = generate_error_with_backtrace @request, @response
|
22
|
-
error.to_s.
|
22
|
+
expect(error.to_s).to match(/line 1\n.+line 11\n\n/m)
|
23
23
|
end
|
24
24
|
|
25
25
|
it "shows only one line when the response is one line long" do
|
26
26
|
@response[:body] = "<pre>failed</pre>"
|
27
27
|
|
28
28
|
error = generate_error_with_backtrace @request, @response
|
29
|
-
error.to_s.
|
29
|
+
expect(error.to_s).to match(/Error: failed/)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -34,7 +34,7 @@ describe "RSolr::Error" do
|
|
34
34
|
before do
|
35
35
|
response_lines = (1..15).to_a.map { |i| "line #{i}" }
|
36
36
|
|
37
|
-
@request =
|
37
|
+
@request = double :[] => "mocked"
|
38
38
|
@response = {
|
39
39
|
:body => response_lines.join("\n"),
|
40
40
|
:status => 400
|
@@ -43,14 +43,14 @@ describe "RSolr::Error" do
|
|
43
43
|
|
44
44
|
it "only shows the first eleven lines of the response" do
|
45
45
|
error = generate_error_with_backtrace @request, @response
|
46
|
-
error.to_s.
|
46
|
+
expect(error.to_s).to match(/line 1\n.+line 11\n\n/m)
|
47
47
|
end
|
48
48
|
|
49
49
|
it "shows only one line when the response is one line long" do
|
50
50
|
@response[:body] = "failed"
|
51
51
|
|
52
52
|
error = generate_error_with_backtrace @request, @response
|
53
|
-
error.to_s.
|
53
|
+
expect(error.to_s).to match(/Error: failed/)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
data/spec/api/pagination_spec.rb
CHANGED
@@ -6,16 +6,16 @@ describe "RSolr::Pagination" do
|
|
6
6
|
r = c.build_paginated_request 3, 25, "select", {:params => {:q => "test"}}
|
7
7
|
#r[:page].should == 3
|
8
8
|
#r[:per_page].should == 25
|
9
|
-
r[:params]["start"].
|
10
|
-
r[:params]["rows"].
|
11
|
-
r[:uri].query.
|
12
|
-
r[:uri].query.
|
9
|
+
expect(r[:params]["start"]).to eq(50)
|
10
|
+
expect(r[:params]["rows"]).to eq(25)
|
11
|
+
expect(r[:uri].query).to match(/rows=25/)
|
12
|
+
expect(r[:uri].query).to match(/start=50/)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
context "paginate" do
|
16
16
|
it "should build a paginated request context and call execute" do
|
17
17
|
c = RSolr::Client.new(nil, {})#.extend(RSolr::Pagination::Client)
|
18
|
-
c.
|
18
|
+
expect(c).to receive(:execute).with(hash_including({
|
19
19
|
#:page => 1,
|
20
20
|
#:per_page => 10,
|
21
21
|
:params => {
|
data/spec/api/rsolr_spec.rb
CHANGED
@@ -2,18 +2,38 @@ require 'spec_helper'
|
|
2
2
|
describe "RSolr" do
|
3
3
|
|
4
4
|
it "has a version that can be read via #version or VERSION" do
|
5
|
-
RSolr.version.
|
5
|
+
expect(RSolr.version).to eq(RSolr::VERSION)
|
6
6
|
end
|
7
|
-
|
8
|
-
it "can escape" do
|
9
|
-
RSolr.should be_a(RSolr::Char)
|
10
|
-
RSolr.escape("this string").should == "this\\ string"
|
11
|
-
end
|
12
|
-
|
7
|
+
|
13
8
|
context "connect" do
|
14
9
|
it "should return a RSolr::Client instance" do
|
15
|
-
RSolr.connect.
|
10
|
+
expect(RSolr.connect).to be_a(RSolr::Client)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context '.solr_escape' do
|
15
|
+
it "adds backslash to Solr query syntax chars" do
|
16
|
+
# per http://lucene.apache.org/core/4_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Escaping_Special_Characters
|
17
|
+
special_chars = [ "+", "-", "&", "|", "!", "(", ")", "{", "}", "[", "]", "^", '"', "~", "*", "?", ":", "\\", "/" ]
|
18
|
+
escaped_str = RSolr.solr_escape("aa#{special_chars.join('aa')}aa")
|
19
|
+
special_chars.each { |c|
|
20
|
+
# note that the ruby code sending the query to Solr will un-escape the backslashes
|
21
|
+
# so the result sent to Solr is ultimately a single backslash in front of the particular character
|
22
|
+
expect(escaped_str).to match "\\#{c}"
|
23
|
+
}
|
24
|
+
end
|
25
|
+
it "leaves other chars alone" do
|
26
|
+
str = "nothing to see here; let's move along people."
|
27
|
+
expect(RSolr.solr_escape(str)).to eq str
|
16
28
|
end
|
17
29
|
end
|
30
|
+
|
31
|
+
# deprecated as of 2015-02
|
32
|
+
=begin
|
33
|
+
it "can escape" do
|
34
|
+
expect(RSolr).to be_a(RSolr::Char)
|
35
|
+
expect(RSolr.escape("this string")).to eq("this\\ string")
|
36
|
+
end
|
37
|
+
=end
|
18
38
|
|
19
39
|
end
|
data/spec/api/uri_spec.rb
CHANGED
@@ -1,70 +1,128 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
describe "RSolr::Uri" do
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
it "should return a URI object with a trailing slash" do
|
4
|
+
let(:uri) { RSolr::Uri }
|
5
|
+
|
6
|
+
context '.create' do
|
7
|
+
it "returns a URI object" do
|
9
8
|
u = uri.create 'http://apache.org'
|
10
|
-
u.
|
9
|
+
expect(u).to be_a_kind_of URI
|
11
10
|
end
|
12
|
-
|
13
|
-
|
14
|
-
uri.
|
11
|
+
it "calls URI.parse" do
|
12
|
+
expect(URI).to receive(:parse).twice.and_call_original
|
13
|
+
u = uri.create 'http://apache.org'
|
15
14
|
end
|
16
|
-
|
17
|
-
|
15
|
+
it "adds a trailing slash after host if there is none" do
|
16
|
+
u = uri.create 'http://apache.org'
|
17
|
+
u_str = u.to_s
|
18
|
+
size = u_str.size
|
19
|
+
expect(u_str[size - 1]).to eq '/'
|
20
|
+
end
|
21
|
+
it "does not add trailing slash after host if there already is one" do
|
22
|
+
u = uri.create 'http://apache.org/'
|
23
|
+
u_str = u.to_s
|
24
|
+
size = u_str.size
|
25
|
+
expect(u_str[size - 2, 2]).to eq 'g/'
|
26
|
+
end
|
27
|
+
it "adds a trailing slash after path if there is none" do
|
28
|
+
u = uri.create 'http://apache.org/lucene'
|
29
|
+
u_str = u.to_s
|
30
|
+
size = u_str.size
|
31
|
+
expect(u_str[size - 1]).to eq '/'
|
32
|
+
end
|
33
|
+
it "does not add trailing slash after path if there already is one" do
|
34
|
+
u = uri.create 'http://apache.org/lucene/'
|
35
|
+
u_str = u.to_s
|
36
|
+
size = u_str.size
|
37
|
+
expect(u_str[size - 2, 2]).to eq 'e/'
|
38
|
+
end
|
39
|
+
it "does not add trailing slash if there are query params" do
|
40
|
+
u = uri.create 'http://apache.org?foo=bar'
|
41
|
+
u_str = u.to_s
|
42
|
+
size = u_str.size
|
43
|
+
expect(u_str[size - 1]).not_to eq '/'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context '.params_to_solr' do
|
48
|
+
it "converts Hash to Solr query string w/o a starting ?" do
|
18
49
|
hash = {:q => "gold", :fq => ["mode:one", "level:2"]}
|
19
50
|
query = uri.params_to_solr hash
|
20
|
-
query[0].
|
51
|
+
expect(query[0]).not_to eq(??)
|
21
52
|
[/q=gold/, /fq=mode%3Aone/, /fq=level%3A2/].each do |p|
|
22
|
-
query.
|
53
|
+
expect(query).to match p
|
23
54
|
end
|
24
|
-
query.split('&').size.
|
55
|
+
expect(query.split('&').size).to eq(3)
|
56
|
+
end
|
57
|
+
it 'should URL escape &' do
|
58
|
+
expect(uri.params_to_solr(:fq => "&")).to eq('fq=%26')
|
25
59
|
end
|
26
|
-
|
27
|
-
context "escape_query_value" do
|
28
|
-
|
29
|
-
it 'should escape &' do
|
30
|
-
uri.params_to_solr(:fq => "&").should == 'fq=%26'
|
31
|
-
end
|
32
60
|
|
33
|
-
|
34
|
-
|
35
|
-
|
61
|
+
it 'should convert spaces to +' do
|
62
|
+
expect(uri.params_to_solr(:fq => "me and you")).to eq('fq=me+and+you')
|
63
|
+
end
|
36
64
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
65
|
+
it 'should URL escape complex queries, part 1' do
|
66
|
+
my_params = {'fq' => '{!raw f=field_name}crazy+\"field+value'}
|
67
|
+
expected = 'fq=%7B%21raw+f%3Dfield_name%7Dcrazy%2B%5C%22field%2Bvalue'
|
68
|
+
expect(uri.params_to_solr(my_params)).to eq(expected)
|
69
|
+
end
|
42
70
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
71
|
+
it 'should URL escape complex queries, part 2' do
|
72
|
+
my_params = {'q' => '+popularity:[10 TO *] +section:0'}
|
73
|
+
expected = 'q=%2Bpopularity%3A%5B10+TO+*%5D+%2Bsection%3A0'
|
74
|
+
expect(uri.params_to_solr(my_params)).to eq(expected)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
=begin
|
79
|
+
# deprecated
|
80
|
+
context '.build_param' do
|
81
|
+
it "calls URI.encode_www_form_component by default" do
|
82
|
+
expect(URI).to receive(:encode_www_form_component).twice
|
83
|
+
uri.build_param("foo", "bar")
|
84
|
+
end
|
85
|
+
it "calls URI.encode_www_form_component if escape arg = true" do
|
86
|
+
expect(URI).to receive(:encode_www_form_component).twice
|
87
|
+
uri.build_param("foo", "bar", true)
|
88
|
+
end
|
89
|
+
it "doesn't call URI.encode_www_form_component if escape arg = false" do
|
90
|
+
expect(URI).not_to receive(:encode_www_form_component)
|
91
|
+
uri.build_param("foo", "bar", false)
|
92
|
+
end
|
93
|
+
end
|
56
94
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
95
|
+
# deprecated
|
96
|
+
context ".escape_query_value" do
|
97
|
+
it 'should escape properly' do
|
98
|
+
expect(uri.escape_query_value('+')).to eq('%2B')
|
99
|
+
expect(uri.escape_query_value('This is a test')).to eq('This+is+a+test')
|
100
|
+
expect(uri.escape_query_value('<>/\\')).to eq('%3C%3E%2F%5C')
|
101
|
+
expect(uri.escape_query_value('"')).to eq('%22')
|
102
|
+
expect(uri.escape_query_value(':')).to eq('%3A')
|
103
|
+
end
|
61
104
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
105
|
+
it 'should escape brackets' do
|
106
|
+
expect(uri.escape_query_value('{')).to eq('%7B')
|
107
|
+
expect(uri.escape_query_value('}')).to eq('%7D')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should escape exclamation marks!' do
|
111
|
+
expect(uri.escape_query_value('!')).to eq('%21')
|
66
112
|
end
|
67
|
-
|
68
113
|
end
|
69
114
|
|
115
|
+
# deprecated
|
116
|
+
context '.bytesize' do
|
117
|
+
it "calls .bytesize for String" do
|
118
|
+
str = "testing"
|
119
|
+
expect(str).to receive(:bytesize)
|
120
|
+
uri.bytesize(str)
|
121
|
+
end
|
122
|
+
it "returns the size of a String" do
|
123
|
+
expect(uri.bytesize("test")).to eq(4)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
=end
|
127
|
+
|
70
128
|
end
|