faraday 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Gemfile +9 -8
  2. data/README.md +99 -20
  3. data/faraday.gemspec +9 -11
  4. data/lib/faraday.rb +1 -1
  5. data/lib/faraday/adapter.rb +11 -86
  6. data/lib/faraday/adapter/action_dispatch.rb +3 -12
  7. data/lib/faraday/adapter/em_synchrony.rb +9 -24
  8. data/lib/faraday/adapter/excon.rb +7 -19
  9. data/lib/faraday/adapter/net_http.rb +37 -35
  10. data/lib/faraday/adapter/patron.rb +16 -23
  11. data/lib/faraday/adapter/test.rb +4 -10
  12. data/lib/faraday/adapter/typhoeus.rb +11 -39
  13. data/lib/faraday/builder.rb +82 -33
  14. data/lib/faraday/connection.rb +3 -10
  15. data/lib/faraday/error.rb +20 -15
  16. data/lib/faraday/middleware.rb +7 -2
  17. data/lib/faraday/request.rb +13 -10
  18. data/lib/faraday/request/json.rb +31 -0
  19. data/lib/faraday/request/multipart.rb +63 -0
  20. data/lib/faraday/request/url_encoded.rb +37 -0
  21. data/lib/faraday/response.rb +72 -30
  22. data/lib/faraday/response/logger.rb +34 -0
  23. data/lib/faraday/response/raise_error.rb +16 -0
  24. data/lib/faraday/upload_io.rb +14 -6
  25. data/lib/faraday/utils.rb +54 -17
  26. data/test/adapters/live_test.rb +36 -14
  27. data/test/adapters/logger_test.rb +1 -1
  28. data/test/adapters/net_http_test.rb +33 -0
  29. data/test/connection_test.rb +0 -39
  30. data/test/env_test.rb +84 -6
  31. data/test/helper.rb +17 -8
  32. data/test/live_server.rb +19 -17
  33. data/test/middleware_stack_test.rb +91 -0
  34. data/test/request_middleware_test.rb +75 -21
  35. data/test/response_middleware_test.rb +34 -31
  36. metadata +21 -17
  37. data/lib/faraday/adapter/logger.rb +0 -32
  38. data/lib/faraday/request/active_support_json.rb +0 -21
  39. data/lib/faraday/request/yajl.rb +0 -18
  40. data/lib/faraday/response/active_support_json.rb +0 -30
  41. data/lib/faraday/response/yajl.rb +0 -26
  42. data/test/adapters/typhoeus_test.rb +0 -31
  43. data/test/connection_app_test.rb +0 -60
  44. data/test/form_post_test.rb +0 -58
  45. data/test/multipart_test.rb +0 -48
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+
3
+ class MiddlewareStackTest < Faraday::TestCase
4
+ # mock handler classes
5
+ class Handler < Struct.new(:app)
6
+ def call(env)
7
+ (env[:request_headers]['X-Middleware'] ||= '') << ":#{self.class.name.split('::').last}"
8
+ app.call(env)
9
+ end
10
+ end
11
+ class Apple < Handler; end
12
+ class Orange < Handler; end
13
+ class Banana < Handler; end
14
+
15
+ def setup
16
+ @conn = Faraday::Connection.new
17
+ @builder = @conn.builder
18
+ end
19
+
20
+ def test_sets_default_adapter_if_none_set
21
+ default_middleware = Faraday::Request.lookup_module :url_encoded
22
+ default_adapter_klass = Faraday::Adapter.lookup_module Faraday.default_adapter
23
+ assert @builder[0] == default_middleware
24
+ assert @builder[1] == default_adapter_klass
25
+ end
26
+
27
+ def test_allows_rebuilding
28
+ build_stack Apple
29
+ assert_handlers %w[Apple]
30
+
31
+ build_stack Orange
32
+ assert_handlers %w[Orange]
33
+ end
34
+
35
+ def test_allows_extending
36
+ build_stack Apple
37
+ @conn.use Orange
38
+ assert_handlers %w[Apple Orange]
39
+ end
40
+
41
+ def test_builder_is_passed_to_new_faraday_connection
42
+ new_conn = Faraday::Connection.new :builder => @builder
43
+ assert_equal @builder, new_conn.builder
44
+ end
45
+
46
+ def test_insert_before
47
+ build_stack Apple, Orange
48
+ @builder.insert_before Apple, Banana
49
+ assert_handlers %w[Banana Apple Orange]
50
+ end
51
+
52
+ def test_insert_after
53
+ build_stack Apple, Orange
54
+ @builder.insert_after Apple, Banana
55
+ assert_handlers %w[Apple Banana Orange]
56
+ end
57
+
58
+ def test_swap_handlers
59
+ build_stack Apple, Orange
60
+ @builder.swap Apple, Banana
61
+ assert_handlers %w[Banana Orange]
62
+ end
63
+
64
+ def test_delete_handler
65
+ build_stack Apple, Orange
66
+ @builder.delete Apple
67
+ assert_handlers %w[Orange]
68
+ end
69
+
70
+ private
71
+
72
+ # make a stack with test adapter that reflects the order of middleware
73
+ def build_stack(*handlers)
74
+ @builder.build do |b|
75
+ handlers.each { |handler| b.use(*handler) }
76
+
77
+ b.adapter :test do |stub|
78
+ stub.get '/' do |env|
79
+ # echo the "X-Middleware" request header in the body
80
+ [200, {}, env[:request_headers]['X-Middleware'].to_s]
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ def assert_handlers(list)
87
+ echoed_list = @conn.get('/').body.to_s.split(':')
88
+ echoed_list.shift if echoed_list.first == ''
89
+ assert_equal list, echoed_list
90
+ end
91
+ end
@@ -1,31 +1,85 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'rack/utils'
3
+
4
+ Faraday::CompositeReadIO.send :attr_reader, :ios
2
5
 
