rsolr 2.2.0 → 2.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/ruby.yml +44 -0
- data/CHANGES.txt +26 -0
- data/Gemfile +8 -0
- data/README.rdoc +17 -17
- data/lib/rsolr/client.rb +35 -5
- data/lib/rsolr/document.rb +9 -2
- data/lib/rsolr/error.rb +30 -0
- data/lib/rsolr/version.rb +1 -1
- data/rsolr.gemspec +3 -4
- data/spec/api/client_spec.rb +53 -3
- data/spec/api/error_spec.rb +102 -0
- data/spec/api/json_spec.rb +53 -2
- data/spec/lib/rsolr/client_spec.rb +19 -0
- metadata +22 -10
- data/.travis.yml +0 -14
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f44e7e34b8e615204b49052907e322c46387d858f147b7e34bd4c53edf6b336e
         | 
| 4 | 
            +
              data.tar.gz: b5ad262ba4b5777f18b817c529f9cb8768843972f394420a4798191f92a11b17
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c230788c63b34623fa05608af73c25c5c7bd6fbab106afc62c63b1347a688bf302d0b03323204b0efd047f01ddc2d957722cd5ed0f98553ec3974b7ed2653c79
         | 
| 7 | 
            +
              data.tar.gz: 606324146e3acb8cb86c726a528550fefd0bd57fdebce977fc260c5a38caf4b1c5aeca7c3f23637dcf4bf04e8fbc196e60e4cc63f9827ee7e88af01e816ce3a4
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            name: CI
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            on:
         | 
| 4 | 
            +
              push:
         | 
| 5 | 
            +
                branches: [ master ]
         | 
| 6 | 
            +
              pull_request:
         | 
| 7 | 
            +
                branches: [ master ]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            jobs:
         | 
| 10 | 
            +
              tests:
         | 
| 11 | 
            +
                runs-on: ubuntu-latest
         | 
| 12 | 
            +
                strategy:
         | 
| 13 | 
            +
                  matrix:
         | 
| 14 | 
            +
                    ruby: [jruby-9.3.3.0, 2.7, '3.0', '3.1']
         | 
| 15 | 
            +
                    faraday: ['~> 0.17', '~> 1', '~>2']
         | 
| 16 | 
            +
                steps:
         | 
| 17 | 
            +
                - uses: actions/checkout@v2
         | 
| 18 | 
            +
                - name: Set up Ruby
         | 
| 19 | 
            +
                  uses: ruby/setup-ruby@v1
         | 
| 20 | 
            +
                  with:
         | 
| 21 | 
            +
                    ruby-version: ${{ matrix.ruby }}
         | 
| 22 | 
            +
                - name: Install dependencies
         | 
| 23 | 
            +
                  run: bundle install
         | 
| 24 | 
            +
                  env:
         | 
| 25 | 
            +
                    FARADAY_VERSION: ${{ matrix.faraday}}
         | 
| 26 | 
            +
                - name: Run tests
         | 
| 27 | 
            +
                  run: bundle exec rake
         | 
| 28 | 
            +
                  env:
         | 
| 29 | 
            +
                    FARADAY_VERSION: ${{ matrix.faraday}}
         | 
| 30 | 
            +
              legacy_tests:
         | 
| 31 | 
            +
                runs-on: ubuntu-latest
         | 
| 32 | 
            +
                strategy:
         | 
| 33 | 
            +
                  matrix:
         | 
| 34 | 
            +
                    ruby: [jruby-9.2.20.0, 2.4, 2.5, 2.6, 2.7]
         | 
| 35 | 
            +
                steps:
         | 
| 36 | 
            +
                - uses: actions/checkout@v2
         | 
| 37 | 
            +
                - name: Set up Ruby
         | 
| 38 | 
            +
                  uses: ruby/setup-ruby@v1
         | 
| 39 | 
            +
                  with:
         | 
| 40 | 
            +
                    ruby-version: ${{ matrix.ruby }}
         | 
| 41 | 
            +
                - name: Install dependencies
         | 
| 42 | 
            +
                  run: bundle install
         | 
| 43 | 
            +
                - name: Run tests
         | 
| 44 | 
            +
                  run: bundle exec rake
         | 
    
        data/CHANGES.txt
    CHANGED
    
    | @@ -1,3 +1,29 @@ | |
| 1 | 
            +
            2.4.0
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - Raise specific timeout error for solr timeouts. https://github.com/rsolr/rsolr/pull/214
         | 
| 4 | 
            +
            - Pass `timeout` RSolr configuration through to Faraday, deprecate `read_timeout` Rsolr configuration. https://github.com/rsolr/rsolr/pull/215
         | 
| 5 | 
            +
            - Better visibility of Solr error message in `RSolr::Error`. https://github.com/rsolr/rsolr/pull/222
         | 
| 6 | 
            +
            - Add soft-commit function https://github.com/rsolr/rsolr/pull/210 (thanks @giteshnandre)
         | 
| 7 | 
            +
            - Avoid encoding exception in error message display https://github.com/rsolr/rsolr/pull/208 (thanks @expajp)
         | 
| 8 | 
            +
            - Fix JSON generator for atomic updates of array fields https://github.com/rsolr/rsolr/pull/201 (thanks @serggl)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            2.3.0
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            - Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.2.0...v2.3.0
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            2.2.0
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            - Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.1.0...v2.2.0
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            2.1.0
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            - Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.0.0...v2.1.0
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            2.0.0
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            - Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.0.0.pre1...v2.0.0
         | 
| 26 | 
            +
             | 
| 1 27 | 
             
            2.0.0.pre1
         | 
| 2 28 |  | 
| 3 29 | 
             
            In this release, we've added many new features, including:
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -3,3 +3,11 @@ source "https://rubygems.org" | |
| 3 3 | 
             
            gemspec
         | 
| 4 4 |  | 
| 5 5 | 
             
            gem "builder", ">= 2.1.2"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            if defined? JRUBY_VERSION
         | 
| 8 | 
            +
              # HTTP.rb (used by solr_wrapper to download solr for integration testing) fails
         | 
| 9 | 
            +
              # to download the full contents of files (under jruby)?
         | 
