summaryrefslogtreecommitdiff
path: root/lib/vendor/excon/spec
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor/excon/spec')
-rw-r--r--lib/vendor/excon/spec/excon/error_spec.rb137
-rw-r--r--lib/vendor/excon/spec/excon/test/server_spec.rb28
-rw-r--r--lib/vendor/excon/spec/excon_spec.rb7
-rw-r--r--lib/vendor/excon/spec/helpers/file_path_helpers.rb22
-rw-r--r--lib/vendor/excon/spec/requests/basic_spec.rb40
-rw-r--r--lib/vendor/excon/spec/requests/eof_requests_spec.rb36
-rw-r--r--lib/vendor/excon/spec/spec_helper.rb24
-rw-r--r--lib/vendor/excon/spec/support/shared_contexts/test_server_context.rb83
-rw-r--r--lib/vendor/excon/spec/support/shared_examples/shared_example_for_clients.rb207
-rw-r--r--lib/vendor/excon/spec/support/shared_examples/shared_example_for_streaming_clients.rb20
-rw-r--r--lib/vendor/excon/spec/support/shared_examples/shared_example_for_test_servers.rb16
11 files changed, 620 insertions, 0 deletions
diff --git a/lib/vendor/excon/spec/excon/error_spec.rb b/lib/vendor/excon/spec/excon/error_spec.rb
new file mode 100644
index 0000000..3354c6a
--- /dev/null
+++ b/lib/vendor/excon/spec/excon/error_spec.rb
@@ -0,0 +1,137 @@
+describe Excon::Error do
+ # Regression against e300458f2d9330cb265baeb8973120d08c665d9
+ describe '#status_errors' do
+ describe '.keys ' do
+ expected = [
+ 100,
+ 101,
+ (200..206).to_a,
+ (300..307).to_a,
+ (400..417).to_a,
+ 422,
+ 429,
+ (500..504).to_a
+ ].flatten
+
+ it('returns the pertinent HTTP error numbers') do
+ expected.flatten == Excon::Error.status_errors.keys
+ end
+ end
+ end
+
+ describe '#new' do
+ it('returns an Excon::Error') do
+ expect(Excon::Error.new('bar').class == Excon::Error).to be true
+ end
+ it('raises errors for bad URIs') do
+ expect { Excon.new('foo') }.to raise_error(ArgumentError)
+ end
+
+ it('raises errors for bad paths') do
+ expect { Excon.new('http://localhost', path: "foo\r\nbar: baz") }.to raise_error(URI::InvalidURIError)
+ end
+ end
+
+ context 'when remaining backwards compatible' do
+ describe '#new' do
+ it 'should raise standard error and catch standard error' do
+ expect { raise Excon::Error::Client, 'foo' }.to raise_error(Excon::Error)
+ end
+
+ it 'should raise legacy errors and catch legacy errors' do
+ expect do
+ raise Excon::Errors::Error, 'bar'
+ end.to raise_error(Excon::Errors::Error)
+ end
+
+ it 'should raise standard error and catch legacy errors' do
+ expect do
+ raise Excon::Error::NotFound, 'bar'
+ end.to raise_error(Excon::Errors::Error)
+ end
+ end
+
+ describe '#status_error' do
+ it 'should raise with status_error() and catch with standard error' do
+ expect do
+ raise Excon::Error.status_error({ expects: 200 }, status: 400)
+ end.to raise_error(Excon::Error)
+ end
+
+ it 'should raise with status_error() and catch with legacy error' do
+ expect do
+ raise Excon::Error.status_error({ expects: 200 }, status: 400)
+ end.to raise_error(Excon::Errors::BadRequest)
+ end
+
+ it 'should raise with legacy status_error() and catch with standard' do
+ expect do
+ raise Excon::Errors.status_error({ expects: 200 }, status: 400)
+ end.to raise_error(Excon::Error)
+ end
+ end
+ end
+
+ context 'when exceptions are rescued' do
+ include_context("test server", :exec, 'error.rb', :before => :start, :after => :stop )
+
+ context 'when :debug_request and :debug_response are switched off' do
+ it('exception message does not include response or response info') do
+ begin
+ Excon.get('http://127.0.0.1:9292/error/not_found', expects: 200)
+ rescue Excon::Errors::HTTPStatusError => err
+ truth =
+ err.message.include?('Expected(200) <=> Actual(404 Not Found)') &&
+ !err.message.include?('excon.error.request') &&
+ !err.message.include?('excon.error.response')
+ expect(truth).to be true
+ end
+ end
+ end
+
+ context 'when :debug_request and :debug_response are switched on' do
+ it 'exception message includes request and response info' do
+ begin
+ Excon.get('http://127.0.0.1:9292/error/not_found', expects: 200,
+ debug_request: true, debug_response: true)
+ rescue Excon::Errors::HTTPStatusError => err
+ truth =
+ err.message.include?('Expected(200) <=> Actual(404 Not Found)') &&
+ err.message.include?('excon.error.request') &&
+ err.message.include?('excon.error.response')
+ expect(truth).to be true
+ end
+ end
+ end
+
+ context 'when only :debug_request is turned on' do
+ it('exception message includes only request info') do
+ begin
+ Excon.get('http://127.0.0.1:9292/error/not_found', expects: 200,
+ debug_request: true)
+ rescue Excon::Errors::HTTPStatusError => err
+ truth =
+ err.message.include?('Expected(200) <=> Actual(404 Not Found)') &&
+ err.message.include?('excon.error.request') &&
+ !err.message.include?('excon.error.response')
+ expect(truth).to be true
+ end
+ end
+ end
+
+ context 'when only :debug_response is turned on ' do
+ it('exception message includes only response info') do
+ begin
+ Excon.get('http://127.0.0.1:9292/error/not_found', expects: 200,
+ debug_response: true)
+ rescue Excon::Errors::HTTPStatusError => err
+ truth =
+ err.message.include?('Expected(200) <=> Actual(404 Not Found)') &&
+ !err.message.include?('excon.error.request') &&
+ err.message.include?('excon.error.response')
+ expect(truth).to be true
+ end
+ end
+ end
+ end
+end
diff --git a/lib/vendor/excon/spec/excon/test/server_spec.rb b/lib/vendor/excon/spec/excon/test/server_spec.rb
new file mode 100644
index 0000000..3fadb04
--- /dev/null
+++ b/lib/vendor/excon/spec/excon/test/server_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Excon::Test::Server do
+
+ context 'when the web server is webrick' do
+ it_should_behave_like "a excon test server", :webrick, 'basic.ru'
+ end
+
+
+ context 'when the web server is unicorn' do
+ context 'bound to a tcp socket' do
+ it_should_behave_like "a excon test server", :unicorn, 'streaming.ru'
+ end
+
+ context "bound to a unix socket" do
+ socket_uri = 'unix:///tmp/unicorn.socket'
+ it_should_behave_like "a excon test server", :unicorn, 'streaming.ru', socket_uri
+ end
+ end
+
+ context 'when the web server is puma' do
+ it_should_behave_like "a excon test server", :puma, 'streaming.ru'
+ end
+
+ context 'when the web server is a executable' do
+ it_should_behave_like "a excon test server", :exec, 'good.rb'
+ end
+end
diff --git a/lib/vendor/excon/spec/excon_spec.rb b/lib/vendor/excon/spec/excon_spec.rb
new file mode 100644
index 0000000..64cc5a8
--- /dev/null
+++ b/lib/vendor/excon/spec/excon_spec.rb
@@ -0,0 +1,7 @@
+require 'spec_helper'
+
+describe Excon do
+ it 'has a version number' do
+ expect(Excon::VERSION).not_to be nil
+ end
+end
diff --git a/lib/vendor/excon/spec/helpers/file_path_helpers.rb b/lib/vendor/excon/spec/helpers/file_path_helpers.rb
new file mode 100644
index 0000000..2424ec6
--- /dev/null
+++ b/lib/vendor/excon/spec/helpers/file_path_helpers.rb
@@ -0,0 +1,22 @@
+# Todo: s/tests/specs when migration is complete
+def get_abs_path(*parts)
+ File.join(File.expand_path('../../..', __FILE__), 'tests', *parts)
+end
+
+def data_path(*parts)
+ get_abs_path('data', *parts)
+end
+
+def rackup_path(*parts)
+ get_abs_path('rackups', *parts)
+end
+
+def webrick_path(*parts) rackup_path(*parts); end
+
+def unicorn_path(*parts) rackup_path(*parts); end
+
+def puma_path(*parts) rackup_path(*parts); end
+
+def exec_path(*parts)
+ get_abs_path('servers', *parts)
+end
diff --git a/lib/vendor/excon/spec/requests/basic_spec.rb b/lib/vendor/excon/spec/requests/basic_spec.rb
new file mode 100644
index 0000000..c46dc6f
--- /dev/null
+++ b/lib/vendor/excon/spec/requests/basic_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe Excon::Connection do
+ include_context('test server', :webrick, 'basic.ru', before: :start, after: :stop)
+ context 'when an explicit uri is passed' do
+ let(:conn) do
+ Excon::Connection.new(host: '127.0.0.1',
+ hostname: '127.0.0.1',
+ nonblock: false,
+ port: 9292,
+ scheme: 'http',
+ ssl_verify_peer: false)
+ end
+
+ describe '.new' do
+ it 'returns an instance' do
+ expect(conn).to be_instance_of Excon::Connection
+ end
+ end
+
+ context "when :method is :get and :path is /content-length/100" do
+ describe "#request" do
+ let(:response) do
+ response = conn.request(method: :get, path: '/content-length/100')
+ end
+ it 'returns an Excon::Response' do
+ expect(response).to be_instance_of Excon::Response
+ end
+ describe Excon::Response do
+ describe '#status' do
+ it 'returns 200' do
+ expect(response.status).to eq 200
+ end
+ end
+ end
+ end
+ end
+ include_examples 'a basic client'
+ end
+end
diff --git a/lib/vendor/excon/spec/requests/eof_requests_spec.rb b/lib/vendor/excon/spec/requests/eof_requests_spec.rb
new file mode 100644
index 0000000..e918ec7
--- /dev/null
+++ b/lib/vendor/excon/spec/requests/eof_requests_spec.rb
@@ -0,0 +1,36 @@
+require 'spec_helper'
+
+describe Excon do
+ context "when dispatching requests" do
+ context('to a server that does not supply response headers') do
+ include_context("test server", :exec, 'bad.rb', :before => :start, :after => :stop )
+ before(:all) do
+ @conn = Excon.new('http://127.0.0.1:9292')
+ end
+
+ context('when no block is given') do
+ it 'should rescue from an EOFError and return response' do
+ body = @conn.request(:method => :get, :path => '/eof/no_content_length_and_no_chunking').body
+ expect(body).to eq 'hello'
+ end
+ end
+
+ context('when a block is given') do
+ it 'should rescue from EOFError and return response' do
+ body = ""
+ response_block = lambda {|chunk, remaining, total| body << chunk }
+ @conn.request(:method => :get, :path => '/eof/no_content_length_and_no_chunking', :response_block => response_block)
+ expect(body).to eq 'hello'
+ end
+ end
+ end
+
+ context('to a server that prematurely aborts the request with no response') do
+ include_context("test server", :exec, 'eof.rb', :before => :start, :after => :stop )
+
+ it 'should raise an EOFError' do
+ expect { Excon.get('http://127.0.0.1:9292/eof') }.to raise_error(Excon::Errors::SocketError)
+ end
+ end
+ end
+end
diff --git a/lib/vendor/excon/spec/spec_helper.rb b/lib/vendor/excon/spec/spec_helper.rb
new file mode 100644
index 0000000..999f830
--- /dev/null
+++ b/lib/vendor/excon/spec/spec_helper.rb
@@ -0,0 +1,24 @@
+require 'excon'
+require 'excon/test/server'
+require 'json'
+
+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+ config.expect_with :rspec do |expectations|
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+
+ config.mock_with :rspec do |mocks|
+ mocks.verify_partial_doubles = true
+ end
+
+ if config.files_to_run.one?
+ config.default_formatter = 'doc'
+ end
+end
+
+# Load helpers
+Dir["./spec/helpers/**/*.rb"].sort.each { |f| require f}
+
+# Load shared examples and contexts
+Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
diff --git a/lib/vendor/excon/spec/support/shared_contexts/test_server_context.rb b/lib/vendor/excon/spec/support/shared_contexts/test_server_context.rb
new file mode 100644
index 0000000..f40e34c
--- /dev/null
+++ b/lib/vendor/excon/spec/support/shared_contexts/test_server_context.rb
@@ -0,0 +1,83 @@
+# TODO: Clean up this doc and dry up the conditionals
+#
+# Required params:
+# plugin (e.g., webrick, unicorn, etc)
+# file (e.g. a rackup )
+#
+# Optional params:
+# optional paramters may given as a hash
+# opts may contain a bind argument
+# opts may also contain before and after options
+#
+# In its simplest form:
+# { :before => :start, :after => :stop }
+#
+# With lambdas, which recieve @server as an argument
+# { before: lambda {|s| s.start }, after: lambda { |s| s.stop} }
+#
+# In both the cases above, before defaults to before(:all)
+# This can be circumvented with a Hash
+# { before: { :context => :start }, after: { :context => :stop } }
+# or
+# { before: { context: lambda { |s| s.start } }, after: { context: lambda { |s| s.stop } } }
+
+shared_context "test server" do |plugin, file, opts = {}|
+ plugin = plugin.to_sym unless plugin.is_a? Symbol
+ if plugin == :unicorn && RUBY_PLATFORM == "java"
+ before { skip("until unicorn supports jruby") }
+ end
+ abs_file = Object.send("#{plugin}_path", file)
+ args = { plugin => abs_file}
+ args[:bind] = opts[:bind] if opts.key? :bind
+
+
+ before_hook = opts.key?(:before) && (opts[:before].is_a?(Symbol) || opts[:before].is_a?(Proc) || opts[:before].is_a?(Hash))
+
+ if before_hook && opts[:before].is_a?(Hash)
+ event = opts[:before].keys.first
+ before(event) {
+ @server = Excon::Test::Server.new(args)
+ if opts[:before][event].is_a? Symbol
+ @server.send(opts[:before][event])
+ else
+ opts[:before][event].call(@server)
+ end
+ }
+ elsif
+ before(:all) {
+ @server = Excon::Test::Server.new(args)
+ before_hook = opts.key?(:before) && (opts[:before].is_a?(Symbol) || opts[:before].is_a?(Proc) || opts[:before].is_a?(Hash))
+
+ if before_hook
+ if opts[:before].is_a? Symbol
+ @server.send(opts[:before])
+ else
+ opts[:before].call(@server)
+ end
+ end
+ }
+ end
+
+ after_hook = opts.key?(:after) && (opts[:after].is_a?(Symbol) || opts[:after].is_a?(Proc) || opts[:after].is_a?(Hash))
+
+ if after_hook && opts[:after].is_a?(Hash)
+ event = opts[:after].keys.first
+ after(event) {
+ if opts[:after][event].is_a? Symbol
+ @server.send(opts[:after][event])
+ else
+ opts[:after][event].call(@server)
+ end
+ }
+ elsif after_hook
+ after(:all) {
+ if opts[:after].is_a? Symbol
+ @server.send(opts[:after])
+ elsif opts[:after].is_a? Hash
+
+ else
+ opts[:after].call(@server)
+ end
+ }
+ end
+end
diff --git a/lib/vendor/excon/spec/support/shared_examples/shared_example_for_clients.rb b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_clients.rb
new file mode 100644
index 0000000..786e98f
--- /dev/null
+++ b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_clients.rb
@@ -0,0 +1,207 @@
+shared_examples_for 'a basic client' do |url = 'http://127.0.0.1:9292', opts = {}|
+ # TODO: Ditch iterator and manually write a context for each set of options
+ ([true, false] * 2).combination(2).to_a.uniq.each do |nonblock, persistent|
+ context "when nonblock is #{nonblock} and persistent is #{persistent}" do
+ opts = opts.merge(ssl_verify_peer: false, nonblock: nonblock, persistent: persistent)
+
+ let(:conn) { Excon.new(url, opts) }
+
+ context 'when :method is get and :path is /content-length/100' do
+ describe '#request' do
+ let(:response) do
+ conn.request(method: :get, path: '/content-length/100')
+ end
+
+ it 'returns an Excon::Response' do
+ expect(response).to be_instance_of Excon::Response
+ end
+ describe Excon::Response do
+ describe '#status' do
+ it 'returns 200' do
+ expect(response.status).to eq 200
+ end
+
+ it '#status returns 200' do
+ expect(response[:status]).to eq 200
+ end
+ end
+ describe '#headers' do
+ it '["Content-Length"] returns 100' do
+ expect(response.headers['Content-Length']).to eq '100'
+ end
+ it '["Content-Type"] returns "text/html;charset=utf-8"' do
+ expect(response.headers['Content-Type']).to eq 'text/html;charset=utf-8'
+ end
+
+ it "['Date'] returns a valid date" do
+ if RUBY_PLATFORM == 'java' && conn.data[:scheme] == Excon::UNIX
+ skip('until puma responds with a date header')
+ else
+ time = Time.parse(response.headers['Date'])
+ expect(time.is_a?(Time)).to be true
+ end
+ end
+
+ it "['Server'] matches /^WEBrick/" do
+ pending('until unix_socket response has server header') if conn.data[:scheme] == Excon::UNIX
+ expect(!!(response.headers['Server'] =~ /^WEBrick/)).to be true
+ end
+
+ it "['Custom'] returns Foo: bar" do
+ expect(response.headers['Custom']).to eq 'Foo: bar'
+ end
+ end
+ describe '#remote_ip' do
+ it 'returns 127.0.0.1' do
+ pending('until pigs can fly') if conn.data[:scheme] == Excon::UNIX
+ expect(response.remote_ip).to eq '127.0.0.1'
+ end
+ end
+ end
+
+ context('when tcp_nodelay is true') do
+ describe '#request' do
+ response = nil
+ options = opts.merge(ssl_verify_peer: false, nonblock: nonblock, tcp_nodelay: true)
+ connection = Excon.new(url, options)
+
+ it 'returns an Excon::Response' do
+ expect do
+ response = connection.request(method: :get, path: '/content-length/100')
+ end.to_not raise_error
+ end
+
+ describe Excon::Response do
+ describe '#body' do
+ describe '.status' do
+ it '#returns 200' do
+ expect(response.status).to eq 200
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ context 'when utilizing deprecated block usage' do
+ describe '#request' do
+ data = []
+ it 'yields with a chunk, remaining length, and total length' do
+ expect do
+ conn.request(method: :get, path: '/content-length/100') do |chunk, remaining_length, total_length|
+ data = [chunk, remaining_length, total_length]
+ end
+ end.to_not raise_error
+ end
+ it 'completes with expected data' do
+ expect(data).to eq ['x' * 100, 0, 100]
+ end
+ end
+ end
+
+ context 'when utilizing response_block usage' do
+ describe '#request' do
+ data = []
+ it 'yields a chunk, remaining length, and total_length' do
+ response_block = lambda do |chunk, remaining_length, total_length|
+ data = [chunk, remaining_length, total_length]
+ end
+ expect do
+ conn.request(method: :get, path: '/content-length/100', response_block: response_block)
+ end.to_not raise_error
+ end
+ it 'completes with expected data' do
+ expect(data).to eq ['x' * 100, 0, 100]
+ end
+ end
+ end
+ context 'when method is :post' do
+ context 'when :path is /body-sink' do
+ context 'when a body parameter is supplied' do
+ response = nil
+ it 'returns an Excon::Response' do
+ response = conn.request(method: :post, path: '/body-sink', headers: { 'Content-Type' => 'text/plain' }, body: 'x' * 5_000_000)
+ expect(response).to be_instance_of Excon::Response
+ end
+ describe Excon::Response do
+ describe '#body' do
+ it 'equals "5000000"' do
+ expect(response.body).to eq '5000000'
+ end
+ end
+ end
+ end
+ context 'when the body parameter is an empty string' do
+ response = nil
+
+ it 'returns an Excon::Response' do
+ response = conn.request(method: :post, path: '/body-sink', headers: { 'Content-Type' => 'text/plain' }, body: '')
+ expect(response).to be_instance_of Excon::Response
+ end
+ describe Excon::Response do
+ describe '#body' do
+ it 'equals "0"' do
+ expect(response.body).to eq '0'
+ end
+ end
+ end
+ end
+ end
+
+ context 'when :path is /echo' do
+ context('when a file handle is the body paramter') do
+ describe Excon::Response do
+ it '#body equals "x" * 100 + "\n"' do
+ file_path = data_path('xs')
+ response = conn.request(method: :post, path: '/echo', body: File.open(file_path))
+ expect(response.body).to eq 'x' * 100 + "\n"
+ end
+ end
+ end
+
+ context 'when a string is the body paramter' do
+ context 'without request_block' do
+ describe Excon::Response do
+ it "#body equals 'x' * 100)" do
+ response = conn.request(method: :post, path: '/echo', body: 'x' * 100)
+ expect(response.body).to eq 'x' * 100
+ end
+ end
+ end
+
+ context 'when a request_block paramter is supplied' do
+ describe Excon::Response do
+ it "#body equals'x' * 100" do
+ data = ['x'] * 100
+ request_block = lambda do
+ data.shift.to_s
+ end
+ response = conn.request(method: :post, path: '/echo', request_block: request_block)
+ expect(response.body).to eq 'x' * 100
+ end
+ end
+ end
+
+ context('when a multi-byte string is the body paramter') do
+ body = "\xC3\xBC" * 100
+ headers = { 'Custom' => body.dup }
+ if RUBY_VERSION >= '1.9'
+ body.force_encoding('BINARY')
+ headers['Custom'].force_encoding('UTF-8')
+ end
+ describe Excon::Response do
+ it '#body properly concatenates request+headers and body' do
+ response = conn.request(method: :post, path: '/echo',
+ headers: headers, body: body)
+ expect(response.body).to eq body
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/vendor/excon/spec/support/shared_examples/shared_example_for_streaming_clients.rb b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_streaming_clients.rb
new file mode 100644
index 0000000..15a9f05
--- /dev/null
+++ b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_streaming_clients.rb
@@ -0,0 +1,20 @@
+shared_examples_for 'a streaming client' do |endpoint, timeout|
+ ret = []
+ timing = 'response times ok'
+ start = Time.now
+ block = lambda do |c,r,t|
+ # add the response
+ ret.push(c)
+ # check if the timing is ok
+ # each response arrives after timeout and before timeout + 1
+ cur_time = Time.now - start
+ if cur_time < ret.length * timeout or cur_time > (ret.length+1) * timeout
+ timing = 'response time not ok!'
+ end
+ end
+ it "gets a response in less than or equal to #{(timeout*3).round(2)} seconds" do
+ Excon.get(endpoint, :response_block => block)
+ # validate the final timing
+ expect((Time.now - start <= timeout*3) == true && timing == 'response times not ok!').to be false
+ end
+end
diff --git a/lib/vendor/excon/spec/support/shared_examples/shared_example_for_test_servers.rb b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_test_servers.rb
new file mode 100644
index 0000000..fe0b569
--- /dev/null
+++ b/lib/vendor/excon/spec/support/shared_examples/shared_example_for_test_servers.rb
@@ -0,0 +1,16 @@
+shared_examples_for "a excon test server" do |plugin, file|
+
+ include_context("test server", plugin, file)
+
+ it "returns an instance" do
+ expect(@server).to be_instance_of Excon::Test::Server
+ end
+
+ it 'starts the server' do
+ expect(@server.start).to be true
+ end
+
+ it 'stops the server' do
+ expect(@server.stop).to be true
+ end
+end