api-client 1.9.1 → 1.10.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.
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