Skip to content

Commit

Permalink
Merge pull request lostisland#224 from technoweenie/fix-ci
Browse files Browse the repository at this point in the history
Fix CI
  • Loading branch information
technoweenie committed Dec 28, 2012
2 parents 55c2418 + da5ae30 commit b25adc0
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 34 deletions.
7 changes: 6 additions & 1 deletion lib/faraday.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -181,7 +181,12 @@ def lookup_middleware(key)
end end


def middleware_mutex(&block) def middleware_mutex(&block)
(@middleware_mutex ||= Mutex.new).synchronize(&block) @middleware_mutex ||= Mutex.new
if @middleware_mutex.locked?
block.call
else
@middleware_mutex.synchronize(&block)
end
end end


def fetch_middleware(key) def fetch_middleware(key)
Expand Down
1 change: 1 addition & 0 deletions lib/faraday/adapter/net_http.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class NetHttp < Faraday::Adapter
EOFError, EOFError,
Errno::ECONNABORTED, Errno::ECONNABORTED,
Errno::ECONNREFUSED, Errno::ECONNREFUSED,
Errno::ENETUNREACH,
Errno::ECONNRESET, Errno::ECONNRESET,
Errno::EINVAL, Errno::EINVAL,
Net::HTTPBadResponse, Net::HTTPBadResponse,
Expand Down
61 changes: 34 additions & 27 deletions lib/faraday/adapter/test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,46 +28,46 @@ def empty?
@stack.empty? @stack.empty?
end end


def match(request_method, path, body) def match(request_method, path, headers, body)
return false if !@stack.key?(request_method) return false if !@stack.key?(request_method)
stack = @stack[request_method] stack = @stack[request_method]
consumed = (@consumed[request_method] ||= []) consumed = (@consumed[request_method] ||= [])
path = normalize_path(path) path = normalize_path(path)


if stub = matches?(stack, path, body) if stub = matches?(stack, path, headers, body)
consumed << stack.delete(stub) consumed << stack.delete(stub)
stub stub
else else
matches?(consumed, path, body) matches?(consumed, path, headers, body)
end end
end end


def get(path, &block) def get(path, headers = {}, &block)
new_stub(:get, path, &block) new_stub(:get, path, headers, &block)
end end


def head(path, &block) def head(path, headers = {}, &block)
new_stub(:head, path, &block) new_stub(:head, path, headers, &block)
end end


def post(path, body=nil, &block) def post(path, body=nil, headers = {}, &block)
new_stub(:post, path, body, &block) new_stub(:post, path, headers, body, &block)
end end


def put(path, body=nil, &block) def put(path, body=nil, headers = {}, &block)
new_stub(:put, path, body, &block) new_stub(:put, path, headers, body, &block)
end end


def patch(path, body=nil, &block) def patch(path, body=nil, headers = {}, &block)
new_stub(:patch, path, body, &block) new_stub(:patch, path, headers, body, &block)
end end


def delete(path, &block) def delete(path, headers = {}, &block)
new_stub(:delete, path, &block) new_stub(:delete, path, headers, &block)
end end


def options(path, &block) def options(path, headers = {}, &block)
new_stub(:options, path, &block) new_stub(:options, path, headers, &block)
end end


# Raises an error if any of the stubbed calls have not been made. # Raises an error if any of the stubbed calls have not been made.
Expand All @@ -85,12 +85,12 @@ def verify_stubbed_calls


protected protected


def new_stub(request_method, path, body=nil, &block) def new_stub(request_method, path, headers = {}, body=nil, &block)
(@stack[request_method] ||= []) << Stub.new(normalize_path(path), body, block) (@stack[request_method] ||= []) << Stub.new(normalize_path(path), headers, body, block)
end end


def matches?(stack, path, body) def matches?(stack, path, headers, body)
stack.detect { |stub| stub.matches?(path, body) } stack.detect { |stub| stub.matches?(path, headers, body) }
end end


# ensure leading + trailing slash # ensure leading + trailing slash
Expand All @@ -102,23 +102,24 @@ def normalize_path(path)
end end
end end


class Stub < Struct.new(:path, :params, :body, :block) class Stub < Struct.new(:path, :params, :headers, :body, :block)
def initialize(full, body, block) def initialize(full, headers, body, block)
path, query = full.split('?') path, query = full.split('?')
params = query ? params = query ?
Faraday::Utils.parse_nested_query(query) : Faraday::Utils.parse_nested_query(query) :
{} {}
super path, params, body, block super path, params, headers, body, block
end end


def matches?(request_uri, request_body) def matches?(request_uri, request_headers, request_body)
request_path, request_query = request_uri.split('?') request_path, request_query = request_uri.split('?')
request_params = request_query ? request_params = request_query ?
Faraday::Utils.parse_nested_query(request_query) : Faraday::Utils.parse_nested_query(request_query) :
{} {}
request_path == path && request_path == path &&
params_match?(request_params) && params_match?(request_params) &&
(body.to_s.size.zero? || request_body == body) (body.to_s.size.zero? || request_body == body) &&
headers_match?(request_headers)
end end