3
6
  class RequestMiddlewareTest < Faraday::TestCase
4
- [:yajl, :rails_json].each do |key|
5
- encoder = Faraday::Request.lookup_module(key)
6
- next if !encoder.loaded?
7
-
8
- define_method "test_encodes_json_with_#{key}" do
9
- resp = create_json_connection(encoder).post('echo_body', :a => 1)
10
- raw_json = resp.body
11
- raw_json.gsub! /: 1/, ':1' # sometimes rails_json adds a space
12
- assert_equal %({"a":1}), raw_json
13
- assert_match /json/, resp.headers['Content-Type']
7
+ def setup
8
+ @conn = Faraday.new do |b|
9
+ b.request :multipart
10
+ b.request :url_encoded
11
+ b.request :json
12
+ b.adapter :test do |stub|
13
+ stub.post('/echo') do |env|
14
+ posted_as = env[:request_headers]['Content-Type']
15
+ [200, {'Content-Type' => posted_as}, env[:body]]
16
+ end
17
+ end
14
18
  end
15
19
  end
16
20
 
17
- private
18
- def create_json_connection(encoder)
19
- Faraday.new do |b|
20
- b.use encoder
21
- b.adapter :test do |stub|
22
- stub.post('echo_body') do |env|
23
- [200,
24
- {'Content-Type' => env[:request_headers]['Content-Type']},
25
- env[:body]
26
- ]
27
- end
21
+ def test_does_nothing_without_payload
22
+ response = @conn.post('/echo')
23
+ assert_nil response.headers['Content-Type']
24
+ assert response.body.empty?
25
+ end
26
+
27
+ def test_ignores_custom_content_type
28
+ response = @conn.post('/echo', { :some => 'data' }, 'content-type' => 'application/x-foo')
29
+ assert_equal 'application/x-foo', response.headers['Content-Type']
30
+ assert_equal({ :some => 'data' }, response.body)
31
+ end
32
+
33
+ def test_json_encodes_hash
34
+ response = @conn.post('/echo', { :fruit => %w[apples oranges] }, 'content-type' => 'application/json')
35
+ assert_equal 'application/json', response.headers['Content-Type']
36
+ assert_equal '{"fruit":["apples","oranges"]}', response.body
37
+ end
38
+
39
+ def test_json_skips_encoding_for_strings
40
+ response = @conn.post('/echo', '{"a":"b"}', 'content-type' => 'application/json')
41
+ assert_equal 'application/json', response.headers['Content-Type']
42
+ assert_equal '{"a":"b"}', response.body
43
+ end
44
+
45
+ def test_url_encoded_no_header
46
+ response = @conn.post('/echo', { :fruit => %w[apples oranges] })
47
+ assert_equal 'application/x-www-form-urlencoded', response.headers['Content-Type']
48
+ assert_equal 'fruit[]=apples&fruit[]=oranges', response.body
49
+ end
50
+
51
+ def test_url_encoded_with_header
52
+ response = @conn.post('/echo', {'a'=>123}, 'content-type' => 'application/x-www-form-urlencoded')
53
+ assert_equal 'application/x-www-form-urlencoded', response.headers['Content-Type']
54
+ assert_equal 'a=123', response.body
55
+ end
56
+
57
+ def test_url_encoded_nested
58
+ response = @conn.post('/echo', { :user => {:name => 'Mislav', :web => 'mislav.net'} })
59
+ assert_equal 'application/x-www-form-urlencoded', response.headers['Content-Type']
60
+ expected = { 'user' => {'name' => 'Mislav', 'web' => 'mislav.net'} }
61
+ assert_equal expected, Rack::Utils.parse_nested_query(response.body)
62
+ end
63
+
64
+ def test_multipart
65
+ # assume params are out of order
66
+ regexes = [
67
+ /name\=\"a\"/,
68
+ /name=\"b\[c\]\"\; filename\=\"request_middleware_test\.rb\"/,
69
+ /name=\"b\[d\]\"/]
70
+
71
+ payload = {:a => 1, :b => {:c => Faraday::UploadIO.new(__FILE__, 'text/x-ruby'), :d => 2}}
72
+ response = @conn.post('/echo', payload)
73
+
74
+ assert_kind_of Faraday::CompositeReadIO, response.body
75
+ assert_equal "multipart/form-data;boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
76
+ response.headers['Content-Type']
77
+
78
+ response.body.send(:ios).map(&:read).each do |io|
79
+ if re = regexes.detect { |r| io =~ r }
80
+ regexes.delete re
28
81
  end
29
82
  end
83
+ assert_equal [], regexes
30
84
  end
31
85
  end
@@ -1,44 +1,47 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
2
 
3
3
  class ResponseMiddlewareTest < Faraday::TestCase
4
- [:yajl, :rails_json].each do |key|
5
- encoder = Faraday::Response.lookup_module(key)
6
- next if !encoder.loaded?
7
-
8
- define_method "test_uses_#{key}_to_parse_json_content" do
9
- response = create_json_connection(encoder).get('json')
10
- assert response.success?
11
- assert_equal [1,2,3], response.body
4
+ def setup
5
+ @conn = Faraday.new do |b|
6
+ b.response :raise_error
7
+ b.adapter :test do |stub|
8
+ stub.get('ok') { [200, {'Content-Type' => 'text/html'}, '<body></body>'] }
9
+ stub.get('not-found') { [404, {'X-Reason' => 'because'}, 'keep looking'] }
10
+ stub.get('error') { [500, {'X-Error' => 'bailout'}, 'fail'] }
11
+ end
12
12
  end
13
+ end
13
14
 
14
- define_method "test_uses_#{key}_to_skip_blank_content" do
15
- response = create_json_connection(encoder).get('blank')
16
- assert response.success?
17
- assert !response.body
15
+ class ResponseUpcaser < Faraday::Response::Middleware
16
+ def parse(body)
17
+ body.upcase
18
18
  end
19
+ end
19
20
 
20
- define_method "test_uses_#{key}_to_skip_nil_content" do
21
- response = create_json_connection(encoder).get('nil')
22
- assert response.success?
23
- assert !response.body
21
+ def test_success
22
+ assert_nothing_raised do
23
+ @conn.get('ok')
24
24
  end
25
-
26
- define_method "test_use_#{key}_to_raise_Faraday_Error_Parsing_with_no_json_content" do
27
- assert_raises Faraday::Error::ParsingError do
28
- create_json_connection(encoder).get('bad_json')
29
- end
25
+ end
26
+
27
+ def test_raises_not_found
28
+ error = assert_raises Faraday::Error::ResourceNotFound do
29
+ @conn.get('not-found')
30
30
  end
31
+ assert_equal 'the server responded with status 404', error.message
32
+ assert_equal 'because', error.response[:headers]['X-Reason']
31
33
  end
32
-
33
- def create_json_connection(encoder)
34
- Faraday.new do |b|
35
- b.adapter :test do |stub|
36
- stub.get('json') { [200, {'Content-Type' => 'text/html'}, "[1,2,3]"] }
37
- stub.get('blank') { [200, {'Content-Type' => 'text/html'}, ''] }
38
- stub.get('nil') { [200, {'Content-Type' => 'text/html'}, nil] }
39
- stub.get("bad_json") {[200, {'Content-Type' => 'text/html'}, '<body></body>']}
40
- end
41
- b.use encoder
34
+
35
+ def test_raises_error
36
+ error = assert_raises Faraday::Error::ClientError do
37
+ @conn.get('error')
42
38
  end
39
+ assert_equal 'the server responded with status 500', error.message
40
+ assert_equal 'bailout', error.response[:headers]['X-Error']
41
+ end
42
+
43
+ def test_upcase
44
+ @conn.builder.insert(0, ResponseUpcaser)
45
+ assert_equal '<BODY></BODY>', @conn.get('ok').body
43
46
  end
44
47
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 5
8
- - 7
9
- version: 0.5.7
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Rick Olson
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2011-02-27 00:00:00 -08:00
18
+ date: 2011-03-31 00:00:00 -07:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -25,6 +26,7 @@ dependencies:
25
26
  requirements:
26
27
  - - ~>
27
28
  - !ruby/object:Gem::Version
29
+ hash: 27
28
30
  segments:
29
31
  - 0
30
32
  - 8
@@ -39,6 +41,7 @@ dependencies:
39
41
  requirements:
40
42
  - - ~>
41
43
  - !ruby/object:Gem::Version
44
+ hash: 15
42
45
  segments:
43
46
  - 2
44
47
  - 2
@@ -54,6 +57,7 @@ dependencies:
54
57
  requirements:
55
58
  - - ~>
56
59
  - !ruby/object:Gem::Version
60
+ hash: 19
57
61
  segments:
58
62
  - 1
59
63
  - 1
@@ -69,6 +73,7 @@ dependencies:
69
73
  requirements:
70
74
  - - ">="
71
75
  - !ruby/object:Gem::Version
76
+ hash: 19
72
77
  segments:
73
78
  - 1
74
79
  - 1
@@ -76,6 +81,7 @@ dependencies:
76
81
  version: 1.1.0
77
82
  - - <
78
83
  - !ruby/object:Gem::Version
84
+ hash: 7
79
85
  segments:
80
86
  - 2
81
87
  version: "2"
@@ -100,7 +106,6 @@ files:
100
106
  - lib/faraday/adapter/action_dispatch.rb
101
107
  - lib/faraday/adapter/em_synchrony.rb
102
108
  - lib/faraday/adapter/excon.rb
103
- - lib/faraday/adapter/logger.rb
104
109
  - lib/faraday/adapter/net_http.rb
105
110
  - lib/faraday/adapter/patron.rb
106
111
  - lib/faraday/adapter/test.rb
@@ -110,24 +115,23 @@ files:
110
115
  - lib/faraday/error.rb
111
116
  - lib/faraday/middleware.rb
112
117
  - lib/faraday/request.rb
113
- - lib/faraday/request/active_support_json.rb
114
- - lib/faraday/request/yajl.rb
118
+ - lib/faraday/request/json.rb
119
+ - lib/faraday/request/multipart.rb
120
+ - lib/faraday/request/url_encoded.rb
115
121
  - lib/faraday/response.rb
116
- - lib/faraday/response/active_support_json.rb
117
- - lib/faraday/response/yajl.rb
122
+ - lib/faraday/response/logger.rb
123
+ - lib/faraday/response/raise_error.rb
118
124
  - lib/faraday/upload_io.rb
119
125
  - lib/faraday/utils.rb
120
126
  - test/adapters/live_test.rb
121
127
  - test/adapters/logger_test.rb
128
+ - test/adapters/net_http_test.rb
122
129
  - test/adapters/test_middleware_test.rb
123
- - test/adapters/typhoeus_test.rb
124
- - test/connection_app_test.rb
125
130
  - test/connection_test.rb
126
131
  - test/env_test.rb
127
- - test/form_post_test.rb
128
132
  - test/helper.rb
129
133
  - test/live_server.rb
130
- - test/multipart_test.rb
134
+ - test/middleware_stack_test.rb
131
135
  - test/request_middleware_test.rb
132
136
  - test/response_middleware_test.rb
133
137
  has_rdoc: true
@@ -144,6 +148,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
148
  requirements:
145
149
  - - ">="
146
150
  - !ruby/object:Gem::Version
151
+ hash: 3
147
152
  segments:
148
153
  - 0
149
154
  version: "0"
@@ -152,6 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
157
  requirements:
153
158
  - - ">="
154
159
  - !ruby/object:Gem::Version
160
+ hash: 17
155
161
  segments:
156
162
  - 1
157
163
  - 3
@@ -167,12 +173,10 @@ summary: HTTP/REST API client library.
167
173
  test_files:
168
174
  - test/adapters/live_test.rb
169
175
  - test/adapters/logger_test.rb
176
+ - test/adapters/net_http_test.rb
170
177
  - test/adapters/test_middleware_test.rb
171
- - test/adapters/typhoeus_test.rb
172
- - test/connection_app_test.rb
173
178
  - test/connection_test.rb
174
179
  - test/env_test.rb
175
- - test/form_post_test.rb
176
- - test/multipart_test.rb
180
+ - test/middleware_stack_test.rb
177
181
  - test/request_middleware_test.rb
178
182
  - test/response_middleware_test.rb
@@ -1,32 +0,0 @@
1
- module Faraday
2
- class Adapter
3
- class Logger < Faraday::Adapter
4
- def self.loaded?() false end
5
-
6
- def initialize(app = nil, logger = nil)
7
- super(app)
8
- @logger = logger || begin
9
- require 'logger'
10
- ::Logger.new(STDOUT)
11
- end
12
- end
13
-
14
- def call(env)
15
- super
16
- @logger.info "#{env[:method]} #{env[:url].to_s}"
17
- @logger.debug("request") do
18
- env[:request_headers].map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
19
- end
20
-
21
- env[:response].on_complete do |resp_env|
22
- @logger.info("Status") { env[:status].to_s }
23
- @logger.debug("response") do
24
- resp_env[:response_headers].map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
25
- end
26
- end
27
-
28
- @app.call(env)
29
- end
30
- end
31
- end
32
- end
@@ -1,21 +0,0 @@
1
- module Faraday
2
- class Request::ActiveSupportJson < Faraday::Middleware
3
- begin
4
- if !defined?(ActiveSupport::JSON)
5
- require 'active_support'
6
- ActiveSupport::JSON
7
- end
8
-
9
- rescue LoadError, NameError => e
10
- self.load_error = e
11
- end
12
-
13
- def call(env)
14
- env[:request_headers]['Content-Type'] = 'application/json'
15
- if env[:body] && !env[:body].respond_to?(:to_str)
16
- env[:body] = ActiveSupport::JSON.encode(env[:body])
17
- end
18
- @app.call env
19
- end
20
- end
21
- end