faraday 0.6.0 → 0.9.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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +36 -0
  5. data/Gemfile +25 -15
  6. data/{LICENSE → LICENSE.md} +1 -1
  7. data/README.md +187 -137
  8. data/Rakefile +38 -101
  9. data/faraday.gemspec +26 -81
  10. data/lib/faraday/adapter/em_http.rb +237 -0
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
  12. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
  13. data/lib/faraday/adapter/em_synchrony.rb +65 -38
  14. data/lib/faraday/adapter/excon.rb +60 -9
  15. data/lib/faraday/adapter/httpclient.rb +106 -0
  16. data/lib/faraday/adapter/net_http.rb +89 -38
  17. data/lib/faraday/adapter/net_http_persistent.rb +47 -0
  18. data/lib/faraday/adapter/patron.rb +46 -9
  19. data/lib/faraday/adapter/rack.rb +58 -0
  20. data/lib/faraday/adapter/test.rb +68 -28
  21. data/lib/faraday/adapter/typhoeus.rb +94 -16
  22. data/lib/faraday/adapter.rb +33 -25
  23. data/lib/faraday/autoload.rb +85 -0
  24. data/lib/faraday/connection.rb +342 -134
  25. data/lib/faraday/error.rb +44 -29
  26. data/lib/faraday/middleware.rb +18 -10
  27. data/lib/faraday/options.rb +350 -0
  28. data/lib/faraday/parameters.rb +193 -0
  29. data/lib/faraday/rack_builder.rb +212 -0
  30. data/lib/faraday/request/authorization.rb +42 -0
  31. data/lib/faraday/request/basic_authentication.rb +13 -0
  32. data/lib/faraday/request/instrumentation.rb +36 -0
  33. data/lib/faraday/request/multipart.rb +15 -15
  34. data/lib/faraday/request/retry.rb +118 -0
  35. data/lib/faraday/request/token_authentication.rb +15 -0
  36. data/lib/faraday/request/url_encoded.rb +8 -9
  37. data/lib/faraday/request.rb +46 -45
  38. data/lib/faraday/response/logger.rb +4 -4
  39. data/lib/faraday/response/raise_error.rb +8 -3
  40. data/lib/faraday/response.rb +20 -25
  41. data/lib/faraday/upload_io.rb +51 -7
  42. data/lib/faraday/utils.rb +240 -44
  43. data/lib/faraday.rb +218 -38
  44. data/script/console +7 -0
  45. data/script/generate_certs +42 -0
  46. data/script/package +7 -0
  47. data/script/proxy-server +42 -0
  48. data/script/release +17 -0
  49. data/script/server +36 -0
  50. data/script/test +172 -0
  51. data/test/adapters/default_test.rb +14 -0
  52. data/test/adapters/em_http_test.rb +20 -0
  53. data/test/adapters/em_synchrony_test.rb +20 -0
  54. data/test/adapters/excon_test.rb +20 -0
  55. data/test/adapters/httpclient_test.rb +21 -0
  56. data/test/adapters/integration.rb +254 -0
  57. data/test/adapters/logger_test.rb +3 -3
  58. data/test/adapters/net_http_persistent_test.rb +20 -0
  59. data/test/adapters/net_http_test.rb +6 -25
  60. data/test/adapters/patron_test.rb +20 -0
  61. data/test/adapters/rack_test.rb +31 -0
  62. data/test/adapters/test_middleware_test.rb +74 -3
  63. data/test/adapters/typhoeus_test.rb +28 -0
  64. data/test/authentication_middleware_test.rb +65 -0
  65. data/test/composite_read_io_test.rb +111 -0
  66. data/test/connection_test.rb +381 -104
  67. data/test/env_test.rb +116 -40
  68. data/test/helper.rb +61 -25
  69. data/test/live_server.rb +55 -29
  70. data/test/middleware/instrumentation_test.rb +88 -0
  71. data/test/middleware/retry_test.rb +109 -0
  72. data/test/middleware_stack_test.rb +87 -5
  73. data/test/multibyte.txt +1 -0
  74. data/test/options_test.rb +252 -0
  75. data/test/request_middleware_test.rb +78 -21
  76. data/test/response_middleware_test.rb +32 -7
  77. data/test/strawberry.rb +2 -0
  78. data/test/utils_test.rb +58 -0
  79. metadata +116 -117
  80. data/lib/faraday/adapter/action_dispatch.rb +0 -30
  81. data/lib/faraday/builder.rb +0 -137
  82. data/lib/faraday/request/json.rb +0 -31
  83. data/test/adapters/live_test.rb +0 -186
