otis 0.0.4 → 0.0.5
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 +15 -0
- data/README.md +3 -1
- data/lib/otis.rb +2 -0
- data/lib/otis/client.rb +8 -1
- data/lib/otis/hooks.rb +23 -0
- data/lib/otis/http_client.rb +8 -3
- data/lib/otis/model.rb +3 -1
- data/lib/otis/otis_object.rb +13 -5
- data/lib/otis/response.rb +4 -0
- data/lib/otis/version.rb +1 -1
- data/otis.gemspec +1 -0
- data/spec/lib/otis/client_spec.rb +25 -0
- data/spec/lib/otis/hash_content_spec.rb +34 -0
- data/spec/lib/otis/http_client_spec.rb +13 -10
- data/spec/lib/otis/model_spec.rb +0 -31
- data/spec/lib/otis/otis_object_spec.rb +24 -0
- data/spec/lib/otis/soap_client_spec.rb +1 -1
- metadata +27 -19
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjNlNDM2YzIxMTJhOTU3M2QzMjRjMTFjM2ZiOGVhYjc3N2NmYTRmYw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NWJmNjRiNDk0YmY3NTdkOTA5NzY2ZjEwOTAyYjk4NTczNGNkYzVjZg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmZlYzU1M2E5MzYxYTg0MmI3NDI4MDBhMzBkNDcwZDUxM2IyNWQxNGRlMWNi
|
10
|
+
NDk1NThmYTVkMjIzNTM4MDZlMDM0YWJjYTBkYjdmNTJkZmNiZDhhZmY4ZmUz
|
11
|
+
NTMzMGFhMzY4ZmJlMGUyZTI4NTJlZDM3ZDRmNWRjMWRjNzk2YTc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Yzg3NjgxYTc4YTJlN2MxZGU5Y2M4M2Y4YWE5NzkxN2RhYTgyMzQ3NzZlZjE5
|
14
|
+
MGE5NzZiMTM3YWZhOWYzMGM0OTFkZTJjNzRlZDk2ZTUxOWQzZDM0NWZlOTk0
|
15
|
+
YjhlOTc0ZmEzNzNjMGEzODJkYjE0ZjQwODNlODc1MzY4YzlkZmI=
|
data/README.md
CHANGED
@@ -32,10 +32,12 @@ Using the example of [US Zip webservice](https://github.com/tbueno/otis_uszip_ex
|
|
32
32
|
})
|
33
33
|
|
34
34
|
### Client
|
35
|
-
Otis offers a base Client class that handle the response and instantiates the response object accordingly.
|
35
|
+
Otis offers a base Client class that handle the response and instantiates the response object accordingly. In the following example, a SOAP client is instantiated with the proper WSDL
|
36
36
|
|
37
37
|
Otis::Client.new(routes, "http://www.webservicex.net/uszip.asmx?WSDL")
|
38
38
|
|
39
|
+
HTTP clients can also be used as well
|
40
|
+
|
39
41
|
### Model
|
40
42
|
|
41
43
|
The Client takes care of transforming the API response into a Hash. Having hashes, makes it easy to create response objects, called Otis::Model.
|
data/lib/otis.rb
CHANGED
data/lib/otis/client.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
module Otis
|
2
2
|
class Client
|
3
|
+
include Hooks
|
4
|
+
|
3
5
|
protected
|
4
6
|
# Tries to find the requested method in the routes map.
|
5
7
|
# Send it to Object$method_missing if the desired route is not found
|
6
8
|
def method_missing(meth, *args)
|
7
9
|
klass = @routes[meth.to_sym]
|
8
10
|
super unless klass
|
9
|
-
|
11
|
+
if respond_to?("filter_for_#{meth}")
|
12
|
+
filter_meth = send("filter_for_#{meth}")
|
13
|
+
send(filter_meth, call(meth, *args))
|
14
|
+
else
|
15
|
+
klass.new(call(meth, *args))
|
16
|
+
end
|
10
17
|
end
|
11
18
|
end
|
12
19
|
end
|
data/lib/otis/hooks.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Otis
|
2
|
+
module Hooks
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassExtension)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassExtension
|
9
|
+
#
|
10
|
+
# Filter the response of a method with another method
|
11
|
+
#
|
12
|
+
def filter(meth, options = {})
|
13
|
+
meth = meth.to_s
|
14
|
+
class_eval %(
|
15
|
+
def filter_for_#{meth}
|
16
|
+
"#{options[:with]}"
|
17
|
+
end
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/otis/http_client.rb
CHANGED
@@ -12,9 +12,14 @@ module Otis
|
|
12
12
|
end
|
13
13
|
|
14
14
|
protected
|
15
|
-
def call(action, options)
|
16
|
-
response = @client.get "#{
|
17
|
-
|
15
|
+
def call(action, url, options)
|
16
|
+
response = @client.get "#{url}", options, {'Content-Type' => 'application/json'}
|
17
|
+
respond(response)
|
18
|
+
end
|
19
|
+
|
20
|
+
#TODO: make it more robust
|
21
|
+
def respond(response)
|
22
|
+
response.status == 304 ? {} : JSON.parse(response.body).merge(headers: response.headers)
|
18
23
|
end
|
19
24
|
|
20
25
|
def create_client(url)
|
data/lib/otis/model.rb
CHANGED
data/lib/otis/otis_object.rb
CHANGED
@@ -10,11 +10,6 @@ module Otis
|
|
10
10
|
attrs.each_pair do |k, v|
|
11
11
|
m = underscore(k.to_s)
|
12
12
|
self.send("#{m}=", v ) if self.respond_to?("#{m}=")
|
13
|
-
end if respond_to?(:decamelize?) and decamelize?
|
14
|
-
if respond_to?(:hooks)
|
15
|
-
hooks.each do |hook|
|
16
|
-
self.send(hook)
|
17
|
-
end
|
18
13
|
end
|
19
14
|
end
|
20
15
|
|
@@ -24,6 +19,19 @@ module Otis
|
|
24
19
|
class_eval %(attr_accessor :#{m} )
|
25
20
|
end
|
26
21
|
end
|
22
|
+
|
23
|
+
def collection(opts ={})
|
24
|
+
collection = opts[:as].to_s
|
25
|
+
klass = opts[:of]
|
26
|
+
class_eval %(def #{collection}; @#{collection} ||= Array(@response['#{camelize(collection)}']).map{|c| #{klass}.new(c)}; end)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def camelize(string)
|
31
|
+
return string if string !~ /_/ && self =~ /[A-Z]+.*/
|
32
|
+
string.split('_').map{|e| e.capitalize}.join
|
33
|
+
end
|
34
|
+
|
27
35
|
end
|
28
36
|
|
29
37
|
private
|
data/lib/otis/version.rb
CHANGED
data/otis.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "debugger"
|
24
|
+
spec.add_development_dependency "rspec"
|
24
25
|
|
25
26
|
spec.add_dependency 'savon', '~> 2.2.0'
|
26
27
|
spec.add_dependency 'faraday'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Otis::Hooks do
|
4
|
+
|
5
|
+
|
6
|
+
class TestClient < Otis::Client
|
7
|
+
filter :my_method, with: :my_filter
|
8
|
+
def initialize(routes); @routes = routes; end
|
9
|
+
def my_filter(content); content[:foo].upcase! ;end
|
10
|
+
def call(action, url, options)
|
11
|
+
{foo: 'bar'}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'filter' do
|
16
|
+
|
17
|
+
let(:response) { double }
|
18
|
+
|
19
|
+
it 'executes filters with results of method' do
|
20
|
+
object = TestClient.new(my_method: response)
|
21
|
+
expect(object.my_method(double, double)).to eq('BAR')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Otis::HashContent do
|
4
|
+
describe 'accessor generation' do
|
5
|
+
let(:params) do {a: {b: {foo: 'bar'}}} end
|
6
|
+
|
7
|
+
class ComplexClass < Otis::Model
|
8
|
+
root_key to: [:a, :b]
|
9
|
+
attribute :foo, String
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'creates an array to the root key' do
|
13
|
+
ComplexClass.new(params).path.should == [:a, :b]
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets the root key' do
|
17
|
+
ComplexClass.new(params).foo.should == 'bar'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'remaping root key name' do
|
22
|
+
|
23
|
+
let(:params) do {a: {b: {foo: 'bar'}}} end
|
24
|
+
|
25
|
+
class EvenMoreComplex < Otis::Model
|
26
|
+
root_key to: [:a, :b], as: 'baz'
|
27
|
+
attribute :baz, String
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'response accordingly' do
|
31
|
+
EvenMoreComplex.new(params).baz.should == {foo: 'bar'}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -23,7 +23,7 @@ describe Otis::HttpClient do
|
|
23
23
|
let(:url) { 'http://api.site.com' }
|
24
24
|
|
25
25
|
it 'instantiate a faraday client with endpoint url' do
|
26
|
-
Faraday.
|
26
|
+
expect(Faraday).to receive(:new).with(url: url)
|
27
27
|
described_class.new(map, url)
|
28
28
|
end
|
29
29
|
|
@@ -47,25 +47,28 @@ describe Otis::HttpClient do
|
|
47
47
|
|
48
48
|
describe 'call' do
|
49
49
|
|
50
|
-
let(:faraday)
|
51
|
-
let(:
|
52
|
-
let(:
|
50
|
+
let(:faraday) { double(get: response) }
|
51
|
+
let(:url) { 'api/v1' }
|
52
|
+
let(:params) { { param1: 'foo', param2: 'bar' } }
|
53
|
+
let(:response) { double(body: "{ \"my_call\": \"response\"}",
|
54
|
+
status: 200, headers: {}) }
|
55
|
+
let(:routes) { Otis::Map.new({ my_call: ResponseClass } ) }
|
53
56
|
|
54
57
|
before { Otis::HttpClient.any_instance.stub(create_client: faraday)}
|
55
58
|
|
56
59
|
it 'forwards the call to the client' do
|
57
|
-
faraday.
|
58
|
-
MyHttpClient.new(routes, 'url').my_call(
|
60
|
+
expect(faraday).to receive(:get).with(url, params, {'Content-Type' => 'application/json'})
|
61
|
+
MyHttpClient.new(routes, 'url').my_call(url, params)
|
59
62
|
end
|
60
63
|
|
61
64
|
it 'returns response object' do
|
62
|
-
MyHttpClient.new(routes, 'url').my_call(
|
63
|
-
.
|
65
|
+
expect(MyHttpClient.new(routes, 'url').my_call(url, params))
|
66
|
+
.to be_a(ResponseClass)
|
64
67
|
end
|
65
68
|
|
66
69
|
it 'passes the parsed response to response object' do
|
67
|
-
ResponseClass.should_receive(:new).with({'my_call' => 'response'})
|
68
|
-
MyHttpClient.new(routes, 'url').my_call(
|
70
|
+
ResponseClass.should_receive(:new).with({'my_call' => 'response', :headers => {}})
|
71
|
+
MyHttpClient.new(routes, 'url').my_call(url, params)
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
data/spec/lib/otis/model_spec.rb
CHANGED
@@ -13,35 +13,4 @@ describe Otis::Model do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
17
|
-
describe 'accessor generation' do
|
18
|
-
let(:params) do {a: {b: {foo: 'bar'}}} end
|
19
|
-
|
20
|
-
class ComplexClass < Otis::Model
|
21
|
-
root_key to: [:a, :b]
|
22
|
-
attribute :foo, String
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'creates an array to the root key' do
|
26
|
-
ComplexClass.new(params).path.should == [:a, :b]
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'sets the root key' do
|
30
|
-
ComplexClass.new(params).foo.should == 'bar'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe 'remaping root key name' do
|
35
|
-
|
36
|
-
let(:params) do {a: {b: {foo: 'bar'}}} end
|
37
|
-
|
38
|
-
class EvenMoreComplex < Otis::Model
|
39
|
-
root_key to: [:a, :b], as: 'baz'
|
40
|
-
attribute :baz, String
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'response accordingly' do
|
44
|
-
EvenMoreComplex.new(params).baz.should == {foo: 'bar'}
|
45
|
-
end
|
46
|
-
end
|
47
16
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Otis::Object do
|
4
|
+
|
5
|
+
describe 'collection' do
|
6
|
+
class Thing; end
|
7
|
+
|
8
|
+
class TestClass
|
9
|
+
include Otis::Object
|
10
|
+
collection of: Thing, as: :things
|
11
|
+
end
|
12
|
+
let(:klass) { TestClass.new }
|
13
|
+
|
14
|
+
it 'creates the get' do
|
15
|
+
expect(klass).to respond_to(:things)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'holds a collection' do
|
19
|
+
klass.things << Thing.new
|
20
|
+
klass.things << Thing.new
|
21
|
+
expect(klass.things.count).to eq(2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -23,7 +23,7 @@ describe Otis::SoapClient do
|
|
23
23
|
before { client.stub_chain(:call, :body).and_return(response) }
|
24
24
|
|
25
25
|
it 'delegates the call the the client' do
|
26
|
-
client.should_receive(:call).with(:my_call,
|
26
|
+
client.should_receive(:call).with(:my_call, [:params, []])
|
27
27
|
MySoapClient.new(routes, double).my_call(params: [])
|
28
28
|
end
|
29
29
|
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: otis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.5
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Thiago Bueno
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ! '>='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ! '>='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: debugger
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ! '>='
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,20 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
65
|
requirements:
|
59
66
|
- - ! '>='
|
60
67
|
- !ruby/object:Gem::Version
|
@@ -62,7 +69,6 @@ dependencies:
|
|
62
69
|
- !ruby/object:Gem::Dependency
|
63
70
|
name: savon
|
64
71
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
72
|
requirements:
|
67
73
|
- - ~>
|
68
74
|
- !ruby/object:Gem::Version
|
@@ -70,7 +76,6 @@ dependencies:
|
|
70
76
|
type: :runtime
|
71
77
|
prerelease: false
|
72
78
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
79
|
requirements:
|
75
80
|
- - ~>
|
76
81
|
- !ruby/object:Gem::Version
|
@@ -78,7 +83,6 @@ dependencies:
|
|
78
83
|
- !ruby/object:Gem::Dependency
|
79
84
|
name: faraday
|
80
85
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
86
|
requirements:
|
83
87
|
- - ! '>='
|
84
88
|
- !ruby/object:Gem::Version
|
@@ -86,7 +90,6 @@ dependencies:
|
|
86
90
|
type: :runtime
|
87
91
|
prerelease: false
|
88
92
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
93
|
requirements:
|
91
94
|
- - ! '>='
|
92
95
|
- !ruby/object:Gem::Version
|
@@ -94,7 +97,6 @@ dependencies:
|
|
94
97
|
- !ruby/object:Gem::Dependency
|
95
98
|
name: virtus
|
96
99
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
100
|
requirements:
|
99
101
|
- - ! '>='
|
100
102
|
- !ruby/object:Gem::Version
|
@@ -102,7 +104,6 @@ dependencies:
|
|
102
104
|
type: :runtime
|
103
105
|
prerelease: false
|
104
106
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
107
|
requirements:
|
107
108
|
- - ! '>='
|
108
109
|
- !ruby/object:Gem::Version
|
@@ -123,44 +124,51 @@ files:
|
|
123
124
|
- lib/otis.rb
|
124
125
|
- lib/otis/client.rb
|
125
126
|
- lib/otis/hash_content.rb
|
127
|
+
- lib/otis/hooks.rb
|
126
128
|
- lib/otis/http_client.rb
|
127
129
|
- lib/otis/map.rb
|
128
130
|
- lib/otis/model.rb
|
129
131
|
- lib/otis/otis_object.rb
|
132
|
+
- lib/otis/response.rb
|
130
133
|
- lib/otis/soap_client.rb
|
131
134
|
- lib/otis/version.rb
|
132
135
|
- otis.gemspec
|
136
|
+
- spec/lib/otis/client_spec.rb
|
137
|
+
- spec/lib/otis/hash_content_spec.rb
|
133
138
|
- spec/lib/otis/http_client_spec.rb
|
134
139
|
- spec/lib/otis/model_spec.rb
|
140
|
+
- spec/lib/otis/otis_object_spec.rb
|
135
141
|
- spec/lib/otis/soap_client_spec.rb
|
136
142
|
- spec/spec_helper.rb
|
137
143
|
homepage: ''
|
138
144
|
licenses:
|
139
145
|
- MIT
|
146
|
+
metadata: {}
|
140
147
|
post_install_message:
|
141
148
|
rdoc_options: []
|
142
149
|
require_paths:
|
143
150
|
- lib
|
144
151
|
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
152
|
requirements:
|
147
153
|
- - ! '>='
|
148
154
|
- !ruby/object:Gem::Version
|
149
155
|
version: '0'
|
150
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
-
none: false
|
152
157
|
requirements:
|
153
158
|
- - ! '>='
|
154
159
|
- !ruby/object:Gem::Version
|
155
160
|
version: '0'
|
156
161
|
requirements: []
|
157
162
|
rubyforge_project:
|
158
|
-
rubygems_version: 1.
|
163
|
+
rubygems_version: 2.1.11
|
159
164
|
signing_key:
|
160
|
-
specification_version:
|
165
|
+
specification_version: 4
|
161
166
|
summary: A Ruby Api wrapper framework
|
162
167
|
test_files:
|
168
|
+
- spec/lib/otis/client_spec.rb
|
169
|
+
- spec/lib/otis/hash_content_spec.rb
|
163
170
|
- spec/lib/otis/http_client_spec.rb
|
164
171
|
- spec/lib/otis/model_spec.rb
|
172
|
+
- spec/lib/otis/otis_object_spec.rb
|
165
173
|
- spec/lib/otis/soap_client_spec.rb
|
166
174
|
- spec/spec_helper.rb
|