def params_match?(request_params) def params_match?(request_params)
Expand All @@ -127,6 +128,12 @@ def params_match?(request_params)
end end
end end


def headers_match?(request_headers)
headers.keys.all? do |key|
request_headers[key] == headers[key]
end
end

def to_s def to_s
"#{path} #{body}" "#{path} #{body}"
end end
Expand All @@ -146,7 +153,7 @@ def call(env)
super super
normalized_path = Faraday::Utils.normalize_path(env[:url]) normalized_path = Faraday::Utils.normalize_path(env[:url])


if stub = stubs.match(env[:method], normalized_path, env[:body]) if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
env[:params] = (query = env[:url].query) ? env[:params] = (query = env[:url].query) ?
Faraday::Utils.parse_nested_query(query) : Faraday::Utils.parse_nested_query(query) :
{} {}
Expand Down
2 changes: 1 addition & 1 deletion lib/faraday/request/basic_authentication.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'base64' require 'base64'


module Faraday module Faraday
class Request::BasicAuthentication < Request::Authorization class Request::BasicAuthentication < Request.load_middleware(:authorization)
# Public # Public
def self.header(login, pass) def self.header(login, pass)
value = Base64.encode64([login, pass].join(':')) value = Base64.encode64([login, pass].join(':'))
Expand Down
2 changes: 1 addition & 1 deletion lib/faraday/request/token_authentication.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
module Faraday module Faraday
class Request::TokenAuthentication < Request::Authorization class Request::TokenAuthentication < Request.load_middleware(:authorization)
# Public # Public
def self.header(token, options = nil) def self.header(token, options = nil)
options ||= {} options ||= {}
Expand Down
9 changes: 9 additions & 0 deletions script/console
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env ruby
# Usage: script/console
# Starts an IRB console with this library loaded.

require 'rubygems'
require 'irb'
require File.expand_path("../ruby", __FILE__)
require File.expand_path("../../lib/#{MakeScript.lib_name}", __FILE__)
IRB.start
32 changes: 32 additions & 0 deletions script/gemspec
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env ruby
# Usage: script/gemspec
# Updates the gemspec's name, version, and file manifest.

require File.expand_path("../ruby", __FILE__)

def replace_header(head, header_name)
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{MakeScript.send(header_name)}'"}
end

# read spec file and split out manifest section
spec = File.read(MakeScript.gemspec_file)
head, manifest, tail = spec.split(" # = MANIFEST =\n")

# replace name version and date
replace_header(head, :lib_name)
replace_header(head, :version)

files = `git ls-files`.
split("\n").
sort.
reject { |file| file =~ /^\./ }.
reject { |file| file =~ /^(rdoc|pkg)/ }.
map { |file| " #{file}" }.
join("\n")

# piece file back together and write
manifest = " s.files = %w[\n#{files}\n ]\n"
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
File.open(MakeScript.gemspec_file, 'w') { |io| io.write(spec) }
puts "Updated #{MakeScript.gemspec_file}"

29 changes: 29 additions & 0 deletions script/generate_certs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env ruby
# Usage: generate_certs
# Generate test certs for testing Faraday with SSL

require File.expand_path("../ruby", __FILE__)
require 'openssl'
require 'fileutils'

# Adapted from WEBrick::Utils. Skips cert extensions so it
# can be used as a CA bundle
def create_self_signed_cert(bits, cn, comment)
rsa = OpenSSL::PKey::RSA.new(bits)
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 1
name = OpenSSL::X509::Name.new(cn)
cert.subject = name
cert.issuer = name
cert.not_before = Time.now
cert.not_after = Time.now + (365*24*60*60)
cert.public_key = rsa.public_key
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
return [cert, rsa]
end

cert, key = create_self_signed_cert(1024, [['CN', 'localhost']], 'Faraday Test CA')
FileUtils.mkdir_p 'tmp'
File.open('tmp/faraday-cert.key', 'w') {|f| f.puts(key) }
File.open('tmp/faraday-cert.crt', 'w') {|f| f.puts(cert.to_s) }
12 changes: 12 additions & 0 deletions script/package
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env ruby
# Usage: script/gem
# Updates the gemspec and builds a new gem in the pkg directory.

require File.expand_path("../ruby", __FILE__)
require 'fileutils'

FileUtils.mkdir_p File.expand_path("../../pkg", __FILE__)
system "script/gemspec"
system "gem build #{MakeScript.gemspec_file}"
system "mv #{MakeScript.gem_file} pkg"

14 changes: 14 additions & 0 deletions script/release
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby
# Usage: script/release
# Build the package, tag a commit, push it to origin, and then release the
# package publicly.

require File.expand_path("../ruby", __FILE__)