data/lib/faraday.rb CHANGED
@@ -1,88 +1,268 @@
1
+ require 'thread'
2
+ require 'cgi'
3
+ require 'set'
4
+ require 'forwardable'
5
+
6
+ # Public: This is the main namespace for Faraday. You can either use it to
7
+ # create Faraday::Connection objects, or access it directly.
8
+ #
9
+ # Examples
10
+ #
11
+ # Faraday.get "http://faraday.com"
12
+ #
13
+ # conn = Faraday.new "http://faraday.com"
14
+ # conn.get '/'
15
+ #
1
16
  module Faraday
2
- VERSION = "0.6.0"
17
+ VERSION = "0.9.0"
3
18
 
4
19
  class << self
5
- attr_accessor :default_adapter
6
- attr_writer :default_connection
20
+ # Public: Gets or sets the root path that Faraday is being loaded from.
21
+ # This is the root from where the libraries are auto-loaded from.
22
+ attr_accessor :root_path
23
+
24
+ # Public: Gets or sets the path that the Faraday libs are loaded from.
25
+ attr_accessor :lib_path
26
+
27
+ # Public: Gets or sets the Symbol key identifying a default Adapter to use
28
+ # for the default Faraday::Connection.
29
+ attr_reader :default_adapter
30
+
31
+ # Public: Sets the default Faraday::Connection for simple scripts that
32
+ # access the Faraday constant directly.
33
+ #
34
+ # Faraday.get "https://faraday.com"
35
+ attr_writer :default_connection
7
36
 
8
- def new(url = nil, options = {})
37
+ # Public: Sets the default options used when calling Faraday#new.
38
+ attr_writer :default_connection_options
39
+
40
+ # Public: Initializes a new Faraday::Connection.
41
+ #
42
+ # url - The optional String base URL to use as a prefix for all
43
+ # requests. Can also be the options Hash.
44
+ # options - The optional Hash used to configure this Faraday::Connection.
45
+ # Any of these values will be set on every request made, unless
46
+ # overridden for a specific request.
47
+ # :url - String base URL.
48
+ # :params - Hash of URI query unencoded key/value pairs.
49
+ # :headers - Hash of unencoded HTTP header key/value pairs.
50
+ # :request - Hash of request options.
51
+ # :ssl - Hash of SSL options.
52
+ # :proxy - Hash of Proxy options.
53
+ #
54
+ # Examples
55
+ #
56
+ # Faraday.new 'http://faraday.com'
57
+ #
58
+ # # http://faraday.com?page=1
59
+ # Faraday.new 'http://faraday.com', :params => {:page => 1}
60
+ #
61
+ # # same
62
+ #
63
+ # Faraday.new :url => 'http://faraday.com',
64
+ # :params => {:page => 1}
65
+ #
66
+ # Returns a Faraday::Connection.
67
+ def new(url = nil, options = nil)
9
68
  block = block_given? ? Proc.new : nil
69
+ options = options ? default_connection_options.merge(options) : default_connection_options.dup
10
70
  Faraday::Connection.new(url, options, &block)
11
71
  end
12
72
 
73
+ # Internal: Requires internal Faraday libraries.
74
+ #
75
+ # *libs - One or more relative String names to Faraday classes.
76
+ #
77
+ # Returns nothing.
78
+ def require_libs(*libs)
79
+ libs.each do |lib|
80
+ require "#{lib_path}/#{lib}"
81
+ end
82
+ end
83
+
84
+ # Public: Updates default adapter while resetting
85
+ # #default_connection.
86
+ #
87
+ # Returns the new default_adapter.
88
+ def default_adapter=(adapter)
89
+ @default_connection = nil
90
+ @default_adapter = adapter
91
+ end
92
+
93
+ alias require_lib require_libs
94
+
13
95
  private
96
+ # Internal: Proxies method calls on the Faraday constant to
97
+ # #default_connection.
14
98
  def method_missing(name, *args, &block)
15
99
  default_connection.send(name, *args, &block)
16
100
  end
17
101
  end
18
102
 