| 10 | 
            +
              gem "http", '< 5', platforms: :jruby
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            gem 'faraday', ENV['FARADAY_VERSION'] if ENV['FARADAY_VERSION']
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -1,6 +1,4 @@ | |
| 1 1 | 
             
            =RSolr
         | 
| 2 | 
            -
            {<img src="https://travis-ci.org/rsolr/rsolr.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/rsolr/rsolr] {<img src="https://badge.fury.io/rb/rsolr.svg" alt="Gem Version" />}[http://badge.fury.io/rb/rsolr]
         | 
| 3 | 
            -
             | 
| 4 2 |  | 
| 5 3 | 
             
            A simple, extensible Ruby client for Apache Solr.
         | 
| 6 4 |  | 
| @@ -12,26 +10,26 @@ The code docs http://www.rubydoc.info/gems/rsolr | |
| 12 10 |  | 
| 13 11 | 
             
            == Example:
         | 
| 14 12 | 
             
              require 'rsolr'
         | 
| 15 | 
            -
             | 
| 13 | 
            +
             | 
| 16 14 | 
             
              # Direct connection
         | 
| 17 15 | 
             
              solr = RSolr.connect :url => 'http://solrserver.com'
         | 
| 18 | 
            -
             | 
| 16 | 
            +
             | 
| 19 17 | 
             
              # Connecting over a proxy server
         | 
| 20 18 | 
             
              solr = RSolr.connect :url => 'http://solrserver.com', :proxy=>'http://user:pass@proxy.example.com:8080'
         | 
| 21 19 |  | 
| 22 20 | 
             
              # Using an alternate Faraday adapter
         | 
| 23 21 | 
             
              solr = RSolr.connect :url => 'http://solrserver.com', :adapter => :em_http
         | 
| 24 | 
            -
             | 
| 22 | 
            +
             | 
| 25 23 | 
             
              # Using a custom Faraday connection
         | 
| 26 24 | 
             
              conn = Faraday.new do |faraday|
         | 
| 27 25 | 
             
                faraday.response :logger                  # log requests to STDOUT
         | 
| 28 26 | 
             
                faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
         | 
| 29 27 | 
             
              end
         | 
| 30 28 | 
             
              solr = RSolr.connect conn, :url => 'http://solrserver.com'
         | 
| 31 | 
            -
             | 
| 29 | 
            +
             | 
| 32 30 | 
             
              # send a request to /select
         | 
| 33 31 | 
             
              response = solr.get 'select', :params => {:q => '*:*'}
         | 
| 34 | 
            -
             | 
| 32 | 
            +
             | 
| 35 33 | 
             
              # send a request to /catalog
         | 
| 36 34 | 
             
              response = solr.get 'catalog', :params => {:q => '*:*'}
         | 
| 37 35 |  | 
| @@ -52,8 +50,10 @@ By default, RSolr uses the Solr JSON command format for all requests. | |
| 52 50 | 
             
              RSolr.connect :url => 'http://solrserver.com', update_format: :xml
         | 
| 53 51 |  | 
| 54 52 | 
             
            == Timeouts
         | 
| 55 | 
            -
            The read and connect timeout settings can be set when creating a new instance of RSolr | 
| 56 | 
            -
             | 
| 53 | 
            +
            The read and connect timeout settings can be set when creating a new instance of RSolr, and will
         | 
| 54 | 
            +
            be passed on to underlying Faraday instance:
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              solr = RSolr.connect(:timeout => 120, :open_timeout => 120)
         | 
| 57 57 |  | 
| 58 58 | 
             
            == Retry 503s
         | 
| 59 59 | 
             
            A 503 is usually a temporary error which RSolr may retry if requested. You may specify the number of retry attempts with the +:retry_503+ option.
         | 
| @@ -74,11 +74,11 @@ Use the #get / #post method to send search requests to the /select handler: | |
| 74 74 |  | 
| 75 75 | 
             
            The +:params+ sent into the method are sent to Solr as-is, which is to say they are converted to Solr url style, but no special mapping is used.
         | 
| 76 76 | 
             
            When an array is used, multiple parameters *with the same name* are generated for the Solr query. Example:
         | 
| 77 | 
            -
             | 
| 77 | 
            +
             | 
| 78 78 | 
             
              solr.get 'select', :params => {:q=>'roses', :fq=>['red', 'violet']}
         | 
| 79 79 |  | 
| 80 80 | 
             
            The above statement generates this Solr query:
         | 
| 81 | 
            -
             | 
| 81 | 
            +
             | 
| 82 82 | 
             
              select?q=roses&fq=red&fq=violet
         | 
| 83 83 |  | 
| 84 84 | 
             
            ===Pagination
         | 
| @@ -92,14 +92,14 @@ The paginate method returns WillPaginate ready "docs" objects, so for example in | |
| 92 92 |  | 
| 93 93 | 
             
            ===Method Missing
         | 
| 94 94 | 
             
            The +RSolr::Client+ class also uses +method_missing+ for setting the request handler/path:
         | 
| 95 | 
            -
             | 
| 95 | 
            +
             | 
| 96 96 | 
             
              solr.paintings :params => {:q=>'roses', :fq=>['red', 'violet']}
         | 
| 97 | 
            -
             | 
| 97 | 
            +
             | 
| 98 98 | 
             
            This is sent to Solr as:
         | 
| 99 99 | 
             
              paintings?q=roses&fq=red&fq=violet
         | 
| 100 100 |  | 
| 101 101 | 
             
            This works with pagination as well:
         | 
| 102 | 
            -
             | 
| 102 | 
            +
             | 
| 103 103 | 
             
              solr.paginate_paintings 1, 10, {:q=>'roses', :fq=>['red', 'violet']}
         | 
| 104 104 |  | 
| 105 105 | 
             
            ===Using POST for Search Queries
         | 
| @@ -120,10 +120,10 @@ To send header information to Solr using RSolr, just use the +:headers+ option: | |
| 120 120 | 
             
            ===Building a Request
         | 
| 121 121 | 
             
            +RSolr::Client+ provides a method for building a request context, which can be useful for debugging or logging etc.:
         | 
| 122 122 | 
             
              request_context = solr.build_request "select", :data => {:q => "*:*"}, :method => :post, :headers => {}
         | 
| 123 | 
            -
             | 
| 123 | 
            +
             | 
| 124 124 | 
             
            To build a paginated request use build_paginated_request:
         | 
| 125 125 | 
             
              request_context = solr.build_paginated_request 1, 10, "select", ...
         | 
| 126 | 
            -
             | 
| 126 | 
            +
             | 
| 127 127 | 
             
            == Updating Solr
         | 
| 128 128 | 
             
            Updating is done using native Ruby objects. Hashes are used for single documents and arrays are used for a collection of documents (hashes). These objects get turned into simple XML "messages". Raw XML strings can also be used.
         | 
| 129 129 |  | 
| @@ -142,7 +142,7 @@ Raw commands via  #update | |
| 142 142 | 
             
              solr.update data: { optimize: true }.to_json, headers: { 'Content-Type' => 'application/json' }
         | 
| 143 143 |  | 
| 144 144 | 
             
            When adding, you can also supply "add" xml element attributes and/or a block for manipulating other "add" related elements (docs and fields) by calling the +xml+ method directly:
         | 
| 145 | 
            -
             | 
| 145 | 
            +
             | 
| 146 146 | 
             
              doc = {:id=>1, :price=>1.00}
         | 
| 147 147 | 
             
              add_attributes = {:allowDups=>false, :commitWithin=>10}
         | 
| 148 148 | 
             
              add_xml = solr.xml.add(doc, add_attributes) do |doc|
         | 
    
        data/lib/rsolr/client.rb
    CHANGED
    
    | @@ -35,6 +35,10 @@ class RSolr::Client | |
| 35 35 | 
             
                @update_format = options.delete(:update_format) || RSolr::JSON::Generator
         | 
| 36 36 | 
             
                @update_path = options.fetch(:update_path, 'update')
         | 
| 37 37 | 
             
                @options = options
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                if options[:read_timeout]
         | 
| 40 | 
            +
                  warn "DEPRECATION: Rsolr.new/connect option `read_timeout` is deprecated and will be removed in Rsolr 3. `timeout` is currently a synonym, use that instead."
         | 
| 41 | 
            +
                end
         | 
| 38 42 | 
             
              end
         | 
| 39 43 |  | 
| 40 44 | 
             
              def extract_url_from_options(options)
         | 
| @@ -122,6 +126,14 @@ class RSolr::Client | |
| 122 126 | 
             
                update opts.merge(:data => builder.commit( commit_attrs ))
         | 
| 123 127 | 
             
              end
         | 
| 124 128 |  | 
| 129 | 
            +
              # soft commit
         | 
| 130 | 
            +
              #
         | 
| 131 | 
            +
              # https://lucene.apache.org/solr/guide/updatehandlers-in-solrconfig.html#commit-and-softcommit
         | 
| 132 | 
            +
              #
         | 
| 133 | 
            +
              def soft_commit opts = {}
         | 
| 134 | 
            +
                commit(opts.merge params: { softCommit: true })
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 125 137 | 
             
              # send "optimize" xml with opts.
         | 
| 126 138 | 
             
              #
         | 
| 127 139 | 
             
              # http://wiki.apache.org/solr/UpdateXmlMessages#A.22commit.22_and_.22optimize.22
         | 
| @@ -200,7 +212,9 @@ class RSolr::Client | |
| 200 212 | 
             
                  end
         | 
| 201 213 |  | 
| 202 214 | 
             
                  { status: response.status.to_i, headers: response.headers, body: response.body.force_encoding('utf-8') }
         | 
| 203 | 
            -
                rescue  | 
| 215 | 
            +
                rescue Faraday::TimeoutError => e
         | 
| 216 | 
            +
                  raise RSolr::Error::Timeout.new(request_context, e.response)
         | 
| 217 | 
            +
                rescue Errno::ECONNREFUSED, defined?(Faraday::ConnectionFailed) ? Faraday::ConnectionFailed : Faraday::Error::ConnectionFailed
         | 
| 204 218 | 
             
                  raise RSolr::Error::ConnectionRefused, request_context.inspect
         | 
| 205 219 | 
             
                rescue Faraday::Error => e
         | 
| 206 220 | 
             
                  raise RSolr::Error::Http.new(request_context, e.response)
         | 
| @@ -283,23 +297,39 @@ class RSolr::Client | |
| 283 297 |  | 
| 284 298 | 
             
                result
         | 
| 285 299 | 
             
              end
         | 
| 286 | 
            -
             | 
| 300 | 
            +
             | 
| 287 301 | 
             
              def connection
         | 
| 288 302 | 
             
                @connection ||= begin
         | 
| 289 303 | 
             
                  conn_opts = { request: {} }
         | 
| 290 304 | 
             
                  conn_opts[:url] = uri.to_s
         | 
| 291 305 | 
             
                  conn_opts[:proxy] = proxy if proxy
         | 
| 292 306 | 
             
                  conn_opts[:request][:open_timeout] = options[:open_timeout] if options[:open_timeout]
         | 
| 293 | 
            -
             | 
| 307 | 
            +
             | 
| 308 | 
            +
                  if options[:read_timeout] || options[:timeout]
         | 
| 309 | 
            +
                    # read_timeout was being passed to faraday as timeout since Rsolr 2.0,
         | 
| 310 | 
            +
                    # it's now deprecated, just use `timeout` directly.
         | 
| 311 | 
            +
                    conn_opts[:request][:timeout] = options[:timeout] || options[:read_timeout]
         | 
| 312 | 
            +
                  end
         | 
| 313 | 
            +
             | 
| 294 314 | 
             
                  conn_opts[:request][:params_encoder] = Faraday::FlatParamsEncoder
         | 
| 295 315 |  | 
| 296 316 | 
             
                  Faraday.new(conn_opts) do |conn|
         | 
| 297 | 
            -
                     | 
| 317 | 
            +
                    if uri.user && uri.password
         | 
| 318 | 
            +
                      case Faraday::VERSION
         | 
| 319 | 
            +
                      when /^0/
         | 
| 320 | 
            +
                        conn.basic_auth uri.user, uri.password
         | 
| 321 | 
            +
                      when /^1/
         | 
| 322 | 
            +
                        conn.request :basic_auth, uri.user, uri.password
         | 
| 323 | 
            +
                      else
         | 
| 324 | 
            +
                        conn.request :authorization, :basic_auth, uri.user, uri.password
         | 
| 325 | 
            +
                      end
         | 
| 326 | 
            +
                    end
         | 
| 327 | 
            +
             | 
| 298 328 | 
             
                    conn.response :raise_error
         | 
| 299 329 | 
             
                    conn.request :retry, max: options[:retry_after_limit], interval: 0.05,
         | 
| 300 330 | 
             
                                         interval_randomness: 0.5, backoff_factor: 2,
         | 
| 301 331 | 
             
                                         exceptions: ['Faraday::Error', 'Timeout::Error'] if options[:retry_503]
         | 
| 302 | 
            -
                    conn.adapter options[:adapter] || Faraday.default_adapter
         | 
| 332 | 
            +
                    conn.adapter options[:adapter] || Faraday.default_adapter || :net_http
         | 
| 303 333 | 
             
                  end
         | 
| 304 334 | 
             
                end
         | 
| 305 335 | 
             
              end
         | 
    
        data/lib/rsolr/document.rb
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            module RSolr
         | 
| 2 2 | 
             
              class Document
         | 
| 3 3 | 
             
                CHILD_DOCUMENT_KEY = '_childDocuments_'.freeze
         | 
| 4 | 
            +
                ATOMIC_MULTI_VALUE_OPERATIONS = %i[set add add-distinct remove]
         | 
| 4 5 |  | 
| 5 6 | 
             
                # "attrs" is a hash for setting the "doc" xml attributes
         | 
| 6 7 | 
             
                # "fields" is an array of Field objects
         | 
| @@ -48,8 +49,14 @@ module RSolr | |
| 48 49 | 
             
                def as_json
         | 
| 49 50 | 
             
                  @fields.group_by(&:name).each_with_object({}) do |(field, values), result|
         | 
| 50 51 | 
             
                    v = values.map(&:as_json)
         | 
| 51 | 
            -
                    if v.length > 1 && v.first.is_a?(Hash) | 
| 52 | 
            -
                       | 
| 52 | 
            +
                    if v.length > 1 && v.first.is_a?(Hash)
         | 
| 53 | 
            +
                      if v.first.key?(:value)
         | 
| 54 | 
            +
                        v = v.first.merge(value: v.map { |single| single[:value] })
         | 
| 55 | 
            +
                      else
         | 
| 56 | 
            +
                        (v.first.keys & ATOMIC_MULTI_VALUE_OPERATIONS).each do |op|
         | 
| 57 | 
            +
                          v = [{ op => v.map { |single| single[op] } }]
         | 
| 58 | 
            +
                        end
         | 
| 59 | 
            +
                      end
         | 
| 53 60 | 
             
                    end
         | 
| 54 61 | 
             
                    v = v.first if v.length == 1 && field.to_s != CHILD_DOCUMENT_KEY
         | 
| 55 62 | 
             
                    result[field] = v
         | 
    
        data/lib/rsolr/error.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module RSolr::Error
         | 
| 2 4 |  | 
| 3 5 | 
             
              module SolrContext
         | 
| @@ -24,6 +26,18 @@ module RSolr::Error | |
| 24 26 |  | 
| 25 27 | 
             
                def parse_solr_error_response body
         | 
| 26 28 | 
             
                  begin
         | 
| 29 | 
            +
                    # Default JSON response, try to parse and retrieve error message
         | 
| 30 | 
            +
                    if response[:headers] && response[:headers]["content-type"].start_with?("application/json")
         | 
| 31 | 
            +
                      begin
         | 
| 32 | 
            +
                        parsed_body = JSON.parse(body)
         | 
| 33 | 
            +
                        info = parsed_body && parsed_body["error"] && parsed_body["error"]["msg"]
         | 
| 34 | 
            +
                      rescue JSON::ParserError
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                    return info if info
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    # legacy analysis, I think trying to handle wt=ruby responses without
         | 
| 40 | 
            +
                    # a full parse?
         | 
| 27 41 | 
             
                    if body =~ /<pre>/
         | 
| 28 42 | 
             
                      info = body.scan(/<pre>(.*)<\/pre>/mi)[0]
         | 
| 29 43 | 
             
                    elsif body =~ /'msg'=>/
         | 
| @@ -110,9 +124,16 @@ module RSolr::Error | |
| 110 124 | 
             
                }
         | 
