berkeley_library-tind 0.4.0 → 0.5.0
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 +1 -1
- data/.idea/inspectionProfiles/Project_Default.xml +18 -0
- data/.idea/tind.iml +91 -91
- data/.ruby-version +1 -1
- data/CHANGES.md +33 -1
- data/README.md +15 -1
- data/berkeley_library-tind.gemspec +3 -2
- data/lib/berkeley_library/tind/api/api.rb +17 -11
- data/lib/berkeley_library/tind/api/collection.rb +1 -1
- data/lib/berkeley_library/tind/api/search.rb +2 -2
- data/lib/berkeley_library/tind/export/exporter.rb +1 -1
- data/lib/berkeley_library/tind/export/table.rb +1 -1
- data/lib/berkeley_library/tind/export/table_metrics.rb +1 -1
- data/lib/berkeley_library/tind/marc/xml_builder.rb +62 -0
- data/lib/berkeley_library/tind/marc/xml_reader.rb +32 -19
- data/lib/berkeley_library/tind/marc/xml_writer.rb +152 -0
- data/lib/berkeley_library/tind/module_info.rb +1 -1
- data/lib/berkeley_library/util/files.rb +39 -0
- data/lib/berkeley_library/util/ods/spreadsheet.rb +1 -1
- data/lib/berkeley_library/util/ods/xml/element_node.rb +1 -1
- data/spec/berkeley_library/tind/export/export_spec.rb +3 -1
- data/spec/berkeley_library/tind/export/table_spec.rb +2 -0
- data/spec/berkeley_library/tind/marc/xml_reader_spec.rb +42 -1
- data/spec/berkeley_library/tind/marc/xml_writer_spec.rb +156 -0
- data/spec/data/new-records.xml +46 -0
- metadata +36 -39
- data/Jenkinsfile +0 -18
- data/lib/berkeley_library/util/arrays.rb +0 -178
- data/lib/berkeley_library/util/logging.rb +0 -1
- data/lib/berkeley_library/util/paths.rb +0 -111
- data/lib/berkeley_library/util/stringios.rb +0 -30
- data/lib/berkeley_library/util/strings.rb +0 -42
- data/lib/berkeley_library/util/sys_exits.rb +0 -15
- data/lib/berkeley_library/util/times.rb +0 -22
- data/lib/berkeley_library/util/uris/appender.rb +0 -162
- data/lib/berkeley_library/util/uris/requester.rb +0 -62
- data/lib/berkeley_library/util/uris/validator.rb +0 -32
- data/lib/berkeley_library/util/uris.rb +0 -44
- data/spec/berkeley_library/util/arrays_spec.rb +0 -340
- data/spec/berkeley_library/util/paths_spec.rb +0 -90
- data/spec/berkeley_library/util/stringios_spec.rb +0 -34
- data/spec/berkeley_library/util/strings_spec.rb +0 -27
- data/spec/berkeley_library/util/times_spec.rb +0 -39
- data/spec/berkeley_library/util/uris_spec.rb +0 -118
| @@ -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
         |