103
+ self.root_path = File.expand_path "..", __FILE__
104
+ self.lib_path = File.expand_path "../faraday", __FILE__
19
105
  self.default_adapter = :net_http
20
106
 
107
+ # Gets the default connection used for simple scripts.
108
+ #
109
+ # Returns a Faraday::Connection, configured with the #default_adapter.
21
110
  def self.default_connection
22
111
  @default_connection ||= Connection.new
23
112
  end
24
113
 
25
- module AutoloadHelper
26
- def register_lookup_modules(mods)
27
- (@lookup_module_index ||= {}).update(mods)
114
+ # Gets the default connection options used when calling Faraday#new.
115
+ #
116
+ # Returns a Faraday::ConnectionOptions.
117
+ def self.default_connection_options
118
+ @default_connection_options ||= ConnectionOptions.new
119
+ end
120
+
121
+ if (!defined?(RUBY_ENGINE) || "ruby" == RUBY_ENGINE) && RUBY_VERSION < '1.9'
122
+ begin
123
+ require 'system_timer'
124
+ Timer = SystemTimer
125
+ rescue LoadError
126
+ warn "Faraday: you may want to install system_timer for reliable timeouts"
127
+ end
128
+ end
129
+
130
+ unless const_defined? :Timer
131
+ require 'timeout'
132
+ Timer = Timeout
133
+ end
134
+
135
+ # Public: Adds the ability for other modules to register and lookup
136
+ # middleware classes.
137
+ module MiddlewareRegistry
138
+ # Public: Register middleware class(es) on the current module.
139
+ #
140
+ # mapping - A Hash mapping Symbol keys to classes. Classes can be expressed
141
+ # as fully qualified constant, or a Proc that will be lazily
142
+ # called to return the former.
143
+ #
144
+ # Examples
145
+ #
146
+ # module Faraday
147
+ # class Whatever
148
+ # # Middleware looked up by :foo returns Faraday::Whatever::Foo.
149
+ # register_middleware :foo => Foo
150
+ #
151
+ # # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
152
+ # register_middleware :bar => :Bar
153
+ #
154
+ # # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
155
+ # register_middleware :baz => [:Baz, 'baz']
156
+ # end
157
+ # end
158
+ #
159
+ # Returns nothing.
160
+ def register_middleware(autoload_path = nil, mapping = nil)
161
+ if mapping.nil?
162
+ mapping = autoload_path
163
+ autoload_path = nil
164
+ end
165
+ middleware_mutex do
166
+ @middleware_autoload_path = autoload_path if autoload_path
167
+ (@registered_middleware ||= {}).update(mapping)
168
+ end
28
169
  end
29
170
 
30
- def lookup_module(key)
31
- return if !@lookup_module_index
32
- const_get @lookup_module_index[key] || key
171
+ # Public: Lookup middleware class with a registered Symbol shortcut.
172
+ #
173
+ # key - The Symbol key for the registered middleware.
174
+ #
175
+ # Examples
176
+ #
177
+ # module Faraday
178
+ # class Whatever
179
+ # register_middleware :foo => Foo
180
+ # end
181
+ # end
182
+ #
183
+ # Faraday::Whatever.lookup_middleware(:foo)
184
+ # # => Faraday::Whatever::Foo
185
+ #
186
+ # Returns a middleware Class.
187
+ def lookup_middleware(key)
188
+ load_middleware(key) ||
189
+ raise(Faraday::Error.new("#{key.inspect} is not registered on #{self}"))
33
190
  end
34
191
 
35
- def autoload_all(prefix, options)
36
- options.each do |const_name, path|
37
- autoload const_name, File.join(prefix, path)
192
+ def middleware_mutex(&block)
193
+ @middleware_mutex ||= begin
194
+ require 'monitor'
195
+ Monitor.new
38
196
  end
197
+ @middleware_mutex.synchronize(&block)
39
198
  end
40
199
 
