takeout 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +138 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +54 -0
- data/LICENSE.txt +22 -0
- data/README.md +140 -0
- data/Rakefile +2 -0
- data/circle.yml +3 -0
- data/lib/.DS_Store +0 -0
- data/lib/takeout/client.rb +201 -0
- data/lib/takeout/endpoint_failure_error.rb +13 -0
- data/lib/takeout/version.rb +3 -0
- data/lib/takeout.rb +6 -0
- data/spec/.DS_Store +0 -0
- data/spec/client_spec.rb +129 -0
- data/spec/spec_helper.rb +104 -0
- data/spec/support/.DS_Store +0 -0
- data/spec/support/fake_test_api.rb +43 -0
- data/spec/support/fixtures/post.json +3 -0
- data/spec/support/fixtures/posts.json +8 -0
- data/takeout.gemspec +37 -0
- metadata +283 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b13e0750c7cac978c5789724348a99f57994021b
|
4
|
+
data.tar.gz: 274d6759e43802ffe0558e505c61cf097cda7e9c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b5c31da352a23bf7395a87fa103319aa7529d129104a86a3f785b1f9ceada1dba22ed6e9879ad625ca62dd7160b116b4027bfc2a9c1a47dd10ab4e3b48842f2a
|
7
|
+
data.tar.gz: 63e2cc81e661b3c064350e41ce77465c072a958b027baa006a99c4eccd3ebd826f4dd3ca29d0c2457fead6e44e97a6a0530facb4e6191caebd1423a4c3e070d6
|
data/.gitignore
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
|
24
|
+
# Created by https://www.gitignore.io
|
25
|
+
|
26
|
+
### RubyMine ###
|
27
|
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
28
|
+
|
29
|
+
*.iml
|
30
|
+
|
31
|
+
## Directory-based project format:
|
32
|
+
.idea/
|
33
|
+
# if you remove the above rule, at least ignore the following:
|
34
|
+
|
35
|
+
# User-specific stuff:
|
36
|
+
# .idea/workspace.xml
|
37
|
+
# .idea/tasks.xml
|
38
|
+
# .idea/dictionaries
|
39
|
+
|
40
|
+
# Sensitive or high-churn files:
|
41
|
+
# .idea/dataSources.ids
|
42
|
+
# .idea/dataSources.xml
|
43
|
+
# .idea/sqlDataSources.xml
|
44
|
+
# .idea/dynamic.xml
|
45
|
+
# .idea/uiDesigner.xml
|
46
|
+
|
47
|
+
# Gradle:
|
48
|
+
# .idea/gradle.xml
|
49
|
+
# .idea/libraries
|
50
|
+
|
51
|
+
# Mongo Explorer plugin:
|
52
|
+
# .idea/mongoSettings.xml
|
53
|
+
|
54
|
+
## File-based project format:
|
55
|
+
*.ipr
|
56
|
+
*.iws
|
57
|
+
|
58
|
+
## Plugin-specific files:
|
59
|
+
|
60
|
+
# IntelliJ
|
61
|
+
/out/
|
62
|
+
|
63
|
+
# mpeltonen/sbt-idea plugin
|
64
|
+
.idea_modules/
|
65
|
+
|
66
|
+
# JIRA plugin
|
67
|
+
atlassian-ide-plugin.xml
|
68
|
+
|
69
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
70
|
+
com_crashlytics_export_strings.xml
|
71
|
+
crashlytics.properties
|
72
|
+
crashlytics-build.properties
|
73
|
+
|
74
|
+
|
75
|
+
### SublimeText ###
|
76
|
+
# cache files for sublime text
|
77
|
+
*.tmlanguage.cache
|
78
|
+
*.tmPreferences.cache
|
79
|
+
*.stTheme.cache
|
80
|
+
|
81
|
+
# workspace files are user-specific
|
82
|
+
*.sublime-workspace
|
83
|
+
|
84
|
+
# project files should be checked into the repository, unless a significant
|
85
|
+
# proportion of contributors will probably not be using SublimeText
|
86
|
+
# *.sublime-project
|
87
|
+
|
88
|
+
# sftp configuration file
|
89
|
+
sftp-config.json
|
90
|
+
|
91
|
+
|
92
|
+
### Vim ###
|
93
|
+
[._]*.s[a-w][a-z]
|
94
|
+
[._]s[a-w][a-z]
|
95
|
+
*.un~
|
96
|
+
Session.vim
|
97
|
+
.netrwhist
|
98
|
+
*~
|
99
|
+
|
100
|
+
|
101
|
+
### Ruby ###
|
102
|
+
*.gem
|
103
|
+
*.rbc
|
104
|
+
/.config
|
105
|
+
/coverage/
|
106
|
+
/InstalledFiles
|
107
|
+
/pkg/
|
108
|
+
/spec/reports/
|
109
|
+
/test/tmp/
|
110
|
+
/test/version_tmp/
|
111
|
+
/tmp/
|
112
|
+
|
113
|
+
## Specific to RubyMotion:
|
114
|
+
.dat*
|
115
|
+
.repl_history
|
116
|
+
build/
|
117
|
+
|
118
|
+
## Documentation cache and generated files:
|
119
|
+
/.yardoc/
|
120
|
+
/_yardoc/
|
121
|
+
/doc/
|
122
|
+
/rdoc/
|
123
|
+
|
124
|
+
## Environment normalisation:
|
125
|
+
/.bundle/
|
126
|
+
/vendor/bundle
|
127
|
+
/lib/bundler/man/
|
128
|
+
|
129
|
+
# for a library or gem, you might want to ignore these files since the code is
|
130
|
+
# intended to run in multiple environments; otherwise, check them in:
|
131
|
+
# Gemfile.lock
|
132
|
+
# .ruby-version
|
133
|
+
# .ruby-gemset
|
134
|
+
|
135
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
136
|
+
.rvmrc
|
137
|
+
|
138
|
+
.idea
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :bundler do
|
5
|
+
require 'guard/bundler'
|
6
|
+
require 'guard/bundler/verify'
|
7
|
+
helper = Guard::Bundler::Verify.new
|
8
|
+
|
9
|
+
files = ['Gemfile']
|
10
|
+
files += Dir['*.gemspec'] if files.any? { |f| helper.uses_gemspec?(f) }
|
11
|
+
|
12
|
+
# Assume files are symlinked from somewhere
|
13
|
+
files.each { |file| watch(helper.real_path(file)) }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
17
|
+
# rspec may be run, below are examples of the most common uses.
|
18
|
+
# * bundler: 'bundle exec rspec'
|
19
|
+
# * bundler binstubs: 'bin/rspec'
|
20
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
21
|
+
# installed the spring binstubs per the docs)
|
22
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
23
|
+
# * 'just' rspec: 'rspec'
|
24
|
+
|
25
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
26
|
+
require "guard/rspec/dsl"
|
27
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
28
|
+
|
29
|
+
# Feel free to open issues for suggestions and improvements
|
30
|
+
|
31
|
+
# RSpec files
|
32
|
+
rspec = dsl.rspec
|
33
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
34
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
35
|
+
watch(rspec.spec_files)
|
36
|
+
|
37
|
+
# Ruby files
|
38
|
+
watch(%r{^lib/takeout/(.+)\.rb$}) { |m| puts m; "spec/#{m.last}_spec.rb" }
|
39
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m.last}_spec.rb" }
|
40
|
+
end
|
41
|
+
|
42
|
+
guard 'rake', task: 'build', run_on_all: true, run_on_start: true do
|
43
|
+
watch(%r{^lib/takeout/client.rb})
|
44
|
+
end
|
45
|
+
|
46
|
+
guard 'rake', task: 'install', run_on_all: true, run_on_start: true do
|
47
|
+
watch(%r{^lib/takeout/client.rb})
|
48
|
+
end
|
49
|
+
|
50
|
+
guard 'yard' do
|
51
|
+
watch(%r{app/.+\.rb})
|
52
|
+
watch(%r{lib/.+\.rb})
|
53
|
+
watch(%r{ext/.+\.c})
|
54
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Kyle Lucas
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# Takeout
|
2
|
+
[![Code Climate](https://codeclimate.com/github/kylegrantlucas/takeout/badges/gpa.svg)](https://codeclimate.com/github/kylegrantlucas/takeout) [![Test Coverage](https://codeclimate.com/github/kylegrantlucas/takeout/badges/coverage.svg)](https://codeclimate.com/github/kylegrantlucas/takeout/coverage) [![Circle CI](https://circleci.com/gh/kylegrantlucas/takeout/tree/master.svg?style=shield)](https://circleci.com/gh/kylegrantlucas/takeout/tree/master) [![Inline docs](http://inch-ci.org/github/kylegrantlucas/takeout.svg?branch=master&style=shields)](http://inch-ci.org/github/kylegrantlucas/takeout)
|
3
|
+
|
4
|
+
A powerful little tool for generating on-the-fly API clients.
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
|
8
|
+
All version of MRI 1.8 and up are supported, it probably work sunder other variations of ruby it just hasn't been tested on the,
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'takeout'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install takeout
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
### Quick Use
|
27
|
+
|
28
|
+
The first step is to instantiate a client with the URI and given endpoints you would like the gem to create methods for:
|
29
|
+
|
30
|
+
client = Takeout::Client.new(uri: 'testing.com', endpoints: {get: [:test, :test2], post: :test2})
|
31
|
+
|
32
|
+
This can also be done using block format:
|
33
|
+
|
34
|
+
client = Takeout::Client.new do |client|
|
35
|
+
client.uri = 'testing.com'
|
36
|
+
client.endpoints = {get: [:test, :test2], post: :test2}
|
37
|
+
end
|
38
|
+
|
39
|
+
From here you can begin calling your api methods! They take on the form ```(request_type)_(endpoint_name)```
|
40
|
+
So given the example instantiation our method list would look like:
|
41
|
+
|
42
|
+
client.get_test
|
43
|
+
client.get_test2
|
44
|
+
client.post_test2
|
45
|
+
|
46
|
+
You can at anytime see a list of the methods available to you by running this:
|
47
|
+
|
48
|
+
(client.methods - Object.methods - Takeout::Client.instance_methods(false))
|
49
|
+
|
50
|
+
Results are returned as parsed ruby objects:
|
51
|
+
|
52
|
+
client.get_test
|
53
|
+
#=> {test: 1}
|
54
|
+
|
55
|
+
### Options
|
56
|
+
#### Extensions
|
57
|
+
|
58
|
+
You have the ability to specify an extension that gets tacked on, if you need it.
|
59
|
+
You may do this in either the call or in teh client instantiation, however the call will always override the clients extension if there is a confilct.
|
60
|
+
|
61
|
+
client = Takeout::Client.new do |client|
|
62
|
+
client.uri = 'testing.com'
|
63
|
+
client.endpoints = {get: [:test, :test2], post: :test2}
|
64
|
+
client.extension = 'json'
|
65
|
+
end
|
66
|
+
|
67
|
+
client.get_test(extension: 'json')
|
68
|
+
|
69
|
+
#### Templating
|
70
|
+
|
71
|
+
Takeout includes support for specifying customs endpoint schemas using the [Liquid Templating Engine](http://liquidmarkup.org):
|
72
|
+
|
73
|
+
To define a schema do so in the instantiation of the client:
|
74
|
+
|
75
|
+
client = Takeout::Client.new do |client|
|
76
|
+
client.uri = 'testing.com'
|
77
|
+
client.endpoints = {get: [:test, :test2], post: :test2}
|
78
|
+
client.schemas = {get: {test: '/{{endpoint}}{% if param %}/required-param-{{param}}{% endif %}'}
|
79
|
+
end
|
80
|
+
|
81
|
+
From there when you call the endpoint you may pass in your params as part of the options and it will fill in accordingly:
|
82
|
+
|
83
|
+
client.get_test(param: 'Testing')
|
84
|
+
URL => "http://testing.com/test/required-param-Testing
|
85
|
+
|
86
|
+
client.get_test
|
87
|
+
URL => "http://testing.com/test"
|
88
|
+
|
89
|
+
As you can see in the above example I use ```{{endpoint}}``` as one of the template values, it is only one of two reserved keywords for the templates, the other is ```{{object_id}}```.
|
90
|
+
|
91
|
+
#### SSL Support
|
92
|
+
|
93
|
+
SSL is also supported, and it very easy to flip on.
|
94
|
+
|
95
|
+
You can either specify ssl when instantiating the object:
|
96
|
+
|
97
|
+
client = Takeout::Client.new(uri: 'testing.com', endpoints: {get: :test}, ssl: true)
|
98
|
+
|
99
|
+
Or you can flip it on once already created:
|
100
|
+
|
101
|
+
client.enable_ssl
|
102
|
+
|
103
|
+
You can disable it using the same method:
|
104
|
+
|
105
|
+
client.disable_ssl
|
106
|
+
|
107
|
+
#### Headers
|
108
|
+
|
109
|
+
Takeout also feature full support for headers:
|
110
|
+
|
111
|
+
client = Takeout::Client.new do |client|
|
112
|
+
client.uri = 'testing.com'
|
113
|
+
client.endpoints = {get: [:test, :test2], post: :test2}
|
114
|
+
client.headers = {auth_token: 'asdjhdskjfh23423423'}
|
115
|
+
end
|
116
|
+
|
117
|
+
Much like extensions this can be done in the endpoint call too, and it will merge with the clients global headers:
|
118
|
+
|
119
|
+
client.get_test(headers: {auth_token: 'asdjhdskjfh23423423'})
|
120
|
+
|
121
|
+
#### Basic Authentication
|
122
|
+
|
123
|
+
Takeout also has support for basic auth by specifying both the ```username``` and ```password``` options during a call or instantiation
|
124
|
+
Unlike most other features these are simply passed as options to the call:
|
125
|
+
|
126
|
+
client = Takeout::Client.new do |client|
|
127
|
+
client.uri = 'testing.com'
|
128
|
+
client.endpoints = {get: [:test, :test2], post: :test2}
|
129
|
+
client.options = {username: 'user', password: 'pass'}
|
130
|
+
end
|
131
|
+
|
132
|
+
client.get_test(username: 'user', password: 'pass')
|
133
|
+
|
134
|
+
## Contributing
|
135
|
+
|
136
|
+
1. Fork it ( https://github.com/[my-github-username]/takeout/fork )
|
137
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
138
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
139
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
140
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/circle.yml
ADDED
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module Takeout
|
2
|
+
class Client
|
3
|
+
require 'curb'
|
4
|
+
require 'oj'
|
5
|
+
require 'uri'
|
6
|
+
require 'erb'
|
7
|
+
require 'liquid'
|
8
|
+
|
9
|
+
# @return [Boolean] a boolean specifying whether or not to run curl with teh verbose setting
|
10
|
+
attr_accessor :debug
|
11
|
+
|
12
|
+
# @return [Hash] a hash specifying the global options to apply to each request
|
13
|
+
attr_accessor :options
|
14
|
+
|
15
|
+
# @return [Hash] a hash specifying the headers to apply to each request
|
16
|
+
attr_accessor :headers
|
17
|
+
|
18
|
+
# @return [String] a string with the extension to be appended on each request
|
19
|
+
attr_accessor :extension
|
20
|
+
|
21
|
+
# @return [Boolean] a boolean to specify whether or not SSL is turned on
|
22
|
+
attr_accessor :ssl
|
23
|
+
|
24
|
+
# @return [Hash] a hash specifying the custom per-endpoint schema templates
|
25
|
+
attr_accessor :schemas
|
26
|
+
|
27
|
+
# @return [String] the uri to send requests to
|
28
|
+
attr_accessor :uri
|
29
|
+
|
30
|
+
# @return [Hash] the hash containing the endpoints by request type to generate methods for
|
31
|
+
attr_reader :endpoints
|
32
|
+
|
33
|
+
# A constant specifying the kind of event callbacks to raise errors for
|
34
|
+
FAILURES = [:failure, :missing, :redirect]
|
35
|
+
|
36
|
+
# The main client initialization method.
|
37
|
+
# ==== Attributes
|
38
|
+
#
|
39
|
+
# * +options+ - The main atrtibute and extra global options to set for the client
|
40
|
+
# ==== Options
|
41
|
+
#
|
42
|
+
# * +:uri+ - A string defining the URI for the API to call.
|
43
|
+
# * +:endpoints+ - A hash containing the endpoints by request type to generate methods for
|
44
|
+
# * +:headers+ - A hash specifying the headers to apply to each request
|
45
|
+
# * +:ssl+ - A boolean to specify whether or not SSL is turned on
|
46
|
+
# * +:schemas+ - A hash specifying the custom per-endpoint schema templates
|
47
|
+
# * +:extension+ - A string with the extension to be appended on each request
|
48
|
+
def initialize(options={})
|
49
|
+
if block_given?
|
50
|
+
yield self
|
51
|
+
else
|
52
|
+
# Set instance variables
|
53
|
+
@uri = options[:uri] ? options[:uri] : ''
|
54
|
+
self.endpoints = options[:endpoints] ? options[:endpoints] : {}
|
55
|
+
@headers = options[:headers] ? options[:headers] : {}
|
56
|
+
@debug = options[:debug] ? options[:debug] : false
|
57
|
+
@ssl = options[:ssl] ? options[:ssl] : false
|
58
|
+
@schemas = options[:schemas] ? options[:schemas] : {}
|
59
|
+
@extension = options[:extension] ? options[:extension] : nil
|
60
|
+
|
61
|
+
# Clean instance variables out of options hash and set that as options instance variable
|
62
|
+
[:uri, :endpoints, :headers, :debug, :ssl, :schemas, :extension].each { |v| options.delete(v) }
|
63
|
+
@options = options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Check if SSL is enabled.
|
68
|
+
# @return [Boolean] Returns true if SSL is enabled, false if disabled
|
69
|
+
def ssl?
|
70
|
+
return @ssl
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets the instance variable and then generates the dynamic methods by calling #generate_enpoint_methods
|
74
|
+
# @param [Hash] value A hash specifying the custom per-endpoint schema templates
|
75
|
+
def endpoints=(value)
|
76
|
+
generate_endpoint_methods(value)
|
77
|
+
@endpoints = value
|
78
|
+
end
|
79
|
+
|
80
|
+
# Flips the @ssl instance variable to true
|
81
|
+
def enable_ssl
|
82
|
+
@ssl=true
|
83
|
+
end
|
84
|
+
|
85
|
+
# Flips the @ssl instance variable to false
|
86
|
+
def disable_ssl
|
87
|
+
@ssl=false
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Generates the dynamic (request_type)_(endpoint_name) methods that allow you to access your API.
|
93
|
+
# @param [Hash] endpoints A hash with the form {request_type: :endpoint_name} or {request_type: [:endpoint_name1, :endpoint_name_2]}
|
94
|
+
def generate_endpoint_methods(endpoints)
|
95
|
+
endpoints.each do |request_type, endpoint_names|
|
96
|
+
# Force any give values into an array and then iterate over that
|
97
|
+
[endpoint_names].flatten(1).each do |request_name|
|
98
|
+
define_singleton_method("#{request_type}_#{request_name}".to_sym) do |options={}|
|
99
|
+
# Extract values that we store separately from the options hash and then clean it up
|
100
|
+
headers.merge!(options[:headers]) if options[:headers]
|
101
|
+
|
102
|
+
# Merge in global options
|
103
|
+
options.merge!(@options) if @options
|
104
|
+
|
105
|
+
# Build the request_url and update the options to remove templated values (if there are any)
|
106
|
+
request_url, options = generate_request_url(request_name, request_type, options)
|
107
|
+
|
108
|
+
# Clean up options hash before performing request
|
109
|
+
[:headers, :extension, :object_id].each { |value| options.delete(value)}
|
110
|
+
|
111
|
+
return perform_curl_request(request_type, request_url, options, headers)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end if endpoints.is_a? Hash
|
115
|
+
end
|
116
|
+
|
117
|
+
# Render out the template values and return the updated options hash
|
118
|
+
# @param [String] endpoint
|
119
|
+
# @param [String] request_type
|
120
|
+
# @param [Hash] options
|
121
|
+
# @return [String] rendered_template
|
122
|
+
# @return [Hash] options
|
123
|
+
def substitute_template_values(endpoint, request_type, options={})
|
124
|
+
# Gets the proper template for the give CUSTOM_SCHEMA string for this endpoint and substitutes value for it based on give options
|
125
|
+
endpoint_templates = @schemas.fetch(request_type, nil)
|
126
|
+
template = endpoint_templates.fetch(endpoint, nil) if endpoint_templates
|
127
|
+
|
128
|
+
if template
|
129
|
+
extracted_options, options = extract_template_options(options.merge({endpoint: endpoint}), template)
|
130
|
+
# Render out the template
|
131
|
+
rendered_template = Liquid::Template.parse(template).render(extracted_options)
|
132
|
+
end
|
133
|
+
|
134
|
+
return rendered_template, options
|
135
|
+
end
|
136
|
+
|
137
|
+
def extract_template_options(options, template)
|
138
|
+
extracted_options = {}
|
139
|
+
|
140
|
+
# Build new options hash for templating
|
141
|
+
extracted_options.merge!({endpoint: options[:endpoint]}) if options[:object_id]
|
142
|
+
extracted_options.merge!({object_id: options[:object_id]}) if options[:object_id]
|
143
|
+
template.scan(/\{\{(\w+)\}\}/).flatten(1).each { |template_key| extracted_options.merge!(options.select {|key| key == template_key.to_sym }) }
|
144
|
+
|
145
|
+
# Convert keys to strings
|
146
|
+
extracted_options = extracted_options.inject({}){|memo,(k,v)| memo[k.to_s] = v; memo}
|
147
|
+
|
148
|
+
# Encode the template values and remove template values from original options hash
|
149
|
+
extracted_options.each do |key, value|
|
150
|
+
extracted_options[key] = ERB::Util.url_encode(value.to_s)
|
151
|
+
options.delete(key.to_sym)
|
152
|
+
end
|
153
|
+
|
154
|
+
return extracted_options, options
|
155
|
+
end
|
156
|
+
|
157
|
+
def perform_curl_request(request_type, request_url, options=nil, headers=nil)
|
158
|
+
curl = Curl.send(request_type.to_sym, request_url.to_s, options) do |curl|
|
159
|
+
curl.verbose = true if @debug
|
160
|
+
|
161
|
+
if options[:basic_auth]
|
162
|
+
curl.http_auth_types = :basic
|
163
|
+
curl.username = options[:basic_auth][:username]
|
164
|
+
curl.password = options[:basic_auth][:password]
|
165
|
+
end
|
166
|
+
|
167
|
+
headers.each { |key, value| curl.headers[key.to_s] = value } if headers
|
168
|
+
|
169
|
+
curl.on_success {|response| @parsed_body, @failure = Oj.load(response.body_str), false }
|
170
|
+
|
171
|
+
FAILURES.each { |failure_type| curl.send("on_#{failure_type}") {@failure=true} }
|
172
|
+
end
|
173
|
+
|
174
|
+
raise Takeout::EndpointFailureError.new(curl, request_type) if @failure
|
175
|
+
|
176
|
+
return @parsed_body if @parsed_body
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
def generate_request_url(endpoint_name, request_type=nil, options=nil)
|
181
|
+
# Generate custom templated path string and update options hash
|
182
|
+
custom_schema, options = substitute_template_values(endpoint_name, request_type, options) unless schemas.empty?
|
183
|
+
|
184
|
+
# Generate URL based on if the custom schema exists, and if there is a given object_id
|
185
|
+
request_url = if custom_schema.nil? || (custom_schema && custom_schema.empty?)
|
186
|
+
(options[:object_id] ? url("/#{endpoint_name.to_s}/#{options[:object_id]}") : url("/#{endpoint_name.to_s}"))
|
187
|
+
else
|
188
|
+
url(custom_schema)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Append extension if one is given
|
192
|
+
request_url = "#{request_url}.#{options[:extension] ? options[:extension] : self.extension}" if options[:extension] || self.extension
|
193
|
+
|
194
|
+
return request_url, options
|
195
|
+
end
|
196
|
+
|
197
|
+
def url(endpoint=nil)
|
198
|
+
ssl? ? URI::HTTPS.build(host: @uri, path: endpoint) : URI::HTTP.build(host: @uri, path: endpoint)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Takeout
|
2
|
+
class EndpointFailureError < StandardError
|
3
|
+
attr_reader :object, :request_type, :request_url, :response_code
|
4
|
+
|
5
|
+
def initialize(object, request_type)
|
6
|
+
@object, @request_type = object, request_type
|
7
|
+
end
|
8
|
+
|
9
|
+
def message
|
10
|
+
"Error in calling #{@request_type.to_s.upcase} on the endpoint: #{@object.url}, response_code: #{@object.response_code}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/takeout.rb
ADDED
data/spec/.DS_Store
ADDED
Binary file
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
ENDPOINTS = [:posts, :fake_failure, :fake_missing, :fake_redirect]
|
3
|
+
describe Takeout::Client do
|
4
|
+
let (:client) {Takeout::Client.new(uri: 'test.com', endpoints: {get: ENDPOINTS, post: ENDPOINTS, put: ENDPOINTS, delete: ENDPOINTS})}
|
5
|
+
|
6
|
+
context 'initialization' do
|
7
|
+
it 'creates methods for all provided endpoints' do
|
8
|
+
expect((client.methods - Object.methods - Takeout::Client.instance_methods(false))).to eq([:get_posts, :get_fake_failure, :get_fake_missing, :get_fake_redirect,
|
9
|
+
:post_posts, :post_fake_failure, :post_fake_missing, :post_fake_redirect,
|
10
|
+
:put_posts, :put_fake_failure, :put_fake_missing, :put_fake_redirect,
|
11
|
+
:delete_posts, :delete_fake_failure, :delete_fake_missing, :delete_fake_redirect])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'ssl' do
|
16
|
+
it 'uses https protocol when enabled' do
|
17
|
+
client.enable_ssl
|
18
|
+
expect(client.send(:url).scheme).to eql 'https'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'uses http protocol when disabled' do
|
22
|
+
client.disable_ssl
|
23
|
+
expect(client.send(:url).scheme).to eql 'http'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'templating' do
|
28
|
+
it 'properly substitutes template keys' do
|
29
|
+
temp_client = Takeout::Client.new(uri: 'test.com', endpoints: {get: ENDPOINTS}, schemas: {get: {posts: '/{{endpoint}}/{{test}}'}})
|
30
|
+
expect(temp_client.send(:generate_request_url, :posts, :get, {test: 'STRING'}).first.to_s).to eq 'http://test.com/posts/STRING'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'properly returns updated options hash' do
|
34
|
+
temp_client = Takeout::Client.new(uri: 'test.com', endpoints: {get: ENDPOINTS}, schemas: {get: {posts: '/{{endpoint}}/{{test}}'}})
|
35
|
+
expect(temp_client.send(:generate_request_url, :posts, :get, {test: 'STRING', auth_key: '111'}).last).to eq auth_key: '111'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'properly handles an object_id' do
|
39
|
+
expect(client.send(:generate_request_url, :posts, :get, {object_id: 1}).first.to_s).to eq 'http://test.com/posts/1'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
context 'headers' do
|
45
|
+
pending 'submits headers'
|
46
|
+
pending 'merges instance headers with call headers'
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'options' do
|
50
|
+
pending 'merges instance options with call options'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'get' do
|
54
|
+
it 'returns array on success' do
|
55
|
+
expect(client.get_posts).to be_an(Array)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises EndpointFailureError on missing' do
|
59
|
+
expect{client.get_fake_missing}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:get, 'fake_missing'))
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises EndpointFailureError on failure' do
|
63
|
+
expect{client.get_fake_failure}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:get, 'fake_failure'))
|
64
|
+
end
|
65
|
+
pending 'raises EndPointFailureError on redirect'
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'post' do
|
69
|
+
it 'returns hash on success' do
|
70
|
+
expect(client.post_posts).to be_an(Hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'raises EndpointFailureError when called without object_id' do
|
74
|
+
expect{client.post_posts(object_id: 1)}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:post, 'posts/1'))
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'raises EndpointFailureError on missing' do
|
78
|
+
expect{client.post_fake_missing}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:post, 'fake_missing'))
|
79
|
+
end
|
80
|
+
it 'raises EndpointFailureError on failure' do
|
81
|
+
expect{client.post_fake_failure}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:post, 'fake_failure'))
|
82
|
+
end
|
83
|
+
|
84
|
+
pending 'raises EndpointFailureError on redirect'
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'delete' do
|
88
|
+
it 'returns hash on success with object_id' do
|
89
|
+
expect(client.delete_posts(object_id: 1)).to be_a(Hash)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises EndpointFailureError when called without object_id' do
|
93
|
+
expect{client.delete_posts}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:delete, 'posts'))
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'raises EndpointFailureError on missing' do
|
97
|
+
expect{client.delete_fake_missing}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:delete, 'fake_missing'))
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'raises EndpointFailureError on failure' do
|
101
|
+
expect{client.delete_fake_failure}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:delete, 'fake_failure'))
|
102
|
+
end
|
103
|
+
|
104
|
+
pending 'raises EndPointFailureError on redirect'
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'put' do
|
108
|
+
it 'returns hash on success with object_id' do
|
109
|
+
expect(client.put_posts(object_id: 1)).to be_a(Hash)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'raises EndpointFailureError when called without object_id' do
|
113
|
+
expect{client.put_posts}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:put, 'posts'))
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'raises EndpointFailureError on missing' do
|
117
|
+
expect{client.put_fake_missing}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:put, 'fake_missing'))
|
118
|
+
end
|
119
|
+
it 'raises EndpointFailureError on failure' do
|
120
|
+
expect{client.put_fake_failure}.to raise_error(Takeout::EndpointFailureError, generate_error_message(:put, 'fake_failure'))
|
121
|
+
end
|
122
|
+
pending 'raises EndPointFailureError on redirect'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def generate_error_message(request_type, endpoint)
|
127
|
+
codes = {fake_failure: 500, fake_missing: 404, fake_redirect: 301, :'posts/1' => 404, posts: 404}
|
128
|
+
return "Error in calling #{request_type.to_s.upcase} on the endpoint: http://test.com/#{endpoint}, response_code: #{codes[endpoint.to_sym]}"
|
129
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
require 'bundler/setup'
|
4
|
+
Bundler.setup
|
5
|
+
require 'takeout'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
WebMock.disable_net_connect!(:allow => "codeclimate.com")
|
8
|
+
|
9
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
10
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
11
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
12
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
13
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
14
|
+
# files.
|
15
|
+
#
|
16
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
17
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
18
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
19
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
20
|
+
# a separate helper file that requires the additional dependencies and performs
|
21
|
+
# the additional setup, and require it from the spec files that actually need
|
22
|
+
# it.
|
23
|
+
#
|
24
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
25
|
+
# users commonly want.
|
26
|
+
#
|
27
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
28
|
+
RSpec.configure do |config|
|
29
|
+
# rspec-expectations config goes here. You can use an alternate
|
30
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
31
|
+
# assertions if you prefer.
|
32
|
+
config.expect_with :rspec do |expectations|
|
33
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
34
|
+
# and `failure_message` of custom matchers include text for helper methods
|
35
|
+
# defined using `chain`, e.g.:
|
36
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
37
|
+
# # => "be bigger than 2 and smaller than 4"
|
38
|
+
# ...rather than:
|
39
|
+
# # => "be bigger than 2"
|
40
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
44
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
45
|
+
config.mock_with :rspec do |mocks|
|
46
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
47
|
+
# a real object. This is generally recommended, and will default to
|
48
|
+
# `true` in RSpec 4.
|
49
|
+
mocks.verify_partial_doubles = true
|
50
|
+
end
|
51
|
+
|
52
|
+
# The settings below are suggested to provide a good initial experience
|
53
|
+
# with RSpec, but feel free to customize to your heart's content.
|
54
|
+
=begin
|
55
|
+
# These two settings work together to allow you to limit a spec run
|
56
|
+
# to individual examples or groups you care about by tagging them with
|
57
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
58
|
+
# get run.
|
59
|
+
config.filter_run :focus
|
60
|
+
config.run_all_when_everything_filtered = true
|
61
|
+
|
62
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
63
|
+
# recommended. For more details, see:
|
64
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
65
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
66
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
67
|
+
config.disable_monkey_patching!
|
68
|
+
|
69
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
70
|
+
# be too noisy due to issues in dependencies.
|
71
|
+
config.warnings = true
|
72
|
+
|
73
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
74
|
+
# file, and it's useful to allow more verbose output when running an
|
75
|
+
# individual spec file.
|
76
|
+
if config.files_to_run.one?
|
77
|
+
# Use the documentation formatter for detailed output,
|
78
|
+
# unless a formatter has already been configured
|
79
|
+
# (e.g. via a command-line flag).
|
80
|
+
config.default_formatter = 'doc'
|
81
|
+
end
|
82
|
+
|
83
|
+
# Print the 10 slowest examples and example groups at the
|
84
|
+
# end of the spec run, to help surface which specs are running
|
85
|
+
# particularly slow.
|
86
|
+
config.profile_examples = 10
|
87
|
+
|
88
|
+
# Run specs in random order to surface order dependencies. If you find an
|
89
|
+
# order dependency and want to debug it, you can fix the order by providing
|
90
|
+
# the seed, which is printed after each run.
|
91
|
+
# --seed 1234
|
92
|
+
config.order = :random
|
93
|
+
|
94
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
95
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
96
|
+
# test failures related to randomization by passing the same `--seed` value
|
97
|
+
# as the one that triggered the failure.
|
98
|
+
Kernel.srand config.seed
|
99
|
+
=end
|
100
|
+
|
101
|
+
config.before(:each) do
|
102
|
+
stub_request(:any, /test.com/).to_rack(FakeTestApi)
|
103
|
+
end
|
104
|
+
end
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
class FakeTestApi < Sinatra::Base
|
4
|
+
REQUEST_TYPES = [:get, :put, :post, :delete]
|
5
|
+
#
|
6
|
+
# /posts endpoints
|
7
|
+
#
|
8
|
+
get('/posts') {json_response 200, 'posts.json'}
|
9
|
+
post('/posts') {json_response 200, 'post.json'}
|
10
|
+
delete('/posts') {json_response 404, nil}
|
11
|
+
put('/posts') {json_response 404, nil}
|
12
|
+
|
13
|
+
#
|
14
|
+
# /posts/1 endpoints
|
15
|
+
#
|
16
|
+
get('/posts/1') {json_response 200, 'post.json'}
|
17
|
+
delete('/posts/1') {json_response 200, 'post.json'}
|
18
|
+
put('/posts/1') {json_response 200, 'post.json'}
|
19
|
+
post('/posts/1') {json_response 404, nil}
|
20
|
+
|
21
|
+
#
|
22
|
+
# /fake_failure
|
23
|
+
#
|
24
|
+
REQUEST_TYPES.each {|rt| self.superclass.send(rt, '/fake_failure') {json_response 500, nil}}
|
25
|
+
|
26
|
+
#
|
27
|
+
# /fake_missing
|
28
|
+
#
|
29
|
+
REQUEST_TYPES.each {|rt| self.superclass.send(rt, '/fake_missing') {json_response 404, nil}}
|
30
|
+
|
31
|
+
#
|
32
|
+
# /fake_redirect
|
33
|
+
#
|
34
|
+
REQUEST_TYPES.each {|rt| self.superclass.send(rt, '/fake_redirect') {json_response 301, nil}}
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def json_response(response_code, file_name)
|
39
|
+
content_type :json
|
40
|
+
status response_code
|
41
|
+
File.open(File.dirname(__FILE__) + '/fixtures/' + file_name, 'rb').read if file_name
|
42
|
+
end
|
43
|
+
end
|
data/takeout.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'takeout/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "takeout"
|
8
|
+
spec.version = Takeout::VERSION
|
9
|
+
spec.authors = ["Kyle Lucas"]
|
10
|
+
spec.email = ["kglucas93@gmail.com"]
|
11
|
+
spec.summary = %q{A simple ruby library to autogenerate api clients.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = '>= 1.8.0'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_runtime_dependency "oj"
|
25
|
+
spec.add_runtime_dependency "curb"
|
26
|
+
spec.add_runtime_dependency "liquid"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "sinatra"
|
29
|
+
spec.add_development_dependency "webmock"
|
30
|
+
spec.add_development_dependency "guard", "2.12.5"
|
31
|
+
spec.add_development_dependency "guard-rspec", '4.5.0'
|
32
|
+
spec.add_development_dependency "guard-bundler"
|
33
|
+
spec.add_development_dependency "guard-rake"
|
34
|
+
spec.add_development_dependency "terminal-notifier-guard"
|
35
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
36
|
+
spec.add_development_dependency 'guard-yard'
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: takeout
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kyle Lucas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: oj
|
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: curb
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
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: liquid
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
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: rspec
|
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: sinatra
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webmock
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: guard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 2.12.5
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.12.5
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: guard-rspec
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 4.5.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 4.5.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: guard-bundler
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: guard-rake
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: terminal-notifier-guard
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: codeclimate-test-reporter
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: guard-yard
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
description: ''
|
224
|
+
email:
|
225
|
+
- kglucas93@gmail.com
|
226
|
+
executables: []
|
227
|
+
extensions: []
|
228
|
+
extra_rdoc_files: []
|
229
|
+
files:
|
230
|
+
- ".gitignore"
|
231
|
+
- ".rspec"
|
232
|
+
- Gemfile
|
233
|
+
- Guardfile
|
234
|
+
- LICENSE.txt
|
235
|
+
- README.md
|
236
|
+
- Rakefile
|
237
|
+
- circle.yml
|
238
|
+
- lib/.DS_Store
|
239
|
+
- lib/takeout.rb
|
240
|
+
- lib/takeout/client.rb
|
241
|
+
- lib/takeout/endpoint_failure_error.rb
|
242
|
+
- lib/takeout/version.rb
|
243
|
+
- spec/.DS_Store
|
244
|
+
- spec/client_spec.rb
|
245
|
+
- spec/spec_helper.rb
|
246
|
+
- spec/support/.DS_Store
|
247
|
+
- spec/support/fake_test_api.rb
|
248
|
+
- spec/support/fixtures/post.json
|
249
|
+
- spec/support/fixtures/posts.json
|
250
|
+
- takeout.gemspec
|
251
|
+
homepage: ''
|
252
|
+
licenses:
|
253
|
+
- MIT
|
254
|
+
metadata: {}
|
255
|
+
post_install_message:
|
256
|
+
rdoc_options: []
|
257
|
+
require_paths:
|
258
|
+
- lib
|
259
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
260
|
+
requirements:
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: 1.8.0
|
264
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
265
|
+
requirements:
|
266
|
+
- - ">="
|
267
|
+
- !ruby/object:Gem::Version
|
268
|
+
version: '0'
|
269
|
+
requirements: []
|
270
|
+
rubyforge_project:
|
271
|
+
rubygems_version: 2.2.2
|
272
|
+
signing_key:
|
273
|
+
specification_version: 4
|
274
|
+
summary: A simple ruby library to autogenerate api clients.
|
275
|
+
test_files:
|
276
|
+
- spec/.DS_Store
|
277
|
+
- spec/client_spec.rb
|
278
|
+
- spec/spec_helper.rb
|
279
|
+
- spec/support/.DS_Store
|
280
|
+
- spec/support/fake_test_api.rb
|
281
|
+
- spec/support/fixtures/post.json
|
282
|
+
- spec/support/fixtures/posts.json
|
283
|
+
has_rdoc:
|