api-client 1.9.1 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .coveralls.yml
6
7
  *.swp
7
8
  Gemfile.lock
8
9
  InstalledFiles
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ api-client
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p429
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ApiClient
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/zertico/api-client.png?branch=master)](http://travis-ci.org/zertico/api-client) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/zertico/api-client)
3
+ [![Gem Version](https://badge.fury.io/rb/api-client.png)](http://badge.fury.io/rb/api-client) [![Build Status](https://secure.travis-ci.org/zertico/api-client.png?branch=master)](http://travis-ci.org/zertico/api-client) [![Dependency Status](https://gemnasium.com/zertico/api-client.png)](https://gemnasium.com/zertico/api-client) [![Coverage Status](https://coveralls.io/repos/zertico/api-client/badge.png?branch=master)](https://coveralls.io/r/zertico/api-client) [![Code Climate](https://codeclimate.com/github/zertico/api-client.png)](https://codeclimate.com/github/zertico/api-client)
4
4
 
5
5
  ApiClient handle all the logic necessary to call Some API, catch the response and initialize an object with it for you.
6
6
  It is possible to use Typhoeus or the native Ruby Library Net::Http.
data/api-client.gemspec CHANGED
@@ -6,7 +6,6 @@ Gem::Specification.new do |gem|
6
6
  gem.version = ApiClient::VERSION
7
7
  gem.authors = %q{Paulo Henrique Lopes Ribeiro}
8
8
  gem.email = %q{plribeiro3000@gmail.com}
9
- gem.homepage = ""
10
9
  gem.summary = %q{Client to make Api calls}
11
10
 
12
11
  gem.files = `git ls-files`.split("\n")
@@ -18,6 +17,7 @@ Gem::Specification.new do |gem|
18
17
  gem.add_development_dependency "webmock"
19
18
  gem.add_development_dependency "rspec"
20
19
  gem.add_development_dependency "yard"
20
+ gem.add_development_dependency "coveralls"
21
21
 
22
22
  gem.add_runtime_dependency "activemodel"
23
23
  gem.add_runtime_dependency "json_pure"
@@ -1,5 +1,3 @@
1
1
  source :rubygems
2
2
 
3
- gem 'typhoeus', '0.4.2'
4
-
5
- gemspec :path => '../'
3
+ gemspec :path => '../'
data/lib/api-client.rb CHANGED
@@ -4,7 +4,27 @@ require "api-client/version"
4
4
  module ApiClient
5
5
  autoload :Exceptions, 'api-client/exceptions'
6
6
  autoload :Errors, 'api-client/errors'
7
+ autoload :Configuration, 'api-client/configuration'
7
8
  autoload :Base, 'api-client/base'
9
+ autoload :Collection, 'api-client/collection'
8
10
  autoload :Dispatcher, 'api-client/dispatcher'
9
11
  autoload :Parser, 'api-client/parser'
10
- end
12
+ autoload :Builder, 'api-client/builder'
13
+
14
+ # Configures global settings
15
+ # ApiClient.configure do |config|
16
+ # config.url_path = "api.example.com"
17
+ # end
18
+ def self.configure(&block)
19
+ yield @config ||= ApiClient::Configuration.new
20
+ end
21
+
22
+ # Global settings for ApiClient
23
+ def self.config
24
+ @config
25
+ end
26
+
27
+ configure do |config|
28
+ config.path = ''
29
+ end
30
+ end
@@ -12,6 +12,8 @@ module ApiClient
12
12
  include ActiveModel::Conversion
13
13
  extend ActiveModel::Naming
14
14
 
15
+ extend ApiClient::Builder
16
+
15
17
  # @return [Hash] the request response.
16
18
  attr_accessor :response
17
19
 
@@ -23,7 +25,7 @@ module ApiClient
23
25
  # @param [Hash] attributes object attributes.
24
26
  # @return [Base] the object initialized.
25
27
  def initialize(attributes = {})
26
- @errors = Errors.new(self)
28
+ @errors = ApiClient::Errors.new(self)
27
29
  attributes.each do |name, value|
28
30
  send("#{name.to_s}=", value)
29
31
  end
@@ -36,6 +38,22 @@ module ApiClient
36
38
  false
37
39
  end
38
40
 
41
+ # Return the path of the object on the api url.
42
+ #
43
+ # @return [String] the api path for this object.
44
+ def self.path
45
+ return self.to_s.gsub("::", "/").downcase.pluralize unless @path
46
+ @path
47
+ end
48
+
49
+ # Set the path of the object on the api url.
50
+ #
51
+ # @param [String] path string.
52
+ def self.path=(path)
53
+ path = path[1, path.size - 1] if path[0, 1] == "/"
54
+ @path = path
55
+ end
56
+
39
57
  # Return the Remote Object Name.
40
58
  #
41
59
  # @return [String] a string with the remote object class name.
@@ -91,13 +109,20 @@ module ApiClient
91
109
  #
92
110
  # @return [Hash] instance variables and its values.
93
111
  def attributes
94
- attributes = {}
95
- self.class.instance_variable_get("@attributes").map { |attribute| attributes[attribute.to_sym] = self.send("#{attribute}") }
96
- attributes
112
+ self.class.instance_variable_get("@attributes").inject({}) { |hash, attribute| hash.merge(attribute.to_sym => self.send("#{attribute}")) }
97
113
  end
98
114
 
99
115
  alias_method :to_hash, :attributes
100
116
 
117
+ # Initialize a collection of objects. The collection will be an ApiClient::Collection object.
118
+ # The objects in the collection will be all instances of this (ApiClient::Base) class.
119
+ #
120
+ # @param [String] url to get the collection.
121
+ # @return [Collection] a collection of objects.
122
+ def self.collection(url)
123
+ ApiClient::Collection.new(self, url).collection
124
+ end
125
+
101
126
  # Set the hash of errors, making keys symbolic.
102
127
  #
103
128
  # @param [Hash] errors of the object.
@@ -108,13 +133,8 @@ module ApiClient
108
133
  protected
109
134
 
110
135
  def self.method_missing(method, *args)
111
- @response = Parser.response(Dispatcher.send(method, *args), *args[0])
112
- case true
113
- when @response.instance_of?(Array) then return @response.map { |a| new(a.merge(:response => @response)) }
114
- when @response.key?(remote_object) then return new(@response[remote_object].merge(:response => @response))
115
- when @response.key?(remote_object.pluralize) then return @response[remote_object.pluralize].map { |a| new(a.merge(:response => @response)) }
116
- else return new(@response.merge(:response => @response))
117
- end
136
+ @response = ApiClient::Parser.response(ApiClient::Dispatcher.send(method, *args), *args[0])
137
+ build(self, @response)
118
138
  end
119
139
  end
120
140
  end
@@ -0,0 +1,12 @@
1
+ module ApiClient
2
+ module Builder
3
+ def build(object, params)
4
+ case true
5
+ when params.instance_of?(Array) then return params.map { |a| new(a.merge(:response => params)) }
6
+ when params.key?(remote_object) then return new(params[remote_object].merge(:response => params))
7
+ when params.key?(remote_object.pluralize) then return params[remote_object.pluralize].map { |a| new(a.merge(:response => params)) }
8
+ else return new(params.merge(:response => params))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # ApiClient::Collection handle a collection of objects
2
+ class ApiClient::Collection
3
+ include Enumerable
4
+
5
+ attr_accessor :collection
6
+
7
+ # Initialize a collection of given objects
8
+ #
9
+ # @param [Class] The class to instantiate the objects.
10
+ # @param [String] The url to get the data.
11
+ # @return [Collection] the collection of objects.
12
+ def initialize(klass, url)
13
+ @collection = ApiClient::Parser.response(ApiClient::Dispatcher.get(url), url)
14
+ @collection.map! do |attributes|
15
+ klass.new(attributes)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module ApiClient
2
+ # ApiClient::Configuration provides a way to configure ApiClient globally.
3
+ class Configuration
4
+ # Return the api url.
5
+ #
6
+ # @return [String] the api url.
7
+ def path
8
+ raise Exceptions::NotConfigured unless @path.size > 1
9
+ @path
10
+ end
11
+
12
+ # Set the api url.
13
+ #
14
+ # @param [String] api url.
15
+ def path=(path)
16
+ path = "#{path}/" unless path[path.size - 1, 1] == "/"
17
+ @path = path
18
+ end
19
+ end
20
+ end
@@ -5,9 +5,9 @@ module ApiClient::Dispatcher
5
5
 
6
6
  def self.method_missing(method, *args)
7
7
  if defined?(::Typhoeus)
8
- Typhoeus.send(method, *args)
8
+ Typhoeus.send(method, *args)
9
9
  else
10
- NetHttp.send(method, *args)
10
+ NetHttp.send(method, *args)
11
11
  end
12
12
  end
13
13
  end
@@ -8,4 +8,5 @@ module ApiClient::Exceptions
8
8
  autoload :BadGateway, 'api-client/exceptions/bad_gateway'
9
9
  autoload :ServiceUnavailable, 'api-client/exceptions/service_unavailable'
10
10
  autoload :ConnectionRefused, 'api-client/exceptions/connection_refused'
11
- end
11
+ autoload :NotConfigured, 'api-client/exceptions/not_configured'
12
+ end
@@ -0,0 +1,9 @@
1
+ # Exception for requests where the full path is not properly configured.
2
+ class ApiClient::Exceptions::NotConfigured < StandardError
3
+ # Initialize a new exception.
4
+ #
5
+ # @return [NotConfigured] a new exception.
6
+ def self.initialize
7
+ super("The api path is not properly configured!")
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  # High Level Namespace of the library ApiClient.
2
2
  module ApiClient
3
3
  # Version of the library.
4
- VERSION = "1.9.1"
4
+ VERSION = "1.10.0"
5
5
  end
@@ -1,6 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ApiClient::Base do
4
+ let(:user) { User.new }
5
+ let(:collection) { Object.new }
6
+
4
7
  describe "#initialize" do
5
8
  context "with a hash {:a => 'a', :b => 'b'}" do
6
9
  before :each do
@@ -21,6 +24,46 @@ describe ApiClient::Base do
21
24
  end
22
25
  end
23
26
 
27
+ describe "#path" do
28
+ describe "when not configured" do
29
+ it "should return a name based on the class name" do
30
+ User.path.should == "users"
31
+ end
32
+ end
33
+
34
+ describe "when properly configured" do
35
+ before :each do
36
+ User.path = "admins"
37
+ end
38
+
39
+ it "should return the path value" do
40
+ User.path.should == "admins"
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#path=" do
46
+ describe "with a string without '/'" do
47
+ before :each do
48
+ User.path = "users"
49
+ end
50
+
51
+ it "should set it as passed" do
52
+ User.path.should == "users"
53
+ end
54
+ end
55
+
56
+ describe "with a string with '/'" do
57
+ before :each do
58
+ User.path = "/users"
59
+ end
60
+
61
+ it "should set it without the '/'" do
62
+ User.path.should == "users"
63
+ end
64
+ end
65
+ end
66
+
24
67
  describe "#remote_object" do
25
68
  context "on a class without remote object specification" do
26
69
  it "should return the class name" do
@@ -73,6 +116,17 @@ describe ApiClient::Base do
73
116
  end
74
117
  end
75
118
 
119
+ describe "#collection" do
120
+ before :each do
121
+ ApiClient::Collection.stub(:new).with(User, "http://api.example.com").and_return(collection)
122
+ collection.stub(:collection => [ user, user ])
123
+ end
124
+
125
+ it "should return a collection of objects" do
126
+ User.collection("http://api.example.com").should == [ user, user ]
127
+ end
128
+ end
129
+
76
130
  describe "#errors=" do
77
131
  before :each do
78
132
  @user = User.new(:errors => { "a" => "message", "b" => "message" })
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiClient::Collection do
4
+ let(:user) { User.new }
5
+
6
+ before :each do
7
+ stub_request(:get, "http://api.example.com").to_return(:body => [ {"a" => "b"}, {"a" => "b2"} ].to_json)
8
+ User.stub(:new => user)
9
+ @collection = ApiClient::Collection.new(User, "http://api.example.com")
10
+ end
11
+
12
+ it "should include enumerable module" do
13
+ @collection.should respond_to(:first)
14
+ end
15
+
16
+ describe "#initialize" do
17
+ it "Should initialize a collection of Objects" do
18
+ @collection.collection.should == [user, user]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiClient::Configuration do
4
+ describe "#path" do
5
+ describe "when not configured" do
6
+ it "should raise an error" do
7
+ lambda { ApiClient.config.path }.should raise_error(ApiClient::Exceptions::NotConfigured)
8
+ end
9
+ end
10
+
11
+ describe "when properly configured" do
12
+ before :each do
13
+ ApiClient.configure do |config|
14
+ config.path = "api.example.com"
15
+ end
16
+ end
17
+
18
+ it "should return the path value" do
19
+ ApiClient.config.path.should_not be_nil
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#path=" do
25
+ describe "with a string without '/'" do
26
+ before :each do
27
+ ApiClient.config.path = "api.example.com"
28
+ end
29
+
30
+ it "should set it with a '/'" do
31
+ ApiClient.config.path.should == "api.example.com/"
32
+ end
33
+ end
34
+
35
+ describe "with a string with '/'" do
36
+ before :each do
37
+ ApiClient.config.path = "api.example.com/"
38
+ end
39
+
40
+ it "should set it as passed" do
41
+ ApiClient.config.path.should == "api.example.com/"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -31,7 +31,7 @@ describe ApiClient::Parser do
31
31
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
32
32
  end
33
33
 
34
- it "should return a Unauthorized exception" do
34
+ it "should raise a Unauthorized exception" do
35
35
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::Unauthorized)
36
36
  end
37
37
  end
@@ -42,7 +42,7 @@ describe ApiClient::Parser do
42
42
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
43
43
  end
44
44
 
45
- it "should return a Forbidden exception" do
45
+ it "should raise a Forbidden exception" do
46
46
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::Forbidden)
47
47
  end
48
48
  end
@@ -53,7 +53,7 @@ describe ApiClient::Parser do
53
53
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
54
54
  end
55
55
 
56
- it "should return a NotFound exception" do
56
+ it "should raise a NotFound exception" do
57
57
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::NotFound, "http://api.example.com/user/5")
58
58
  end
