faraday 0.1.0 → 0.1.1

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/faraday.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{faraday}
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["rick"]
12
- s.date = %q{2010-01-02}
12
+ s.date = %q{2010-01-05}
13
13
  s.description = %q{HTTP/REST API client library with pluggable components}
14
14
  s.email = %q{technoweenie@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,9 @@ Gem::Specification.new do |s|
30
30
  "lib/faraday/adapter/typhoeus.rb",
31
31
  "lib/faraday/connection.rb",
32
32
  "lib/faraday/error.rb",
33
+ "lib/faraday/loadable.rb",
34
+ "lib/faraday/request/post_request.rb",
35
+ "lib/faraday/request/yajl_request.rb",
33
36
  "lib/faraday/response.rb",
34
37
  "lib/faraday/response/yajl_response.rb",
35
38
  "lib/faraday/test_connection.rb",
data/lib/faraday.rb CHANGED
@@ -21,7 +21,15 @@ module Faraday
21
21
  :Connection => 'connection',
22
22
  :TestConnection => 'test_connection',
23
23
  :Response => 'response',
24
- :Error => 'error'
24
+ :Error => 'error',
25
+ :Loadable => 'loadable'
26
+
27
+ module Request
28
+ extend AutoloadHelper
29
+ autoload_all 'faraday/request',
30
+ :YajlRequest => 'yajl_request',
31
+ :PostRequest => 'post_request'
32
+ end
25
33
 
26
34
  module Adapter
27
35
  extend AutoloadHelper
@@ -17,27 +17,42 @@ module Faraday
17
17
  @stack.empty?
18
18
  end
19
19
 
20
- def match(request_method, path, request_headers)
20
+ def match(request_method, path, data, request_headers)
21
21
  return false if !@stack.key?(request_method)
22
- @stack[request_method].detect { |stub| stub.matches?(path, request_headers) }
22
+ stub = @stack[request_method].detect { |stub| stub.matches?(path, data, request_headers) }
23
+ @stack[request_method].delete(stub) if stub
23
24
  end
24
25
 
25
26
  def get(path, request_headers = {}, &block)
26
- (@stack[:get] ||= []) << new_stub(path, request_headers, block)
27
+ (@stack[:get] ||= []) << new_stub(path, {}, request_headers, block)
27
28
  end
28
29
 
29
- def new_stub(path, request_headers, block)
30
+ def delete(path, request_headers = {}, &block)
31
+ (@stack[:delete] ||= []) << new_stub(path, {}, request_headers, block)
32
+ end
33
+
34
+ def post(path, data, request_headers = {}, &block)
35
+ (@stack[:post] ||= []) << new_stub(path, data, request_headers, block)
36
+ end
37
+
38
+ def put(path, data, request_headers = {}, &block)
39
+ (@stack[:put] ||= []) << new_stub(path, data, request_headers, block)
40
+ end
41
+
42
+ def new_stub(path, data, request_headers, block)
30
43
  status, response_headers, body = block.call
31
- Stub.new(path, request_headers, status, response_headers, body)
44
+ Stub.new(path, request_headers, status, response_headers, body, data)
32
45
  end
33
46
  end
34
47
 
35
- class Stub < Struct.new(:path, :request_headers, :status, :response_headers, :body)
36
- def matches?(request_path, headers)
48
+ class Stub < Struct.new(:path, :request_headers, :status, :response_headers, :body, :data)
49
+ def matches?(request_path, params, headers)
37
50
  return false if request_path != path
51
+ return false if params != data
52
+ return true if request_headers.empty?
38
53
  request_headers.each do |key, value|
39
54
  return false if headers[key] != value
40
- end
55
+ end
41
56
  true
42
57
  end
43
58
  end
@@ -57,7 +72,41 @@ module Faraday
57
72
 
58
73
  def _get(uri, headers)
59
74
  raise ConnectionFailed, "no stubbed requests" if stubs.empty?
60
- if stub = @stubs.match(:get, uri.path, headers)
75
+ if stub = @stubs.match(:get, uri.path, {}, headers)
76
+ response_class.new do |resp|
77
+ resp.headers = stub.response_headers
78
+ resp.process stub.body
79
+ end
80
+ else
81
+ nil
82
+ end
83
+ end
84
+
85
+ def _delete(uri, headers)
86
+ raise ConnectionFailed, "no stubbed requests" if stubs.empty?
87
+ if stub = @stubs.match(:delete, uri.path, {}, headers)
88
+ response_class.new do |resp|
89
+ resp.headers = stub.response_headers
90
+ resp.process stub.body
91
+ end
92
+ else
93
+ nil
94
+ end
95
+ end
96
+ def _post(uri, data, headers)
97
+ raise ConnectionFailed, "no stubbed requests" if stubs.empty?
98
+ if stub = @stubs.match(:post, uri.path, data, headers)
99
+ response_class.new do |resp|
100
+ resp.headers = stub.response_headers
101
+ resp.process stub.body
102
+ end
103
+ else
104
+ nil
105
+ end
106
+ end
107
+ def _put(uri, data, headers)
108
+ raise ConnectionFailed, "no stubbed requests" if stubs.empty?
109
+ if stub = @stubs.match(:put, uri.path, data, headers)
61
110
  response_class.new do |resp|
62
111
  resp.headers = stub.response_headers
63
112
  resp.process stub.body
@@ -1,15 +1,16 @@
1
1
  require 'net/http'
2
+ require 'cgi'
2
3
  module Faraday
3
4
  module Adapter
4
5
  module NetHttp
5
6
  extend Faraday::Connection::Options
6
7
 
7
- def _get(uri, request_headers)
8
+ def _perform(method, uri, data, request_headers)
8
9
  http = Net::HTTP.new(uri.host, uri.port)
9
10
  response_class.new do |resp|
10
- http_resp = http.get(path_for(uri), request_headers) do |chunk|
11
- resp.process(chunk)
12
- end
11
+ http_resp = http.send_request(method, path_for(uri), data, request_headers)
12
+ raise Faraday::Error::ResourceNotFound if http_resp.code == '404'
13
+ resp.process http_resp.body
13
14
  http_resp.each_header do |key, value|
14
15
  resp.headers[key] = value
15
16
  end
@@ -17,6 +18,25 @@ module Faraday
17
18
  rescue Errno::ECONNREFUSED
18
19
  raise Faraday::Error::ConnectionFailed, "connection refused"
19
20
  end
21
+
22
+ def _put(uri, data, request_headers)
23
+ request = request_class.new(data, request_headers)
24
+ _perform('PUT', uri, request.body, request.headers)
25
+ end
26
+
27
+ def _post(uri, data, request_headers)
28
+ request = request_class.new(data, request_headers)
29
+ _perform('POST', uri, request.body, request.headers)
30
+ end
31
+
32
+ def _get(uri, request_headers)
33
+ _perform('GET', uri, uri.query, request_headers)
34
+ end
35
+
36
+ def _delete(uri, request_headers)
37
+ _perform('DELETE', uri, uri.query, request_headers)
38
+ end
39
+
20
40
  end
21
41
  end
22
42
  end
@@ -25,12 +25,32 @@ module Faraday
25
25
  @parallel_manager = nil
26
26
  end
27
27
 
28
+ def _post(uri, data, request_headers)
29
+ request = request_class.new(data, request_headers)
30
+ _perform(:post, uri, :headers => request.headers, :body => request.body)
31
+ end
32
+
28
33
  def _get(uri, request_headers)
34
+ _perform(:get, uri, :headers => request_headers)
35
+ end
36
+
37
+ def _put(uri, data, request_headers)
38
+ request = request_class.new(data, request_headers)
39
+ _perform(:put, uri, :headers => request.headers, :body => request.body)
40
+ end
41
+
42
+ def _delete(uri, request_headers)
43
+ _perform(:delete, uri, :headers => request_headers)
44
+ end
45
+
46
+ def _perform method, uri, params
29
47
  response_class.new do |resp|
30
48
  is_async = in_parallel?
31
49
  setup_parallel_manager
32
- req = ::Typhoeus::Request.new(uri.to_s, :headers => request_headers, :method => :get)
50
+ params[:method] = method
51
+ req = ::Typhoeus::Request.new(uri.to_s, params)
33
52
  req.on_complete do |response|
53
+ raise Faraday::Error::ResourceNotFound if response.code == 404
34
54
  resp.process!(response.body)
35
55
  resp.headers = parse_response_headers(response.headers)
36
56
  end
@@ -42,6 +62,7 @@ module Faraday
42
62
  end
43
63
 
44
64
  def parse_response_headers(header_string)
65
+ return {} unless header_string # XXX
45
66
  Hash[*header_string.split(/\r\n/).
46
67
  tap { |a| a.shift }. # drop the HTTP status line
47
68
  map! { |h| h.split(/:\s+/,2) }. # split key and value
@@ -38,6 +38,34 @@ module Faraday
38
38
  self.path_prefix = uri.path
39
39
  end
40
40
 
41
+
42
+ # Override in a subclass, or include an adapter
43
+ #
44
+ # def _post(uri, post_params, headers)
45
+ # end
46
+ #
47
+ def post(uri, params = {}, headers = {})
48
+ _post build_uri(uri), build_params(params), build_headers(headers)
49
+ end
50
+
51
+ # Override in a subclass, or include an adapter
52
+ #
53
+ # def _put(uri, post_params, headers)
54
+ # end
55
+ #
56
+ def put(uri, params = {}, headers = {})
57
+ _put build_uri(uri), build_params(params), build_headers(headers)
58
+ end
59
+
60
+ # Override in a subclass, or include an adapter
61
+ #
62
+ # def _delete(uri, headers)
63
+ # end
64
+ #
65
+ def delete(uri, params = {}, headers = {})
66
+ _delete build_uri(uri, build_params(params)), build_headers(headers)
67
+ end
68
+
41
69
  # Override in a subclass, or include an adapter
42
70
  #
43
71
  # def _get(uri, headers)
@@ -48,6 +76,10 @@ module Faraday
48
76
  _get(uri, build_headers(headers))
49
77
  end
50
78
 
79
+ def request_class
80
+ @request_class || Request::PostRequest
81
+ end
82
+
51
83
  def response_class
52
84
  @response_class || Response
53
85
  end
@@ -59,6 +91,13 @@ module Faraday
59
91
  @response_class = v
60
92
  end
61
93
 
94
+ def request_class=(v)
95
+ if v.respond_to?(:loaded?) && !v.loaded?
96
+ raise ArgumentError, "The request class: #{v.inspect} does not appear to be loaded."
97
+ end
98
+ @request_class = v
99
+ end
100
+
62
101
  def in_parallel?
63
102
  !!@parallel_manager
64
103
  end
data/lib/faraday/error.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Faraday
2
2
  module Error
3
3
  class ConnectionFailed < StandardError; end
4
+ class ResourceNotFound < StandardError; end
4
5
  end
5
6
  end
@@ -0,0 +1,13 @@
1
+ module Faraday
2
+ module Loadable
3
+ def self.extended mod
4
+ class << mod
5
+ attr_accessor :load_error
6
+ end
7
+ end
8
+
9
+ def self.loaded?
10
+ load_error.nil?
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module Faraday
2
+ module Request
3
+ class PostRequest
4
+ extend Loadable
5
+
6
+ def initialize params, headers={}
7
+ @params = params
8
+ @headers = headers
9
+ end
10
+
11
+ def headers
12
+ @headers.merge('Content-Type' => 'application/x-www-form-urlencoded')
13
+ end
14
+
15
+ def body
16
+ create_post_params @params
17
+ end
18
+
19
+ private
20
+ def create_post_params(params, base = "")
21
+ [].tap do |toreturn|
22
+ params.each_key do |key|
23
+ keystring = base == '' ? key : "#{base}[#{key}]"
24
+ toreturn << (params[key].kind_of?(Hash) ? create_post_params(params[key], keystring) : "#{keystring}=#{CGI.escape(params[key].to_s)}")
25
+ end
26
+ end.join('&')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ module Faraday
2
+ module Request
3
+ class YajlRequest
4
+ extend Loadable
5
+
6
+ begin
7
+ require 'yajl'
8
+
9
+ def initialize params, headers={}
10
+ @params = params
11
+ @headers = headers
12
+ end
13
+
14
+ def headers
15
+ @headers.merge('Content-Type' => 'application/json')
16
+ end
17
+
18
+ # TODO streaming
19
+ def body
20
+ Yajl::Encoder.encode @params
21
+ end
22
+ rescue LoadError => e
23
+ self.load_error = e
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,11 +1,6 @@
1
1
  module Faraday
2
2
  class Response < Struct.new(:headers, :body)
3
- class << self
4
- attr_accessor :load_error
5
- def loaded?
6
- !load_error
7
- end
8
- end
3
+ extend Loadable
9
4
 
10
5
  extend AutoloadHelper
11
6
  autoload_all 'faraday/response',
@@ -40,4 +35,4 @@ module Faraday
40
35
  self.body = body.join if body.respond_to?(:join)
41
36
  end
42
37
  end
43
- end
38
+ end
data/test/adapter_test.rb CHANGED
@@ -6,11 +6,23 @@ class AdapterTest < Faraday::TestCase
6
6
  end
7
7
 
8
8
  Faraday::Adapter.loaded_adapters.each do |adapter|
9
- describe "#get with #{adapter} adapter" do
9
+ describe "with #{adapter} adapter" do
10
10
  before do
11
11
  @connection.extend adapter
12
12
  end
13
13
 
14
+ describe "#delete" do
15
+ it "retrieves the response body with YajlResponse" do
16
+ @connection.response_class = Faraday::Response::YajlResponse
17
+ assert_equal({'deleted' => true},
18
+ @connection.delete('delete_with_json').body)
19
+ end
20
+
21
+ it "send url-encoded params" do
22
+ assert_equal('foobar', @connection.delete('delete_with_params', 'deleted' => 'foobar').body)
23
+ end
24
+ end
25
+
14
26
  it "passes params" do
15
27
  @connection.params = {:a => 1}
16
28
  assert_equal "params[:a] == 1", @connection.get('params').body
@@ -25,13 +37,50 @@ class AdapterTest < Faraday::TestCase
25
37
  assert_equal 'hello world', @connection.get('hello_world').body
26
38
  end
27
39
 
28
- it "retrieves the response body with YajlResponse" do
29
- @connection.response_class = Faraday::Response::YajlResponse
30
- assert_equal [1,2,3], @connection.get('json').body
40
+ describe "#put" do
41
+ it "sends params" do
42
+ assert_equal 'hello zack', @connection.put('hello', 'name' => 'zack').body
43
+ end
44
+
45
+ it "retrieves the response body with YajlResponse" do
46
+ @connection.response_class = Faraday::Response::YajlResponse
47
+ assert_equal({'name' => 'zack'},
48
+ @connection.put('echo_name', 'name' => 'zack').body)
49
+ end
31
50
  end
32
51
 
33
- it "retrieves the response headers" do
34
- assert_equal 'text/html', @connection.get('hello_world').headers['content-type']
52
+ describe "#post" do
53
+ it "sends params" do
54
+ assert_equal 'hello zack', @connection.post('hello', 'name' => 'zack').body
55
+ end
56
+
57
+ it "retrieves the response body with YajlResponse" do
58
+ @connection.response_class = Faraday::Response::YajlResponse
59
+ assert_equal({'name' => 'zack'},
60
+ @connection.post('echo_name', 'name' => 'zack').body)
61
+ end
62
+ end
63
+
64
+ describe "#get" do
65
+ it "raises on 404" do
66
+ assert_raise(Faraday::Error::ResourceNotFound) { @connection.get('/nothing') }
67
+ end
68
+ it "retrieves the response body" do
69
+ assert_equal 'hello world', @connection.get('hello_world').body
70
+ end
71
+
72
+ it "send url-encoded params" do
73
+ assert_equal('hello zack', @connection.get('hello', 'name' => 'zack').body)
74
+ end
75
+
76
+ it "retrieves the response body with YajlResponse" do
77
+ @connection.response_class = Faraday::Response::YajlResponse
78
+ assert_equal [1,2,3], @connection.get('json').body
79
+ end
80
+
81
+ it "retrieves the response headers" do
82
+ assert_equal 'text/html', @connection.get('hello_world').headers['content-type']
83
+ end
35
84
  end
36
85
  end
37
86
 
data/test/helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'context'
3
+ require 'ruby-debug'
3
4
  if ENV['LEFTRIGHT']
4
5
  require 'leftright'
5
6
  end
data/test/live_server.rb CHANGED
@@ -9,10 +9,39 @@ get '/json' do
9
9
  "[1,2,3]"
10
10
  end
11
11
 
12
+ post '/hello' do
13
+ "hello #{params[:name]}"
14
+ end
15
+
16
+ get '/hello' do
17
+ "hello #{params[:name]}"
18
+ end
19
+
20
+ put '/hello' do
21
+ "hello #{params[:name]}"
22
+ end
23
+
24
+ post '/echo_name' do
25
+ %/{"name":#{params[:name].inspect}}/
26
+ end
27
+
28
+ put '/echo_name' do
29
+ %/{"name":#{params[:name].inspect}}/
30
+ end
31
+
32
+ delete '/delete_with_json' do
33
+ %/{"deleted":true}/
34
+ end
35
+
36
+ delete '/delete_with_params' do
37
+ params[:deleted]
38
+ end
39
+
12
40
  get '/params' do
13
41
  %(params[:a] == #{params[:a]})
14
42
  end
15
43
 
16
44
  get "/headers" do
17
45
  %(env[HTTP_X_TEST] == #{env["HTTP_X_TEST"]})
18
- end
46
+ end
47
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rick
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-02 00:00:00 -08:00
12
+ date: 2010-01-05 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -36,6 +36,9 @@ files:
36
36
  - lib/faraday/adapter/typhoeus.rb
37
37
  - lib/faraday/connection.rb
38
38
  - lib/faraday/error.rb
39
+ - lib/faraday/loadable.rb
40
+ - lib/faraday/request/post_request.rb
41
+ - lib/faraday/request/yajl_request.rb
39
42
  - lib/faraday/response.rb
40
43
  - lib/faraday/response/yajl_response.rb
41
44
  - lib/faraday/test_connection.rb