apis 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.yardopts +1 -0
- data/Gemfile +7 -0
- data/README.md +43 -0
- data/Rakefile +4 -0
- data/apis.gemspec +32 -0
- data/lib/apis.rb +55 -0
- data/lib/apis/adapter/abstract.rb +27 -0
- data/lib/apis/adapter/net_http.rb +21 -0
- data/lib/apis/adapter/rack_test.rb +19 -0
- data/lib/apis/builder.rb +76 -0
- data/lib/apis/connection.rb +96 -0
- data/lib/apis/connection_scope.rb +27 -0
- data/lib/apis/middleware/response/json.rb +28 -0
- data/lib/apis/response.rb +25 -0
- data/lib/apis/version.rb +3 -0
- data/spec/apis/adapter/net_http_spec.rb +45 -0
- data/spec/apis/adapter/rack_test_spec.rb +57 -0
- data/spec/apis/adapter_spec.rb +12 -0
- data/spec/apis/builder_spec.rb +100 -0
- data/spec/apis/connection_spec.rb +230 -0
- data/spec/apis/middleware/response/json_spec.rb +19 -0
- data/spec/apis_spec.rb +4 -0
- data/spec/quality_spec.rb +56 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/test_app.ru +16 -0
- metadata +167 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-m markdown
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
## Usage
|
2
|
+
|
3
|
+
connection = Apis::Connecton.new(:url => 'http://api.example.com') do
|
4
|
+
request do
|
5
|
+
use Apis::Request::JSON # |
|
6
|
+
use Apis::Request::OAuth2 # |
|
7
|
+
use Apis::Request::Logger # \/
|
8
|
+
end
|
9
|
+
adapter :net_http # -->
|
10
|
+
response do
|
11
|
+
use Apis::Response::JSON # |
|
12
|
+
use Apis::Response::Logger # \/
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
connection.get('/hello')
|
17
|
+
|
18
|
+
connection.request.replace Apis::Request::OAuth2, Apis::Request::OAuth
|
19
|
+
|
20
|
+
connection.post('/post_with_oauth_10') do |request|
|
21
|
+
request.params = {:q => 'm'}
|
22
|
+
end
|
23
|
+
|
24
|
+
## Request Middleware
|
25
|
+
|
26
|
+
### Example
|
27
|
+
|
28
|
+
class Request::Middleware
|
29
|
+
def call(env)
|
30
|
+
env[:params][:token] = 'abcdef'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
### Description
|
35
|
+
|
36
|
+
Basically, request middleware is an object that responds to `#call`.
|
37
|
+
It will be initialized with args passed if any.
|
38
|
+
|
39
|
+
### Environment
|
40
|
+
|
41
|
+
* `:method` - HTTP method name
|
42
|
+
* `:body` – body of request sent to server
|
43
|
+
* `:headers` – headers hash
|
data/Rakefile
ADDED
data/apis.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "apis/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "apis"
|
7
|
+
s.version = Apis::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Marjan Krekoten' (Мар'ян Крекотень)"]
|
10
|
+
s.email = ["m@hmarynka.com"]
|
11
|
+
s.homepage = "http://hmarynka.com/labs/apis"
|
12
|
+
s.summary = %q{Working bee of API wrapper}
|
13
|
+
s.description = %q{Rack-like HTTP client library inspired by Faraday done my way}
|
14
|
+
|
15
|
+
s.rubyforge_project = "apis"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency 'rspec', '>= 2.5'
|
23
|
+
s.add_development_dependency 'sinatra'
|
24
|
+
s.add_development_dependency 'rack-test'
|
25
|
+
s.add_development_dependency 'unicorn'
|
26
|
+
|
27
|
+
# Middlewares
|
28
|
+
s.add_development_dependency 'multi_json'
|
29
|
+
s.add_development_dependency 'yajl-ruby'
|
30
|
+
|
31
|
+
s.add_dependency 'addressable'
|
32
|
+
end
|
data/lib/apis.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
$: << lib_dir unless $:.include?(lib_dir = File.expand_path('..', __FILE__))
|
2
|
+
|
3
|
+
module Apis
|
4
|
+
class DuplicateMiddleware < StandardError; end
|
5
|
+
autoload :Connection, 'apis/connection'
|
6
|
+
autoload :ConnectionScope, 'apis/connection_scope'
|
7
|
+
autoload :Builder, 'apis/builder'
|
8
|
+
autoload :Response, 'apis/response'
|
9
|
+
|
10
|
+
module Registerable
|
11
|
+
def register(symbol, klass)
|
12
|
+
@lookup_table ||= {}
|
13
|
+
@lookup_table[symbol] = klass
|
14
|
+
end
|
15
|
+
|
16
|
+
def lookup(symbol)
|
17
|
+
@lookup_table ||= {}
|
18
|
+
self.const_get(@lookup_table[symbol])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Adapter
|
23
|
+
autoload :Abstract, 'apis/adapter/abstract'
|
24
|
+
autoload :NetHTTP, 'apis/adapter/net_http'
|
25
|
+
autoload :RackTest, 'apis/adapter/rack_test'
|
26
|
+
|
27
|
+
extend Registerable
|
28
|
+
|
29
|
+
class << self
|
30
|
+
# Default connection adapter
|
31
|
+
# You can change it by assignin new value
|
32
|
+
def default
|
33
|
+
@default ||= :net_http
|
34
|
+
end
|
35
|
+
attr_writer :default
|
36
|
+
end
|
37
|
+
|
38
|
+
register :net_http, :NetHTTP
|
39
|
+
register :rack_test, :RackTest
|
40
|
+
end
|
41
|
+
|
42
|
+
module Middleware
|
43
|
+
module Request
|
44
|
+
extend Registerable
|
45
|
+
end
|
46
|
+
|
47
|
+
module Response
|
48
|
+
autoload :Json, 'apis/middleware/response/json'
|
49
|
+
|
50
|
+
extend Registerable
|
51
|
+
|
52
|
+
register :json, :Json
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Apis
|
2
|
+
module Adapter
|
3
|
+
class Abstract
|
4
|
+
class NotImplemented < StandardError; end
|
5
|
+
|
6
|
+
attr_accessor :uri
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
options.each do |key, value|
|
10
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Performs request to resource
|
15
|
+
#
|
16
|
+
# @param [Symbol, String] method HTTP method to perform
|
17
|
+
# @param [String] path Relative path to resource host
|
18
|
+
# @param [Hash] params Params to be sent
|
19
|
+
# @param [Hash] headers Headers to be sent
|
20
|
+
#
|
21
|
+
# @return [Array] headers, body
|
22
|
+
def run(method, path, params = {}, headers = {})
|
23
|
+
raise Apis::Adapter::Abstract::NotImplemented
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Apis
|
4
|
+
module Adapter
|
5
|
+
class NetHTTP < Abstract
|
6
|
+
def connection
|
7
|
+
Net::HTTP.start(uri.host, uri.port)
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(method, path, params = {}, headers = {})
|
11
|
+
_module = Net::HTTP.const_get(method.to_s.capitalize)
|
12
|
+
request = _module.new(path)
|
13
|
+
response = connection.request(
|
14
|
+
request,
|
15
|
+
params.empty? ? nil : Addressable::URI.new.tap { |uri| uri.query_values = params }.query
|
16
|
+
)
|
17
|
+
[response.code.to_i] + response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rack/test'
|
2
|
+
|
3
|
+
module Apis
|
4
|
+
module Adapter
|
5
|
+
class RackTest < Abstract
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
attr_accessor :app
|
9
|
+
|
10
|
+
attr_reader :last_path, :last_params, :last_headers
|
11
|
+
|
12
|
+
def run(method, path, params = {}, headers = {})
|
13
|
+
@last_path, @last_params, @last_headers = path, params, headers
|
14
|
+
send(method, path, params, headers)
|
15
|
+
[last_response.status, last_response.headers, last_response.body]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/apis/builder.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Apis
|
2
|
+
class Builder
|
3
|
+
attr_accessor :lookup_context
|
4
|
+
def initialize(options = {}, &block)
|
5
|
+
options.each do |key, value|
|
6
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
7
|
+
end
|
8
|
+
@stack = []
|
9
|
+
@mapping = {}
|
10
|
+
block_eval(&block) if block
|
11
|
+
end
|
12
|
+
|
13
|
+
def use(middleware)
|
14
|
+
insert(middleware)
|
15
|
+
end
|
16
|
+
|
17
|
+
def replace(old, middleware)
|
18
|
+
if index = index(old)
|
19
|
+
insert(middleware, index)
|
20
|
+
remove(old)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def insert(middleware, index = nil)
|
25
|
+
middleware = lookup_middleware(middleware)
|
26
|
+
raise Apis::DuplicateMiddleware, "#{middleware} already in stack" if include?(middleware)
|
27
|
+
index ||= @stack.length
|
28
|
+
@stack[index] = lambda do |parent|
|
29
|
+
middleware.new(parent)
|
30
|
+
end
|
31
|
+
@mapping[middleware] = index
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove(middleware)
|
35
|
+
middleware = lookup_middleware(middleware)
|
36
|
+
@stack.delete_at(@mapping.delete(middleware))
|
37
|
+
end
|
38
|
+
|
39
|
+
def index(middleware)
|
40
|
+
middleware = lookup_middleware(middleware)
|
41
|
+
@mapping[middleware]
|
42
|
+
end
|
43
|
+
|
44
|
+
def length
|
45
|
+
@stack.length
|
46
|
+
end
|
47
|
+
|
48
|
+
def include?(middleware)
|
49
|
+
!!index(middleware)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_a
|
53
|
+
@mapping.to_a.sort { |a, b| a.last <=> b.last}.map { |e| e.first }
|
54
|
+
end
|
55
|
+
alias to_ary to_s
|
56
|
+
|
57
|
+
def to_app
|
58
|
+
unless @stack.empty?
|
59
|
+
inner_app = @stack.last.call(nil)
|
60
|
+
@stack.reverse[1..-1].inject(inner_app) { |parent, lazy| lazy.call(parent) }
|
61
|
+
else
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def block_eval(&block)
|
67
|
+
instance_eval(&block)
|
68
|
+
end
|
69
|
+
|
70
|
+
def lookup_middleware(middleware)
|
71
|
+
@lookup_context && !(Class === middleware) ?
|
72
|
+
@lookup_context.lookup(middleware) :
|
73
|
+
middleware
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module Apis
|
4
|
+
class Connection
|
5
|
+
def initialize(options = {})
|
6
|
+
@scope = Apis::ConnectionScope.new
|
7
|
+
@scope.headers, @scope.params = {}, {}
|
8
|
+
|
9
|
+
if String === options
|
10
|
+
self.uri = options
|
11
|
+
else
|
12
|
+
options.each do |key, value|
|
13
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if block_given?
|
18
|
+
block = Proc.new
|
19
|
+
instance_eval(&block)
|
20
|
+
end
|
21
|
+
adapter(Apis::Adapter.default) unless @adapter
|
22
|
+
end
|
23
|
+
|
24
|
+
def uri
|
25
|
+
@scope.uri
|
26
|
+
end
|
27
|
+
|
28
|
+
def uri=(value)
|
29
|
+
@scope.uri = Addressable::URI.parse(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def headers
|
33
|
+
@scope.headers
|
34
|
+
end
|
35
|
+
|
36
|
+
def headers=(value)
|
37
|
+
@scope.headers.merge!(value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def params
|
41
|
+
@scope.params
|
42
|
+
end
|
43
|
+
|
44
|
+
def params=(value)
|
45
|
+
@scope.params.merge!(value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def request
|
49
|
+
block = block_given? ? Proc.new : nil
|
50
|
+
@request ||= Apis::Builder.new(:lookup_context => Apis::Middleware::Request, &block)
|
51
|
+
@request
|
52
|
+
end
|
53
|
+
|
54
|
+
def response
|
55
|
+
block = block_given? ? Proc.new : nil
|
56
|
+
@response ||= Apis::Builder.new(:lookup_context => Apis::Middleware::Response, &block)
|
57
|
+
@response
|
58
|
+
end
|
59
|
+
|
60
|
+
def adapter(value = nil)
|
61
|
+
if Symbol === value
|
62
|
+
value = Apis::Adapter.lookup(value)
|
63
|
+
end
|
64
|
+
|
65
|
+
@adapter = value.new(:uri => uri) if value
|
66
|
+
@adapter
|
67
|
+
end
|
68
|
+
|
69
|
+
[:get, :head, :post, :put, :delete].each do |method|
|
70
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
71
|
+
def #{method}(path = nil, params = {}, headers = {})
|
72
|
+
run_request(#{method.inspect}, path, params, headers, &(block_given? ? Proc.new : nil))
|
73
|
+
end
|
74
|
+
RUBY
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_request(method, path = nil, params = {}, headers = {}, &block)
|
78
|
+
#block = block_given? ? Proc.new : nil
|
79
|
+
# TODO: refactor this, it's ugly
|
80
|
+
@scope.scoped do
|
81
|
+
self.params = params if params
|
82
|
+
self.headers = headers if headers
|
83
|
+
block.call(self) if block
|
84
|
+
path ||= uri.path.empty? ? '/' : uri.path
|
85
|
+
self.request.to_app.call(
|
86
|
+
:method => method,
|
87
|
+
:params => self.params,
|
88
|
+
:headers => self.headers
|
89
|
+
) unless self.request.to_a.empty?
|
90
|
+
res = Apis::Response.new(*adapter.run(method, path, self.params, self.headers))
|
91
|
+
self.response.to_app.call(res) unless self.response.to_a.empty?
|
92
|
+
res
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Apis
|
2
|
+
class ConnectionScope
|
3
|
+
def initialize
|
4
|
+
@data = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def method_missing(method, value = nil)
|
8
|
+
if method =~ /\=$/ && value
|
9
|
+
@data[method.to_s.gsub(/\=/, '').to_sym] = value
|
10
|
+
else
|
11
|
+
@data[method]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def scoped
|
16
|
+
backup = {}
|
17
|
+
@data.each do |key, value|
|
18
|
+
backup[key] = value.dup
|
19
|
+
end
|
20
|
+
yield
|
21
|
+
ensure
|
22
|
+
backup.each do |key, value|
|
23
|
+
@data[key] = value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module Apis
|
4
|
+
module Middleware
|
5
|
+
module Response
|
6
|
+
class Json
|
7
|
+
attr_accessor :app
|
8
|
+
def initialize(app = nil)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
env.body = case env.body
|
14
|
+
when ''
|
15
|
+
nil
|
16
|
+
when 'true'
|
17
|
+
true
|
18
|
+
when 'false'
|
19
|
+
false
|
20
|
+
else
|
21
|
+
::MultiJson.decode(env.body)
|
22
|
+
end
|
23
|
+
@app.call(env) if @app
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Apis
|
2
|
+
class Response
|
3
|
+
attr_accessor :status, :headers, :body
|
4
|
+
def initialize(status, headers, body)
|
5
|
+
@status, @headers, @body = status, headers, body
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_env
|
9
|
+
{:status => status, :headers => headers, :body => body}
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_a
|
13
|
+
[status, headers, body]
|
14
|
+
end
|
15
|
+
alias to_ary to_a
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
respond_to?(key) ? send(key) : nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(key, value)
|
22
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/apis/version.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'addressable/uri'
|
3
|
+
|
4
|
+
describe Apis::Adapter::NetHTTP do
|
5
|
+
before(:all) do
|
6
|
+
start_server
|
7
|
+
end
|
8
|
+
after(:all) do
|
9
|
+
stop_server
|
10
|
+
end
|
11
|
+
|
12
|
+
[:get, :post, :put, :delete, :head].each do |method|
|
13
|
+
context method.to_s.upcase do
|
14
|
+
it "returns body" do
|
15
|
+
adapter = Apis::Adapter::NetHTTP.new(:uri => Addressable::URI.parse(server_host))
|
16
|
+
status, headers, body = adapter.run(method, '/')
|
17
|
+
body.should == method.to_s.upcase
|
18
|
+
end unless method == :head
|
19
|
+
|
20
|
+
it "returns headers" do
|
21
|
+
adapter = Apis::Adapter::NetHTTP.new(:uri => Addressable::URI.parse(server_host))
|
22
|
+
status, headers, body = adapter.run(method, '/')
|
23
|
+
headers['X-Requested-With-Method'].should == method.to_s.upcase
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns status" do
|
27
|
+
adapter = Apis::Adapter::NetHTTP.new(:uri => Addressable::URI.parse(server_host))
|
28
|
+
status, headers, body = adapter.run(method, '/')
|
29
|
+
status.should == 200
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sends params" do
|
33
|
+
adapter = Apis::Adapter::NetHTTP.new(:uri => Addressable::URI.parse(server_host))
|
34
|
+
status, headers, body = adapter.run(method, "/#{method}", {:param => 'value'})
|
35
|
+
headers['X-Sent-Params'].should == '{"param"=>"value"}'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'registered under :net_http' do
|
41
|
+
Apis::Connection.new do
|
42
|
+
adapter :net_http
|
43
|
+
end.adapter.should be_instance_of(Apis::Adapter::NetHTTP)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class RackApp
|
4
|
+
def call(env)
|
5
|
+
[
|
6
|
+
200,
|
7
|
+
{
|
8
|
+
'X-Request-Method' => env['REQUEST_METHOD'],
|
9
|
+
'X-Request-At' => env['PATH_INFO']
|
10
|
+
},
|
11
|
+
env['REQUEST_METHOD'] == 'HEAD' ? [] : [env['REQUEST_METHOD']]
|
12
|
+
]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Apis::Adapter::RackTest do
|
17
|
+
[:get, :post, :put, :delete, :head].each do |method|
|
18
|
+
context method.to_s.upcase do
|
19
|
+
let(:adapter) { Apis::Adapter::RackTest.new(:app => RackApp.new) }
|
20
|
+
it "returns body" do
|
21
|
+
status, headers, body = adapter.run(method, '/')
|
22
|
+
body.should == method.to_s.upcase
|
23
|
+
end unless method == :head
|
24
|
+
|
25
|
+
it "returns headers" do
|
26
|
+
status, headers, body = adapter.run(method, '/')
|
27
|
+
headers['X-Request-Method'].should == method.to_s.upcase
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns status" do
|
31
|
+
status, headers, body = adapter.run(method, '/')
|
32
|
+
status.should == 200
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'saves passed path' do
|
36
|
+
adapter.run(method, "/#{method}")
|
37
|
+
adapter.last_path.should == "/#{method}"
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'saves passed params' do
|
41
|
+
adapter.run(method, '/', {:test => 'param'})
|
42
|
+
adapter.last_params.should == {:test => 'param'}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'saves passed headers' do
|
46
|
+
adapter.run(method, '/', {}, {'Content-Type' => 'text'})
|
47
|
+
adapter.last_headers.should == {'Content-Type' => 'text'}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'registered under :rack_test' do
|
53
|
+
Apis::Connection.new do
|
54
|
+
adapter :rack_test
|
55
|
+
end.adapter.should be_instance_of(Apis::Adapter::RackTest)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apis::Adapter do
|
4
|
+
it 'registers adapters shortnames' do
|
5
|
+
Apis::Adapter.register(:fake, :FakeAdapter)
|
6
|
+
Apis::Adapter.lookup(:fake).should == FakeAdapter
|
7
|
+
end
|
8
|
+
|
9
|
+
specify ':net_http is set as default adapter' do
|
10
|
+
Apis::Adapter.default.should == :net_http
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apis::Builder do
|
4
|
+
it 'adds middleware to stack' do
|
5
|
+
builder = Apis::Builder.new
|
6
|
+
builder.use Middleware
|
7
|
+
builder.length.should == 1
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'raises error when duplicate middleware added' do
|
11
|
+
builder = Apis::Builder.new
|
12
|
+
builder.use Middleware
|
13
|
+
expect { builder.use Middleware }.to raise_error(Apis::DuplicateMiddleware, 'Middleware already in stack')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'shows if middleware in stack' do
|
17
|
+
builder = Apis::Builder.new
|
18
|
+
builder.use Middleware
|
19
|
+
builder.include?(Middleware).should == true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'replaces middleware with another' do
|
23
|
+
builder = Apis::Builder.new
|
24
|
+
builder.use Middleware
|
25
|
+
builder.use RESTMiddleware
|
26
|
+
builder.replace Middleware, NewMiddleware
|
27
|
+
builder.include?(Middleware).should == false
|
28
|
+
builder.include?(NewMiddleware).should == true
|
29
|
+
builder.to_a.should == [NewMiddleware, RESTMiddleware]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'removes middleware from stack' do
|
33
|
+
builder = Apis::Builder.new
|
34
|
+
builder.use Middleware
|
35
|
+
builder.include?(Middleware).should == true
|
36
|
+
builder.remove(Middleware)
|
37
|
+
builder.include?(Middleware).should == false
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns stacked middlewares in order' do
|
41
|
+
builder = Apis::Builder.new
|
42
|
+
builder.use Middleware
|
43
|
+
builder.use NewMiddleware
|
44
|
+
builder.use RESTMiddleware
|
45
|
+
app = builder.to_app
|
46
|
+
app.should be_instance_of(Middleware)
|
47
|
+
app.app.should be_instance_of(NewMiddleware)
|
48
|
+
app.app.app.should be_instance_of(RESTMiddleware)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'evals block' do
|
52
|
+
builder = Apis::Builder.new
|
53
|
+
builder.block_eval do |builder|
|
54
|
+
use Middleware
|
55
|
+
use NewMiddleware
|
56
|
+
use RESTMiddleware
|
57
|
+
end
|
58
|
+
|
59
|
+
app = builder.to_app
|
60
|
+
app.should be_instance_of(Middleware)
|
61
|
+
app.app.should be_instance_of(NewMiddleware)
|
62
|
+
app.app.app.should be_instance_of(RESTMiddleware)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'evals block passed to constructor' do
|
66
|
+
builder = Apis::Builder.new do
|
67
|
+
use Middleware
|
68
|
+
use NewMiddleware
|
69
|
+
use RESTMiddleware
|
70
|
+
end
|
71
|
+
|
72
|
+
app = builder.to_app
|
73
|
+
app.should be_instance_of(Middleware)
|
74
|
+
app.app.should be_instance_of(NewMiddleware)
|
75
|
+
app.app.app.should be_instance_of(RESTMiddleware)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'inserts middleware only once' do
|
79
|
+
builder = Apis::Builder.new do
|
80
|
+
use Middleware
|
81
|
+
end
|
82
|
+
|
83
|
+
app = builder.to_app
|
84
|
+
app.should be_instance_of(Middleware)
|
85
|
+
app.app.should be_nil
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'lookups middleware by shortcut if lookup object givven' do
|
89
|
+
Lookup = Module.new do
|
90
|
+
extend Apis::Registerable
|
91
|
+
end
|
92
|
+
Lookup.register(:middleware, :Middleware)
|
93
|
+
builder = Apis::Builder.new(:lookup_context => Lookup) do
|
94
|
+
use :middleware
|
95
|
+
end
|
96
|
+
|
97
|
+
app = builder.to_app
|
98
|
+
app.should be_instance_of(Middleware)
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apis::Connection do
|
4
|
+
context 'configuration' do
|
5
|
+
context 'options' do
|
6
|
+
it 'sets url' do
|
7
|
+
Apis::Connection.new(:uri => 'http://api.example.org').uri.should == Addressable::URI.parse('http://api.example.org')
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'sets url if it is only parameter' do
|
11
|
+
Apis::Connection.new('http://api.example.org').uri.should == Addressable::URI.parse('http://api.example.org')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'sets headers' do
|
15
|
+
Apis::Connection.new(
|
16
|
+
:headers => {
|
17
|
+
'Content-Type' => 'text',
|
18
|
+
'User-Agent' => 'apis'
|
19
|
+
}
|
20
|
+
).headers.should == {
|
21
|
+
'Content-Type' => 'text',
|
22
|
+
'User-Agent' => 'apis'
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'sets params' do
|
27
|
+
Apis::Connection.new(
|
28
|
+
:params => {:q => 'apis', :hl => 'uk'}
|
29
|
+
).params.should == {:q => 'apis', :hl => 'uk'}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'methods' do
|
34
|
+
let(:connection) { Apis::Connection.new }
|
35
|
+
it 'sets url' do
|
36
|
+
connection.uri = 'http://api.example.org'
|
37
|
+
connection.uri.should == Addressable::URI.parse('http://api.example.org')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'sets headers' do
|
41
|
+
connection.headers = {
|
42
|
+
'Content-Type' => 'text',
|
43
|
+
'User-Agent' => 'apis'
|
44
|
+
}
|
45
|
+
connection.headers.should == {
|
46
|
+
'Content-Type' => 'text',
|
47
|
+
'User-Agent' => 'apis'
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'sets params' do
|
52
|
+
connection.params = {:q => 'apis', :hl => 'uk'}
|
53
|
+
connection.params.should == {:q => 'apis', :hl => 'uk'}
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'updates headers' do
|
57
|
+
connection.headers = {'Content-Type' => 'text'}
|
58
|
+
connection.headers = {'User-Agent' => 'apis'}
|
59
|
+
connection.headers.should == {
|
60
|
+
'Content-Type' => 'text',
|
61
|
+
'User-Agent' => 'apis'
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'updates params' do
|
66
|
+
connection.params = {:q => 'apis'}
|
67
|
+
connection.params = {:hl => 'uk'}
|
68
|
+
connection.params.should == {:q => 'apis', :hl => 'uk'}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'stack building' do
|
73
|
+
it 'constructs request stack' do
|
74
|
+
connection = Apis::Connection.new do
|
75
|
+
request do
|
76
|
+
use Middleware
|
77
|
+
use NewMiddleware
|
78
|
+
use RESTMiddleware
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
connection.request.to_a.should == [Middleware, NewMiddleware, RESTMiddleware]
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'constructs response stack' do
|
86
|
+
connection = Apis::Connection.new do
|
87
|
+
response do
|
88
|
+
use Middleware
|
89
|
+
use NewMiddleware
|
90
|
+
use RESTMiddleware
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
connection.response.to_a.should == [Middleware, NewMiddleware, RESTMiddleware]
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'sets adapter' do
|
98
|
+
connection = Apis::Connection.new do
|
99
|
+
adapter FakeAdapter
|
100
|
+
end
|
101
|
+
connection.adapter.should be_instance_of(FakeAdapter)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'finds adapter using symbol shortcut' do
|
105
|
+
Apis::Adapter.register(:fake, :FakeAdapter)
|
106
|
+
connection = Apis::Connection.new do
|
107
|
+
adapter :fake
|
108
|
+
end
|
109
|
+
connection.adapter.should be_instance_of(FakeAdapter)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'uses default adapter if none specified' do
|
113
|
+
connection = Apis::Connection.new
|
114
|
+
connection.adapter nil
|
115
|
+
connection.adapter.should be_instance_of(Apis::Adapter::NetHTTP)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'performing request' do
|
121
|
+
before do
|
122
|
+
@connection = Apis::Connection.new(:uri => server_host) do
|
123
|
+
adapter FakeAdapter
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
[:get, :head, :post, :put, :delete].each do |method|
|
128
|
+
context method.to_s.upcase do
|
129
|
+
it 'passes method to adapter' do
|
130
|
+
@connection.send(method)
|
131
|
+
@connection.adapter.last_method.should == method
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'passes path to adapter' do
|
135
|
+
@connection.send(method, "/#{method}")
|
136
|
+
@connection.adapter.last_path.should == "/#{method}"
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'passes query params to adapter' do
|
140
|
+
@connection.send(method, "/#{method}", {:q => 'text'})
|
141
|
+
@connection.adapter.last_params.should == {:q => 'text'}
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'passes params specified in block' do
|
145
|
+
@connection.send(method, "/#{method}") do |request|
|
146
|
+
request.params = {:test => 'params'}
|
147
|
+
end
|
148
|
+
@connection.adapter.last_params.should == {:test => 'params'}
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'doesn\'t not overwrite params of connection' do
|
152
|
+
@connection.params = {:q => 'test'}
|
153
|
+
@connection.send(method, "/#{method}") do |request|
|
154
|
+
request.params = {:test => 'params'}
|
155
|
+
end
|
156
|
+
@connection.adapter.last_params.should == {:q => 'test', :test => 'params'}
|
157
|
+
@connection.params.should == {:q => 'test'}
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'merges connection params with method params' do
|
161
|
+
@connection.params = {:test => 'param'}
|
162
|
+
@connection.send(method, "/#{method}", {:q => 'text'})
|
163
|
+
@connection.adapter.last_params.should == {:q => 'text', :test => 'param'}
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'passes headers to adapter' do
|
167
|
+
@connection.send(method, "/#{method}", {}, {'Content-Type' => 'text'})
|
168
|
+
@connection.adapter.last_headers.should == {'Content-Type' => 'text'}
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'merges connection headers with method headers' do
|
172
|
+
@connection.headers = {'User-Agent' => 'apis'}
|
173
|
+
@connection.send(method, "/#{method}", {}, {'Content-Type' => 'text'})
|
174
|
+
@connection.adapter.last_headers.should == {'Content-Type' => 'text', 'User-Agent' => 'apis'}
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'doesn\'t overwrite headers of connection' do
|
178
|
+
@connection.headers = {:q => 'test'}
|
179
|
+
@connection.send(method, "/#{method}") do |request|
|
180
|
+
request.headers = {:test => 'params'}
|
181
|
+
end
|
182
|
+
@connection.adapter.last_headers.should == {:q => 'test', :test => 'params'}
|
183
|
+
@connection.headers.should == {:q => 'test'}
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'request with middleware' do
|
190
|
+
context 'request middleware' do
|
191
|
+
before do
|
192
|
+
Apis::Middleware::Request.register(:middleware, :Middleware)
|
193
|
+
@connection = Apis::Connection.new(:uri => server_host) do
|
194
|
+
request do
|
195
|
+
use :middleware
|
196
|
+
end
|
197
|
+
adapter FakeAdapter
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'calls midleware' do
|
202
|
+
@connection.get
|
203
|
+
@connection.adapter.last_headers.should == {'Middleware' => 'true'}
|
204
|
+
end
|
205
|
+
|
206
|
+
it "doesn't overwrite headers of connection" do
|
207
|
+
@connection.get
|
208
|
+
@connection.adapter.last_headers.should == {'Middleware' => 'true'}
|
209
|
+
@connection.headers.should == {}
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'response midleware' do
|
214
|
+
before do
|
215
|
+
Apis::Middleware::Response.register(:res, :Response)
|
216
|
+
@connection = Apis::Connection.new(:uri => server_host) do
|
217
|
+
adapter FakeAdapter
|
218
|
+
response do
|
219
|
+
use :res
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'calls midleware' do
|
225
|
+
response = @connection.get
|
226
|
+
response.body.should == 'altered'
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apis::Middleware::Response::Json do
|
4
|
+
it 'replaces body with parsed data' do
|
5
|
+
MultiJson.engine = :yajl
|
6
|
+
json = Apis::Middleware::Response::Json.new
|
7
|
+
request = Apis::Response.new(200, {}, %|{"name":"Marjan Krekoten'","age": 23}|)
|
8
|
+
json.call(request)
|
9
|
+
request.body.should == {"name" => "Marjan Krekoten'", "age" => 23}
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'registered under :json' do
|
13
|
+
Apis::Connection.new do
|
14
|
+
response do
|
15
|
+
use :json
|
16
|
+
end
|
17
|
+
end.response.to_a.should include(Apis::Middleware::Response::Json)
|
18
|
+
end
|
19
|
+
end
|
data/spec/apis_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "The library itself" do
|
4
|
+
def check_for_tab_characters(filename)
|
5
|
+
failing_lines = []
|
6
|
+
File.readlines(filename).each_with_index do |line,number|
|
7
|
+
failing_lines << number + 1 if line =~ /\t/
|
8
|
+
end
|
9
|
+
|
10
|
+
unless failing_lines.empty?
|
11
|
+
"#{filename} has tab characters on lines #{failing_lines.join(', ')}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_for_extra_spaces(filename)
|
16
|
+
failing_lines = []
|
17
|
+
File.readlines(filename).each_with_index do |line,number|
|
18
|
+
next if line =~ /^\s+#.*\s+\n$/
|
19
|
+
failing_lines << number + 1 if line =~ /\s+\n$/
|
20
|
+
end
|
21
|
+
|
22
|
+
unless failing_lines.empty?
|
23
|
+
"#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec::Matchers.define :be_well_formed do
|
28
|
+
failure_message_for_should do |actual|
|
29
|
+
actual.join("\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
match do |actual|
|
33
|
+
actual.empty?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has no malformed whitespace" do
|
38
|
+
error_messages = []
|
39
|
+
Dir.chdir(File.expand_path("../..", __FILE__)) do
|
40
|
+
`git ls-files`.split("\n").each do |filename|
|
41
|
+
next if filename =~ /\.gitmodules|fixtures|\.md/
|
42
|
+
error_messages << check_for_tab_characters(filename)
|
43
|
+
error_messages << check_for_extra_spaces(filename)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
error_messages.compact.should be_well_formed
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can still be built" do
|
50
|
+
Dir.chdir(root) do
|
51
|
+
`gem build apis.gemspec`
|
52
|
+
$?.should == 0
|
53
|
+
`rm apis-*.gem`
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path('../../lib/apis', __FILE__)
|
2
|
+
|
3
|
+
class BaseMiddleware
|
4
|
+
attr_accessor :app
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
end
|
9
|
+
class Middleware < BaseMiddleware
|
10
|
+
def call(env)
|
11
|
+
env[:params][:middleware] = 'true'
|
12
|
+
env[:headers]['Middleware'] = 'true'
|
13
|
+
@app.call(env) if @app
|
14
|
+
end
|
15
|
+
end
|
16
|
+
NewMiddleware = Class.new(BaseMiddleware)
|
17
|
+
RESTMiddleware = Class.new(BaseMiddleware)
|
18
|
+
|
19
|
+
class Response < BaseMiddleware
|
20
|
+
def call(env)
|
21
|
+
env[:body] = 'altered'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class FakeAdapter < Apis::Adapter::Abstract
|
26
|
+
attr_accessor :last_method, :last_path, :last_params, :last_headers
|
27
|
+
def run(method, path = nil, params = {}, headers = {})
|
28
|
+
@last_method, @last_path, @last_params, @last_headers = method, path, params, headers
|
29
|
+
[200, {}, 'body']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module DirHelper
|
34
|
+
def root
|
35
|
+
@root ||= File.expand_path('../..', __FILE__)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module SinatraHelper
|
40
|
+
def server_port
|
41
|
+
1234
|
42
|
+
end
|
43
|
+
|
44
|
+
def server_host
|
45
|
+
"http://localhost:#{server_port}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def start_server
|
49
|
+
%x{unicorn -p #{server_port} #{root}/spec/test_app.ru -D -P #{root}/spec/uni.pid} # 3&> /dev/null
|
50
|
+
end
|
51
|
+
|
52
|
+
def stop_server
|
53
|
+
%x{kill `cat #{root}/spec/uni.pid`}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec.configure do |rspec|
|
58
|
+
rspec.include DirHelper
|
59
|
+
rspec.include SinatraHelper
|
60
|
+
end
|
data/spec/test_app.ru
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
|
3
|
+
[:head, :get, :post, :put, :delete].each do |method|
|
4
|
+
send(method, '/') do
|
5
|
+
headers['X-Requested-With-Method'] = method.to_s.upcase
|
6
|
+
"#{method.to_s.upcase}" unless method == :head
|
7
|
+
end
|
8
|
+
|
9
|
+
send(method, "/#{method}") do
|
10
|
+
headers['X-Requested-With-Method'] = method.to_s.upcase
|
11
|
+
headers['X-Sent-Params'] = params.inspect
|
12
|
+
"#{method.to_s.upcase}" unless method == :head
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
run Sinatra::Application
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.4.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- "Marjan Krekoten' (\xD0\x9C\xD0\xB0\xD1\x80'\xD1\x8F\xD0\xBD \xD0\x9A\xD1\x80\xD0\xB5\xD0\xBA\xD0\xBE\xD1\x82\xD0\xB5\xD0\xBD\xD1\x8C)"
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-07 00:00:00 +03:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "2.5"
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sinatra
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rack-test
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: unicorn
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: multi_json
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: yajl-ruby
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: addressable
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
type: :runtime
|
92
|
+
version_requirements: *id007
|
93
|
+
description: Rack-like HTTP client library inspired by Faraday done my way
|
94
|
+
email:
|
95
|
+
- m@hmarynka.com
|
96
|
+
executables: []
|
97
|
+
|
98
|
+
extensions: []
|
99
|
+
|
100
|
+
extra_rdoc_files: []
|
101
|
+
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- .yardopts
|
105
|
+
- Gemfile
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- apis.gemspec
|
109
|
+
- lib/apis.rb
|
110
|
+
- lib/apis/adapter/abstract.rb
|
111
|
+
- lib/apis/adapter/net_http.rb
|
112
|
+
- lib/apis/adapter/rack_test.rb
|
113
|
+
- lib/apis/builder.rb
|
114
|
+
- lib/apis/connection.rb
|
115
|
+
- lib/apis/connection_scope.rb
|
116
|
+
- lib/apis/middleware/response/json.rb
|
117
|
+
- lib/apis/response.rb
|
118
|
+
- lib/apis/version.rb
|
119
|
+
- spec/apis/adapter/net_http_spec.rb
|
120
|
+
- spec/apis/adapter/rack_test_spec.rb
|
121
|
+
- spec/apis/adapter_spec.rb
|
122
|
+
- spec/apis/builder_spec.rb
|
123
|
+
- spec/apis/connection_spec.rb
|
124
|
+
- spec/apis/middleware/response/json_spec.rb
|
125
|
+
- spec/apis_spec.rb
|
126
|
+
- spec/quality_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/test_app.ru
|
129
|
+
has_rdoc: true
|
130
|
+
homepage: http://hmarynka.com/labs/apis
|
131
|
+
licenses: []
|
132
|
+
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: "0"
|
144
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: "0"
|
150
|
+
requirements: []
|
151
|
+
|
152
|
+
rubyforge_project: apis
|
153
|
+
rubygems_version: 1.6.2
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Working bee of API wrapper
|
157
|
+
test_files:
|
158
|
+
- spec/apis/adapter/net_http_spec.rb
|
159
|
+
- spec/apis/adapter/rack_test_spec.rb
|
160
|
+
- spec/apis/adapter_spec.rb
|
161
|
+
- spec/apis/builder_spec.rb
|
162
|
+
- spec/apis/connection_spec.rb
|
163
|
+
- spec/apis/middleware/response/json_spec.rb
|
164
|
+
- spec/apis_spec.rb
|
165
|
+
- spec/quality_spec.rb
|
166
|
+
- spec/spec_helper.rb
|
167
|
+
- spec/test_app.ru
|