berkeley_library-tind 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/tind.iml +12 -16
  3. data/CHANGES.md +4 -0
  4. data/berkeley_library-tind.gemspec +1 -0
  5. data/lib/berkeley_library/tind/api/api.rb +17 -11
  6. data/lib/berkeley_library/tind/api/collection.rb +1 -1
  7. data/lib/berkeley_library/tind/api/search.rb +1 -1
  8. data/lib/berkeley_library/tind/export/exporter.rb +1 -1
  9. data/lib/berkeley_library/tind/export/table.rb +1 -1
  10. data/lib/berkeley_library/tind/export/table_metrics.rb +1 -1
  11. data/lib/berkeley_library/tind/module_info.rb +1 -1
  12. data/lib/berkeley_library/util/ods/spreadsheet.rb +1 -1
  13. data/lib/berkeley_library/util/ods/xml/element_node.rb +1 -1
  14. metadata +16 -25
  15. data/lib/berkeley_library/util/arrays.rb +0 -178
  16. data/lib/berkeley_library/util/logging.rb +0 -1
  17. data/lib/berkeley_library/util/paths.rb +0 -111
  18. data/lib/berkeley_library/util/stringios.rb +0 -30
  19. data/lib/berkeley_library/util/strings.rb +0 -42
  20. data/lib/berkeley_library/util/sys_exits.rb +0 -15
  21. data/lib/berkeley_library/util/times.rb +0 -22
  22. data/lib/berkeley_library/util/uris/appender.rb +0 -162
  23. data/lib/berkeley_library/util/uris/requester.rb +0 -62
  24. data/lib/berkeley_library/util/uris/validator.rb +0 -32
  25. data/lib/berkeley_library/util/uris.rb +0 -44
  26. data/spec/berkeley_library/util/arrays_spec.rb +0 -340
  27. data/spec/berkeley_library/util/paths_spec.rb +0 -90
  28. data/spec/berkeley_library/util/stringios_spec.rb +0 -34
  29. data/spec/berkeley_library/util/strings_spec.rb +0 -27
  30. data/spec/berkeley_library/util/times_spec.rb +0 -39
  31. data/spec/berkeley_library/util/uris_spec.rb +0 -118
