berkeley_library-util 0.1.4 → 0.1.6
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/.github/workflows/build.yml +17 -5
- data/.idea/inspectionProfiles/Project_Default.xml +1 -0
- data/.idea/util.iml +48 -51
- data/.rubocop.yml +161 -2
- data/.simplecov +5 -6
- data/CHANGES.md +17 -0
- data/Rakefile +2 -2
- data/berkeley_library-util.gemspec +5 -6
- data/lib/berkeley_library/util/arrays.rb +3 -3
- data/lib/berkeley_library/util/files.rb +2 -2
- data/lib/berkeley_library/util/module_info.rb +1 -1
- data/lib/berkeley_library/util/uris/appender.rb +15 -19
- data/lib/berkeley_library/util/uris/requester.rb +40 -13
- data/lib/berkeley_library/util/uris.rb +68 -3
- data/rakelib/.rubocop.yml +4 -0
- data/spec/.rubocop.yml +89 -0
- data/spec/berkeley_library/util/arrays_spec.rb +10 -1
- data/spec/berkeley_library/util/files_spec.rb +1 -0
- data/spec/berkeley_library/util/stringios_spec.rb +7 -0
- data/spec/berkeley_library/util/strings_spec.rb +4 -0
- data/spec/berkeley_library/util/times_spec.rb +4 -0
- data/spec/berkeley_library/util/uris/requester_spec.rb +79 -0
- data/spec/berkeley_library/util/uris_spec.rb +157 -14
- data/spec/spec_helper.rb +2 -2
- metadata +16 -54
- data/rakelib/bundle.rake +0 -8
@@ -3,6 +3,10 @@ require 'spec_helper'
|
|
3
3
|
module BerkeleyLibrary::Util
|
4
4
|
describe URIs do
|
5
5
|
describe :append do
|
6
|
+
it 'rejects a nil URI' do
|
7
|
+
expect { URIs.append(nil, 'foo') }.to raise_error(ArgumentError)
|
8
|
+
end
|
9
|
+
|
6
10
|
it 'appends paths' do
|
7
11
|
original_uri = URI('https://example.org/foo/bar')
|
8
12
|
new_uri = URIs.append(original_uri, 'qux', 'corge', 'garply')
|
@@ -16,16 +20,14 @@ module BerkeleyLibrary::Util
|
|
16
20
|
expect(new_uri).to eq(expected_uri)
|
17
21
|
end
|
18
22
|
|
19
|
-
|
20
|
-
xit "doesn't append to a bare URI when there's nothing to append" do
|
23
|
+
it 'returns a bare URI when there\'s nothing to append' do
|
21
24
|
original_url = 'https://example.org'
|
22
25
|
new_uri = URIs.append(original_url)
|
23
26
|
expected_uri = URI(original_url)
|
24
27
|
expect(new_uri).to eq(expected_uri)
|
25
28
|
end
|
26
29
|
|
27
|
-
|
28
|
-
xit "doesn't append to a bare URI when there's only a query string" do
|
30
|
+
it 'appends to a bare URI even when there\'s only a query string' do
|
29
31
|
original_url = 'https://example.org'
|
30
32
|
new_uri = URIs.append(original_url, '?foo=bar')
|
31
33
|
expected_uri = URI("#{original_url}?foo=bar")
|
@@ -94,29 +96,67 @@ module BerkeleyLibrary::Util
|
|
94
96
|
expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?baz=qux#grault'))
|
95
97
|
end
|
96
98
|
|
97
|
-
it 'rejects a query string if the original URI already has one' do
|
98
|
-
original_uri = URI('https://example.org/foo/bar?baz=qux')
|
99
|
-
expect { URIs.append(original_uri, '/qux?corge') }.to raise_error(URI::InvalidComponentError)
|
100
|
-
end
|
101
|
-
|
102
99
|
it 'rejects a fragment if the original URI already has one' do
|
103
100
|
original_uri = URI('https://example.org/foo/bar#baz')
|
104
101
|
expect { URIs.append(original_uri, '/qux#corge') }.to raise_error(URI::InvalidComponentError)
|
105
102
|
end
|
106
103
|
|
107
|
-
|
104
|
+
# Per RFC3986, "3.4. Query"
|
105
|
+
it 'allows queries containing ?' do
|
108
106
|
original_uri = URI('https://example.org/foo/bar')
|
109
|
-
|
107
|
+
expected_url = "#{original_uri}/baz?qux=corge?grault?plugh=xyzzy"
|
108
|
+
expected_uri = URI.parse(expected_url)
|
109
|
+
|
110
|
+
uri1 = URIs.append(original_uri, 'baz?qux=corge', '?grault?plugh=xyzzy')
|
111
|
+
expect(uri1).to eq(expected_uri)
|
112
|
+
|
113
|
+
uri2 = URIs.append(original_uri, 'baz?qux=corge?grault?plugh=xyzzy')
|
114
|
+
expect(uri2).to eq(expected_uri)
|
110
115
|
end
|
111
116
|
|
112
|
-
|
117
|
+
# Per RFC3986, "3.4. Query"
|
118
|
+
it 'allows queries containing /' do
|
119
|
+
original_uri = URI('https://example.org/foo/bar')
|
120
|
+
expected_url = "#{original_uri}/baz?qux=corge/grault/plugh=xyzzy"
|
121
|
+
expected_uri = URI.parse(expected_url)
|
122
|
+
|
123
|
+
uri1 = URIs.append(original_uri, 'baz?qux=corge', '/grault/plugh=xyzzy')
|
124
|
+
expect(uri1).to eq(expected_uri)
|
125
|
+
|
126
|
+
uri2 = URIs.append(original_uri, 'baz?qux=corge/grault/plugh=xyzzy')
|
127
|
+
expect(uri2).to eq(expected_uri)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'rejects fragments containing #' do
|
113
131
|
original_uri = URI('https://example.org/foo/bar')
|
114
132
|
expect { URIs.append(original_uri, 'baz#qux', 'grault#plugh') }.to raise_error(URI::InvalidComponentError)
|
133
|
+
expect { URIs.append(original_uri, 'baz#qux#plugh') }.to raise_error(URI::InvalidComponentError)
|
115
134
|
end
|
116
135
|
|
117
|
-
|
136
|
+
# Per RFC3986, "3.5. Fragment"
|
137
|
+
it 'allows fragments containing ?' do
|
118
138
|
original_uri = URI('https://example.org/foo/bar')
|
119
|
-
|
139
|
+
expected_url = "#{original_uri}/baz#qux?grault=plugh"
|
140
|
+
expected_uri = URI.parse(expected_url)
|
141
|
+
|
142
|
+
uri1 = URIs.append(original_uri, 'baz#qux', '?grault=plugh')
|
143
|
+
expect(uri1).to eq(expected_uri)
|
144
|
+
|
145
|
+
uri2 = URIs.append(original_uri, 'baz#qux?grault=plugh')
|
146
|
+
expect(uri2).to eq(expected_uri)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Per RFC3986, "3.5. Fragment"
|
150
|
+
it 'allows fragments containing /' do
|
151
|
+
original_uri = URI('https://example.org/foo/bar')
|
152
|
+
expected_url = "#{original_uri}/baz#qux/grault=plugh"
|
153
|
+
expected_uri = URI.parse(expected_url)
|
154
|
+
|
155
|
+
uri1 = URIs.append(original_uri, 'baz#qux', '/grault=plugh')
|
156
|
+
expect(uri1).to eq(expected_uri)
|
157
|
+
|
158
|
+
uri2 = URIs.append(original_uri, 'baz#qux/grault=plugh')
|
159
|
+
expect(uri2).to eq(expected_uri)
|
120
160
|
end
|
121
161
|
|
122
162
|
it 'correctly handles fragments in mid-path-segment' do
|
@@ -136,6 +176,28 @@ module BerkeleyLibrary::Util
|
|
136
176
|
new_uri = URIs.append(original_uri, '?qux=corge', '&grault=plugh#xyzzy')
|
137
177
|
expect(new_uri).to eq(URI('https://example.org/foo/bar?qux=corge&grault=plugh#xyzzy'))
|
138
178
|
end
|
179
|
+
|
180
|
+
it 'rejects invalid characters' do
|
181
|
+
original_uri = URI('https://example.org/')
|
182
|
+
expect { URIs.append(original_uri, '精力善用') }.to raise_error(URI::InvalidComponentError)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'accepts percent-encoded path segments' do
|
186
|
+
original_uri = URI('https://example.org/')
|
187
|
+
encoded_segment = URIs.path_escape('精力善用')
|
188
|
+
new_uri = URIs.append(original_uri, encoded_segment, 'foo.html')
|
189
|
+
expected_url = "https://example.org/#{encoded_segment}/foo.html"
|
190
|
+
expect(new_uri).to eq(URI(expected_url))
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'accepts path segments with allowed punctuation' do
|
194
|
+
original_uri = URI('https://example.org/')
|
195
|
+
path = 'foo/bar/baz@qux&corge=garply+grault$waldo/fred'
|
196
|
+
new_uri = URIs.append(original_uri, path, 'plugh')
|
197
|
+
expected_url = "#{original_uri}#{path}/plugh"
|
198
|
+
expect(new_uri).to eq(URI(expected_url))
|
199
|
+
end
|
200
|
+
|
139
201
|
end
|
140
202
|
|
141
203
|
describe 'requests' do
|
@@ -177,6 +239,42 @@ module BerkeleyLibrary::Util
|
|
177
239
|
expect(response.code).to eq(404)
|
178
240
|
end
|
179
241
|
end
|
242
|
+
|
243
|
+
describe :head do
|
244
|
+
it 'makes a HEAD request' do
|
245
|
+
expected_status = 200
|
246
|
+
stub_request(:head, url_with_query).with(headers: headers).to_return(status: expected_status)
|
247
|
+
|
248
|
+
result = URIs.head(url, params: params, headers: headers)
|
249
|
+
expect(result).to eq(expected_status)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'returns the status even for unsuccessful requests' do
|
253
|
+
expected_status = 404
|
254
|
+
stub_request(:head, url_with_query).with(headers: headers).to_return(status: expected_status)
|
255
|
+
|
256
|
+
result = URIs.head(url, params: params, headers: headers)
|
257
|
+
expect(result).to eq(expected_status)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe :head_response do
|
262
|
+
it 'makes a HEAD request' do
|
263
|
+
stub_request(:head, url_with_query).with(headers: headers).to_return(body: expected_body)
|
264
|
+
|
265
|
+
response = URIs.head_response(url, params: params, headers: headers)
|
266
|
+
expect(response.body).to eq(expected_body)
|
267
|
+
expect(response.code).to eq(200)
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'returns the response even for errors' do
|
271
|
+
stub_request(:head, url_with_query).with(headers: headers).to_return(status: 404, body: expected_body)
|
272
|
+
|
273
|
+
response = URIs.head_response(url, params: params, headers: headers)
|
274
|
+
expect(response.body).to eq(expected_body)
|
275
|
+
expect(response.code).to eq(404)
|
276
|
+
end
|
277
|
+
end
|
180
278
|
end
|
181
279
|
|
182
280
|
describe :safe_parse_uri do
|
@@ -210,5 +308,50 @@ module BerkeleyLibrary::Util
|
|
210
308
|
end
|
211
309
|
end
|
212
310
|
end
|
311
|
+
|
312
|
+
describe :path_escape do
|
313
|
+
let(:in_out) do
|
314
|
+
{
|
315
|
+
'' => '',
|
316
|
+
'corge' => 'corge',
|
317
|
+
'foo+bar' => 'foo+bar',
|
318
|
+
'qux/quux' => 'qux%2Fquux',
|
319
|
+
'foo bar baz' => 'foo%20bar%20baz',
|
320
|
+
'Corge-Grault.Fred_Waldo~Plugh' => 'Corge-Grault.Fred_Waldo~Plugh',
|
321
|
+
'25%' => '25%25',
|
322
|
+
"\t !\"#$%&'()*+,/:;<=>?@[\\]^`{|}☺" => '%09%20%21%22%23$%25&%27%28%29%2A+%2C%2F:%3B%3C=%3E%3F@%5B%5C%5D%5E%60%7B%7C%7D%E2%98%BA',
|
323
|
+
'精力善用' => '%E7%B2%BE%E5%8A%9B%E5%96%84%E7%94%A8'
|
324
|
+
}
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'escapes a path segment' do
|
328
|
+
aggregate_failures do
|
329
|
+
in_out.each do |in_str, out_str|
|
330
|
+
expect(URIs.path_escape(in_str)).to eq(out_str)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'rejects non-strings' do
|
336
|
+
str = in_out.keys.last
|
337
|
+
expect { URIs.path_escape(str.bytes) }.to raise_error(ArgumentError)
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'rejects non-UTF-8 strings' do
|
341
|
+
str = in_out.keys.last
|
342
|
+
expect { URIs.path_escape(str.encode(Encoding::Shift_JIS)) }.to raise_error(ArgumentError)
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'accepts non-UTF-8 strings converted to UTF-8' do
|
346
|
+
in_str = in_out.keys.last
|
347
|
+
out_str = in_out[in_str]
|
348
|
+
|
349
|
+
# OK, we're really just testing String#encode here, but
|
350
|
+
# it's useful for documentation
|
351
|
+
in_str_sjis = in_str.encode(Encoding::Shift_JIS)
|
352
|
+
in_str_utf8 = in_str_sjis.encode(Encoding::UTF_8)
|
353
|
+
expect(URIs.path_escape(in_str_utf8)).to eq(out_str)
|
354
|
+
end
|
355
|
+
end
|
213
356
|
end
|
214
357
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,8 +13,8 @@ RSpec.configure do |config|
|
|
13
13
|
config.color = true
|
14
14
|
config.tty = true
|
15
15
|
config.formatter = :documentation
|
16
|
-
config.before
|
17
|
-
config.after
|
16
|
+
config.before { WebMock.disable_net_connect!(allow_localhost: true) }
|
17
|
+
config.after { WebMock.allow_net_connect! }
|
18
18
|
config.mock_with :rspec do |mocks|
|
19
19
|
mocks.verify_partial_doubles = true
|
20
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berkeley_library-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Moles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: berkeley_library-logging
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.3'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundle-audit
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0.1'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0.1'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: ci_reporter_rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,42 +128,42 @@ dependencies:
|
|
142
128
|
requirements:
|
143
129
|
- - '='
|
144
130
|
- !ruby/object:Gem::Version
|
145
|
-
version: '1.
|
131
|
+
version: '1.39'
|
146
132
|
type: :development
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
136
|
- - '='
|
151
137
|
- !ruby/object:Gem::Version
|
152
|
-
version: '1.
|
138
|
+
version: '1.39'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: rubocop-rake
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
|
-
- -
|
143
|
+
- - '='
|
158
144
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
145
|
+
version: 0.6.0
|
160
146
|
type: :development
|
161
147
|
prerelease: false
|
162
148
|
version_requirements: !ruby/object:Gem::Requirement
|
163
149
|
requirements:
|
164
|
-
- -
|
150
|
+
- - '='
|
165
151
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
152
|
+
version: 0.6.0
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
name: rubocop-rspec
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
170
156
|
requirements:
|
171
|
-
- -
|
157
|
+
- - '='
|
172
158
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
159
|
+
version: 2.4.0
|
174
160
|
type: :development
|
175
161
|
prerelease: false
|
176
162
|
version_requirements: !ruby/object:Gem::Requirement
|
177
163
|
requirements:
|
178
|
-
- -
|
164
|
+
- - '='
|
179
165
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
166
|
+
version: 2.4.0
|
181
167
|
- !ruby/object:Gem::Dependency
|
182
168
|
name: ruby-prof
|
183
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,20 +192,6 @@ dependencies:
|
|
206
192
|
- - "~>"
|
207
193
|
- !ruby/object:Gem::Version
|
208
194
|
version: '0.21'
|
209
|
-
- !ruby/object:Gem::Dependency
|
210
|
-
name: simplecov-rcov
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - "~>"
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: '0.2'
|
216
|
-
type: :development
|
217
|
-
prerelease: false
|
218
|
-
version_requirements: !ruby/object:Gem::Requirement
|
219
|
-
requirements:
|
220
|
-
- - "~>"
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: '0.2'
|
223
195
|
- !ruby/object:Gem::Dependency
|
224
196
|
name: webmock
|
225
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -271,7 +243,7 @@ files:
|
|
271
243
|
- lib/berkeley_library/util/uris/appender.rb
|
272
244
|
- lib/berkeley_library/util/uris/requester.rb
|
273
245
|
- lib/berkeley_library/util/uris/validator.rb
|
274
|
-
- rakelib
|
246
|
+
- rakelib/.rubocop.yml
|
275
247
|
- rakelib/coverage.rake
|
276
248
|
- rakelib/gem.rake
|
277
249
|
- rakelib/rubocop.rake
|
@@ -290,7 +262,8 @@ files:
|
|
290
262
|
homepage: https://github.com/BerkeleyLibrary/util
|
291
263
|
licenses:
|
292
264
|
- MIT
|
293
|
-
metadata:
|
265
|
+
metadata:
|
266
|
+
rubygems_mfa_required: 'true'
|
294
267
|
post_install_message:
|
295
268
|
rdoc_options: []
|
296
269
|
require_paths:
|
@@ -310,15 +283,4 @@ rubygems_version: 3.1.6
|
|
310
283
|
signing_key:
|
311
284
|
specification_version: 4
|
312
285
|
summary: Miscellaneous Ruby utilities for the UC Berkeley Library
|
313
|
-
test_files:
|
314
|
-
- spec/.rubocop.yml
|
315
|
-
- spec/berkeley_library/util/arrays_spec.rb
|
316
|
-
- spec/berkeley_library/util/files_spec.rb
|
317
|
-
- spec/berkeley_library/util/paths_spec.rb
|
318
|
-
- spec/berkeley_library/util/stringios_spec.rb
|
319
|
-
- spec/berkeley_library/util/strings_spec.rb
|
320
|
-
- spec/berkeley_library/util/times_spec.rb
|
321
|
-
- spec/berkeley_library/util/uris/requester_spec.rb
|
322
|
-
- spec/berkeley_library/util/uris/validator_spec.rb
|
323
|
-
- spec/berkeley_library/util/uris_spec.rb
|
324
|
-
- spec/spec_helper.rb
|
286
|
+
test_files: []
|
data/rakelib/bundle.rake
DELETED