41
- # Loads each autoloaded constant. If thread safety is a concern, wrap
42
- # this in a Mutex.
43
- def load_autoloaded_constants
44
- constants.each do |const|
45
- const_get(const) if autoload?(const)
200
+ def fetch_middleware(key)
201
+ defined?(@registered_middleware) && @registered_middleware[key]
202
+ end
203
+
204
+ def load_middleware(key)
205
+ value = fetch_middleware(key)
206
+ case value
207
+ when Module
208
+ value
209
+ when Symbol, String
210
+ middleware_mutex do
211
+ @registered_middleware[key] = const_get(value)
212
+ end
213
+ when Proc
214
+ middleware_mutex do
215
+ @registered_middleware[key] = value.call
216
+ end
217
+ when Array
218
+ middleware_mutex do
219
+ const, path = value
220
+ if root = @middleware_autoload_path
221
+ path = "#{root}/#{path}"
222
+ end
223
+ require(path)
224
+ @registered_middleware[key] = const
225
+ end
226
+ load_middleware(key)
46
227
  end
47
228
  end
229
+ end
48
230
 
49
- def all_loaded_constants
50
- constants.map { |c| const_get(c) }.
51
- select { |a| a.respond_to?(:loaded?) && a.loaded? }
231
+ def self.const_missing(name)
232
+ if name.to_sym == :Builder
233
+ warn "Faraday::Builder is now Faraday::RackBuilder."
234
+ const_set name, RackBuilder
235
+ else
236
+ super
52
237
  end
53
238
  end
54
239
 
55
- extend AutoloadHelper
240
+ require_libs "utils", "options", "connection", "rack_builder", "parameters",
241
+ "middleware", "adapter", "request", "response", "upload_io", "error"
56
242
 
57
- autoload_all 'faraday',
58
- :Middleware => 'middleware',
59
- :Builder => 'builder',
60
- :Request => 'request',
61
- :Response => 'response',
62
- :CompositeReadIO => 'upload_io',
63
- :UploadIO => 'upload_io',
64
- :Parts => 'upload_io'
243
+ if !ENV["FARADAY_NO_AUTOLOAD"]
244
+ require_lib 'autoload'
245
+ end
65
246
  end
66
247
 
67
- require 'faraday/utils'
68
- require 'faraday/connection'
69
- require 'faraday/adapter'
70
- require 'faraday/error'
71
-
72
- # not pulling in active-support JUST for this method.
248
+ # not pulling in active-support JUST for this method. And I love this method.
73
249
  class Object
74
- # Yields <code>x</code> to the block, and then returns <code>x</code>.
75
250
  # The primary purpose of this method is to "tap into" a method chain,
76
251
  # in order to perform operations on intermediate results within the chain.
77
252
  #
253
+ # Examples
254
+ #
78
255
  # (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
79
256
  # tap { |x| puts "array: #{x.inspect}" }.
80
257
  # select { |x| x%2 == 0 }.
81
258
  # tap { |x| puts "evens: #{x.inspect}" }.
82
259
  # map { |x| x*x }.
83
260
  # tap { |x| puts "squares: #{x.inspect}" }
261
+ #
262
+ # Yields self.
263
+ # Returns self.
84
264
  def tap
85
- yield self
265
+ yield(self)
86
266
  self
87
267
  end unless Object.respond_to?(:tap)
88
268
  end