@@ -1,340 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'berkeley_library/util/arrays'
4
-
5
- module BerkeleyLibrary::Util
6
- describe Arrays do
7
- describe :ordered_superset do
8
- let(:sup) { %w[a b c d e] }
9
-
10
- it 'returns true for an identical subset' do
11
- expect(Arrays.ordered_superset?(superset: sup, subset: sup.dup)).to eq(true)
12
- end
13
-
14
- it 'returns true for an empty subset' do
15
- expect(Arrays.ordered_superset?(superset: sup, subset: [])).to eq(true)
16
- end
17
-
18
- it 'returns true for an exact sublist' do
19
- subs = [
20
- %w[a b c],
21
- %w[b c d],
22
- %w[c d e]
23
- ]
24
- subs.each do |sub|
25
- expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to eq(true)
26
- end
27
- end
28
-
29
- it 'returns true when the superset interpolates extra elements' do
30
- subs = [
31
- %w[a c e],
32
- %w[b d],
33
- %w[a b d e]
34
- ]
35
- subs.each do |sub|
36
- expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to eq(true)
37
- end
38
- end
39
-
40
- it 'returns false for a too-large subset' do
41
- sub = %w[a b c d e f g]
42
- expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to eq(false)
43
- end
44
-
45
- it 'returns false when extra elements are present' do
46
- subs = [
47
- %w[a b c x],
48
- %w[x b c d],
49
- %w[c d x e]
50
- ]
51
- subs.each do |sub|
52
- expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to eq(false)
53
- end
54
- end
55
- end
56
-
57
- describe :count_while do
58
- it 'returns the count of matching elements' do
59
- a = [1, 3, 5, 2, 4, 6, 7, 11, 13]
60
- expect(Arrays.count_while(values: a, &:odd?)).to eq(3)
61
- end
62
-
63
- it 'returns 0 if the first element does not match' do
64
- a = [2, 4, 6, 7, 11, 13]
65
- expect(Arrays.count_while(values: a, &:odd?)).to eq(0)
66
- end
67
-
68
- it 'returns an enumerator if not passed a block' do
69
- a = [1, 3, 5, 2, 4, 6, 7, 11, 13]
70
- e = Arrays.count_while(values: a)
71
- expect(e.each(&:odd?)).to eq(3)
72
- end
73
-
74
- it 'works on non-arrays' do
75
- a = [1, 3, 5, 2, 4, 6, 7, 11, 13]
76
- e = Enumerator.new { |y| a.each { |x| y << x } }
77
- expect(Arrays.count_while(values: e, &:odd?)).to eq(3)
78
- end
79
- end
80
-
81
- describe :find_indices do
82
- let(:target) { %w[a b c d e] }
83
-
84
- it 'returns identity indices for an identical subset' do
85
- expect(Arrays.find_indices(for_array: target.dup, in_array: target)).to eq([0, 1, 2, 3, 4])
86
- end
87
-
88
- it 'returns an empty array for an empty subset' do
89
- expect(Arrays.find_indices(for_array: [], in_array: target)).to eq([])
90
- end
91
-
92
- it 'returns the expected subindices for an exact sublist' do
93
- sources = {
94
- %w[a b c] => [0, 1, 2],
95
- %w[b c d] => [1, 2, 3],
96
- %w[c d e] => [2, 3, 4]
97
- }
98
- sources.each do |source, expected|
99
- expect(Arrays.find_indices(for_array: source, in_array: target)).to eq(expected)
100
- end
101
- end
102
-
103
- it 'returns nil for a too-large subset' do
104
- source = %w[a b c d e f g]
105
- expect(Arrays.find_indices(for_array: source, in_array: target)).to be_nil
106
- end
107
-
108
- it 'returns nil when extra elements are present' do
109
- sources = [
110
- %w[a b c x],
111
- %w[x b c d],
112
- %w[c d x e]
113
- ]
114
- sources.each do |source|
115
- expect(Arrays.find_indices(for_array: source, in_array: target)).to be_nil
116
- end
117
- end
118
-
119
- it 'takes a comparison block' do
120
- sub = %i[a c e]
121
- expect(Arrays.find_indices(for_array: sub, in_array: target) { |source, target| target == source.to_s }).to eq([0, 2, 4])
122
- end
123
- end
124
-
125
- describe :find_index do
126
- let(:arr) { [0, 2, 4, 6, 4] }
127
-
128
- it 'finds an index based on a value' do
129
- expect(Arrays.find_index(4, in_array: arr)).to eq(2)
130
- expect(Arrays.find_index(4, in_array: arr, start_index: 3)).to eq(4)
131
- end
132
-
133
- it 'finds an index based on a block' do
134
- expect(Arrays.find_index(in_array: arr) { |x| x > 3 }).to eq(2)
135
- expect(Arrays.find_index(in_array: arr, start_index: 3) { |x| x < 5 }).to eq(4)
136
- end
137
-
138
- it 'returns nil if no equal value found' do
139
- expect(Arrays.find_index(7, in_array: arr)).to be_nil
140
- expect(Arrays.find_index(2, in_array: arr, start_index: 2)).to be_nil
141
- end
142
-
143
- it 'returns nil if no matching value found' do
144
- expect(Arrays.find_index(in_array: arr, &:odd?)).to be_nil
145
- expect(Arrays.find_index(in_array: arr, start_index: 2) { |x| x < 4 }).to be_nil
146
- end
147
-
148
- # rubocop:disable Lint/Void
149
- it 'returns an enumerator if given no arguments' do
150
- e = Arrays.find_index(in_array: arr)
151
- expect(e.each { |x| x > 3 }).to eq(2)
152
-
153
- e = Arrays.find_index(in_array: arr, start_index: 3)
154
- expect(e.each { |x| x < 5 }).to eq(4)
155
- end
156
- # rubocop:enable Lint/Void
157
- end
158
-
159
- describe :merge do
160
- it 'merges two arrays' do
161
- a1 = [1, 2, 3]
162
- a2 = [2, 3, 4]
163
- expect(Arrays.merge(a1, a2)).to eq([1, 2, 3, 4])
164
- expect(Arrays.merge(a2, a1)).to eq([1, 2, 3, 4])
165
- end
166
-
167
- it 'merges disjoint arrays' do
168
- a1 = [1, 3, 5]
169
- a2 = [2, 4, 6]
170
- expect(Arrays.merge(a1, a2)).to eq([1, 3, 5, 2, 4, 6])
171
- end
172
-
173
- it 'preserves duplicates' do
174
- a1 = [1, 2, 2, 3, 4, 5]
175
- a2 = [2, 4, 4, 5, 5, 6]
176
-
177
- merged = Arrays.merge(a1, a2)
178
- [a1, a2].each do |a|
179
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
180
- end
181
-
182
- expected = [1, 2, 2, 3, 4, 4, 5, 5, 6]
183
- expect(merged.size).to eq(expected.size)
184
- expect(merged).to eq(expected)
185
- end
186
-
187
- it 'merges gappy arrays' do
188
- a1 = [1, 4, 5, 7, 9]
189
- a2 = [2, 3, 4, 7, 8, 9]
190
-
191
- merged = Arrays.merge(a1, a2)
192
- [a1, a2].each do |a|
193
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
194
- end
195
-
196
- expected = [1, 2, 3, 4, 5, 7, 8, 9]
197
- expect(merged.size).to eq(expected.size)
198
- expect(merged).to eq(expected)
199
- end
200
-
201
- it 'preserves order when merging arrays with duplicates' do
202
- a1 = [1, 3, 2, 2, 4]
203
- a2 = [1, 2, 3, 2, 4]
204
-
205
- merged = Arrays.merge(a1, a2)
206
- [a1, a2].each do |a|
207
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
208
- end
209
-
210
- expected = [1, 2, 3, 2, 2, 4]
211
- expect(merged.size).to eq(expected.size)
212
- expect(merged).to eq(expected)
213
- end
214
-
215
- it 'preserves nil' do
216
- a1 = [1, 3, nil, nil, 4]
217
- a2 = [1, nil, 3, nil, 4]
218
-
219
- merged = Arrays.merge(a1, a2)
220
- [a1, a2].each do |a|
221
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
222
- end
223
-
224
- expected = [1, nil, 3, nil, nil, 4]
225
- expect(merged.size).to eq(expected.size)
226
- expect(merged).to eq(expected)
227
- end
228
-
229
- it 'works with non-comparable types' do
230
- a1 = [1, 3, 'two', 'two', 4]
231
- a2 = [1, 'two', 3, 'two', 4]
232
-
233
- merged = Arrays.merge(a1, a2)
234
- [a1, a2].each do |a|
235
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
236
- end
237
-
238
- expected = [1, 'two', 3, 'two', 'two', 4]
239
- expect(merged.size).to eq(expected.size)
240
- expect(merged).to eq(expected)
241
- end
242
-
243
- it 'returns the larger array if the smaller is already a subarray' do
244
- a1 = [2, 3, 4]
245
- a2 = [1, 2, 3, 4, 5]
246
-
247
- merged = Arrays.merge(a1, a2)
248
- [a1, a2].each do |a|
249
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
250
- end
251
-
252
- expected = a2
253
- expect(merged.size).to eq(expected.size)
254
- expect(merged).to eq(expected)
255
-
256
- expect(Arrays.merge(a2, a1)).to eq(expected)
257
- end
258
-
259
- it 'sorts where sorting preserves order' do
260
- a1 = [1, 2, 3, 4, 5]
261
- a2 = [2, 3, 6, 9]
262
-
263
- merged = Arrays.merge(a1, a2)
264
- [a1, a2].each do |a|
265
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
266
- end
267
-
268
- expected = [1, 2, 3, 4, 5, 6, 9]
269
- expect(merged.size).to eq(expected.size)
270
- expect(merged).to eq(expected)
271
-
272
- expect(Arrays.merge(a2, a1)).to eq(expected)
273
- end
274
-
275
- it "doesn't muck up partial matches" do
276
- a1 = [1, 2, 3, 4, 5]
277
- a2 = [6, 9, 2, 3]
278
-
279
- merged = Arrays.merge(a1, a2)
280
- [a1, a2].each do |a|
281
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
282
- end
283
-
284
- expected = [1, 6, 9, 2, 3, 4, 5]
285
- expect(merged.size).to eq(expected.size)
286
- expect(merged).to eq(expected)
287
-
288
- expect(Arrays.merge(a2, a1)).to eq(expected)
289
- end
290
-
291
- it "doesn't much up disjoints" do
292
- a1 = [1, 2, 3, 4, 5]
293
- a2 = [6, 9]
294
-
295
- merged = Arrays.merge(a1, a2)
296
- [a1, a2].each do |a|
297
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
298
- end
299
-
300
- expected = [1, 2, 3, 4, 5, 6, 9]
301
- expect(merged.size).to eq(expected.size)
302
- expect(merged).to eq(expected)
303
-
304
- expect(Arrays.merge(a2, a1)).to eq(expected)
305
- end
306
-
307
- it 'works on a selection of random values' do
308
- next_int = ->(n) { (n * rand).to_i }
309
- rand_array = -> { (0...next_int.call(10)).map { next_int.call(10) } }
310
- aggregate_failures 'random values' do
311
- 100.times do
312
- a1 = rand_array.call
313
- a2 = rand_array.call
314
-
315
- merged = Arrays.merge(a1, a2)
316
- [a1, a2].each do |a|
317
- expect(Arrays.ordered_superset?(superset: merged, subset: a)).to eq(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
318
- end
319
- end
320
- end
321
- end
322
-
323
- end
324
-
325
- describe :invert do
326
- it 'inverts an array of ints' do
327
- expect(Arrays.invert([0, 2, 3])).to eq([0, nil, 1, 2])
328
- end
329
-
330
- it 'fails if values are not ints' do
331
- # noinspection RubyYardParamTypeMatch
332
- expect { Arrays.invert(%i[a b c]) }.to raise_error(TypeError)
333
- end
334
-
335
- it 'fails if given duplicate values' do
336
- expect { Arrays.invert([1, 2, 3, 2]) }.to raise_error(ArgumentError)
337
- end
338
- end
339
- end
340
- end
@@ -1,90 +0,0 @@
1
- require 'spec_helper'
2
- require 'berkeley_library/util/paths'
3
-
4
- module BerkeleyLibrary::Util
5
- describe Paths do
6
- describe :clean do
7
- {
8
- # nil
9
- nil => nil,
10
-
11
- # Already clean
12
- '' => '.',
13
- 'abc' => 'abc',
14
- 'abc/def' => 'abc/def',
15
- 'a/b/c' => 'a/b/c',
16
- '.' => '.',
17
- '..' => '..',
18
- '../..' => '../..',
19
- '../../abc' => '../../abc',
20
- '/abc' => '/abc',
21
- '/' => '/',
22
-
23
- # Remove trailing slash
24
- 'abc/' => 'abc',
25
- 'abc/def/' => 'abc/def',
26
- 'a/b/c/' => 'a/b/c',
27
- './' => '.',
28
- '../' => '..',
29
- '../../' => '../..',
30
- '/abc/' => '/abc',
31
-
32
- # Remove doubled slash
33
- 'abc//def//ghi' => 'abc/def/ghi',
34
- '//abc' => '/abc',
35
- '///abc' => '/abc',
36
- '//abc//' => '/abc',
37
- 'abc//' => 'abc',
38
-
39
- # Remove . elements
40
- 'abc/./def' => 'abc/def',
41
- '/./abc/def' => '/abc/def',
42
- 'abc/.' => 'abc',
43
-
44
- # Remove .. elements
45
- 'abc/def/ghi/../jkl' => 'abc/def/jkl',
46
- 'abc/def/../ghi/../jkl' => 'abc/jkl',
47
- 'abc/def/..' => 'abc',
48
- 'abc/def/../..' => '.',
49
- '/abc/def/../..' => '/',
50
- 'abc/def/../../..' => '..',
51
- '/abc/def/../../..' => '/',
52
- 'abc/def/../../../ghi/jkl/../../../mno' => '../../mno',
53
-
54
- # Combinations
55
- 'abc/./../def' => 'def',
56
- 'abc//./../def' => 'def',
57
- 'abc/../../././../def' => '../../def'
58
- }.each do |orig, expected|
59
- it "clean(#{orig.inspect}) -> #{expected.inspect}" do
60
- expect(Paths.clean(orig)).to eq(expected)
61
- end
62
- end
63
- end
64
-
65
- describe :join do
66
- {
67
- # zero parameters
68
- [] => '',
69
-
70
- # one parameter
71
- [''] => '',
72
- ['a'] => 'a',
73
-
74
- # two parameters
75
- ['a', 'b'] => 'a/b',
76
- ['a', ''] => 'a',
77
- ['', 'b'] => 'b',
78
- ['/', 'a'] => '/a',
79
- ['/', ''] => '/',
80
- ['a/', 'b'] => 'a/b',
81
- ['a/', ''] => 'a',
82
- ['', ''] => ''
83
- }.each do |orig, expected|
84
- it "join(#{orig.map(&:inspect).join(', ')}) -> #{expected.inspect}" do
85
- expect(Paths.join(*orig)).to eq(expected)
86
- end
87
- end
88
- end
89
- end
90
- end
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'berkeley_library/util/stringios'
4
-
5
- module BerkeleyLibrary
6
- module Util
7
- describe StringIOs do
8
- describe :getbyte do
9
- let(:s) { '祇園精舎の鐘の声、諸行無常の響きあり。' }
10
- let(:bytes) { s.bytes }
11
- let(:sio) { StringIO.new(s) }
12
-
13
- it 'gets the byte at the specified byte index' do
14
- bytes.each_with_index do |b, i|
15
- expect(StringIOs.getbyte(sio, i)).to eq(b)
16
- end
17
- end
18
-
19
- it 'resets the current offset' do
20
- StringIOs.getbyte(sio, bytes.size / 2)
21
- expect(sio.pos).to eq(0)
22
- end
23
-
24
- it 'returns nil for a too-large positive offset' do
25
- expect(StringIOs.getbyte(s, bytes.size)).to be_nil
26
- end
27
-
28
- it 'returns nil for a too-large negative offset' do
29
- expect(StringIOs.getbyte(s, -(1 + bytes.size))).to be_nil
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module BerkeleyLibrary
4
- module Util
5
- describe Strings do
6
- describe :diff_index do
7
- it 'returns nil for identical strings' do
8
- s = 'elvis'
9
- expect(Strings.diff_index(s, s)).to be_nil
10
- end
11
-
12
- it 'returns the index for different strings' do
13
- s1 = 'elvis aaron presley'
14
- s2 = 'elvis nikita presley'
15
- expect(Strings.diff_index(s1, s2)).to eq(6)
16
- end
17
-
18
- it 'returns the length of the shorter string for prefixes' do
19
- s1 = 'elvis'
20
- s2 = 'elvis aaron presley'
21
- expect(Strings.diff_index(s1, s2)).to eq(5)
22
- expect(Strings.diff_index(s2, s1)).to eq(5)
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
- require 'berkeley_library/util/times'
3
-
4
- module BerkeleyLibrary
5
- module Util
6
- describe Times do
7
- describe :ensure_utc do
8
- it 'returns a UTC time unchanged' do
9
- time = Time.parse('2021-02-05 16:19:11.37707 -0800')
10
- utc_time = time.getutc
11
- expect(Times.ensure_utc(utc_time)).to be(utc_time)
12
- end
13
-
14
- it 'converts a non-UTC time' do
15
- time = Time.parse('2021-02-06 08:19:11.37707 +0800')
16
- expect(Times.ensure_utc(time)).to eq(time.getutc)
17
- expect(time.gmt_offset).to eq(28_800), 'Times.ensure_utc() should not modify its argument'
18
- end
19
-
20
- it 'accepts a Date' do
21
- date = Date.new(2021, 2, 6)
22
- utc_time = Time.new(2021, 2, 6).getutc
23
- expect(Times.ensure_utc(date)).to eq(utc_time)
24
- end
25
-
26
- it 'accepts a Datetime' do
27
- datetime = DateTime.parse('2021-02-05 16:19:11.37707 -0800')
28
- utc_time = Time.parse('2021-02-06 00:19:11.37707 UTC')
29
- expect(Times.ensure_utc(datetime)).to eq(utc_time)
30
- end
31
-
32
- it 'rejects non-date/time objects' do
33
- # noinspection RubyYardParamTypeMatch
34
- expect { Times.ensure_utc(Object.new) }.to raise_error(ArgumentError)
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,118 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module BerkeleyLibrary::Util
4
- describe URIs do
5
- describe :append do
6
- it 'appends paths' do
7
- original_uri = URI('https://example.org/foo/bar')
8
- new_uri = URIs.append(original_uri, 'qux', 'corge', 'garply')
9
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply'))
10
- end
11
-
12
- it 'does not modify the original URI' do
13
- original_uri = URI('https://example.org/foo/bar')
14
- original_url = original_uri.to_s
15
- new_uri = URIs.append(original_uri, 'qux', 'corge', 'garply')
16
- expect(new_uri).not_to be(original_uri)
17
- expect(original_uri.to_s).to eq(original_url)
18
- end
19
-
20
- it 'removes extraneous slashes' do
21
- original_uri = URI('https://example.org/foo/bar')
22
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply')
23
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply'))
24
- end
25
-
26
- it 'preserves queries' do
27
- original_uri = URI('https://example.org/foo/bar?baz=qux')
28
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply')
29
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?baz=qux'))
30
- end
31
-
32
- it 'preserves fragments' do
33
- original_uri = URI('https://example.org/foo/bar#baz')
34
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply')
35
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply#baz'))
36
- end
37
-
38
- it 'accepts a query string if no previous query present' do
39
- original_uri = URI('https://example.org/foo/bar#baz')
40
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply?grault=xyzzy')
41
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?grault=xyzzy#baz'))
42
- end
43
-
44
- it 'allows the ? to be passed separately' do
45
- original_uri = URI('https://example.org/foo/bar#baz')
46
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply', '?', 'grault=xyzzy')
47
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?grault=xyzzy#baz'))
48
- end
49
-
50
- it 'appends query parameters with &' do
51
- original_uri = URI('https://example.org/foo/bar#baz')
52
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply?grault=xyzzy', '&plugh=flob')
53
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?grault=xyzzy&plugh=flob#baz'))
54
- end
55
-
56
- it 'appends query parameters to original URI query' do
57
- original_uri = URI('https://example.org/foo/bar/qux/corge/garply?grault=xyzzy')
58
- new_uri = URIs.append(original_uri, '&plugh=flob')
59
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?grault=xyzzy&plugh=flob'))
60
- end
61
-
62
- it 'treats & as a path element if no query is present' do
63
- original_uri = URI('https://example.org/foo/bar#baz')
64
- new_uri = URIs.append(original_uri, '/qux', '/corge/', 'garply', '&plugh=flob')
65
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply/&plugh=flob#baz'))
66
- end
67
-
68
- it 'accepts a fragment if no previous fragment present' do
69
- original_uri = URI('https://example.org/foo/bar?baz=qux')
70
- new_uri = URIs.append(original_uri, '/qux', '/corge/', '//garply#grault')
71
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply?baz=qux#grault'))
72
- end
73
-
74
- it 'rejects a query string if the original URI already has one' do
75
- original_uri = URI('https://example.org/foo/bar?baz=qux')
76
- expect { URIs.append(original_uri, '/qux?corge') }.to raise_error(URI::InvalidComponentError)
77
- end
78
-
79
- it 'rejects a fragment if the original URI already has one' do
80
- original_uri = URI('https://example.org/foo/bar#baz')
81
- expect { URIs.append(original_uri, '/qux#corge') }.to raise_error(URI::InvalidComponentError)
82
- end
83
-
84
- it 'rejects appending multiple queries' do
85
- original_uri = URI('https://example.org/foo/bar')
86
- expect { URIs.append(original_uri, 'baz?qux=corge', 'grault?plugh=xyzzy') }.to raise_error(URI::InvalidComponentError)
87
- end
88
-
89
- it 'rejects appending multiple fragments' do
90
- original_uri = URI('https://example.org/foo/bar')
91
- expect { URIs.append(original_uri, 'baz#qux', 'grault#plugh') }.to raise_error(URI::InvalidComponentError)
92
- end
93
-
94
- it 'rejects queries after fragments' do
95
- original_uri = URI('https://example.org/foo/bar')
96
- expect { URIs.append(original_uri, 'baz#qux', '?grault=plugh') }.to raise_error(URI::InvalidComponentError)
97
- end
98
-
99
- it 'correctly handles fragments in mid-path-segment' do
100
- original_uri = URI('https://example.org/foo/bar')
101
- new_uri = URIs.append(original_uri, 'qux#corge')
102
- expect(new_uri).to eq(URI('https://example.org/foo/bar/qux#corge'))
103
- end
104
-
105
- it 'correctly handles fragments in query start' do
106
- original_uri = URI('https://example.org/foo/bar')
107
- new_uri = URIs.append(original_uri, '?qux=corge&grault=plugh#xyzzy')
108
- expect(new_uri).to eq(URI('https://example.org/foo/bar?qux=corge&grault=plugh#xyzzy'))
109
- end
110
-
111
- it 'correctly handles fragments in mid-query' do
112
- original_uri = URI('https://example.org/foo/bar')
113
- new_uri = URIs.append(original_uri, '?qux=corge', '&grault=plugh#xyzzy')
114
- expect(new_uri).to eq(URI('https://example.org/foo/bar?qux=corge&grault=plugh#xyzzy'))
115
- end
116
- end
117
- end
118
- end