| 111 125 |  | 
| 112 126 | 
             
                def initialize request, response
         | 
| 127 | 
            +
                  response = response_with_force_encoded_body(response)
         | 
| 113 128 | 
             
                  @request, @response = request, response
         | 
| 114 129 | 
             
                end
         | 
| 115 130 |  | 
| 131 | 
            +
                private
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                def response_with_force_encoded_body(response)
         | 
| 134 | 
            +
                  response[:body] = response[:body].force_encoding('UTF-8') if response
         | 
| 135 | 
            +
                  response
         | 
| 136 | 
            +
                end
         | 
| 116 137 | 
             
              end
         | 
| 117 138 |  | 
| 118 139 | 
             
              # Thrown if the :wt is :ruby
         | 
| @@ -121,6 +142,15 @@ module RSolr::Error | |
| 121 142 |  | 
| 122 143 | 
             
              end
         | 
| 123 144 |  | 
| 145 | 
            +
              # Subclasses Rsolr::Error::Http for legacy backwards compatibility
         | 
| 146 | 
            +
              # purposes, because earlier RSolr 2 didn't distinguish these
         | 
| 147 | 
            +
              # from Http errors.
         | 
| 148 | 
            +
              #
         | 
| 149 | 
            +
              # In RSolr 3, it could make sense to `< Timeout::Error` instead,
         | 
