apis 0.4.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/.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
|