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 +7 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +69 -0
- data/README.md +1 -0
- data/api-model.gemspec +24 -0
- data/lib/api-model.rb +43 -0
- data/lib/api_model/http_request.rb +30 -0
- data/lib/api_model/initializer.rb +28 -0
- data/lib/api_model/response.rb +57 -0
- data/spec/lib/api_host_spec.rb +20 -0
- data/spec/lib/api_model_spec.rb +34 -0
- data/spec/lib/http_request_spec.rb +43 -0
- data/spec/lib/initializer_spec.rb +34 -0
- data/spec/lib/response_spec.rb +89 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/fixtures/posts.yml +57 -0
- data/spec/support/mock_models/banana.rb +8 -0
- data/spec/support/mock_models/blog_post.rb +10 -0
- data/spec/support/mock_models/multiple_hosts.rb +10 -0
- metadata +172 -0
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
data/.rspec
ADDED
data/Gemfile
ADDED
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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
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:
|