59
59
  end
@@ -64,7 +64,7 @@ describe ApiClient::Parser do
64
64
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
65
65
  end
66
66
 
67
- it "should return a InternalServerError exception" do
67
+ it "should raise a InternalServerError exception" do
68
68
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::InternalServerError)
69
69
  end
70
70
  end
@@ -75,7 +75,7 @@ describe ApiClient::Parser do
75
75
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
76
76
  end
77
77
 
78
- it "should return a BadGateway exception" do
78
+ it "should raise a BadGateway exception" do
79
79
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::BadGateway)
80
80
  end
81
81
  end
@@ -86,7 +86,7 @@ describe ApiClient::Parser do
86
86
  @response = ApiClient::Dispatcher.get('http://api.example.com/user/5')
87
87
  end
88
88
 
89
- it "should return a ServiceUnavailable exception" do
89
+ it "should raise a ServiceUnavailable exception" do
90
90
  lambda { ApiClient::Parser.response(@response, 'http://api.example.com/user/5') }.should raise_error(ApiClient::Exceptions::ServiceUnavailable)
91
91
  end
92
92
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require "rspec"
2
- require 'webmock/rspec'
2
+ require "webmock/rspec"
3
3
  require "json"
4
+ require "coveralls"
5
+
6
+ Coveralls.wear!
4
7
 