data/script/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: script/console
3
+ # Starts an IRB console with this library loaded.
4
+
5
+ gemspec="$(ls *.gemspec | head -1)"
6
+
7
+ exec bundle exec irb -r "${gemspec%.*}"
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: generate_certs
3
+ # Generate test certs for testing Faraday with SSL
4
+
5
+ require 'openssl'
6
+ require 'fileutils'
7
+
8
+ $shell = ARGV.include? '-s'
9
+
10
+ # Adapted from WEBrick::Utils. Skips cert extensions so it
11
+ # can be used as a CA bundle
12
+ def create_self_signed_cert(bits, cn, comment)
13
+ rsa = OpenSSL::PKey::RSA.new(bits)
14
+ cert = OpenSSL::X509::Certificate.new
15
+ cert.version = 2
16
+ cert.serial = 1
17
+ name = OpenSSL::X509::Name.new(cn)
18
+ cert.subject = name
19
+ cert.issuer = name
20
+ cert.not_before = Time.now
21
+ cert.not_after = Time.now + (365*24*60*60)
22
+ cert.public_key = rsa.public_key
23
+ cert.sign(rsa, OpenSSL::Digest::SHA1.new)
24
+ return [cert, rsa]
25
+ end
26
+
27
+ def write(file, contents, env_var)
28
+ FileUtils.mkdir_p(File.dirname(file))
29
+ File.open(file, 'w') {|f| f.puts(contents) }
30
+ puts %(export #{env_var}="#{file}") if $shell
31
+ end
32
+
33
+
34
+ # One cert / CA for ease of testing when ignoring verification
35
+ cert, key = create_self_signed_cert(1024, [['CN', 'localhost']], 'Faraday Test CA')
36
+ write 'tmp/faraday-cert.key', key, 'SSL_KEY'
37
+ write 'tmp/faraday-cert.crt', cert, 'SSL_FILE'
38
+
39
+ # And a second CA to prove that verification can fail
40
+ cert, key = create_self_signed_cert(1024, [['CN', 'real-ca.com']], 'A different CA')
41
+ write 'tmp/faraday-different-ca-cert.key', key, 'SSL_KEY_ALT'
42
+ write 'tmp/faraday-different-ca-cert.crt', cert, 'SSL_FILE_ALT'
data/script/package ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: script/gem
3
+ # Updates the gemspec and builds a new gem in the pkg directory.
4
+
5
+ mkdir -p pkg
6
+ gem build *.gemspec
7
+ mv *.gem pkg
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: script/proxy-server [-p PORT] [-u USER:PASSWORD]
3
+ require 'webrick'
4
+ require 'webrick/httpproxy'
5
+
6
+ port = 4001
7
+
8
+ if found = ARGV.index('-p')
9
+ port = ARGV[found + 1].to_i
10
+ end
11
+ if found = ARGV.index('-u')
12
+ username, password = ARGV[found + 1].split(':', 2)
13
+ end
14
+
15
+ match_credentials = lambda { |credentials|
16
+ got_username, got_password = credentials.to_s.unpack("m*")[0].split(":", 2)
17
+ got_username == username && got_password == password
18
+ }
19
+
20
+ log_io = $stdout
21
+ log_io.sync = true
22
+
23
+ webrick_opts = {
24
+ :Port => port, :Logger => WEBrick::Log::new(log_io),
25
+ :AccessLog => [[log_io, "[%{X-Faraday-Adapter}i] %m %U -> %s %b"]],
26
+ :ProxyAuthProc => lambda { |req, res|
27
+ if username
28
+ type, credentials = req.header['proxy-authorization'].first.to_s.split(/\s+/, 2)
29
+ unless "Basic" == type && match_credentials.call(credentials)
30
+ res['proxy-authenticate'] = %{Basic realm="testing"}
31
+ raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
32
+ end
33
+ end
34
+ }
35
+ }
36
+
37
+ proxy = WEBrick::HTTPProxyServer.new(webrick_opts)
38
+
39
+ trap(:TERM) { proxy.shutdown }
40
+ trap(:INT) { proxy.shutdown }
41
+
42
+ proxy.start
data/script/release ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: script/release
3
+ # Build the package, tag a commit, push it to origin, and then release the
4
+ # package publicly.
5
+
6
+ set -e
7
+
8
+ version="$(script/package | grep Version: | awk '{print $2}')"
9
+ [ -n "$version" ] || exit 1
10
+
11
+ git commit --allow-empty -a -m "Release $version"
12
+ git tag "v$version"
13
+ git push origin
14
+ git push origin "v$version"
15
+ git push legacy
16
+ git push legacy "v$version"
17
+ gem push pkg/*-${version}.gem
data/script/server ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ old_verbose, $VERBOSE = $VERBOSE, nil
3
+ begin
4
+ require File.expand_path('../../test/live_server', __FILE__)
5
+ ensure
6
+ $VERBOSE = old_verbose
7
+ end
8
+ require 'webrick'
9
+
10
+ port = 4000
11
+ if found = ARGV.index('-p')
12
+ port = ARGV[found + 1].to_i
13
+ end
14
+
15
+ log_io = $stdout
16
+ log_io.sync = true
17
+
18
+ webrick_opts = {
19
+ :Port => port, :Logger => WEBrick::Log::new(log_io),
20
+ :AccessLog => [[log_io, "[%{X-Faraday-Adapter}i] %m %U -> %s %b"]]
21
+ }
22
+
23
+ if ENV['SSL_KEY']
24
+ require 'openssl'
25
+ require 'webrick/https'
26
+ webrick_opts.update \
27
+ :SSLEnable => true,
28
+ :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read(ENV['SSL_KEY'])),
29
+ :SSLCertificate => OpenSSL::X509::Certificate.new(File.read(ENV['SSL_FILE'])),
30
+ :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
31
+ end
32
+
33
+ Rack::Handler::WEBrick.run(Faraday::LiveServer, webrick_opts) do |server|
34
+ trap(:INT) { server.stop }
35
+ trap(:TERM) { server.stop }
36
+ end
data/script/test ADDED
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: script/test [file] [adapter]... -- [test/unit options]
3
+ # Runs the test suite against a local server spawned automatically in a
4
+ # thread. After tests are done, the server is shut down.
5
+ #
6
+ # If filename arguments are given, only those files are run. If arguments given
7
+ # are not filenames, they are taken as words that filter the list of files to run.
8
+ #
9
+ # Examples:
10
+ #
11
+ # $ script/test
12
+ # $ script/test test/env_test.rb
13
+ # $ script/test excon typhoeus
14
+ #
15
+ # # Run only tests matching /ssl/ for the net_http adapter, with SSL enabled.
16
+ # $ SSL=yes script/test net_http -- -n /ssl/
17
+ #
18
+ # # Run against multiple rbenv versions
19
+ # $ RBENV_VERSIONS="1.9.3-p194 ree-1.8.7-2012.02" script/test
20
+ set -e
21
+
22
+ if [[ "$RUBYOPT" != *"bundler/setup"* ]]; then
23
+ export RUBYOPT="-rbundler/setup $RUBYOPT"
24
+ fi
25
+
26
+ port=3999
27
+ proxy_port=3998
28
+ scheme=http
29
+
30
+ if [ "$SSL" = "yes" ]; then
31
+ scheme=https
32
+ if [ -z "$SSL_KEY" ] || [ -z "$SSL_FILE" ]; then
33
+ eval "$(script/generate_certs -s)"
34
+ fi
35
+ fi
36
+
37
+ find_test_files() {
38
+ find "$1" -name '*_test.rb'
39
+ }
40
+
41
+ filter_matching() {
42
+ pattern="$1"
43
+ shift
44
+ for line in "$@"; do
45
+ [[ $line == *"$pattern"* ]] && echo "$line"
46
+ done
47
+ }
48
+
49
+ start_server() {
50
+ mkdir -p log
51
+ script/server -p $port >log/test.log 2>&1 &
52
+ echo $!
53
+ }
54
+
55
+ start_proxy() {
56
+ mkdir -p log
57
+ script/proxy-server -p $proxy_port -u "faraday@test.local:there is cake" >log/proxy.log 2>&1 &
58
+ echo $!
59
+ }
60
+
61
+ server_started() {
62
+ lsof -i :${1?} >/dev/null
63
+ }
64
+
65
+ timestamp() {
66
+ date +%s
67
+ }
68
+
69
+ wait_for_server() {
70
+ timeout=$(( `timestamp` + $1 ))
71
+ while true; do
72
+ if server_started "$2"; then
73
+ break
74
+ elif [ `timestamp` -gt "$timeout" ]; then
75
+ echo "timed out after $1 seconds" >&2
76
+ return 1
77
+ fi
78
+ done
79
+ }
80
+
81
+ filtered=
82
+ IFS=$'\n' test_files=($(find_test_files "test"))
83
+ declare -a explicit_files
84
+
85
+ # Process filter arguments:
86
+ # - test filenames as taken as-is
87
+ # - other words are taken as pattern to match the list of known files against
88
+ # - arguments after "--" are forwarded to the ruby process
89
+ while [ $# -gt 0 ]; do
90
+ arg="$1"
91
+ shift
92
+ if [ "$arg" = "--" ]; then
93
+ break
94
+ elif [ -f "$arg" ]; then
95
+ filtered=true
96
+ explicit_files[${#explicit_files[@]}+1]="$arg"
97
+ else
98
+ filtered=true
99
+ IFS=$'\n' explicit_files=(
100
+ ${explicit_files[@]}
101
+ $(filter_matching "$arg" "${test_files[@]}" || true)
102
+ )
103
+ fi
104
+ done
105
+
106
+ # If there were filter args, replace test files list with the results
107
+ if [ -n "$filtered" ]; then
108
+ if [ ${#explicit_files[@]} -eq 0 ]; then
109
+ echo "Error: no test files match" >&2
110
+ exit 1
111
+ else
112
+ test_files=(${explicit_files[@]})
113
+ echo running "${test_files[@]}"
114
+ fi
115
+ fi
116
+
117
+ # If there are any adapter tests, spin up the HTTP server
118
+ if [ -n "$(filter_matching "adapters" "${test_files[@]}")" ]; then
119
+ if server_started $port; then
120
+ echo "aborted: another instance of server running on $port" >&2
121
+ exit 1
122
+ fi
123
+ server_pid=$(start_server)
124
+ proxy_pid=$(start_proxy)
125
+ wait_for_server 30 $port || {
126
+ cat log/test.log
127
+ kill "$server_pid"
128
+ kill "$proxy_pid"
129
+ exit 1
130
+ }
131
+ wait_for_server 5 $proxy_port
132
+ cleanup() {
133
+ if [ $? -ne 0 ] && [ -n "$TRAVIS" ]; then
134
+ cat log/test.log
135
+ fi
136
+ kill "$server_pid"
137
+ kill "$proxy_pid"
138
+ }
139
+ trap cleanup INT EXIT
140
+ export LIVE="${scheme}://localhost:${port}"
141
+ export LIVE_PROXY="http://faraday%40test.local:there%20is%20cake@localhost:${proxy_port}"
142
+ fi
143
+
144
+ warnings="${TMPDIR:-/tmp}/faraday-warnings.$$"
145
+
146
+ run_test_files() {
147
+ # Save warnings on stderr to a separate file
148
+ RUBYOPT="$RUBYOPT -w" ruby -e 'while f=ARGV.shift and f!="--"; load f; end' "${test_files[@]}" -- "$@" \
149
+ 2> >(tee >(grep 'warning:' >"$warnings") | grep -v 'warning:')
150
+ }
151
+
152
+ check_warnings() {
153
+ # Display Ruby warnings from this project's source files. Abort if any were found.
154
+ num="$(grep -F "$PWD" "$warnings" | grep -v "${PWD}/bundle" | sort | uniq -c | sort -rn | tee /dev/stderr | wc -l)"
155
+ rm -f "$warnings"
156
+ if [ "$num" -gt 0 ]; then
157
+ echo "FAILED: this test suite doesn't tolerate Ruby syntax warnings!" >&2
158
+ exit 1
159
+ fi
160
+ }
161
+
162
+ if [ -n "$RBENV_VERSIONS" ]; then
163
+ IFS=' ' versions=($RBENV_VERSIONS)
164
+ for version in "${versions[@]}"; do
165
+ echo "[${version}]"
166
+ RBENV_VERSION="$version" run_test_files "$@"
167
+ done
168
+ else
169
+ run_test_files "$@"
170
+ fi
171
+
172
+ check_warnings
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../integration', __FILE__)
2
+
3
+ module Adapters
4
+ class DefaultTest < Faraday::TestCase
5
+
6
+ def adapter() :default end
7
+
8
+ Integration.apply(self, :NonParallel) do
9
+ # default stack is not configured with Multipart
10
+ undef :test_POST_sends_files
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../integration', __FILE__)
2
+
3
+ module Adapters
4
+ class EMHttpTest < Faraday::TestCase
5
+
6
+ def adapter() :em_http end
7
+
8
+ Integration.apply(self, :Parallel) do
9
+ # https://github.com/eventmachine/eventmachine/pull/289
10
+ undef :test_timeout
11
+
12
+ def test_binds_local_socket
13
+ host = '1.2.3.4'
14
+ conn = create_connection :request => { :bind => { :host => host } }
15
+ assert_equal host, conn.options[:bind][:host]
16
+ end
17
+ end unless jruby? and ssl_mode?
18
+ # https://github.com/eventmachine/eventmachine/issues/180
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../integration', __FILE__)
2
+
3
+ module Adapters
4
+ class EMSynchronyTest < Faraday::TestCase
5
+
6
+ def adapter() :em_synchrony end
7
+
8
+ Integration.apply(self, :Parallel) do
9
+ # https://github.com/eventmachine/eventmachine/pull/289
10
+ undef :test_timeout
11
+
12
+ def test_binds_local_socket
13
+ host = '1.2.3.4'
14
+ conn = create_connection :request => { :bind => { :host => host } }
15
+ #put conn.get('/who-am-i').body
16
+ assert_equal host, conn.options[:bind][:host]
17
+ end
18
+ end unless RUBY_VERSION < '1.9' or jruby?
19
+ end
20
+ end