system "script/package"
system "git commit --allow-empty -a -m 'Release #{MakeScript.version}'"
system "git tag v#{MakeScript.version}"
system "git push origin"
system "git push origin v#{MakeScript.version}"
system "gem push pkg/#{MakeScript.gem_file}"

36 changes: 36 additions & 0 deletions script/ruby.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,36 @@
# Opinionated module that picks out a ruby library's name and version based on
# some conventions:
#
# * #{lib_name}.gemspec
# * A VERSION constant defined in lib/#{lib_name}.rb
#
# Example:
#
# # foo.gemspec
# # lib/foo.rb
# module Foo
# VERSION = "0.1"
# end

module MakeScript
extend self

def lib_name
@lib_name ||= Dir['*.gemspec'].first.split('.').first
end

def version
@version ||= begin
line = File.read("lib/#{lib_name}.rb")[/^\s*VERSION\s*=\s*.*/]
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
end
end

def gemspec_file
@gemspec_file ||= "#{lib_name}.gemspec"
end

def gem_file
@gem_file ||= "#{lib_name}-#{version}.gem"
end
end
7 changes: 5 additions & 2 deletions script/test
Original file line number Original file line Diff line number Diff line change
@@ -1,15 +1,18 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# Usage: script/test [file] [adapter]... -- [test/unit options]
# Runs the test suite against a local server spawned automatically in a # Runs the test suite against a local server spawned automatically in a
# thread. After tests are done, the server is shut down. # thread. After tests are done, the server is shut down.
# #
# If filename arguments are given, only those files are run. If arguments given # If filename arguments are given, only those files are run. If arguments given
# are not filenames, they are taken as words that filter the list of files to run. # are not filenames, they are taken as words that filter the list of files to run.
# #
# Examples # Examples:
# #
# $ script/test # $ script/test
# $ script/test test/env_test.rb # $ script/test test/env_test.rb
# $ script/test excon typhoeus # $ script/test excon typhoeus
#
# # Run only tests matching /ssl/ for the net_http adapter, with SSL enabled.
# $ SSL=yes script/test net_http -- -n /ssl/ # $ SSL=yes script/test net_http -- -n /ssl/


require 'rubygems' require 'rubygems'
Expand All @@ -33,7 +36,7 @@ if ssl_mode = ENV['SSL'] == 'yes'
unless ENV['SSL_KEY'] and ENV['SSL_FILE'] unless ENV['SSL_KEY'] and ENV['SSL_FILE']
key_file = ENV['SSL_KEY'] = 'tmp/faraday-cert.key' key_file = ENV['SSL_KEY'] = 'tmp/faraday-cert.key'
cert_file = ENV['SSL_FILE'] = 'tmp/faraday-cert.crt' cert_file = ENV['SSL_FILE'] = 'tmp/faraday-cert.crt'
system 'rake', key_file, cert_file system 'script/generate_certs'
abort unless $?.success? abort unless $?.success?
end end
end end
Expand Down
19 changes: 17 additions & 2 deletions test/adapters/test_middleware_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@


module Adapters module Adapters
class TestMiddleware < Faraday::TestCase class TestMiddleware < Faraday::TestCase
Stubs = Faraday::Adapter.lookup_middleware(:test)::Stubs
def setup def setup
@stubs = Faraday::Adapter::Test::Stubs.new @stubs = Stubs.new
@conn = Faraday.new do |builder| @conn = Faraday.new do |builder|
builder.adapter :test, @stubs builder.adapter :test, @stubs
end end
Expand Down Expand Up @@ -41,6 +42,13 @@ def test_middleware_ignores_unspecified_get_params
end end
end end


def test_middleware_with_http_headers
@stubs.get('/yo', { 'X-HELLO' => 'hello' }) { [200, {}, 'a'] }
@stubs.get('/yo') { [200, {}, 'b'] }
assert_equal 'a', @conn.get('/yo') { |env| env.headers['X-HELLO'] = 'hello' }.body
assert_equal 'b', @conn.get('/yo').body
end

def test_middleware_allow_different_outcomes_for_the_same_request def test_middleware_allow_different_outcomes_for_the_same_request
@stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] } @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
@stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'world'] } @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'world'] }
Expand All @@ -62,9 +70,16 @@ def test_yields_env_to_stubs
end end


def test_raises_an_error_if_no_stub_is_found_for_request def test_raises_an_error_if_no_stub_is_found_for_request
assert_raises Faraday::Adapter::Test::Stubs::NotFound do assert_raises Stubs::NotFound do
@conn.get('/invalid'){ [200, {}, []] } @conn.get('/invalid'){ [200, {}, []] }
end end
end end

def test_raises_an_error_if_no_stub_is_found_for_request_without_this_header
@stubs.get('/yo', { 'X-HELLO' => 'hello' }) { [200, {}, 'a'] }
assert_raises Faraday::Adapter::Test::Stubs::NotFound do
@conn.get('/yo')
end
end
end end
end end

0 comments on commit b25adc0

Please sign in to comment.