diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be1382ad0..78719a57c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: push: - branches: [main, 0.1x] + branches: [main, 1.x, 0.1x] env: GIT_COMMIT_SHA: ${{ github.sha }} @@ -14,9 +14,12 @@ env: jobs: linting: runs-on: ubuntu-latest + env: + BUNDLE_WITH: lint + BUNDLE_WITHOUT: development:test steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Ruby 2.7 uses: ruby/setup-ruby@v1 @@ -24,17 +27,10 @@ jobs: ruby-version: 2.7 - name: Rubocop - run: | - gem install bundler - bundle config set without 'development test' - bundle config set with 'lint' - bundle install - bundle exec rubocop --format progress + run: bundle exec rubocop --format progress - name: Yard-Junk - run: | - gem install yard-junk --no-document - yard-junk --path lib + run: bundle exec yard-junk --path lib build: needs: [linting] @@ -43,22 +39,14 @@ jobs: strategy: fail-fast: false matrix: - ruby: ['2.4', '2.5', '2.6', '2.7', '3.0'] + ruby: ['2.6', '2.7', '3.0'] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - - - name: Install dependencies - run: | - sudo apt-get install libcurl4-openssl-dev - - - name: Build - run: | - gem install bundler -v '<2' - bundle install --jobs 4 --retry 3 + bundler-cache: true - name: Test continue-on-error: ${{ matrix.experimental }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 993dd06b3..e86f8cc9f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,20 +10,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v2 - - name: Set up Ruby 2.6 + - name: Set up Ruby 2.7 uses: actions/setup-ruby@v1 with: - ruby-version: 2.6.x + ruby-version: 2.7 - name: Publish to RubyGems - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build faraday.gemspec - gem push faraday-*.gem - env: - GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }} + uses: dawidd6/action-publish-gem@v1 + with: + api_key: ${{secrets.RUBYGEMS_AUTH_TOKEN}} diff --git a/Gemfile b/Gemfile index 66c9d29f4..1cad39848 100644 --- a/Gemfile +++ b/Gemfile @@ -2,39 +2,28 @@ source 'https://rubygems.org' -ruby RUBY_VERSION - +# Even though we don't officially support JRuby, this dependency makes Faraday +# compatible with it, so we're leaving it in for jruby users to use it. gem 'jruby-openssl', '~> 0.10.7', platforms: :jruby group :development, :test do + gem 'coveralls_reborn', require: false + gem 'multipart-parser' gem 'pry' + gem 'rack', '~> 2.2' gem 'rake' + gem 'rspec', '~> 3.7' + gem 'rspec_junit_formatter', '~> 0.4' + gem 'simplecov' + gem 'webmock', '~> 3.4' end -group :lint, :development do +group :development, :lint do gem 'rubocop', '~> 0.90.0' gem 'rubocop-inclusivity', '~> 1.0' gem 'rubocop-packaging', '~> 0.5' gem 'rubocop-performance', '~> 1.0' -end - -group :test, :development do - gem 'coveralls_reborn', require: false - gem 'em-http-request', '>= 1.1', require: 'em-http', platform: :ruby - gem 'em-synchrony', '>= 1.0.3', require: %w[em-synchrony em-synchrony/em-http], platform: :ruby - gem 'excon', '>= 0.27.4' - gem 'httpclient', '>= 2.2' - gem 'multipart-parser' - # TODO: remove this once v4 is released - options = (RUBY_VERSION.start_with?('3') ? { github: 'grosser/net-http-persistent', branch: 'grosser/spec' } : {}) - gem 'net-http-persistent', '>= 3.0', **options - gem 'patron', '>= 0.4.2', platforms: :ruby - gem 'rack-test', '>= 0.6', require: 'rack/test' - gem 'rspec', '~> 3.7' - gem 'rspec_junit_formatter', '~> 0.4' - gem 'simplecov' - gem 'typhoeus', '~> 1.4' - gem 'webmock', '~> 3.4' + gem 'yard-junk' end gemspec diff --git a/README.md b/README.md index 2eca7371a..b8372cb73 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ Need more details? See the [Faraday API Documentation][apidoc] to see how it wor ## Supported Ruby versions -This library aims to support and is [tested against][actions] the following Ruby -implementations: - -* Ruby 2.4+ +This library aims to support and is [tested against][actions] the currently officially supported Ruby +implementations. This means that, even without a major release, we could add or drop support for Ruby versions, +following their [EOL](https://endoflife.date/ruby). +Currently that means we support Ruby 2.6+ If something doesn't work on one of these Ruby versions, it's a bug. diff --git a/spec/faraday/adapter/em_http_spec.rb b/spec/faraday/adapter/em_http_spec.rb deleted file mode 100644 index 721bd8251..000000000 --- a/spec/faraday/adapter/em_http_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -unless defined?(JRUBY_VERSION) - RSpec.describe Faraday::Adapter::EMHttp do - features :request_body_on_query_methods, :reason_phrase_parse, :trace_method, - :skip_response_body_on_head, :parallel, :local_socket_binding - - it_behaves_like 'an adapter' - - it 'allows to provide adapter specific configs' do - url = URI('https://example.com:1234') - adapter = described_class.new nil, inactivity_timeout: 20 - req = adapter.create_request(url: url, request: {}) - - expect(req.connopts.inactivity_timeout).to eq(20) - end - - context 'Options' do - let(:request) { Faraday::RequestOptions.new } - let(:env) { { request: request } } - let(:options) { {} } - let(:adapter) { Faraday::Adapter::EMHttp.new } - - it 'configures timeout' do - request.timeout = 5 - adapter.configure_timeout(options, env) - expect(options[:inactivity_timeout]).to eq(5) - expect(options[:connect_timeout]).to eq(5) - end - - it 'configures timeout and open_timeout' do - request.timeout = 5 - request.open_timeout = 1 - adapter.configure_timeout(options, env) - expect(options[:inactivity_timeout]).to eq(5) - expect(options[:connect_timeout]).to eq(1) - end - - it 'configures all timeout settings' do - request.timeout = 5 - request.read_timeout = 3 - request.open_timeout = 1 - adapter.configure_timeout(options, env) - expect(options[:inactivity_timeout]).to eq(3) - expect(options[:connect_timeout]).to eq(1) - end - end - end -end diff --git a/spec/faraday/adapter/em_synchrony_spec.rb b/spec/faraday/adapter/em_synchrony_spec.rb deleted file mode 100644 index ce29e7186..000000000 --- a/spec/faraday/adapter/em_synchrony_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -unless defined?(JRUBY_VERSION) - RSpec.describe Faraday::Adapter::EMSynchrony do - features :request_body_on_query_methods, :reason_phrase_parse, - :skip_response_body_on_head, :parallel, :local_socket_binding - - it_behaves_like 'an adapter' - - it 'allows to provide adapter specific configs' do - url = URI('https://example.com:1234') - adapter = described_class.new nil, inactivity_timeout: 20 - req = adapter.create_request(url: url, request: {}) - - expect(req.connopts.inactivity_timeout).to eq(20) - end - end -end diff --git a/spec/faraday/adapter/excon_spec.rb b/spec/faraday/adapter/excon_spec.rb deleted file mode 100644 index d80abc376..000000000 --- a/spec/faraday/adapter/excon_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Faraday::Adapter::Excon do - features :request_body_on_query_methods, :reason_phrase_parse, :trace_method - - it_behaves_like 'an adapter' - - it 'allows to provide adapter specific configs' do - url = URI('https://example.com:1234') - - adapter = described_class.new(nil, debug_request: true) - - conn = adapter.build_connection(url: url) - - expect(conn.data[:debug_request]).to be_truthy - end - - context 'config' do - let(:adapter) { Faraday::Adapter::Excon.new } - let(:request) { Faraday::RequestOptions.new } - let(:uri) { URI.parse('https://example.com') } - let(:env) { { request: request, url: uri } } - - it 'sets timeout' do - request.timeout = 5 - options = adapter.send(:opts_from_env, env) - expect(options[:read_timeout]).to eq(5) - expect(options[:write_timeout]).to eq(5) - expect(options[:connect_timeout]).to eq(5) - end - - it 'sets timeout and open_timeout' do - request.timeout = 5 - request.open_timeout = 3 - options = adapter.send(:opts_from_env, env) - expect(options[:read_timeout]).to eq(5) - expect(options[:write_timeout]).to eq(5) - expect(options[:connect_timeout]).to eq(3) - end - - it 'sets open_timeout' do - request.open_timeout = 3 - options = adapter.send(:opts_from_env, env) - expect(options[:read_timeout]).to eq(nil) - expect(options[:write_timeout]).to eq(nil) - expect(options[:connect_timeout]).to eq(3) - end - end -end diff --git a/spec/faraday/adapter/httpclient_spec.rb b/spec/faraday/adapter/httpclient_spec.rb deleted file mode 100644 index 3cbf2c624..000000000 --- a/spec/faraday/adapter/httpclient_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Faraday::Adapter::HTTPClient do - # ruby gem defaults for testing purposes - HTTPCLIENT_OPEN = 60 - HTTPCLIENT_READ = 60 - HTTPCLIENT_WRITE = 120 - - features :request_body_on_query_methods, :reason_phrase_parse, :compression, - :trace_method, :local_socket_binding - - it_behaves_like 'an adapter' - - it 'allows to provide adapter specific configs' do - adapter = described_class.new do |client| - client.keep_alive_timeout = 20 - client.ssl_config.timeout = 25 - end - - client = adapter.build_connection(url: URI.parse('https://example.com')) - expect(client.keep_alive_timeout).to eq(20) - expect(client.ssl_config.timeout).to eq(25) - end - - context 'Options' do - let(:request) { Faraday::RequestOptions.new } - let(:env) { { request: request } } - let(:options) { {} } - let(:adapter) { Faraday::Adapter::HTTPClient.new } - let(:client) { adapter.connection(url: URI.parse('https://example.com')) } - - it 'configures timeout' do - assert_default_timeouts! - - request.timeout = 5 - adapter.configure_timeouts(client, request) - - expect(client.connect_timeout).to eq(5) - expect(client.send_timeout).to eq(5) - expect(client.receive_timeout).to eq(5) - end - - it 'configures open timeout' do - assert_default_timeouts! - - request.open_timeout = 1 - adapter.configure_timeouts(client, request) - - expect(client.connect_timeout).to eq(1) - expect(client.send_timeout).to eq(HTTPCLIENT_WRITE) - expect(client.receive_timeout).to eq(HTTPCLIENT_READ) - end - - it 'configures multiple timeouts' do - assert_default_timeouts! - - request.open_timeout = 1 - request.write_timeout = 10 - request.read_timeout = 5 - adapter.configure_timeouts(client, request) - - expect(client.connect_timeout).to eq(1) - expect(client.send_timeout).to eq(10) - expect(client.receive_timeout).to eq(5) - end - - def assert_default_timeouts! - expect(client.connect_timeout).to eq(HTTPCLIENT_OPEN) - expect(client.send_timeout).to eq(HTTPCLIENT_WRITE) - expect(client.receive_timeout).to eq(HTTPCLIENT_READ) - end - end -end diff --git a/spec/faraday/adapter/net_http_spec.rb b/spec/faraday/adapter/net_http_spec.rb index fda9b64d5..01f3c807e 100644 --- a/spec/faraday/adapter/net_http_spec.rb +++ b/spec/faraday/adapter/net_http_spec.rb @@ -1,64 +1,9 @@ # frozen_string_literal: true +# Even though Faraday::Adapter::NetHttp is not shipped with Faraday anymore, +# this is still useful to test `it_behaves_like 'an adapter'` shared examples. RSpec.describe Faraday::Adapter::NetHttp do features :request_body_on_query_methods, :reason_phrase_parse, :compression, :streaming, :trace_method it_behaves_like 'an adapter' - - context 'checking http' do - let(:url) { URI('http://example.com') } - let(:adapter) { described_class.new } - let(:http) { adapter.send(:connection, url: url, request: {}) } - - it { expect(http.port).to eq(80) } - - it 'sets max_retries to 0' do - adapter.send(:configure_request, http, {}) - - expect(http.max_retries).to eq(0) if http.respond_to?(:max_retries=) - end - - it 'supports write_timeout' do - adapter.send(:configure_request, http, write_timeout: 10) - - expect(http.write_timeout).to eq(10) if http.respond_to?(:write_timeout=) - end - - it 'supports open_timeout' do - adapter.send(:configure_request, http, open_timeout: 10) - - expect(http.open_timeout).to eq(10) - end - - it 'supports read_timeout' do - adapter.send(:configure_request, http, read_timeout: 10) - - expect(http.read_timeout).to eq(10) - end - - context 'with https url' do - let(:url) { URI('https://example.com') } - - it { expect(http.port).to eq(443) } - end - - context 'with http url including port' do - let(:url) { URI('https://example.com:1234') } - - it { expect(http.port).to eq(1234) } - end - - context 'with custom adapter config' do - let(:adapter) do - described_class.new do |http| - http.continue_timeout = 123 - end - end - - it do - adapter.send(:configure_request, http, {}) - expect(http.continue_timeout).to eq(123) - end - end - end end diff --git a/spec/faraday/adapter/patron_spec.rb b/spec/faraday/adapter/patron_spec.rb deleted file mode 100644 index 2408ab044..000000000 --- a/spec/faraday/adapter/patron_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Faraday::Adapter::Patron, unless: defined?(JRUBY_VERSION) do - features :reason_phrase_parse - - it_behaves_like 'an adapter' - - it 'allows to provide adapter specific configs' do - conn = Faraday.new do |f| - f.adapter :patron do |session| - session.max_redirects = 10 - raise 'Configuration block called' - end - end - - expect { conn.get('/') }.to raise_error(RuntimeError, 'Configuration block called') - end -end diff --git a/spec/faraday/adapter/rack_spec.rb b/spec/faraday/adapter/rack_spec.rb deleted file mode 100644 index 4fe6cba28..000000000 --- a/spec/faraday/adapter/rack_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Faraday::Adapter::Rack do - features :request_body_on_query_methods, :trace_method, - :skip_response_body_on_head - - it_behaves_like 'an adapter', adapter_options: WebmockRackApp.new -end diff --git a/spec/faraday/adapter/typhoeus_spec.rb b/spec/faraday/adapter/typhoeus_spec.rb deleted file mode 100644 index 7f63f9700..000000000 --- a/spec/faraday/adapter/typhoeus_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Faraday::Adapter::Typhoeus do - features :request_body_on_query_methods, :parallel, :trace_method - - it_behaves_like 'an adapter' -end diff --git a/spec/support/webmock_rack_app.rb b/spec/support/webmock_rack_app.rb deleted file mode 100644 index a3212c71c..000000000 --- a/spec/support/webmock_rack_app.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -# Rack app used to test the Rack adapter. -# Uses Webmock to check if requests are registered, in which case it returns -# the registered response. -class WebmockRackApp - def call(env) - req_signature = WebMock::RequestSignature.new( - req_method(env), - req_uri(env), - body: req_body(env), - headers: req_headers(env) - ) - - WebMock::RequestRegistry - .instance - .requested_signatures - .put(req_signature) - - process_response(req_signature) - end - - def req_method(env) - env['REQUEST_METHOD'].downcase.to_sym - end - - def req_uri(env) - scheme = env['rack.url_scheme'] - host = env['SERVER_NAME'] - port = env['SERVER_PORT'] - path = env['PATH_INFO'] - query = env['QUERY_STRING'] - - url = +"#{scheme}://#{host}:#{port}#{path}" - url += "?#{query}" if query - - uri = WebMock::Util::URI.heuristic_parse(url) - uri.path = uri.normalized_path.gsub('[^:]//', '/') - uri - end - - def req_headers(env) - http_headers = env.select { |k, _| k.start_with?('HTTP_') } - .map { |k, v| [k[5..-1], v] } - .to_h - - special_headers = Faraday::Adapter::Rack::SPECIAL_HEADERS - http_headers.merge(env.select { |k, _| special_headers.include?(k) }) - end - - def req_body(env) - env['rack.input'].read - end - - def process_response(req_signature) - res = WebMock::StubRegistry.instance.response_for_request(req_signature) - - if res.nil? && req_signature.uri.host == 'localhost' - raise Faraday::ConnectionFailed, 'Trying to connect to localhost' - end - - raise WebMock::NetConnectNotAllowedError, req_signature unless res - - raise Faraday::TimeoutError if res.should_timeout - - [res.status[0], res.headers || {}, [res.body || '']] - end -end