5
8
  require File.dirname(__FILE__) + "/../lib/api-client"
6
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-23 00:00:00.000000000 Z
12
+ date: 2013-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: coveralls
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  - !ruby/object:Gem::Dependency
79
95
  name: activemodel
80
96
  requirement: !ruby/object:Gem::Requirement
@@ -115,7 +131,8 @@ extra_rdoc_files: []
115
131
  files:
116
132
  - .gitignore
117
133
  - .rspec
118
- - .rvmrc
134
+ - .ruby-gemset
135
+ - .ruby-version
119
136
  - .travis.yml
120
137
  - CHANGELOG.md
121
138
  - Gemfile
@@ -132,6 +149,9 @@ files:
132
149
  - gemfiles/Gemfile.typhoeus
133
150
  - lib/api-client.rb
134
151
  - lib/api-client/base.rb
152
+ - lib/api-client/builder.rb
153
+ - lib/api-client/collection.rb
154
+ - lib/api-client/configuration.rb
135
155
  - lib/api-client/dispatcher.rb
136
156
  - lib/api-client/dispatcher/net-http.rb
137
157
  - lib/api-client/dispatcher/typhoeus.rb
@@ -142,6 +162,7 @@ files:
142
162
  - lib/api-client/exceptions/forbidden.rb
