faraday 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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