| 150 | 
            +
              # analagous to ConnectionRefused above
         | 
| 151 | 
            +
              class Timeout < Http
         | 
| 152 | 
            +
              end
         | 
| 153 | 
            +
             | 
| 124 154 | 
             
              # Thrown if the :wt is :ruby
         | 
| 125 155 | 
             
              # but the body wasn't succesfully parsed/evaluated
         | 
| 126 156 | 
             
              class InvalidJsonResponse < InvalidResponse
         | 
    
        data/lib/rsolr/version.rb
    CHANGED
    
    
    
        data/rsolr.gemspec
    CHANGED
    
    | @@ -23,18 +23,17 @@ Gem::Specification.new do |s| | |
| 23 23 | 
             
              s.email       = ["goodieboy@gmail.com"]
         | 
| 24 24 | 
             
              s.license     = 'Apache-2.0'
         | 
| 25 25 | 
             
              s.homepage    = "https://github.com/rsolr/rsolr"
         | 
| 26 | 
            -
              s.rubyforge_project = "rsolr"
         | 
| 27 26 | 
             
              s.files         = `git ls-files`.split("\n")
         | 
| 28 27 | 
             
              s.test_files    = `git ls-files -- {spec}/*`.split("\n")
         | 
| 29 28 | 
             
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 30 29 | 
             
              s.require_paths = ["lib"]
         | 
