api-model 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6e80eb51e30b3e5dacade8092adb4e6160224ab4
4
+ data.tar.gz: 91c1d13d150318c136d49c16f19aaa8d491234c6
5
+ SHA512:
6
+ metadata.gz: f584b017ee477b3e5630c2cf73725f77cec863f1e42f522a548f01a1993e6e679f5d81d9c938df44e0ca934a5eed8cc8a037a6d8b94f7ac6aeb71b81c740a7f8
7
+ data.tar.gz: 031a973ad6b657c11bf5ea819a4b6dcf54cacaf56aa9838118cf3cb450aa4750aae41f8cc546cd92c7fd33397380d341c491d2cc132e0719f25122a0649acc02
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ *.gem
5
+ .idea
6
+ *.iml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ api-model (0.0.1)
5
+ activemodel
6
+ activesupport
7
+ typhoeus
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (4.0.1)
13
+ activesupport (= 4.0.1)
14
+ builder (~> 3.1.0)
15
+ activesupport (4.0.1)
16
+ i18n (~> 0.6, >= 0.6.4)
17
+ minitest (~> 4.2)
18
+ multi_json (~> 1.3)
19
+ thread_safe (~> 0.1)
20
+ tzinfo (~> 0.3.37)
21
+ addressable (2.3.5)
22
+ atomic (1.1.14)
23
+ builder (3.1.4)
24
+ coderay (1.0.9)
25
+ crack (0.4.1)
26
+ safe_yaml (~> 0.9.0)
27
+ diff-lcs (1.2.5)
28
+ ethon (0.6.1)
29
+ ffi (>= 1.3.0)
30
+ mime-types (~> 1.18)
31
+ ffi (1.9.0)
32
+ i18n (0.6.5)
33
+ method_source (0.8.2)
34
+ mime-types (1.25.1)
35
+ minitest (4.7.5)
36
+ multi_json (1.8.2)
37
+ pry (0.9.12.2)
38
+ coderay (~> 1.0.5)
39
+ method_source (~> 0.8)
40
+ slop (~> 3.4)
41
+ rspec (2.14.1)
42
+ rspec-core (~> 2.14.0)
43
+ rspec-expectations (~> 2.14.0)
44
+ rspec-mocks (~> 2.14.0)
45
+ rspec-core (2.14.7)
46
+ rspec-expectations (2.14.4)
47
+ diff-lcs (>= 1.1.3, < 2.0)
48
+ rspec-mocks (2.14.4)
49
+ safe_yaml (0.9.7)
50
+ slop (3.4.6)
51
+ thread_safe (0.1.3)
52
+ atomic
53
+ typhoeus (0.6.5)
54
+ ethon (~> 0.6.1)
55
+ tzinfo (0.3.38)
56
+ vcr (2.8.0)
57
+ webmock (1.15.0)
58
+ addressable (>= 2.2.7)
59
+ crack (>= 0.3.2)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ api-model!
66
+ pry
67
+ rspec
68
+ vcr
69
+ webmock (= 1.15.0)
data/README.md ADDED
@@ -0,0 +1 @@
1
+ Api Model README
data/api-model.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "api-model"
5
+ s.version = "0.0.2"
6
+ s.authors = ["Damien Timewell"]
7
+ s.email = ["mail@damientimewell.com"]
8
+ s.homepage = "https://github.com/iZettle/api-model"
9
+ s.summary = "A simple way of interacting with rest APIs"
10
+ s.description = "A simple way of interacting with rest APIs"
11
+
12
+ # s.add_dependency 'redis'
13
+ s.add_dependency 'activesupport'
14
+ s.add_dependency 'activemodel'
15
+ s.add_dependency 'typhoeus'
16
+
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "pry"
19
+ s.add_development_dependency "vcr"
20
+ s.add_development_dependency "webmock", "1.15.0"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- spec/*`.split("\n")
24
+ end
data/lib/api-model.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'active_model'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+ require 'logger'
5
+
6
+ require 'api_model/initializer'
7
+ require 'api_model/http_request'
8
+ require 'api_model/response'
9
+
10
+ module ApiModel
11
+
12
+ if defined? Rails
13
+ Log = Rails.logger
14
+ else
15
+ Log = Logger.new STDOUT
16
+ end
17
+
18
+ class Base
19
+ include ActiveModel::Conversion
20
+ include ActiveModel::Validations
21
+ extend ActiveModel::Naming
22
+ extend ActiveModel::Callbacks
23
+
24
+ include ApiModel::Initializer
25
+
26
+ def self.api_host=(api_host)
27
+ @api_host = api_host
28
+ end
29
+
30
+ def self.api_host
31
+ @api_host || ""
32
+ end
33
+
34
+ def self.get_json(path, options={})
35
+ # TODO - tidy this up...
36
+ builder = options.delete(:builder) || self
37
+ options[:api_host] = api_host
38
+
39
+ HttpRequest.run(options.merge(path: path)).build_objects builder
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ module ApiModel
2
+ class HttpRequest
3
+ include ApiModel::Initializer
4
+
5
+ attr_accessor :path, :method, :options, :api_call, :api_host
6
+
7
+ def self.run(options={})
8
+ self.new(options).run
9
+ end
10
+
11
+ def run
12
+ self.api_call = Typhoeus.send(method, full_path, options)
13
+ Response.new self.api_call
14
+ end
15
+
16
+ def method
17
+ @method ||= :get
18
+ end
19
+
20
+ def options
21
+ @options ||= {}
22
+ end
23
+
24
+ def full_path
25
+ return path if path =~ /^http/
26
+ "#{api_host}#{path}"
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ module ApiModel
2
+ module Initializer
3
+
4
+ def self.included(klass)
5
+ klass.extend ActiveModel::Callbacks
6
+ klass.define_model_callbacks :initialize
7
+ end
8
+
9
+ def initialize(values={})
10
+ run_callbacks :initialize do
11
+ update_attributes values
12
+ end
13
+ end
14
+
15
+ def update_attributes(values={})
16
+ return unless values.present?
17
+
18
+ values.each do |key,value|
19
+ begin
20
+ public_send "#{key}=", value
21
+ rescue
22
+ Log.debug "Could not set #{key} on #{self.class.name}"
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ module ApiModel
2
+ class Response
3
+ FALL_THROUGH_METHODS = [
4
+ :class, :nil?, :empty?, :acts_like?, :as_json, :blank?, :duplicable?,
5
+ :eval_js, :html_safe?, :in?, :presence, :present?, :psych_to_yaml, :to_json,
6
+ :to_param, :to_query, :to_yaml, :to_yaml_properties, :with_options, :is_a?,
7
+ :respond_to?, :kind_of?
8
+ ]
9
+
10
+ attr_accessor :http_response, :objects
11
+
12
+ def initialize(http_response)
13
+ @http_response = http_response
14
+ end
15
+
16
+ # TODO - make json root configurable
17
+ def build_objects(builder)
18
+ if json_response_body.is_a? Array
19
+ self.objects = json_response_body.collect{ |hash| build builder, hash }
20
+ elsif json_response_body.is_a? Hash
21
+ self.objects = self.build builder, json_response_body
22
+ end
23
+
24
+ self
25
+ end
26
+
27
+ def build(builder, hash)
28
+ if builder.respond_to? :build
29
+ builder.build hash
30
+ else
31
+ builder.new hash
32
+ end
33
+ end
34
+
35
+ def json_response_body
36
+ JSON.parse http_response.body
37
+ rescue JSON::ParserError
38
+ Log.info "Could not parse JSON response: #{http_response.body}"
39
+ return nil
40
+ end
41
+
42
+ # Define common methods which should never be called on this abstract class, and should always be
43
+ # passed down to the #objects
44
+ FALL_THROUGH_METHODS.each do |transparent_method|
45
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
46
+ def #{transparent_method}(*args, &block)
47
+ objects.send '#{transparent_method}', *args, &block
48
+ end
49
+ RUBY_EVAL
50
+ end
51
+
52
+ def method_missing(method_name, *args, &block)
53
+ objects.send method_name, *args, &block
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_models/banana'
3
+ require 'support/mock_models/multiple_hosts'
4
+
5
+ describe ApiModel do
6
+ describe "api_host" do
7
+ it "should be possible to set the base api_host" do
8
+ Banana.api_host = "http://api-model-specs.com"
9
+ Banana.api_host.should eq "http://api-model-specs.com"
10
+ end
11
+
12
+ describe "with combinations of setting different hosts" do
13
+ it "should no override each other" do
14
+ MultipleHostsFoo.api_host.should eq("http://foo.com")
15
+ MultipleHostsBar.api_host.should eq("http://bar.com")
16
+ MultipleHostsNone.api_host.should eq("")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_models/blog_post'
3
+
4
+ describe ApiModel do
5
+
6
+ describe "retrieving a single object" do
7
+ describe "with the default builder" do
8
+ let(:blog_post) do
9
+ VCR.use_cassette('posts') do
10
+ BlogPost.get_json "http://api-model-specs.com/single_post"
11
+ end
12
+ end
13
+
14
+ it "should run the request and objectify the response hash" do
15
+ blog_post.should be_a(BlogPost)
16
+ blog_post.name.should eq "foo"
17
+ end
18
+ end
19
+
20
+ describe "with a custom builder" do
21
+ let(:custom_built_blog_post) do
22
+ VCR.use_cassette('posts') do
23
+ BlogPost.get_json "http://api-model-specs.com/single_post", builder: BlogPost::CustomBuilder.new
24
+ end
25
+ end
26
+
27
+ it "should be possible to use a custom builder class when objectifing" do
28
+ custom_built_blog_post.should be_a(BlogPost)
29
+ custom_built_blog_post.title.should eq "FOOBAR"
30
+ end
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_models/blog_post'
3
+
4
+ describe ApiModel::HttpRequest do
5
+
6
+ describe "default attributes" do
7
+ subject { ApiModel::HttpRequest.new }
8
+
9
+ it "should default #method to :get" do
10
+ subject.method.should eq :get
11
+ end
12
+
13
+ it "should default #options to a blank hash" do
14
+ subject.options.should eq Hash.new
15
+ end
16
+ end
17
+
18
+ describe "using api_host" do
19
+ let(:blog_post) do
20
+ BlogPost.api_host = "http://api-model-specs.com"
21
+
22
+ VCR.use_cassette('posts') do
23
+ BlogPost.get_json "/single_post"
24
+ end
25
+ end
26
+
27
+ it "should be used with #path to generate a #full_path" do
28
+ blog_post.http_response.request.url.should eq "http://api-model-specs.com/single_post"
29
+ end
30
+ end
31
+
32
+ describe "sending a GET request" do
33
+ let(:request) { ApiModel::HttpRequest.new path: "http://api-model-specs.com/posts", method: :get }
34
+
35
+ it "should use typhoeus to send a request" do
36
+ VCR.use_cassette('posts') do
37
+ request.run
38
+ end
39
+
40
+ request.api_call.success?.should eq true
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_models/banana'
3
+
4
+ describe ApiModel::Initializer do
5
+
6
+ let(:banana) { Banana.new color: "yellow", size: "large" }
7
+
8
+ it "should set attributes when initializing with a hash" do
9
+ expect(banana.color).to eq "yellow"
10
+ expect(banana.size).to eq "large"
11
+ end
12
+
13
+ it "should be easy to update attributes once set" do
14
+ banana.update_attributes color: "green", size: "small"
15
+ expect(banana.color).to eq "green"
16
+ expect(banana.size).to eq "small"
17
+ end
18
+
19
+ it "should not blog up if update_attributes is called with nil" do
20
+ expect {
21
+ banana.update_attributes nil
22
+ }.to_not raise_error
23
+ end
24
+
25
+ it "should run callbacks on initialize" do
26
+ banana.ripe.should eq true
27
+ end
28
+
29
+ it "should log if an attempt was made to set an attribute which is not defined" do
30
+ ApiModel::Log.should_receive(:debug).with "Could not set foo on Banana"
31
+ Banana.new foo: "bar"
32
+ end
33
+
34
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_models/blog_post'
3
+
4
+ describe ApiModel::Response do
5
+
6
+ let(:valid_response) do
7
+ VCR.use_cassette('posts') do
8
+ ApiModel::HttpRequest.new(path: "http://api-model-specs.com/single_post", method: :get).run
9
+ end
10
+ end
11
+
12
+ describe "parsing the json body" do
13
+ it "should produce a hash given valid json" do
14
+ valid_response.json_response_body.should be_a(Hash)
15
+ valid_response.json_response_body["name"].should eq "foo"
16
+ end
17
+
18
+ it "should catch errors from parsing invalid json" do
19
+ valid_response.stub_chain(:http_response, :body).and_return "blah"
20
+ ApiModel::Log.should_receive(:info).with "Could not parse JSON response: blah"
21
+
22
+ expect {
23
+ valid_response.json_response_body
24
+ }.to_not raise_error
25
+ end
26
+ end
27
+
28
+ describe "#build" do
29
+ it "should use the builder.build method if present" do
30
+ builder = double
31
+ builder.should_receive(:build).with something: "foo"
32
+
33
+ valid_response.build builder, something: "foo"
34
+ end
35
+
36
+ it "should use builder.new if there's no builder.build method" do
37
+ builder = double
38
+ builder.should_receive(:new).with something_else: "hi"
39
+
40
+ valid_response.build builder, something_else: "hi"
41
+ end
42
+ end
43
+
44
+ describe "#build_objects" do
45
+ let(:single_object) do
46
+ valid_response.stub(:json_response_body).and_return name: "foo"
47
+ valid_response.build_objects BlogPost
48
+ end
49
+
50
+ let(:array_of_objects) do
51
+ valid_response.stub(:json_response_body).and_return [{name: "foo"}, {name: "bar"}]
52
+ valid_response.build_objects BlogPost
53
+ end
54
+
55
+ it "should build a single object" do
56
+ single_object.should be_a(BlogPost)
57
+ single_object.name.should eq "foo"
58
+ end
59
+
60
+ it "should build an array of objects" do
61
+ array_of_objects[0].should be_a(BlogPost)
62
+ array_of_objects[0].name.should eq "foo"
63
+
64
+ array_of_objects[1].should be_a(BlogPost)
65
+ array_of_objects[1].name.should eq "bar"
66
+ end
67
+
68
+ it "should include the Typhoeus::Response object" do
69
+ single_object.http_response.should be_a(Typhoeus::Response)
70
+ end
71
+
72
+ it "should include the #json_response_body" do
73
+ single_object.json_response_body.should eq name: "foo"
74
+ end
75
+ end
76
+
77
+ describe "passing core methods down to the built class" do
78
+
79
+ ApiModel::Response::FALL_THROUGH_METHODS.each do |fall_trhough_method|
80
+ it "should pass ##{fall_trhough_method} on the built object class" do
81
+ allow_message_expectations_on_nil
82
+ valid_response.objects.should_receive(fall_trhough_method)
83
+ valid_response.send fall_trhough_method
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'pry'
4
+ require 'vcr'
5
+
6
+ require 'api-model'
7
+
8
+ VCR.configure do |c|
9
+ c.cassette_library_dir = 'spec/support/fixtures'
10
+ c.hook_into :webmock # or :fakeweb
11
+ end
@@ -0,0 +1,57 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://api-model-specs.com/posts
6
+ headers:
7
+ User-Agent:
8
+ - Typhoeus - https://github.com/typhoeus/typhoeus
9
+ response:
10
+ status:
11
+ code: 200
12
+ message: OK
13
+ headers:
14
+ Server:
15
+ - nginx/1.4.1
16
+ Date:
17
+ - Thu, 28 Nov 2013 16:02:56 GMT
18
+ Content-Type:
19
+ - text/plain; charset=utf-8
20
+ Content-Length:
21
+ - '248'
22
+ Connection:
23
+ - keep-alive
24
+ body:
25
+ encoding: UTF-8
26
+ string: "[{\"name\":\"foo\"},{\"name\":\"bar\"}]"
27
+ http_version:
28
+ recorded_at: Thu, 28 Nov 2013 16:02:20 GMT
29
+
30
+ - request:
31
+ method: get
32
+ uri: http://api-model-specs.com/single_post
33
+ headers:
34
+ User-Agent:
35
+ - Typhoeus - https://github.com/typhoeus/typhoeus
36
+ response:
37
+ status:
38
+ code: 200
39
+ message: OK
40
+ headers:
41
+ Server:
42
+ - nginx/1.4.1
43
+ Date:
44
+ - Thu, 28 Nov 2013 16:02:56 GMT
45
+ Content-Type:
46
+ - text/plain; charset=utf-8
47
+ Content-Length:
48
+ - '248'
49
+ Connection:
50
+ - keep-alive
51
+ body:
52
+ encoding: UTF-8
53
+ string: "{\"name\":\"foo\"}"
54
+ http_version:
55
+ recorded_at: Thu, 28 Nov 2013 16:02:20 GMT
56
+
57
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,8 @@
1
+ class Banana < ApiModel::Base
2
+ attr_accessor :color, :size, :ripe
3
+ after_initialize :set_ripeness
4
+
5
+ def set_ripeness
6
+ self.ripe = color == "yellow"
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ class BlogPost < ApiModel::Base
2
+ attr_accessor :name, :title
3
+
4
+ class CustomBuilder
5
+ def build(hash)
6
+ BlogPost.new hash.merge(title: "FOOBAR")
7
+ end
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ class MultipleHostsFoo < ApiModel::Base
2
+ self.api_host = "http://foo.com"
3
+ end
4
+
5
+ class MultipleHostsBar < ApiModel::Base
6
+ self.api_host = "http://bar.com"
7
+ end
8
+
9
+ class MultipleHostsNone < ApiModel::Base
10
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: api-model
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Damien Timewell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: typhoeus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
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
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 1.15.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 1.15.0
111
+ description: A simple way of interacting with rest APIs
112
+ email:
113
+ - mail@damientimewell.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - README.md
123
+ - api-model.gemspec
124
+ - lib/api-model.rb
125
+ - lib/api_model/http_request.rb
126
+ - lib/api_model/initializer.rb
127
+ - lib/api_model/response.rb
128
+ - spec/lib/api_host_spec.rb
129
+ - spec/lib/api_model_spec.rb
130
+ - spec/lib/http_request_spec.rb
131
+ - spec/lib/initializer_spec.rb
132
+ - spec/lib/response_spec.rb
133
+ - spec/spec_helper.rb
134
+ - spec/support/fixtures/posts.yml
135
+ - spec/support/mock_models/banana.rb
136
+ - spec/support/mock_models/blog_post.rb
137
+ - spec/support/mock_models/multiple_hosts.rb
138
+ homepage: https://github.com/iZettle/api-model
139
+ licenses: []
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.0.6
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: A simple way of interacting with rest APIs
161
+ test_files:
162
+ - spec/lib/api_host_spec.rb
163
+ - spec/lib/api_model_spec.rb
164
+ - spec/lib/http_request_spec.rb
165
+ - spec/lib/initializer_spec.rb
166
+ - spec/lib/response_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/support/fixtures/posts.yml
169
+ - spec/support/mock_models/banana.rb
170
+ - spec/support/mock_models/blog_post.rb
171
+ - spec/support/mock_models/multiple_hosts.rb
172
+ has_rdoc: