jeckle 0.0.1 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +14 -0
- data/Gemfile +2 -0
- data/README.md +56 -3
- data/Rakefile +1 -1
- data/examples/dribbble.rb +29 -0
- data/jeckle.gemspec +24 -14
- data/lib/jeckle/api.rb +55 -0
- data/lib/jeckle/errors.rb +29 -0
- data/lib/jeckle/model.rb +8 -0
- data/lib/jeckle/request.rb +33 -0
- data/lib/jeckle/resource.rb +30 -33
- data/lib/jeckle/setup.rb +28 -0
- data/lib/jeckle/version.rb +1 -1
- data/lib/jeckle.rb +15 -7
- data/spec/fixtures/jeckle_config.rb +31 -0
- data/spec/fixtures/models/fake_model.rb +3 -0
- data/spec/fixtures/resources/fake_resource.rb +7 -0
- data/spec/jeckle/api_spec.rb +180 -0
- data/spec/jeckle/model_spec.rb +11 -0
- data/spec/jeckle/request_spec.rb +73 -0
- data/spec/jeckle/resource_spec.rb +126 -0
- data/spec/jeckle/setup_spec.rb +57 -0
- data/spec/spec_helper.rb +16 -2
- data/spec/support/shared_examples.rb +47 -0
- metadata +64 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be467f303f461477c44a2ff12a334918e42cf833
|
4
|
+
data.tar.gz: 73c1eca8358f96530eabf65c5398898c3f516e18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69e64c0210fde8e8b577ad46b00f0bbca449fb234940bb5236f40838d7fbd9912fca85776328a9d126b1d495f736b191d04468b62a9871dd02ba8613de9d1ac2
|
7
|
+
data.tar.gz: 945e10b3420ba0b94f59358eeab47ac976bcf07eae78d1c6c699f5e634ecbfc2856b92f2c74bdef58f8c1b3c26c00280319124be0f95d631b8261f5fb1820392
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
# Jeckle
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/tomas-stefano/jeckle)
|
4
|
+
[](https://codeclimate.com/github/tomas-stefano/jeckle)
|
5
|
+
[](https://codeclimate.com/github/tomas-stefano/jeckle)
|
6
|
+
|
7
|
+
Wrap APIs with easiness and flexibility.
|
4
8
|
|
5
9
|
<img src="http://www.toonopedia.com/hekljekl.jpg" alt="Jeckle" />
|
6
10
|
|
11
|
+
> Heckle usually refers to Jeckle familiarly, as "chum" or "pal", while Jeckle
|
12
|
+
often calls Heckle "old chap", "old thing", "old boy" or "old featherhead",
|
13
|
+
indicating a close friendship between them.
|
14
|
+
|
15
|
+
<small>*[Extracted from Wikipedia](http://en.wikipedia.org/wiki/Heckle_and_Jeckle)*</small>
|
16
|
+
|
17
|
+
Let third party APIs be Heckle for your app's Jeckle.
|
18
|
+
|
7
19
|
## Installation
|
8
20
|
|
9
21
|
Add this line to your application's Gemfile:
|
@@ -14,6 +26,47 @@ And then execute:
|
|
14
26
|
|
15
27
|
$ bundle
|
16
28
|
|
17
|
-
|
29
|
+
### For Rails applications
|
30
|
+
|
31
|
+
We recommend to create a initializer:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
# config/initializers/jeckle.rb
|
35
|
+
|
36
|
+
Jeckle.configure do |config|
|
37
|
+
config.register :some_service do |api|
|
38
|
+
api.base_uri = 'http://api.someservice.com'
|
39
|
+
api.headers = {
|
40
|
+
'Accept' => 'application/json'
|
41
|
+
}
|
42
|
+
api.namespaces = { prefix: 'api', version: 'v1' }
|
43
|
+
api.logger = Rails.logger
|
44
|
+
api.read_timeout = 5
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
And then put your API stuff scoped inside a `services` folder:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# app/services/some_service/models/my_resource.rb
|
53
|
+
|
54
|
+
module SomeService
|
55
|
+
module Models
|
56
|
+
class MyResource
|
57
|
+
include Jeckle::Resource
|
58
|
+
|
59
|
+
default_api :some_service
|
60
|
+
|
61
|
+
attribute :id
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
## Roadmap
|
18
68
|
|
19
|
-
|
69
|
+
- Faraday middleware abstraction
|
70
|
+
- Per action API
|
71
|
+
- Comprehensive restful actions
|
72
|
+
- Testability
|
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'jeckle'
|
2
|
+
|
3
|
+
Jeckle.configure do |config|
|
4
|
+
config.register :dribbble do |api|
|
5
|
+
api.base_uri = 'http://api.dribbble.com'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Shot
|
10
|
+
include Jeckle::Resource
|
11
|
+
|
12
|
+
default_api :dribbble
|
13
|
+
|
14
|
+
attribute :id, Integer
|
15
|
+
attribute :name, String
|
16
|
+
attribute :url, String
|
17
|
+
attribute :image_url, String
|
18
|
+
end
|
19
|
+
|
20
|
+
shot = Shot.find 1600459
|
21
|
+
|
22
|
+
shot.id
|
23
|
+
# => 1600459
|
24
|
+
|
25
|
+
shot.name
|
26
|
+
# => Daryl Heckle And Jeckle Oates
|
27
|
+
|
28
|
+
shot.image_url
|
29
|
+
# => https://d13yacurqjgara.cloudfront.net/users/85699/screenshots/1600459/daryl_heckle_and_jeckle_oates-dribble.jpg
|
data/jeckle.gemspec
CHANGED
@@ -1,29 +1,39 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
4
|
require 'jeckle/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'jeckle'
|
8
8
|
spec.version = Jeckle::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description = %q{Simple module for
|
12
|
-
spec.summary = %q{Simple module for
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['Tomas D\'Stefano', 'Brenno Costa']
|
10
|
+
spec.email = ['tomas_stefano@successoft.com', 'brennolncosta@gmail.com']
|
11
|
+
spec.description = %q{Simple module for building client APIs}
|
12
|
+
spec.summary = %q{Simple module for building client APIs}
|
13
|
+
spec.homepage = 'https://github.com/tomas-stefano/jeckle'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'httparty'
|
22
|
-
spec.add_dependency 'virtus'
|
23
21
|
spec.add_dependency 'activemodel', '>= 4.0'
|
24
|
-
spec.add_dependency '
|
22
|
+
spec.add_dependency 'faraday', '~> 0.9'
|
23
|
+
spec.add_dependency 'faraday_middleware'
|
24
|
+
spec.add_dependency 'virtus', '~> 1.0'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
27
27
|
spec.add_development_dependency 'rake'
|
28
|
-
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
29
|
+
|
30
|
+
if RUBY_ENGINE == 'rbx'
|
31
|
+
spec.add_development_dependency 'rubinius-compiler'
|
32
|
+
spec.add_development_dependency 'rubinius-debugger'
|
33
|
+
elsif RUBY_ENGINE == 'jruby'
|
34
|
+
spec.add_development_dependency 'pry'
|
35
|
+
else
|
36
|
+
spec.add_development_dependency 'pry-nav' if RUBY_VERSION < '2.0.0'
|
37
|
+
spec.add_development_dependency 'pry-byebug' if RUBY_VERSION >= '2.0.0'
|
38
|
+
end
|
29
39
|
end
|
data/lib/jeckle/api.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Jeckle
|
2
|
+
class API
|
3
|
+
attr_accessor :logger
|
4
|
+
attr_writer :base_uri, :namespaces, :params, :headers, :open_timeout, :read_timeout
|
5
|
+
attr_reader :basic_auth, :request_timeout
|
6
|
+
|
7
|
+
def connection
|
8
|
+
@connection ||= Faraday.new(url: base_uri, request: timeout).tap do |conn|
|
9
|
+
conn.headers = headers
|
10
|
+
conn.params = params
|
11
|
+
conn.response :logger, logger
|
12
|
+
|
13
|
+
conn.basic_auth basic_auth[:username], basic_auth[:password] if basic_auth
|
14
|
+
conn.instance_exec &@middlewares_block if @middlewares_block
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def basic_auth=(credential_params)
|
19
|
+
[:username, :password].all? do |key|
|
20
|
+
credential_params.has_key? key
|
21
|
+
end or raise Jeckle::NoUsernameOrPasswordError, credential_params
|
22
|
+
|
23
|
+
@basic_auth = credential_params
|
24
|
+
end
|
25
|
+
|
26
|
+
def base_uri
|
27
|
+
[@base_uri, *namespaces.values].join '/'
|
28
|
+
end
|
29
|
+
|
30
|
+
def params
|
31
|
+
@params || {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def headers
|
35
|
+
@headers || {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def namespaces
|
39
|
+
@namespaces || {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def middlewares(&block)
|
43
|
+
raise Jeckle::ArgumentError, 'A block is required when configuring API middlewares' unless block_given?
|
44
|
+
|
45
|
+
@middlewares_block = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def timeout
|
49
|
+
{}.tap do |t|
|
50
|
+
t[:open_timeout] = @open_timeout if @open_timeout
|
51
|
+
t[:timeout] = @read_timeout if @read_timeout
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Jeckle
|
2
|
+
class ArgumentError < ::ArgumentError; end
|
3
|
+
|
4
|
+
class NoSuchAPIError < ArgumentError
|
5
|
+
def initialize(api)
|
6
|
+
message = %{The API name '#{api}' doesn't exist in Jeckle definitions.
|
7
|
+
|
8
|
+
Heckle: - Hey chum, what we can do now?
|
9
|
+
Jeckle: - Old chap, you need to put the right API name!
|
10
|
+
Heckle: - Hey pal, tell me the APIs then!
|
11
|
+
Jeckle: - Deal the trays, old thing: #{Jeckle::Setup.registered_apis.keys}.
|
12
|
+
}
|
13
|
+
|
14
|
+
super message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class NoUsernameOrPasswordError < ArgumentError
|
19
|
+
def initialize(credentials)
|
20
|
+
message = %{No such keys "username" and "password" on `basic_auth` definition"
|
21
|
+
|
22
|
+
Heckle: - Hey chum, what we can do now?
|
23
|
+
Jeckle: - Old chap, you need to define a username and a password for basic auth!
|
24
|
+
}
|
25
|
+
|
26
|
+
super message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/jeckle/model.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Jeckle
|
2
|
+
class Request
|
3
|
+
attr_reader :api, :body, :headers, :method, :params, :response, :endpoint
|
4
|
+
|
5
|
+
def initialize(api, endpoint, options = {})
|
6
|
+
@api = api
|
7
|
+
|
8
|
+
@method = options.delete(:method) || :get
|
9
|
+
@body = options.delete(:body) if %w(post put).include?(method.to_s)
|
10
|
+
@headers = options.delete(:headers)
|
11
|
+
|
12
|
+
@endpoint = endpoint
|
13
|
+
@params = options
|
14
|
+
|
15
|
+
@response = perform_api_request
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.run(*args)
|
19
|
+
new *args
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def perform_api_request
|
25
|
+
api.connection.public_send method do |api_request|
|
26
|
+
api_request.url endpoint
|
27
|
+
api_request.params = params
|
28
|
+
api_request.body = body
|
29
|
+
api_request.headers = api_request.headers.merge(headers) if headers
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/jeckle/resource.rb
CHANGED
@@ -1,52 +1,49 @@
|
|
1
1
|
module Jeckle
|
2
2
|
module Resource
|
3
|
-
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, Jeckle::Model
|
5
|
+
base.send :include, ActiveModel::Naming
|
4
6
|
|
5
|
-
|
6
|
-
include HTTParty
|
7
|
-
include Virtus.model
|
8
|
-
include ActiveModel::Validations
|
9
|
-
|
10
|
-
attribute :response
|
7
|
+
base.send :extend, Jeckle::Resource::ClassMethods
|
11
8
|
end
|
12
9
|
|
13
10
|
module ClassMethods
|
14
|
-
def
|
15
|
-
|
11
|
+
def inherited(base)
|
12
|
+
base.class_eval do
|
13
|
+
@api_mapping = superclass.api_mapping.dup
|
14
|
+
end
|
16
15
|
end
|
17
16
|
|
18
|
-
def
|
19
|
-
|
17
|
+
def resource_name
|
18
|
+
model_name.element.pluralize
|
20
19
|
end
|
21
20
|
|
22
|
-
def
|
23
|
-
|
21
|
+
def default_api(registered_api_name)
|
22
|
+
api_mapping[:default_api] = Jeckle::Setup.registered_apis.fetch(registered_api_name)
|
23
|
+
rescue KeyError => e
|
24
|
+
raise Jeckle::NoSuchAPIError, registered_api_name
|
24
25
|
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def save
|
28
|
-
request(:post)
|
29
|
-
end
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def api_mapping
|
28
|
+
@api_mapping ||= {}
|
29
|
+
end
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
'Accept-Encoding' => 'application/json'
|
39
|
-
}
|
40
|
-
end
|
31
|
+
def find(id)
|
32
|
+
endpoint = "#{resource_name}/#{id}"
|
33
|
+
attributes = run_request(endpoint).response.body
|
41
34
|
|
42
|
-
|
35
|
+
new attributes
|
36
|
+
end
|
43
37
|
|
44
|
-
|
45
|
-
|
38
|
+
def search(params = {})
|
39
|
+
collection = run_request(resource_name, params).response.body || []
|
46
40
|
|
47
|
-
|
41
|
+
collection.collect { |attrs| new attrs }
|
42
|
+
end
|
48
43
|
|
49
|
-
|
44
|
+
def run_request(endpoint, options = {})
|
45
|
+
Jeckle::Request.run api_mapping[:default_api], endpoint, options
|
46
|
+
end
|
50
47
|
end
|
51
48
|
end
|
52
|
-
end
|
49
|
+
end
|
data/lib/jeckle/setup.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Jeckle
|
2
|
+
class Setup
|
3
|
+
# Register apis, providing all the configurations to it.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
#
|
7
|
+
# Jeckle.configure do |config|
|
8
|
+
# config.register :my_api_restful do |api|
|
9
|
+
# api.basic_auth = { username: 'chucknorris', password: 'nowThatYouKnowYouMustDie' }
|
10
|
+
# api.namespaces = { version: 'v2' }
|
11
|
+
# api.base_uri = 'myapi.com'
|
12
|
+
# api.headers = { 'Content-Type' => 'application/whatever.complex.header.v2+json;charset=UTF-8' }
|
13
|
+
# api.logger = Rails.logger # or any other logger
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
def self.register(name)
|
18
|
+
Jeckle::API.new.tap do |user_api|
|
19
|
+
yield user_api
|
20
|
+
registered_apis[name] = user_api
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.registered_apis
|
25
|
+
@registered_apis ||= {}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/jeckle/version.rb
CHANGED
data/lib/jeckle.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
-
require 'jeckle/version'
|
2
|
-
require 'active_support/dependencies/autoload'
|
3
|
-
require 'active_support/concern'
|
4
|
-
require 'virtus'
|
5
1
|
require 'active_model'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
require 'virtus'
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
require 'jeckle/version'
|
7
|
+
|
8
|
+
%w(setup api model request resource errors).each do |file_name|
|
9
|
+
require "jeckle/#{file_name}"
|
10
|
+
end
|
9
11
|
|
10
|
-
|
12
|
+
module Jeckle
|
13
|
+
# Configure APIs to be used on Jeckle::Resources.
|
14
|
+
# See Jeckle::Setup for more information.
|
15
|
+
#
|
16
|
+
def self.configure
|
17
|
+
yield Jeckle::Setup
|
18
|
+
end
|
11
19
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Jeckle::Setup.register(:my_super_api) do |api|
|
2
|
+
api.base_uri = 'http://my-super-api.com.br'
|
3
|
+
api.headers = { 'Content-Type' => 'application/json' }
|
4
|
+
api.logger = Logger.new(STDOUT)
|
5
|
+
api.basic_auth = { username: 'steven_seagal', password: 'youAlwaysLose' }
|
6
|
+
api.namespaces = { prefix: 'api', version: 'v1' }
|
7
|
+
api.params = { hello: 'world' }
|
8
|
+
api.open_timeout = 2
|
9
|
+
api.read_timeout = 5
|
10
|
+
|
11
|
+
api.middlewares do
|
12
|
+
request :json
|
13
|
+
response :json
|
14
|
+
response :raise_error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Jeckle::Setup.register(:another_api) do |api|
|
19
|
+
api.base_uri = 'http://another-api.com.br'
|
20
|
+
api.headers = { 'Content-Type' => 'application/json' }
|
21
|
+
api.logger = Logger.new(STDOUT)
|
22
|
+
api.basic_auth = { username: 'heisenberg', password: 'metaAfetaAMina' }
|
23
|
+
api.namespaces = { prefix: 'api', version: 'v5' }
|
24
|
+
api.params = { hi: 'there' }
|
25
|
+
|
26
|
+
api.middlewares do
|
27
|
+
request :json
|
28
|
+
response :json
|
29
|
+
response :raise_error
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::API do
|
4
|
+
subject(:jeckle_api) { Jeckle::Setup.registered_apis[:my_super_api] }
|
5
|
+
|
6
|
+
describe '#connection' do
|
7
|
+
before { jeckle_api.instance_variable_set(:@connection, nil) }
|
8
|
+
|
9
|
+
let(:fake_faraday_connection) { Faraday::Connection.new }
|
10
|
+
|
11
|
+
it 'returns a Faraday connection' do
|
12
|
+
expect(jeckle_api.connection).to be_kind_of Faraday::Connection
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'caches the connection' do
|
16
|
+
expect(Faraday).to receive(:new).once.and_return(fake_faraday_connection)
|
17
|
+
.with(url: jeckle_api.base_uri, request: jeckle_api.timeout)
|
18
|
+
|
19
|
+
expect(fake_faraday_connection).to receive(:tap).once.and_call_original
|
20
|
+
|
21
|
+
10.times { jeckle_api.connection }
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'assigns api_headers' do
|
25
|
+
expect(jeckle_api.connection.headers).to include 'Content-Type' => 'application/json'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'assigns basic auth headers' do
|
29
|
+
expect(jeckle_api.connection.headers.keys).to include 'Authorization'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'assigns params there will be used on all requests' do
|
33
|
+
expect(jeckle_api.connection.params).to eq 'hello' => 'world'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'assigns timeout options' do
|
37
|
+
expect(jeckle_api.connection.options.open_timeout).to eq 2
|
38
|
+
expect(jeckle_api.connection.options.timeout).to eq 5
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when middlewares_block is set' do
|
42
|
+
before do
|
43
|
+
jeckle_api.middlewares do
|
44
|
+
request :retry, max: 2, interval: 0.05
|
45
|
+
request :instrumentation
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'adds middlewares on connection middleware stack' do
|
50
|
+
expect(jeckle_api.connection.builder.handlers.last(2)).to eq [
|
51
|
+
Faraday::Request::Retry,
|
52
|
+
Faraday::Request::Instrumentation
|
53
|
+
]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#base_uri' do
|
59
|
+
context 'when namespaces are defined' do
|
60
|
+
it 'appends namespaces' do
|
61
|
+
expect(jeckle_api.base_uri).to eq 'http://my-super-api.com.br/api/v1'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when no namespaces are defined' do
|
66
|
+
subject(:jeckle_api) { described_class.new }
|
67
|
+
|
68
|
+
before { jeckle_api.base_uri = 'http://my-super-api.com.br' }
|
69
|
+
|
70
|
+
it 'keeps base_uri without adding namespaces or futher slashes' do
|
71
|
+
expect(jeckle_api.base_uri).to eq 'http://my-super-api.com.br'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#basic_auth=' do
|
77
|
+
subject(:jeckle_api) { described_class.new }
|
78
|
+
|
79
|
+
context 'when there is the required credentials' do
|
80
|
+
let(:credentials) { { username: 'sly', password: 'IAmTheLaw'} }
|
81
|
+
|
82
|
+
before { jeckle_api.basic_auth = credentials }
|
83
|
+
|
84
|
+
it 'assigns creditals hash' do
|
85
|
+
expect(jeckle_api.basic_auth).to eq credentials
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when required creadentials is missing' do
|
90
|
+
let(:credentials) { {} }
|
91
|
+
|
92
|
+
it 'raises a argument error NoUsernameOrPasswordError' do
|
93
|
+
expect { jeckle_api.basic_auth = credentials }.to raise_error Jeckle::NoUsernameOrPasswordError
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#params' do
|
99
|
+
context 'when there are params' do
|
100
|
+
it 'assigns params hash' do
|
101
|
+
expect(jeckle_api.params).to eq hello: 'world'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when there are no params' do
|
106
|
+
subject(:jeckle_api) { described_class.new }
|
107
|
+
|
108
|
+
it 'assigns an empty hash' do
|
109
|
+
expect(jeckle_api.params).to eq({})
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#headers' do
|
115
|
+
context 'when there are headers' do
|
116
|
+
it 'assigns headers hash' do
|
117
|
+
expect(jeckle_api.headers).to eq 'Content-Type' => 'application/json'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when there are no headers' do
|
122
|
+
subject(:jeckle_api) { described_class.new }
|
123
|
+
|
124
|
+
it 'assigns an empty hash' do
|
125
|
+
expect(jeckle_api.headers).to eq({})
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#middlewares' do
|
131
|
+
context 'when a block is given' do
|
132
|
+
it 'assigns middleware_block' do
|
133
|
+
jeckle_api.middlewares { 123 }
|
134
|
+
|
135
|
+
expect(jeckle_api.instance_variable_get('@middlewares_block')).not_to be_nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when no block is given' do
|
140
|
+
it 'raises ArgumentError' do
|
141
|
+
expect {
|
142
|
+
jeckle_api.middlewares
|
143
|
+
}.to raise_error Jeckle::ArgumentError, /A block is required when configuring API middlewares/
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#timeout' do
|
149
|
+
let(:timeout) { nil }
|
150
|
+
let(:open_timeout) { nil }
|
151
|
+
|
152
|
+
before do
|
153
|
+
jeckle_api.open_timeout = open_timeout
|
154
|
+
jeckle_api.read_timeout = timeout
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when no timeout is defined' do
|
158
|
+
it 'returns empty hash' do
|
159
|
+
expect(jeckle_api.timeout).to eq({})
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'when a read_timeout is defined' do
|
164
|
+
let(:timeout) { 5 }
|
165
|
+
|
166
|
+
it 'returns a hash with assgned option' do
|
167
|
+
expect(jeckle_api.timeout).to eq timeout: timeout
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when two timeouts are defined for both open and read' do
|
172
|
+
let(:timeout) { 5 }
|
173
|
+
let(:open_timeout) { 2 }
|
174
|
+
|
175
|
+
it 'returns a hash correctly assigned open and read timeouts' do
|
176
|
+
expect(jeckle_api.timeout).to eq open_timeout: open_timeout, timeout: timeout
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::Model do
|
4
|
+
it 'includes active_model/validations' do
|
5
|
+
expect(FakeModel.ancestors).to include ActiveModel::Validations
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'includes virtus' do
|
9
|
+
expect(FakeModel.ancestors).to include Virtus::Model::Core
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::Request do
|
4
|
+
let(:api) { Jeckle::Setup.registered_apis[:my_super_api] }
|
5
|
+
|
6
|
+
before do
|
7
|
+
# Manipulate Faraday internals to avoid real requests
|
8
|
+
class FakeRackBuilder; def build_response(conn, req); end; end
|
9
|
+
fake_builder = FakeRackBuilder.new
|
10
|
+
|
11
|
+
allow(api.connection).to receive(:builder).and_return(fake_builder)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.run' do
|
15
|
+
before { allow(api.connection).to receive(http_method).and_call_original }
|
16
|
+
|
17
|
+
context 'GET' do
|
18
|
+
let(:options) { {} }
|
19
|
+
let(:endpoint) { 'fake_resource/4' }
|
20
|
+
let(:http_method) { :get }
|
21
|
+
|
22
|
+
it_behaves_like Jeckle::Request
|
23
|
+
|
24
|
+
it 'calls GET request on API\'s connection' do
|
25
|
+
expect(api.connection).to receive(http_method).and_call_original
|
26
|
+
|
27
|
+
described_class.run api, endpoint, options
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'POST' do
|
32
|
+
let(:endpoint) { 'fake_resources' }
|
33
|
+
let(:options) { { body: { value: 1000 }, method: http_method } }
|
34
|
+
let(:http_method) { :post }
|
35
|
+
|
36
|
+
it_behaves_like Jeckle::Request
|
37
|
+
|
38
|
+
it 'calls POST request on API\'s connection' do
|
39
|
+
expect(api.connection).to receive(:post).and_call_original
|
40
|
+
|
41
|
+
described_class.run api, endpoint, options
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'PUT' do
|
46
|
+
let(:endpoint) { 'fake_resources' }
|
47
|
+
let(:options) { { body: { id: 1001, value: 1000 }, method: http_method } }
|
48
|
+
let(:http_method) { :put }
|
49
|
+
|
50
|
+
it_behaves_like Jeckle::Request
|
51
|
+
|
52
|
+
it 'calls PUT request on API\'s connection' do
|
53
|
+
expect(api.connection).to receive(:put).and_call_original
|
54
|
+
|
55
|
+
described_class.run api, endpoint, options
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'DELETE' do
|
60
|
+
let(:options) { { method: http_method } }
|
61
|
+
let(:endpoint) { 'fake_resource/4' }
|
62
|
+
let(:http_method) { :delete }
|
63
|
+
|
64
|
+
it_behaves_like Jeckle::Request
|
65
|
+
|
66
|
+
it 'calls DELETE request on API\'s connection' do
|
67
|
+
expect(api.connection).to receive(:delete).and_call_original
|
68
|
+
|
69
|
+
described_class.run api, endpoint, options
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::Resource do
|
4
|
+
subject(:fake_resource) { FakeResource.new }
|
5
|
+
|
6
|
+
let(:api) { FakeResource.api_mapping[:default_api] }
|
7
|
+
|
8
|
+
it 'includes jeckle/model' do
|
9
|
+
expect(FakeResource.ancestors).to include Jeckle::Model
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'includes active_model/naming' do
|
13
|
+
expect(FakeResource.ancestors).to include ActiveModel::Naming
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.resource_name' do
|
17
|
+
it 'returns resource name based on class name' do
|
18
|
+
expect(FakeResource.resource_name).to eq 'fake_resources'
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when resource class is namespaced' do
|
22
|
+
before do
|
23
|
+
MySuperApi = Module.new
|
24
|
+
MySuperApi::FakeResource = Class.new(::FakeResource)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'ignores namespace' do
|
28
|
+
expect(MySuperApi::FakeResource.resource_name).to eq 'fake_resources'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.api_mapping' do
|
34
|
+
it 'returns a hash containing default api' do
|
35
|
+
expect(FakeResource.api_mapping).to match(
|
36
|
+
default_api: an_instance_of(Jeckle::API)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when resource is inherited' do
|
41
|
+
let(:inherited_class) { Class.new(FakeResource) }
|
42
|
+
|
43
|
+
it "contains the parent's api_mapping" do
|
44
|
+
expect(inherited_class.api_mapping).to eq FakeResource.api_mapping
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when api_mapping is changed' do
|
48
|
+
it "does not affect the parent" do
|
49
|
+
inherited_class.default_api :another_api
|
50
|
+
|
51
|
+
expect(FakeResource.api_mapping).not_to eq inherited_class.api_mapping
|
52
|
+
expect(FakeResource.api_mapping[:default_api]).to eq Jeckle::Setup.registered_apis[:my_super_api]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '.default_api' do
|
59
|
+
context 'when defining a registered API via Jeckle::Setup' do
|
60
|
+
it 'returns the assigned API' do
|
61
|
+
expect(FakeResource.default_api :my_super_api).to be_kind_of Jeckle::API
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'assigns API do api_mapping' do
|
65
|
+
expect(FakeResource.api_mapping).to have_key :default_api
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when defining an inexistent API' do
|
70
|
+
it 'raises NoSuchAPIError' do
|
71
|
+
expect { FakeResource.default_api :unknown_api }.to raise_error Jeckle::NoSuchAPIError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '.find' do
|
77
|
+
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: { id: 1001 }) }
|
78
|
+
|
79
|
+
it 'calls default API connection with GET' do
|
80
|
+
expect(Jeckle::Request).to receive(:run)
|
81
|
+
.with(api, 'fake_resources/1001', {}).and_return(fake_request)
|
82
|
+
|
83
|
+
FakeResource.find 1001
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns an instance of resource' do
|
87
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
88
|
+
|
89
|
+
expect(FakeResource.find 1001).to be_an_instance_of(FakeResource)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '.search' do
|
94
|
+
let(:query) { { name: 'cocada' } }
|
95
|
+
|
96
|
+
context 'when there are results' do
|
97
|
+
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: [{ id: 1001 }, { id: 1002 }]) }
|
98
|
+
|
99
|
+
it 'calls default API connection with GET and search params' do
|
100
|
+
expect(Jeckle::Request).to receive(:run)
|
101
|
+
.with(api, 'fake_resources', query).and_return(fake_request)
|
102
|
+
|
103
|
+
FakeResource.search query
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns an Array of resources' do
|
107
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
108
|
+
|
109
|
+
expect(FakeResource.search query).to match [
|
110
|
+
an_instance_of(FakeResource),
|
111
|
+
an_instance_of(FakeResource)
|
112
|
+
]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when there are no results' do
|
117
|
+
let(:fake_request) { OpenStruct.new response: OpenStruct.new(body: nil) }
|
118
|
+
|
119
|
+
it 'returns an empty Array' do
|
120
|
+
allow(Jeckle::Request).to receive(:run).and_return(fake_request)
|
121
|
+
|
122
|
+
expect(FakeResource.search query).to match []
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Jeckle::Setup do
|
4
|
+
describe '.register' do
|
5
|
+
context 'when block is given' do
|
6
|
+
let(:registered_apis) { Jeckle::Setup.registered_apis }
|
7
|
+
|
8
|
+
it 'returns a new registered API' do
|
9
|
+
expect(registered_apis).to have_key(:my_super_api)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'base uri' do
|
13
|
+
it 'assigns to the api instance' do
|
14
|
+
expect(registered_apis[:my_super_api].base_uri).to eq 'http://my-super-api.com.br/api/v1'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'headers' do
|
19
|
+
it 'assigns to the api instance' do
|
20
|
+
expect(registered_apis[:my_super_api].headers).to eq 'Content-Type' => 'application/json'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'logger' do
|
25
|
+
it 'assigns to the api instance' do
|
26
|
+
expect(registered_apis[:my_super_api].logger).to be_kind_of Logger
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'basic auth' do
|
31
|
+
it 'assigns to the api instance' do
|
32
|
+
expect(registered_apis[:my_super_api].basic_auth).to eq username: 'steven_seagal', password: 'youAlwaysLose'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'query string' do
|
37
|
+
it 'assigns to the api instance' do
|
38
|
+
expect(registered_apis[:my_super_api].params).to eq(hello: 'world')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'namespaces' do
|
43
|
+
it 'assigns to the api instance' do
|
44
|
+
expect(registered_apis[:my_super_api].namespaces).to eq prefix: 'api', version: 'v1'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when block is not given' do
|
50
|
+
it 'raises no block given exception' do
|
51
|
+
expect {
|
52
|
+
Jeckle::Setup.register(:my_api)
|
53
|
+
}.to raise_exception(LocalJumpError)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
if ENV['CODECLIMATE_REPO_TOKEN']
|
2
|
+
require 'codeclimate-test-reporter'
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
end
|
5
|
+
|
1
6
|
require 'bundler/setup'
|
2
|
-
|
3
|
-
|
7
|
+
require 'jeckle'
|
8
|
+
|
9
|
+
Dir['spec/support/**/*.rb'].each { |file| require File.expand_path(file) }
|
10
|
+
|
11
|
+
require 'fixtures/jeckle_config'
|
12
|
+
|
13
|
+
Dir['spec/fixtures/**/*.rb'].each { |file| require File.expand_path(file) }
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.disable_monkey_patching!
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
RSpec.shared_examples_for Jeckle::Request do
|
2
|
+
let(:api_params) { api.params.stringify_keys }
|
3
|
+
|
4
|
+
before do
|
5
|
+
allow_any_instance_of(Faraday::Request).to receive(:params=).with(any_args).and_call_original
|
6
|
+
allow_any_instance_of(Faraday::Request).to receive(:headers=).with(any_args).and_call_original
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'sets request URL' do
|
10
|
+
expect_any_instance_of(Faraday::Request).to receive(:url).with endpoint
|
11
|
+
|
12
|
+
described_class.run api, endpoint, options
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets global api params defined via register block' do
|
16
|
+
expect_any_instance_of(Faraday::Request).to receive(:params=).with(api_params).
|
17
|
+
at_least(:once).and_call_original
|
18
|
+
|
19
|
+
described_class.run api, endpoint, options
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'sets request params' do
|
23
|
+
expect_any_instance_of(Faraday::Request).to receive(:params=).with(options).
|
24
|
+
at_least(:once).and_call_original
|
25
|
+
|
26
|
+
described_class.run api, endpoint, options
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets global api headers defined via register block' do
|
30
|
+
expect_any_instance_of(Faraday::Request).to receive(:headers=).with(api.connection.headers).
|
31
|
+
at_least(:once).and_call_original
|
32
|
+
|
33
|
+
described_class.run api, endpoint, options
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when has headers option' do
|
37
|
+
let(:options) { { headers: { 'Accept' => 'application/json' } } }
|
38
|
+
let(:expected_headers) { api.connection.headers.merge options[:headers] }
|
39
|
+
|
40
|
+
it 'merges request headers with global api headers' do
|
41
|
+
expect_any_instance_of(Faraday::Request).to receive(:headers=).with(expected_headers).
|
42
|
+
at_least(:once).and_call_original
|
43
|
+
|
44
|
+
described_class.run api, endpoint, options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,85 +1,86 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeckle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas D'Stefano
|
8
|
+
- Brenno Costa
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-10-09 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: activemodel
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
18
|
- - '>='
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
+
version: '4.0'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - '>='
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
+
version: '4.0'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
+
name: faraday
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- -
|
32
|
+
- - ~>
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
+
version: '0.9'
|
34
35
|
type: :runtime
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- -
|
39
|
+
- - ~>
|
39
40
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
+
version: '0.9'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
+
name: faraday_middleware
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
46
|
- - '>='
|
46
47
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
+
version: '0'
|
48
49
|
type: :runtime
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
53
|
- - '>='
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
+
version: '0'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
+
name: virtus
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- -
|
60
|
+
- - ~>
|
60
61
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
+
version: '1.0'
|
62
63
|
type: :runtime
|
63
64
|
prerelease: false
|
64
65
|
version_requirements: !ruby/object:Gem::Requirement
|
65
66
|
requirements:
|
66
|
-
- -
|
67
|
+
- - ~>
|
67
68
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
69
|
+
version: '1.0'
|
69
70
|
- !ruby/object:Gem::Dependency
|
70
71
|
name: bundler
|
71
72
|
requirement: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
74
|
- - ~>
|
74
75
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1.
|
76
|
+
version: '1.6'
|
76
77
|
type: :development
|
77
78
|
prerelease: false
|
78
79
|
version_requirements: !ruby/object:Gem::Requirement
|
79
80
|
requirements:
|
80
81
|
- - ~>
|
81
82
|
- !ruby/object:Gem::Version
|
82
|
-
version: '1.
|
83
|
+
version: '1.6'
|
83
84
|
- !ruby/object:Gem::Dependency
|
84
85
|
name: rake
|
85
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,6 +97,20 @@ dependencies:
|
|
96
97
|
version: '0'
|
97
98
|
- !ruby/object:Gem::Dependency
|
98
99
|
name: rspec
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '3.1'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '3.1'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: pry-byebug
|
99
114
|
requirement: !ruby/object:Gem::Requirement
|
100
115
|
requirements:
|
101
116
|
- - '>='
|
@@ -108,23 +123,41 @@ dependencies:
|
|
108
123
|
- - '>='
|
109
124
|
- !ruby/object:Gem::Version
|
110
125
|
version: '0'
|
111
|
-
description: Simple module for
|
126
|
+
description: Simple module for building client APIs
|
112
127
|
email:
|
113
128
|
- tomas_stefano@successoft.com
|
129
|
+
- brennolncosta@gmail.com
|
114
130
|
executables: []
|
115
131
|
extensions: []
|
116
132
|
extra_rdoc_files: []
|
117
133
|
files:
|
118
134
|
- .gitignore
|
135
|
+
- .rspec
|
136
|
+
- .travis.yml
|
119
137
|
- Gemfile
|
120
138
|
- LICENSE.txt
|
121
139
|
- README.md
|
122
140
|
- Rakefile
|
141
|
+
- examples/dribbble.rb
|
123
142
|
- jeckle.gemspec
|
124
143
|
- lib/jeckle.rb
|
144
|
+
- lib/jeckle/api.rb
|
145
|
+
- lib/jeckle/errors.rb
|
146
|
+
- lib/jeckle/model.rb
|
147
|
+
- lib/jeckle/request.rb
|
125
148
|
- lib/jeckle/resource.rb
|
149
|
+
- lib/jeckle/setup.rb
|
126
150
|
- lib/jeckle/version.rb
|
151
|
+
- spec/fixtures/jeckle_config.rb
|
152
|
+
- spec/fixtures/models/fake_model.rb
|
153
|
+
- spec/fixtures/resources/fake_resource.rb
|
154
|
+
- spec/jeckle/api_spec.rb
|
155
|
+
- spec/jeckle/model_spec.rb
|
156
|
+
- spec/jeckle/request_spec.rb
|
157
|
+
- spec/jeckle/resource_spec.rb
|
158
|
+
- spec/jeckle/setup_spec.rb
|
127
159
|
- spec/spec_helper.rb
|
160
|
+
- spec/support/shared_examples.rb
|
128
161
|
homepage: https://github.com/tomas-stefano/jeckle
|
129
162
|
licenses:
|
130
163
|
- MIT
|
@@ -148,6 +181,15 @@ rubyforge_project:
|
|
148
181
|
rubygems_version: 2.0.5
|
149
182
|
signing_key:
|
150
183
|
specification_version: 4
|
151
|
-
summary: Simple module for
|
184
|
+
summary: Simple module for building client APIs
|
152
185
|
test_files:
|
186
|
+
- spec/fixtures/jeckle_config.rb
|
187
|
+
- spec/fixtures/models/fake_model.rb
|
188
|
+
- spec/fixtures/resources/fake_resource.rb
|
189
|
+
- spec/jeckle/api_spec.rb
|
190
|
+
- spec/jeckle/model_spec.rb
|
191
|
+
- spec/jeckle/request_spec.rb
|
192
|
+
- spec/jeckle/resource_spec.rb
|
193
|
+
- spec/jeckle/setup_spec.rb
|
153
194
|
- spec/spec_helper.rb
|
195
|
+
- spec/support/shared_examples.rb
|