| 31 | 
            -
             | 
| 30 | 
            +
             | 
| 32 31 | 
             
              s.required_ruby_version      = '>= 1.9.3'
         | 
| 33 | 
            -
             | 
| 32 | 
            +
             | 
| 34 33 | 
             
              s.requirements << 'Apache Solr'
         | 
| 35 34 |  | 
| 36 35 | 
             
              s.add_dependency 'builder', '>= 2.1.2'
         | 
| 37 | 
            -
              s.add_dependency 'faraday', '>= 0.9.0'
         | 
| 36 | 
            +
              s.add_dependency 'faraday', '>= 0.9', '!= 2.0.0', '< 3'
         | 
| 38 37 |  | 
| 39 38 | 
             
              s.add_development_dependency 'activesupport'
         | 
| 40 39 | 
             
              s.add_development_dependency 'nokogiri', '>= 1.4.0'
         | 
    
        data/spec/api/client_spec.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ require 'spec_helper' | |
| 3 3 | 
             
            RSpec.describe RSolr::Client do
         | 
| 4 4 | 
             
              let(:connection) { nil }
         | 
| 5 5 | 
             
              let(:url) { "http://localhost:9999/solr" }
         | 
| 6 | 
            -
              let(:connection_options) { { url: url,  | 
| 6 | 
            +
              let(:connection_options) { { url: url, update_format: :xml } }
         | 
| 7 7 |  | 
| 8 8 | 
             
              let(:client) do
         | 
| 9 9 | 
             
                RSolr::Client.new connection, connection_options
         | 
| @@ -71,6 +71,14 @@ RSpec.describe RSolr::Client do | |
| 71 71 | 
             
                end
         | 
| 72 72 | 
             
              end
         | 
| 73 73 |  | 
| 74 | 
            +
              context "execute" do
         | 
| 75 | 
            +
                it "maps Faraday::TimeoutError to an RSolr::Error::Timeout" do
         | 
| 76 | 
            +
                  allow(client.connection).to receive(:send).and_raise(Faraday::TimeoutError)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  expect{ client.execute({}) }.to raise_error RSolr::Error::Timeout
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 74 82 | 
             
              context "post" do
         | 
| 75 83 | 
             
                it "should pass the expected params to the connection's #execute method" do
         | 
| 76 84 | 
             
                  request_opts = {:data => "the data", :method=>:post, :headers => {"Content-Type" => "text/plain"}}
         | 
| @@ -109,7 +117,7 @@ RSpec.describe RSolr::Client do | |
| 109 117 |  | 
| 110 118 | 
             
                context 'when the client is configured for json updates' do
         | 
| 111 119 | 
             
                  let(:client) do
         | 
| 112 | 
            -
                    RSolr::Client.new nil, :url => "http://localhost:9999/solr", : | 
| 120 | 
            +
                    RSolr::Client.new nil, :url => "http://localhost:9999/solr", :update_format => :json
         | 
| 113 121 | 
             
                  end
         | 
| 114 122 | 
             
                  it "should send json to the connection's #post method" do
         | 
| 115 123 | 
             
                    expect(client).to receive(:execute).
         | 
| @@ -279,6 +287,48 @@ RSpec.describe RSolr::Client do | |
| 279 287 |  | 
| 280 288 | 
             
              end
         | 
| 281 289 |  | 
| 290 | 
            +
              context "commit" do
         | 
| 291 | 
            +
                it "should add hard commit params for hard commit request" do
         | 
| 292 | 
            +
                  expect(client).to receive(:execute).
         | 
| 293 | 
            +
                    with(
         | 
| 294 | 
            +
                      hash_including({
         | 
| 295 | 
            +
                        :path => "update",
         | 
| 296 | 
            +
                        :headers => {"Content-Type"=>"text/xml"},
         | 
| 297 | 
            +
                        :method => :post,
         | 
| 298 | 
            +
                        :data => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><commit/>",
         | 
| 299 | 
            +
                        :params => {:wt=>:json},
         | 
| 300 | 
            +
                        :query => "wt=json"
         | 
| 301 | 
            +
                      })
         | 
| 302 | 
            +
                  ).
         | 
| 303 | 
            +
                  and_return(
         | 
| 304 | 
            +
                    :body => "",
         | 
| 305 | 
            +
                    :status => 200,
         | 
| 306 | 
            +
                    :headers => {"Content-Type"=>"text/xml"}
         | 
| 307 | 
            +
                  )
         | 
| 308 | 
            +
                  client.commit
         | 
| 309 | 
            +
                end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                it "should add soft commit params for soft commit request" do
         | 
| 312 | 
            +
                  expect(client).to receive(:execute).
         | 
| 313 | 
            +
                    with(
         | 
| 314 | 
            +
                      hash_including({
         | 
| 315 | 
            +
                        :path => "update",
         | 
| 316 | 
            +
                        :headers => {"Content-Type"=>"text/xml"},
         | 
| 317 | 
            +
                        :method => :post,
         | 
| 318 | 
            +
                        :data => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><commit/>",
         | 
| 319 | 
            +
                        :params => {:softCommit=>true, :wt=>:json},
         | 
| 320 | 
            +
                        :query => "wt=json&softCommit=true"
         | 
| 321 | 
            +
                      })
         | 
| 322 | 
            +
                  ).
         | 
| 323 | 
            +
                  and_return(
         | 
| 324 | 
            +
                    :body => "",
         | 
| 325 | 
            +
                    :status => 200,
         | 
| 326 | 
            +
                    :headers => {"Content-Type"=>"text/xml"}
         | 
| 327 | 
            +
                  )
         | 
| 328 | 
            +
                  client.soft_commit
         | 
| 329 | 
            +
                end
         | 
| 330 | 
            +
              end
         | 
| 331 | 
            +
             | 
| 282 332 | 
             
              context "indifferent access" do
         | 
| 283 333 | 
             
                it "should raise a RuntimeError if the #with_indifferent_access extension isn't loaded" do
         | 
| 284 334 | 
             
                  hide_const("::RSolr::HashWithIndifferentAccessWithResponse")
         | 
| @@ -342,7 +392,7 @@ RSpec.describe RSolr::Client do | |
| 342 392 | 
             
                    expect(subject[:headers]).to eq({"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8"})
         | 
| 343 393 | 
             
                  end
         | 
| 344 394 | 
             
                end
         | 
| 345 | 
            -
             | 
| 395 | 
            +
             | 
| 346 396 | 
             
                it "should properly handle proxy configuration" do
         | 
| 347 397 | 
             
                  result = client_with_proxy.build_request('select',
         | 
| 348 398 | 
             
                    :method => :post,
         | 
    
        data/spec/api/error_spec.rb
    CHANGED
    
    | @@ -43,5 +43,107 @@ RSpec.describe RSolr::Error do | |
| 43 43 | 
             
                  let(:response_body) { (response_lines << "'error'=>{'msg'=> #{msg}").join("\n") }
         | 
| 44 44 | 
             
                  it { should include msg }
         | 
| 45 45 | 
             
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                context "when the response body is made of multi-byte chars and encoded by ASCII-8bit" do
         | 
| 48 | 
            +
                  let (:response_lines) { (1..15).to_a.map { |i| "レスポンス #{i}".b } }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  it "encodes errorlogs by UTF-8" do
         | 
| 51 | 
            +
                    expect(subject.encoding.to_s).to eq 'UTF-8'
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              context "when response is JSON" do
         | 
| 57 | 
            +
                let(:response) {{
         | 
| 58 | 
            +
                  :body   => response_body,
         | 
| 59 | 
            +
                  :status => 500,
         | 
| 60 | 
            +
                  :headers => {
         | 
| 61 | 
            +
                    "content-type" => "application/json;charset=utf-8"
         | 
| 62 | 
            +
                  }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                }}
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                context "and contains a msg key" do
         | 
| 67 | 
            +
                  let(:msg) { "field 'description_text4_tesim' was indexed without offsets, cannot highlight" }
         | 
| 68 | 
            +
                  let(:response_body) {<<~EOS
         | 
| 69 | 
            +
                    {
         | 
| 70 | 
            +
                      "responseHeader":{
         | 
| 71 | 
            +
                        "status":500,
         | 
| 72 | 
            +
                        "QTime":11,
         | 
| 73 | 
            +
                        "params":{
         | 
| 74 | 
            +
                          "q":"supercali",
         | 
| 75 | 
            +
                          "hl":"true",
         | 
| 76 | 
            +
                          "hl:fl":"description_text4_tesim",
         | 
| 77 | 
            +
                          "hl.method":"unified",
         | 
| 78 | 
            +
                          "hl.offsetSource":"postings"
         | 
| 79 | 
            +
                        }
         | 
| 80 | 
            +
                      },
         | 
| 81 | 
            +
                      "response":{"numFound":0,"start":0,"maxScore":127.32743,"numFoundExact":true,"docs":[]},
         | 
| 82 | 
            +
                      "facet_counts":{
         | 
| 83 | 
            +
                        "facet_queries":{},
         | 
| 84 | 
            +
                        "facet_fields":{}
         | 
| 85 | 
            +
                      },
         | 
| 86 | 
            +
                      "error":{
         | 
| 87 | 
            +
                        "msg":"#{msg}",
         | 
| 88 | 
            +
                        "trace":"java.lang.IllegalArgumentException: field 'description_text4_tesim' was indexed without offsets, cannot highlight\\n\\tat org.apache.lucene.search.uhighlight.FieldHighlighter.highlightOffsetsEnums(FieldHighlighter.java:149)\\n\\tat org.apache.lucene.search.uhighlight.FieldHighlighter.highlightFieldForDoc(FieldHighlighter.java:79)\\n\\tat org.apache.lucene.search.uhighlight.UnifiedHighlighter.highlightFieldsAsObjects(UnifiedHighlighter.java:641)\\n\\tat org.apache.lucene.search.uhighlight.UnifiedHighlighter.highlightFields(UnifiedHighlighter.java:510)\\n\\tat org.apache.solr.highlight.UnifiedSolrHighlighter.doHighlighting(UnifiedSolrHighlighter.java:149)\\n\\tat org.apache.solr.handler.component.HighlightComponent.process(HighlightComponent.java:172)\\n\\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:331)\\n\\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:214)\\n\\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2606)\\n\\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:815)\\n\\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:588)\\n\\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:415)\\n\\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:345)\\n\\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1596)\\n\\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\\n\\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:590)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)\\n\\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1610)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\\n\\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1300)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)\\n\\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)\\n\\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1580)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)\\n\\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1215)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\\n\\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:221)\\n\\tat org.eclipse.jetty.server.handler.InetAccessHandler.handle(InetAccessHandler.java:177)\\n\\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:322)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.server.Server.handle(Server.java:500)\\n\\tat org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)\\n\\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)\\n\\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)\\n\\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)\\n\\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\\n\\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)\\n\\tat org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)\\n\\tat org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)\\n\\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)\\n\\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)\\n\\tat java.base/java.lang.Thread.run(Thread.java:834)\\n",
         | 
| 89 | 
            +
                        "code":500
         | 
| 90 | 
            +
                      }
         | 
| 91 | 
            +
                    }
         | 
| 92 | 
            +
                    EOS
         | 
| 93 | 
            +
                  }
         | 
| 94 | 
            +
                  it {
         | 
| 95 | 
            +
                    should include msg
         | 
| 96 | 
            +
                  }
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                context "and does not contain a msg key" do
         | 
| 100 | 
            +
                  let(:response_body) {<<~EOS
         | 
| 101 | 
            +
                    {
         | 
| 102 | 
            +
                      "responseHeader":{
         | 
| 103 | 
            +
                        "status":500,
         | 
| 104 | 
            +
                        "QTime":11,
         | 
| 105 | 
            +
                        "params":{
         | 
| 106 | 
            +
                          "q":"supercali",
         | 
| 107 | 
            +
                          "hl":"true",
         | 
| 108 | 
            +
                          "hl:fl":"description_text4_tesim",
         | 
| 109 | 
            +
                          "hl.method":"unified",
         | 
| 110 | 
            +
                          "hl.offsetSource":"postings"
         | 
| 111 | 
            +
                        }
         | 
| 112 | 
            +
                      },
         | 
| 113 | 
            +
                      "response":{"numFound":0,"start":0,"maxScore":127.32743,"numFoundExact":true,"docs":[]},
         | 
| 114 | 
            +
                      "facet_counts":{
         | 
| 115 | 
            +
                        "facet_queries":{},
         | 
| 116 | 
            +
                        "facet_fields":{}
         | 
| 117 | 
            +
                      },
         | 
| 118 | 
            +
                    }
         | 
| 119 | 
            +
                    EOS
         | 
| 120 | 
            +
                  }
         | 
| 121 | 
            +
                  it "shows the first eleven lines of the response" do
         | 
| 122 | 
            +
                    expect(subject).to include(response_body.split("\n")[0..10].join("\n"))
         | 
| 123 | 
            +
                    expect(subject).not_to include(response_body.split("\n")[11])
         | 
| 124 | 
            +
                  end
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                context "and is not parseable json" do
         | 
| 128 | 
            +
                  let(:response_body) {<<~EOS
         | 
| 129 | 
            +
                    one
         | 
| 130 | 
            +
                    two
         | 
| 131 | 
            +
                    three
         | 
| 132 | 
            +
                    four
         | 
| 133 | 
            +
                    five
         | 
| 134 | 
            +
                    six
         | 
| 135 | 
            +
                    seven
         | 
| 136 | 
            +
                    eight
         | 
| 137 | 
            +
                    nine
         | 
| 138 | 
            +
                    ten
         | 
| 139 | 
            +
                    eleven
         | 
| 140 | 
            +
                    twelve
         | 
| 141 | 
            +
                  EOS
         | 
| 142 | 
            +
                  }
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
                it "shows the first eleven lines of the response" do
         | 
| 145 | 
            +
                  expect(subject).to include(response_body.split("\n")[0..10].join("\n"))
         | 
| 146 | 
            +
                  expect(subject).not_to include(response_body.split("\n")[11])
         | 
| 147 | 
            +
                end
         | 
| 46 148 | 
             
              end
         | 
| 47 149 | 
             
            end
         | 
    
        data/spec/api/json_spec.rb
    CHANGED
    
    | @@ -150,11 +150,62 @@ RSpec.describe RSolr::JSON do | |
| 150 150 | 
             
              end
         | 
| 151 151 |  | 
| 152 152 | 
             
              it 'should create multiple fields from array values with options' do
         | 
| 153 | 
            +
                test_values = [nil, 'matt1', 'matt2']
         | 
| 153 154 | 
             
                message = JSON.parse(
         | 
| 154 | 
            -
                  generator.add(id: '1') { |doc| doc.add_field(:name,  | 
| 155 | 
            +
                  generator.add(id: '1') { |doc| doc.add_field(:name, test_values, boost: 3) },
         | 
| 155 156 | 
             
                  symbolize_names: true
         | 
| 156 157 | 
             
                )
         | 
| 157 | 
            -
                expect(message).to eq [{ id: '1', name: { boost: 3, value:  | 
| 158 | 
            +
                expect(message).to eq [{ id: '1', name: { boost: 3, value: test_values } }]
         | 
| 159 | 
            +
              end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
              context 'for atomic updates with arrays' do
         | 
| 162 | 
            +
                let(:test_values) { %w[value1 value2] }
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                it 'creates single field from array values on SET' do
         | 
| 165 | 
            +
                  expect(
         | 
| 166 | 
            +
                    JSON.parse(
         | 
| 167 | 
            +
                      generator.add(id: 'set-id') { |doc| doc.add_field(:name, test_values, update: :set) },
         | 
| 168 | 
            +
                      symbolize_names: true
         | 
| 169 | 
            +
                    )
         | 
| 170 | 
            +
                  ).to eq [{ id: 'set-id', name: { set: test_values } }]
         | 
| 171 | 
            +
                end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                it 'creates single field from array values on ADD' do
         | 
| 174 | 
            +
                  expect(
         | 
| 175 | 
            +
                    JSON.parse(
         | 
| 176 | 
            +
                      generator.add(id: 'add-id') { |doc| doc.add_field(:name, test_values, update: :add) },
         | 
| 177 | 
            +
                      symbolize_names: true
         | 
| 178 | 
            +
                    )
         | 
| 179 | 
            +
                  ).to eq [{ id: 'add-id', name: { add: test_values } }]
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                it 'creates single field from array values on ADD-DISTINCT' do
         | 
| 183 | 
            +
                  expect(
         | 
| 184 | 
            +
                    JSON.parse(
         | 
| 185 | 
            +
                      generator.add(id: 'add-distinct-id') { |doc| doc.add_field(:name, test_values, update: :'add-distinct') },
         | 
| 186 | 
            +
                      symbolize_names: true
         | 
| 187 | 
            +
                    )
         | 
| 188 | 
            +
                  ).to eq [{ id: 'add-distinct-id', name: { 'add-distinct': test_values } }]
         | 
| 189 | 
            +
                end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                it 'creates single field from array values on REMOVE' do
         | 
| 192 | 
            +
                  expect(
         | 
| 193 | 
            +
                    JSON.parse(
         | 
| 194 | 
            +
                      generator.add(id: 'remove-id') { |doc| doc.add_field(:name, test_values, update: :remove) },
         | 
| 195 | 
            +
                      symbolize_names: true
         | 
| 196 | 
            +
                    )
         | 
| 197 | 
            +
                  ).to eq [{ id: 'remove-id', name: { remove: test_values } }]
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                it 'creates single field from array values for child document update' do
         | 
| 201 | 
            +
                  test_nested_values = [{id: 1, name: 'value1'}, {id: 1, name: 'value2'}]
         | 
| 202 | 
            +
                  expect(
         | 
| 203 | 
            +
                    JSON.parse(
         | 
| 204 | 
            +
                      generator.add(id: 'set-id') { |doc| doc.add_field(:child_documents, test_nested_values, update: :set) },
         | 
| 205 | 
            +
                      symbolize_names: true
         | 
| 206 | 
            +
                    )
         | 
| 207 | 
            +
                  ).to eq [{ id: 'set-id', child_documents: { set: test_nested_values } }]
         | 
| 208 | 
            +
                end
         | 
| 158 209 | 
             
              end
         | 
| 159 210 |  | 
| 160 211 | 
             
              describe '#commit' do
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe RSolr::Client do
         | 
| 4 | 
            +
              describe "#connection" do
         | 
| 5 | 
            +
                it "accepts a timeout parameter it passes to Faraday" do
         | 
| 6 | 
            +
                  client = described_class.new(nil, timeout: 1000)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  expect(client.connection.options[:timeout]).to eq 1000
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                it "accepts a deprecated read_timeout" do
         | 
| 11 | 
            +
                  client = nil
         | 
| 12 | 
            +
                  expect do
         | 
| 13 | 
            +
                    client = described_class.new(nil, read_timeout: 1000)
         | 
| 14 | 
            +
                  end.to output(/`read_timeout` is deprecated/).to_stderr
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  expect(client.connection.options[:timeout]).to eq 1000
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rsolr
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Antoine Latter
         | 
| @@ -26,10 +26,10 @@ authors: | |
| 26 26 | 
             
            - Nathan Witmer
         | 
| 27 27 | 
             
            - Naomi Dushay
         | 
| 28 28 | 
             
            - '"shima"'
         | 
| 29 | 
            -
            autorequire: | 
| 29 | 
            +
            autorequire:
         | 
| 30 30 | 
             
            bindir: bin
         | 
| 31 31 | 
             
            cert_chain: []
         | 
| 32 | 
            -
            date:  | 
| 32 | 
            +
            date: 2022-02-11 00:00:00.000000000 Z
         | 
| 33 33 | 
             
            dependencies:
         | 
| 34 34 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 35 35 | 
             
              name: builder
         | 
| @@ -51,14 +51,26 @@ dependencies: | |
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - ">="
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version: 0.9 | 
| 54 | 
            +
                    version: '0.9'
         | 
| 55 | 
            +
                - - "!="
         | 
| 56 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 57 | 
            +
                    version: 2.0.0
         | 
| 58 | 
            +
                - - "<"
         | 
| 59 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 60 | 
            +
                    version: '3'
         | 
| 55 61 | 
             
              type: :runtime
         | 
| 56 62 | 
             
              prerelease: false
         | 
| 57 63 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 58 64 | 
             
                requirements:
         | 
| 59 65 | 
             
                - - ">="
         | 
| 60 66 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: 0.9 | 
| 67 | 
            +
                    version: '0.9'
         | 
| 68 | 
            +
                - - "!="
         | 
| 69 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 70 | 
            +
                    version: 2.0.0
         | 
| 71 | 
            +
                - - "<"
         | 
| 72 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 73 | 
            +
                    version: '3'
         | 
| 62 74 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 63 75 | 
             
              name: activesupport
         | 
| 64 76 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -165,9 +177,9 @@ executables: [] | |
| 165 177 | 
             
            extensions: []
         | 
| 166 178 | 
             
            extra_rdoc_files: []
         | 
| 167 179 | 
             
            files:
         | 
| 180 | 
            +
            - ".github/workflows/ruby.yml"
         | 
| 168 181 | 
             
            - ".gitignore"
         | 
| 169 182 | 
             
            - ".rspec"
         | 
| 170 | 
            -
            - ".travis.yml"
         | 
| 171 183 | 
             
            - CHANGES.txt
         | 
| 172 184 | 
             
            - Gemfile
         | 
| 173 185 | 
             
            - LICENSE
         | 
| @@ -203,12 +215,13 @@ files: | |
| 203 215 | 
             
            - spec/fixtures/basic_configs/stopwords.txt
         | 
| 204 216 | 
             
            - spec/fixtures/basic_configs/synonyms.txt
         | 
| 205 217 | 
             
            - spec/integration/solr5_spec.rb
         | 
| 218 | 
            +
            - spec/lib/rsolr/client_spec.rb
         | 
| 206 219 | 
             
            - spec/spec_helper.rb
         | 
| 207 220 | 
             
            homepage: https://github.com/rsolr/rsolr
         | 
| 208 221 | 
             
            licenses:
         | 
| 209 222 | 
             
            - Apache-2.0
         | 
| 210 223 | 
             
            metadata: {}
         | 
| 211 | 
            -
            post_install_message: | 
| 224 | 
            +
            post_install_message:
         | 
| 212 225 | 
             
            rdoc_options: []
         | 
| 213 226 | 
             
            require_paths:
         | 
| 214 227 | 
             
            - lib
         | 
| @@ -224,9 +237,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 224 237 | 
             
                  version: '0'
         | 
| 225 238 | 
             
            requirements:
         | 
| 226 239 | 
             
            - Apache Solr
         | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
            signing_key: 
         | 
| 240 | 
            +
            rubygems_version: 3.3.3
         | 
| 241 | 
            +
            signing_key:
         | 
| 230 242 | 
             
            specification_version: 4
         | 
| 231 243 | 
             
            summary: A Ruby client for Apache Solr
         | 
| 232 244 | 
             
            test_files: []
         |