berkeley_library-tind 0.4.1 → 0.4.2

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.
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