143
163
  - lib/api-client/exceptions/generic.rb
144
164
  - lib/api-client/exceptions/internal_server_error.rb
165
+ - lib/api-client/exceptions/not_configured.rb
145
166
  - lib/api-client/exceptions/not_found.rb
146
167
  - lib/api-client/exceptions/service_unavailable.rb
147
168
  - lib/api-client/exceptions/unauthorized.rb
@@ -149,11 +170,13 @@ files:
149
170
  - lib/api-client/parser.rb
150
171
  - lib/api-client/version.rb
151
172
  - spec/api-client/base_spec.rb
173
+ - spec/api-client/collection_spec.rb
174
+ - spec/api-client/configuration_spec.rb
152
175
  - spec/api-client/dispatcher_spec.rb
153
176
  - spec/api-client/errors_spec.rb
154
177
  - spec/api-client/parser_spec.rb
155
178
  - spec/spec_helper.rb
156
- homepage: ''
179
+ homepage:
157
180
  licenses: []
158
181
  post_install_message:
159
182
  rdoc_options: []
@@ -167,7 +190,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
167
190
  version: '0'
168
191
  segments:
169
192
  - 0
170
- hash: -1190097789751108706
193
+ hash: 4163480247094767209
171
194
  required_rubygems_version: !ruby/object:Gem::Requirement
172
195
  none: false
173
196
  requirements:
@@ -176,10 +199,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
199
  version: '0'
177
200
  segments:
178
201
  - 0
179
- hash: -1190097789751108706
202
+ hash: 4163480247094767209
180
203
  requirements: []
181
204
  rubyforge_project:
182
- rubygems_version: 1.8.24
205
+ rubygems_version: 1.8.25
183
206
  signing_key:
184
207
  specification_version: 3
185
208
  summary: Client to make Api calls
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use 1.9.3@api-client