rapidash 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb726775f243e6328acdfa4a53fba2ecbb81727d
4
+ data.tar.gz: fe0fdea46f6798d999095c5acf7d337c291cba14
5
+ SHA512:
6
+ metadata.gz: 16a571aab676ca4d1f8f4209abbe3104184920c78f65349dbf50f12f6abf089f4347fefc66f57b154a55fd0752a3a548432a29fdd783748293de30f9d9ac0b74
7
+ data.tar.gz: fd8f336dc1436a0ca683c16a692006851dd6f3e9e5eddf0afc7d558740b1006dbbb66b4b92bf47a5656f04d91e1891c06952b3a15d7714788accc4a6c96f289f
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rapidash.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Gary 'Gazler' Rennie
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,116 @@
1
+ # Rapidash
2
+
3
+ Rapidash is an opinionated core for you to build a client for your API on. The goal is to define a standard way that developers can quickly write a client for the consumption of their RESTful API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rapidash'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rapidash
18
+
19
+ ## Usage
20
+
21
+ ### Resources
22
+
23
+ Resources can be defined as follows:
24
+
25
+ class Users < Rapidash::Base
26
+ url "users"
27
+ end
28
+
29
+ ### Client
30
+
31
+ The main thing a client must do is define a method, `oauth` and `http` are currently supported. You can also define resources which links a resource as defined above to the client.
32
+
33
+ class Client < Rapidash::Client
34
+ method :oauth
35
+ resource :users
36
+ end
37
+
38
+ OAuth provides an initialize method which you can see in the Facebook client example.
39
+
40
+ Currently when using the HTTP method, you will need to define your own initialize method to set the site in use.
41
+
42
+ ### Making calls
43
+
44
+ client = Client.new
45
+ client.site = "http://example.com/"
46
+ client.users #Returns an instance of Users
47
+ client.users! #Will make a call to "http://example.com/users
48
+ client.users!(1) #Will make a call to http://example.com/users/1
49
+ client.users!(params => {:page => 1}}) # Will make a call to http://example.com/users?page=1
50
+
51
+ ## Example Clients
52
+
53
+ ### Facebook
54
+
55
+ require 'rapidash'
56
+
57
+ class Me < Rapidash::Base
58
+ url "me"
59
+ end
60
+
61
+ class Facebook < Rapidash::Client
62
+ method :oauth
63
+ resource :me
64
+ end
65
+
66
+ client = Facebook`.new({
67
+ :site => "https://graph.facebook.com",
68
+ :uid => "YOUR_ID",
69
+ :secret => "YOUR_SECRET",
70
+ :access_token => "YOUR_TOKEN"
71
+ })
72
+ p client.me!.first_name #Gary
73
+
74
+ ### Github
75
+
76
+ require 'rapidash'
77
+
78
+ class Users < Rapidash::Base
79
+ url :users
80
+
81
+ def user(name)
82
+ self.url += "/#{name}"
83
+ self
84
+ end
85
+
86
+ def repos!
87
+ self.url += "/repos"
88
+ call!
89
+ end
90
+
91
+ def user!(name)
92
+ user(name)
93
+ call!
94
+ end
95
+ end
96
+
97
+ class Github < Rapidash::Client
98
+ method :http
99
+ resource :users
100
+
101
+ def initialize
102
+ @site = "https://api.github.com/"
103
+ end
104
+ end
105
+
106
+ client = Github.new
107
+ p client.users.user!("Gazler").name #Gary Rennie
108
+ p client.users.user("Gazler").repos![0].name #Githug
109
+
110
+ ## Contributing
111
+
112
+ 1. Fork it
113
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
114
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
115
+ 4. Push to the branch (`git push origin my-new-feature`)
116
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/rapidash.rb ADDED
@@ -0,0 +1,17 @@
1
+ require "rapidash/version"
2
+
3
+ require "rapidash/errors"
4
+
5
+ require "rapidash/response"
6
+
7
+ require "rapidash/clientable"
8
+ require "rapidash/client"
9
+
10
+ require "rapidash/urlable"
11
+ require "rapidash/base"
12
+
13
+ require "rapidash/http_client"
14
+ require "rapidash/oauth_client"
15
+
16
+ module Rapidash
17
+ end
@@ -0,0 +1,20 @@
1
+ module Rapidash
2
+ class Base
3
+
4
+ include Urlable
5
+ attr_accessor :url, :options, :client
6
+
7
+ def initialize
8
+ raise ConfigurationError.new "Missing URL attribute on the resource, set it by calling `url` in your resource class"
9
+ end
10
+
11
+
12
+ def call!
13
+ self.options ||= {}
14
+ self.options[:header] ||= {}
15
+ self.options[:header]["content-type"] = "application/json"
16
+ method = self.options.delete(:method) || :get
17
+ client.send(method, url, self.options)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Rapidash
2
+ class Client
3
+ include Clientable
4
+
5
+ def initialize
6
+ raise ConfigurationError.new "Missing Method, define using `method` on your client"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,37 @@
1
+ module Rapidash
2
+ module Clientable
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ def method(method)
11
+ if method == :http
12
+ include HTTPClient
13
+ elsif method == :oauth
14
+ include OAuthClient
15
+ else
16
+ raise ConfigurationError.new "Invalid API Authentication Method"
17
+ end
18
+ end
19
+
20
+ def resource(name)
21
+ mod = self.to_s.split("::")[0...-1]
22
+ if mod.empty?
23
+ mod = Kernel
24
+ else
25
+ mod = Kernel.const_get(mod.join("::"))
26
+ end
27
+ klass = mod.const_get(name.capitalize)
28
+ define_method(name) do |*args|
29
+ klass.new(self, *args)
30
+ end
31
+ define_method("#{name}!".to_sym) do |*args|
32
+ klass.new(self, *args).call!
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ module Rapidash
2
+ class ParseError < StandardError; end
3
+ class ConfigurationError < StandardError; end
4
+ end
@@ -0,0 +1,39 @@
1
+ require 'faraday'
2
+
3
+ module Rapidash
4
+ module HTTPClient
5
+
6
+ attr_accessor :site
7
+ attr_writer :connection
8
+
9
+ def site=(value)
10
+ @connection = nil
11
+ @site = value
12
+ end
13
+
14
+ def connection
15
+ @connection ||= Faraday.new(site)
16
+ end
17
+
18
+ def get(url, options = {})
19
+ request(:get, url, options)
20
+ end
21
+
22
+ def post(url, options = {})
23
+ request(:post, url, options)
24
+ end
25
+
26
+ def request(verb, url, options = {})
27
+ url = connection.build_url(url, options[:params]).to_s
28
+ response = connection.run_request(verb, url, options[:body], options[:header])
29
+
30
+ case response.status.to_s[0]
31
+ #Handle redirects
32
+ when "3"
33
+ request(verb, response.headers["location"], options)
34
+ when "2"
35
+ return Response.new(response)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ require 'oauth2'
2
+ require 'hashie'
3
+
4
+ module Rapidash
5
+ module OAuthClient
6
+
7
+ attr_accessor :secret, :uid, :access_token, :site
8
+
9
+ def initialize(options)
10
+ [:uid, :secret, :site].each do |key|
11
+ if options[key]
12
+ self.send("#{key.to_s}=".to_sym, options[key])
13
+ else
14
+ raise ConfigurationError.new "Missing #{key} value"
15
+ end
16
+ end
17
+ self.access_token = options[:access_token] if options[:access_token]
18
+ end
19
+
20
+ def get(url, params = {})
21
+ request(:get, url, :params => params)
22
+ end
23
+
24
+ def request(verb, url, options = {})
25
+ response = oauth_access_token.send(verb.to_sym, "#{site}/#{url}", options)
26
+ body = JSON.parse(response.body)
27
+ if body.kind_of?(Hash)
28
+ return Hashie::Mash.new(body)
29
+ elsif body.kind_of?(Array)
30
+ output = []
31
+ body.each do |el|
32
+ output << Hashie::Mash.new(el)
33
+ end
34
+ return output
35
+ end
36
+ end
37
+
38
+ def access_token_from_code(code, url)
39
+ token = client.auth_code.get_token(code, :redirect_uri => url)
40
+ self.access_token = token.token
41
+ end
42
+
43
+ private
44
+
45
+ def client
46
+ @oauth_client ||= ::OAuth2::Client.new(uid, secret, :site => site)
47
+ end
48
+
49
+ def oauth_access_token
50
+ @oauth_access_token ||= ::OAuth2::AccessToken.new(client, access_token)
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+ require 'hashie'
3
+
4
+ module Rapidash
5
+ class Response
6
+
7
+ class << self
8
+ def new(response)
9
+ type = response.headers["content-type"]
10
+ if type.include?("application/json")
11
+ body = JSON.parse(response.body)
12
+ if body.kind_of?(Hash)
13
+ return Hashie::Mash.new(body)
14
+ elsif body.kind_of?(Array)
15
+ output = []
16
+ body.each do |el|
17
+ output << Hashie::Mash.new(el)
18
+ end
19
+ return output
20
+ end
21
+ else
22
+ raise ParseError.new("Cannot parse content type: #{response.headers["content-type"]}")
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+
@@ -0,0 +1,28 @@
1
+ module Rapidash
2
+ module Urlable
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def url(url)
10
+ self.class_eval do
11
+ define_method(:initialize) do |*args|
12
+ @client, id, options = args
13
+ if id.is_a?(Hash)
14
+ options = id
15
+ id = nil
16
+ end
17
+ @options ||= {}
18
+ options ||= {}
19
+ @options.merge!(options)
20
+ @url = url.to_s
21
+ @url += "/#{id}" if id
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Rapidash
2
+ VERSION = "0.0.1"
3
+ end
data/rapidash.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rapidash/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rapidash"
8
+ spec.version = Rapidash::VERSION
9
+ spec.authors = ["Gary 'Gazler' Rennie"]
10
+ spec.email = ["gazler@gmail.com"]
11
+ spec.description = %q{Evolve your API}
12
+ spec.summary = %q{An opinionated core for creating clients for RESTful APIs quickly}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.8"
24
+
25
+ spec.add_dependency 'faraday', '~> 0.8'
26
+ spec.add_dependency "oauth2", "~>0.6"
27
+ spec.add_dependency "hashie", "~>1.2"
28
+
29
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ class BaseTester < Rapidash::Base
4
+ url "tester"
5
+ end
6
+
7
+ class InvalidApiTester < Rapidash::Base
8
+ end
9
+
10
+
11
+ describe Rapidash::Base do
12
+
13
+ describe ".initialize" do
14
+
15
+ it "should raise an error" do
16
+ expect {
17
+ InvalidApiTester.new
18
+ }.to raise_error(Rapidash::ConfigurationError)
19
+ end
20
+
21
+ it "should not raise an error if url has been called" do
22
+ expect {
23
+ BaseTester.new.should be_valid
24
+ }.to_not raise_error(Rapidash::ConfigurationError)
25
+ end
26
+
27
+ end
28
+
29
+ let(:client) { mock }
30
+ let(:headers) { {"content-type" => "application/json"} }
31
+ let (:subject) { BaseTester.new(client) }
32
+
33
+ describe ".call!" do
34
+ it "should call get on the client" do
35
+ subject.url = "tester/1"
36
+ client.should_receive(:get).with("tester/1", {:header => headers})
37
+ subject.call!
38
+ end
39
+
40
+
41
+ it "should call a post on the client if set" do
42
+ client.should_receive(:post).with("tester", {:header => headers})
43
+ subject.options = {:method => :post}
44
+ subject.url = "tester"
45
+ subject.call!
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rapidash::Client do
4
+ it "should raise an error when instantiated" do
5
+ expect {
6
+ Rapidash::Client.new
7
+ }.to raise_error(Rapidash::ConfigurationError)
8
+ end
9
+ end
@@ -0,0 +1,99 @@
1
+ require "spec_helper"
2
+
3
+ class Rapidash::Users
4
+ def initialize(*args)
5
+ end
6
+ end
7
+
8
+ class Users
9
+ def initialize(*args)
10
+ end
11
+ end
12
+
13
+ class Rapidash::ClientTester
14
+ include Rapidash::Clientable
15
+ resource :users
16
+ end
17
+
18
+ class ClientTester
19
+ include Rapidash::Clientable
20
+ resource :users
21
+ end
22
+
23
+ class OAuthClientTester
24
+ include Rapidash::Clientable
25
+ method :oauth
26
+ end
27
+
28
+ class HTTPClientTester
29
+ include Rapidash::Clientable
30
+ method :http
31
+ end
32
+
33
+
34
+
35
+ describe Rapidash::Clientable do
36
+
37
+ describe "#included" do
38
+ it "should include the resource method" do
39
+ Rapidash::ClientTester.methods.should include(:resource)
40
+ end
41
+
42
+ it "should include the method method" do
43
+ Rapidash::ClientTester.methods.should include(:method)
44
+ end
45
+ end
46
+
47
+ describe "#resource" do
48
+ it "should add a method with the name of the argument" do
49
+ Rapidash::ClientTester.new.methods.should include(:users)
50
+ end
51
+
52
+ it "should add a bang method with the name of the argument" do
53
+ Rapidash::ClientTester.new.methods.should include(:users!)
54
+ end
55
+ end
56
+
57
+ describe "#method" do
58
+
59
+ it "should include the HTTPClient" do
60
+ client = HTTPClientTester.new
61
+ client.class.ancestors.should include(Rapidash::HTTPClient)
62
+ end
63
+
64
+ it "should include the OAuthClient" do
65
+ client = OAuthClientTester.new({:uid => "foo", :secret => "bar", :site => "baz"})
66
+ client.class.ancestors.should include(Rapidash::OAuthClient)
67
+ end
68
+
69
+ it "should raise an error on anything else" do
70
+ expect {
71
+ class InvalidClientTester
72
+ include Rapidash::Clientable
73
+ method :invalid
74
+ end
75
+ }.to raise_error(Rapidash::ConfigurationError)
76
+ end
77
+
78
+ end
79
+
80
+ describe ".users" do
81
+ it "should return an instance of the resource" do
82
+ Rapidash::ClientTester.new.users.class.should eql(Rapidash::Users)
83
+ end
84
+
85
+ it "should not use a namespace if not in a module" do
86
+ ClientTester.new.users.class.should eql(Users)
87
+ end
88
+ end
89
+
90
+ describe ".tickets!" do
91
+ it "should return an instance of the resource and call it" do
92
+ users = mock
93
+ Rapidash::Users.should_receive(:new).and_return(users)
94
+ users.should_receive(:call!)
95
+ Rapidash::ClientTester.new.users!
96
+ end
97
+ end
98
+
99
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ class HTTPTester
4
+ include Rapidash::HTTPClient
5
+ end
6
+
7
+ describe Rapidash::HTTPClient do
8
+
9
+ let!(:subject) { HTTPTester.new }
10
+
11
+ describe ".site=" do
12
+ it "should clear the connection variable" do
13
+ subject.instance_variable_get(:@connection).should eql(nil)
14
+ subject.connection
15
+ subject.instance_variable_get(:@connection).class.should eql(Faraday::Connection)
16
+ subject.site = "foo"
17
+ subject.instance_variable_get(:@connection).should eql(nil)
18
+ end
19
+
20
+ it "should set the site variable" do
21
+ subject.instance_variable_get(:@site).should eql(nil)
22
+ subject.site = "foo"
23
+ subject.instance_variable_get(:@site).should eql("foo")
24
+ end
25
+ end
26
+
27
+ describe ".connection" do
28
+ it "should create a Faraday object" do
29
+ subject.connection.class.should eql(Faraday::Connection)
30
+ end
31
+ end
32
+
33
+ describe ".get" do
34
+ it "should call request" do
35
+ subject.should_receive(:request).with(:get, "foo", {})
36
+ subject.get("foo")
37
+ end
38
+ end
39
+
40
+ describe ".get" do
41
+ it "should call request" do
42
+ subject.should_receive(:request).with(:post, "foo", {})
43
+ subject.post("foo")
44
+ end
45
+ end
46
+
47
+
48
+ describe ".request" do
49
+
50
+ let!(:valid_response) { OpenStruct.new(:status => "200")}
51
+ let!(:redirect_response) { OpenStruct.new(:status => "301", :headers => {"location" => "http://example.com/redirect"})}
52
+
53
+ before(:each) do
54
+ subject.site = "http://example.com"
55
+ Rapidash::Response.should_receive(:new).and_return("response")
56
+ end
57
+
58
+ it "should return a response object" do
59
+ subject.connection.should_receive(:run_request).with(:get, "http://example.com/foo", nil, nil).and_return(valid_response)
60
+ response = subject.request(:get, "foo")
61
+ response.should eql("response")
62
+ end
63
+
64
+ it "should perform a redirect" do
65
+ subject.connection.should_receive(:run_request).with(:get, "http://example.com/foo", nil, nil).and_return(redirect_response)
66
+ subject.connection.should_receive(:run_request).with(:get, "http://example.com/redirect", nil, nil).and_return(valid_response)
67
+ response = subject.request(:get, "foo")
68
+ response.should eql("response")
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ class OAuthTester
4
+ include Rapidash::OAuthClient
5
+ end
6
+
7
+ describe Rapidash::OAuthClient do
8
+
9
+ let(:options) do
10
+ Hash({
11
+ :uid => "foo",
12
+ :secret => "bar",
13
+ :access_token => "baz",
14
+ :site => "http://example.com"
15
+ })
16
+ end
17
+
18
+ let(:subject) { OAuthTester.new(options) }
19
+
20
+
21
+ describe ".site" do
22
+ it "should be example.com" do
23
+ subject.site.should eql("http://example.com")
24
+ end
25
+ end
26
+
27
+ describe ".access_token_from_code" do
28
+ it "should call livestax for the access token" do
29
+ auth_code = mock
30
+ client = mock
31
+ subject.stub(:client).and_return(client)
32
+ client.should_receive(:auth_code).and_return(auth_code)
33
+ auth_code.should_receive(:get_token).with("123", :redirect_uri => "http://localhost").and_return(OpenStruct.new(:token => "token"))
34
+ subject.access_token_from_code("123", "http://localhost").should eql("token")
35
+ end
36
+ end
37
+
38
+ describe ".client" do
39
+ it "should be an OAuth2::Client" do
40
+ subject.send(:client).class.should eql(OAuth2::Client)
41
+ end
42
+ end
43
+
44
+ describe ".oauth_access_token" do
45
+ it "should be an OAuth2::AccessToken" do
46
+ subject.send(:oauth_access_token).class.should eql(OAuth2::AccessToken)
47
+ end
48
+ end
49
+
50
+ describe ".get" do
51
+ it "should call request with the parameters" do
52
+ subject.should_receive(:request).with(:get, "me", :params => {:page => 1})
53
+ subject.get("me", {:page => 1})
54
+ end
55
+ end
56
+
57
+ describe ".request" do
58
+
59
+ let(:request) { mock }
60
+
61
+ describe "object returned from API call" do
62
+
63
+ let(:body) { {:foo => "bar"}.to_json }
64
+ let(:response) { OpenStruct.new(:body => body) }
65
+
66
+ before(:each) do
67
+ subject.stub(:oauth_access_token).and_return(request)
68
+ request.stub(:get).and_return(response)
69
+ end
70
+ it "should return a Hashie::Mash" do
71
+ subject.request(:get, "me").class.should eql(Hashie::Mash)
72
+ end
73
+
74
+ it "should return a traversable object" do
75
+ subject.request(:get, "me").foo.should eql("bar")
76
+ end
77
+
78
+ end
79
+
80
+ describe "array returned from API call" do
81
+
82
+ let(:body) { [{:foo => "bar"}, {:baz => "bra"}].to_json }
83
+ let(:response) { OpenStruct.new(:body => body) }
84
+
85
+ before(:each) do
86
+ subject.stub(:oauth_access_token).and_return(request)
87
+ request.stub(:get).and_return(response)
88
+ end
89
+ it "should return an array" do
90
+ subject.request(:get, "me").class.should eql(Array)
91
+ end
92
+
93
+ it "should return a traversable object" do
94
+ response = subject.request(:get, "me")
95
+ response[0].foo.should eql("bar")
96
+ response[1].baz.should eql("bra")
97
+ end
98
+
99
+ end
100
+ end
101
+
102
+
103
+ end
104
+
@@ -0,0 +1,57 @@
1
+ require 'json'
2
+ require "spec_helper"
3
+
4
+ def valid_response_object
5
+ body = {"foo" => "bar" }.to_json
6
+ OpenStruct.new({
7
+ :headers => {
8
+ "content-type" => "application/json"
9
+ },
10
+ :body => body
11
+ })
12
+ end
13
+
14
+
15
+ def valid_response_array
16
+ body = [{"foo" => "bar" }, {"baz" => "bra"}].to_json
17
+ OpenStruct.new({
18
+ :headers => {
19
+ "content-type" => "application/json"
20
+ },
21
+ :body => body
22
+ })
23
+ end
24
+
25
+
26
+ def invalid_response
27
+ OpenStruct.new({
28
+ :headers => {
29
+ "content-type" => "application/xml"
30
+ }
31
+ })
32
+ end
33
+
34
+ describe Rapidash::Response do
35
+
36
+ describe "#new" do
37
+ it "should parse JSON Objects" do
38
+ response = Rapidash::Response.new(valid_response_object)
39
+ response.foo.should eql("bar")
40
+ end
41
+
42
+ it "should parse JSON Arrays" do
43
+ response = Rapidash::Response.new(valid_response_array)
44
+ response[0].foo.should eql("bar")
45
+ response[1].baz.should eql("bra")
46
+ end
47
+
48
+
49
+ it "should raise an error on a non-json response" do
50
+ expect {
51
+ Rapidash::Response.new(invalid_response)
52
+ }.to raise_error(Rapidash::ParseError)
53
+ end
54
+ end
55
+
56
+
57
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ class ApiTester
4
+ attr_accessor :url, :options, :client
5
+ include Rapidash::Urlable
6
+ url :foo
7
+ end
8
+
9
+ class ApiTesterNoUrl
10
+ include Rapidash::Urlable
11
+ end
12
+
13
+ describe Rapidash::Urlable do
14
+
15
+ let!(:client) { mock }
16
+
17
+ describe "#included" do
18
+ it "should add the url method" do
19
+ ApiTester.methods.should include(:url)
20
+ end
21
+ end
22
+
23
+ describe "#url" do
24
+ it "should override the initialize to set a url" do
25
+ ApiTesterNoUrl.new.instance_variable_get(:@url).should eql(nil)
26
+ ApiTester.new.instance_variable_get(:@url).should eql("foo")
27
+ end
28
+
29
+ it "should set options on the class" do
30
+ api = ApiTester.new(client, :option1 => "foo")
31
+ api.instance_variable_get(:@options).should eql({:option1 => "foo"})
32
+ api.instance_variable_get(:@url).should eql("foo")
33
+ end
34
+
35
+ it "should let an id be set on initialization" do
36
+ api = ApiTester.new(client, 1, :option1 => "foo")
37
+ api.instance_variable_get(:@options).should eql({:option1 => "foo"})
38
+ api.instance_variable_get(:@url).should eql("foo/1")
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,2 @@
1
+ require "./lib/rapidash"
2
+ require "ostruct"
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rapidash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gary 'Gazler' Rennie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-07 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: oauth2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.6'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: hashie
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.2'
97
+ description: Evolve your API
98
+ email:
99
+ - gazler@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - lib/rapidash.rb
111
+ - lib/rapidash/base.rb
112
+ - lib/rapidash/client.rb
113
+ - lib/rapidash/clientable.rb
114
+ - lib/rapidash/errors.rb
115
+ - lib/rapidash/http_client.rb
116
+ - lib/rapidash/oauth_client.rb
117
+ - lib/rapidash/response.rb
118
+ - lib/rapidash/urlable.rb
119
+ - lib/rapidash/version.rb
120
+ - rapidash.gemspec
121
+ - spec/rapidash/base_spec.rb
122
+ - spec/rapidash/client_spec.rb
123
+ - spec/rapidash/clientable_spec.rb
124
+ - spec/rapidash/http_client_spec.rb
125
+ - spec/rapidash/oauth_client_spec.rb
126
+ - spec/rapidash/response_spec.rb
127
+ - spec/rapidash/urlable_spec.rb
128
+ - spec/spec_helper.rb
129
+ homepage: ''
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.0.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: An opinionated core for creating clients for RESTful APIs quickly
153
+ test_files:
154
+ - spec/rapidash/base_spec.rb
155
+ - spec/rapidash/client_spec.rb
156
+ - spec/rapidash/clientable_spec.rb
157
+ - spec/rapidash/http_client_spec.rb
158
+ - spec/rapidash/oauth_client_spec.rb
159
+ - spec/rapidash/response_spec.rb
160
+ - spec/rapidash/urlable_spec.rb
161
+ - spec/spec_helper.rb