tankard 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: 15d6c67b39b0fbce1ddce69adcdbca40366f1281
4
+ data.tar.gz: e7db9eff7e9a74a9e4794bb509f1a7d73d4980a7
5
+ SHA512:
6
+ metadata.gz: 48d66cb484f2726da1caa59f15905f46a1494742793d16a00083c1fb5ae21472f776d0997029f7c77362183eca5e4db79b32463466c9df456fdbd65387efdd2b
7
+ data.tar.gz: f06bb814da4bb553a938dd77584cdbd0a41fa8bce2ef4aca962bf5e5b615a280be51ad7d78175ba78c1db074511fc0a30cea8b3d13ffc581d531986cfe183c47
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/.travis.yml ADDED
@@ -0,0 +1,33 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby-19mode
4
+ - rbx-19mode
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - ruby-head
8
+ - jruby-head
9
+ jdk:
10
+ - openjdk6
11
+ - openjdk7
12
+ - oraclejdk7
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
16
+ - rvm: jruby-head
17
+ exclude:
18
+ - rvm: 1.9.3
19
+ jdk: openjdk7
20
+ - rvm: 1.9.3
21
+ jdk: oraclejdk7
22
+ - rvm: 2.0.0
23
+ jdk: openjdk7
24
+ - rvm: 2.0.0
25
+ jdk: oraclejdk7
26
+ - rvm: ruby-head
27
+ jdk: openjdk7
28
+ - rvm: ruby-head
29
+ jdk: oraclejdk7
30
+ - rvm: rbx-19mode
31
+ jdk: openjdk7
32
+ - rvm: rbx-19mode
33
+ jdk: oraclejdk7
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+ * Support for querying a beer
3
+ * Support for querying a list of beers
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tankard.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Matthew Shafer
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,55 @@
1
+ # Tankard
2
+ [![Build Status](https://travis-ci.org/matthewshafer/tankard.png?branch=master)](https://travis-ci.org/matthewshafer/tankard)
3
+ [![Dependency Status](https://gemnasium.com/matthewshafer/tankard.png)](https://gemnasium.com/matthewshafer/tankard)
4
+ [![Code Climate](https://codeclimate.com/github/matthewshafer/tankard.png)](https://codeclimate.com/github/matthewshafer/tankard)
5
+ [![Coverage Status](https://coveralls.io/repos/matthewshafer/tankard/badge.png?branch=master)](https://coveralls.io/r/matthewshafer/tankard)
6
+
7
+ Allows easy quering of the BreweryDB Api
8
+
9
+ ## About
10
+
11
+ I decided to make Tankard for a personal project and then figured why not put it on github as I am working on it.
12
+ Tankard is very immature at the moment. I plan on adding support for all of the get routes to the BreweryDB Api.
13
+ I've also been pretty interested in Jruby as of late and wanted to make Tankard thread safe.
14
+
15
+ ## Installation
16
+
17
+ Soon...
18
+
19
+ ## Documentation
20
+
21
+ Soon...
22
+
23
+ ## Usage
24
+
25
+ If you happen to be using Rails you can do the configuration in an initializer, something like:
26
+
27
+ ```ruby
28
+ require 'tankard'
29
+
30
+ Tankard.configure do |config|
31
+ config.api_key = "YOUR_API_KEY"
32
+ end
33
+ ```
34
+
35
+ After being configured this is a sample of ways to use Tankard:
36
+
37
+ ### Beer
38
+
39
+ ```ruby
40
+ Tankard.beer.id("some_id").breweries.each { |x| p x}
41
+
42
+ beer = Tankard.beer.find(["first_id", "second_id"])
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ ### Issues
48
+
49
+ Issues can be reported right here on the git repo.
50
+ Everyone is encouraged to write an issue if they encounter a bug or have a feature request.
51
+
52
+ ### Pull Requests
53
+
54
+ I will be accepting pull requests once I get most of the endpoints implemented.
55
+ Check back soon for more details.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,88 @@
1
+ require 'hashie'
2
+ require 'tankard/api/request/get'
3
+
4
+ module Tankard
5
+ module Api
6
+ class Beer
7
+ include ::Enumerable
8
+ include Tankard::Api::Request::Get
9
+
10
+ def initialize(request, options={})
11
+ @request = request
12
+ @options = Hashie::Mash.new(options)
13
+ end
14
+
15
+ def each(&block)
16
+ find_on_single_page(block)
17
+ end
18
+
19
+ def find(beer_id, options={})
20
+ @options.merge!(options)
21
+
22
+ if beer_id.is_a?(Array)
23
+ beer_id.map { |beer| request_data_with_nil_on_http_error(@request, "beer/#{beer}", @options) }.compact
24
+ else
25
+ request_data_with_nil_on_http_error(@request, "beer/#{beer_id}", @options)
26
+ end
27
+ end
28
+
29
+ def id(beer_id)
30
+ @options.id = beer_id
31
+ self
32
+ end
33
+
34
+ def breweries
35
+ @options.endpoint = "breweries"
36
+ self
37
+ end
38
+
39
+ def events
40
+ @options.endpoint = "events"
41
+ self
42
+ end
43
+
44
+ def ingredients
45
+ @options.endpoint = "ingredients"
46
+ self
47
+ end
48
+
49
+ def social_accounts
50
+ @options.endpoint = "socialaccounts"
51
+ self
52
+ end
53
+
54
+ def variations
55
+ @options.endpoint = "variations"
56
+ self
57
+ end
58
+
59
+ private
60
+
61
+ def request_data_from_options
62
+ endpoint = "beer/#{raise_if_no_id_in_options}"
63
+
64
+ if @options.endpoint?
65
+ endpoint += "/#{@options.delete(:endpoint)}"
66
+ end
67
+
68
+ request_data(@request, endpoint, @options)
69
+ end
70
+
71
+ def raise_if_no_id_in_options
72
+ raise Tankard::Error::NoBeerId unless @options.id?
73
+ @options.delete(:id)
74
+ end
75
+
76
+ def find_on_single_page(block)
77
+ data = request_data_from_options
78
+ raise Tankard::Error::InvalidResponse unless data
79
+
80
+ if data.is_a?(Hash)
81
+ block.call(data)
82
+ else
83
+ data.each { |beer| block.call(beer) }
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,65 @@
1
+ require 'hashie'
2
+ require 'tankard/api/request/get'
3
+
4
+ module Tankard
5
+ module Api
6
+ class Beers
7
+ include ::Enumerable
8
+ include Tankard::Api::Request::Get
9
+
10
+ def initialize(request, options={})
11
+ @request = request
12
+ @options = Hashie::Mash.new(options)
13
+ end
14
+
15
+ def each(&block)
16
+ if options_have_page_set
17
+ find_on_single_page(block)
18
+ else
19
+ find_on_all_pages(block)
20
+ end
21
+ end
22
+
23
+ def name(beer_name)
24
+ @options[:name] = beer_name
25
+ self
26
+ end
27
+
28
+ def page(number)
29
+ @options[:p] = number
30
+ self
31
+ end
32
+
33
+ private
34
+
35
+ def options_have_page_set
36
+ @options.has_key?(:p)
37
+ end
38
+
39
+ def find_on_all_pages(block)
40
+ page = 0
41
+ options = @options.clone
42
+ begin
43
+ page += 1
44
+ options[:p] = page
45
+ response = get_request(@request, "beers", options)
46
+ total_pages = response["numberOfPages"].to_i
47
+ data = response["data"]
48
+ raise Tankard::Error::InvalidResponse unless data
49
+ data.each { |beer| block.call(beer) }
50
+ end while page < total_pages
51
+ end
52
+
53
+ def find_on_single_page(block)
54
+ data = request_data(@request, "beers", @options)
55
+ raise Tankard::Error::InvalidResponse unless data
56
+
57
+ if data.is_a?(Hash)
58
+ block.call(data)
59
+ else
60
+ data.each { |beer| block.call(beer) }
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ module Tankard
2
+ module Api
3
+ module Request
4
+ module Get
5
+
6
+ private
7
+
8
+ def request_data_with_nil_on_http_error(request_object, uri, options)
9
+ begin
10
+ request_data(request_object, uri, options)
11
+ rescue Tankard::Error::HttpError
12
+ nil
13
+ end
14
+ end
15
+
16
+ # break up the request methods into smaller pieces
17
+ def request_data(request_object, uri, options)
18
+ get_request(request_object, uri, options)["data"]
19
+ end
20
+
21
+ def get_request(request_object, uri, options)
22
+ request_object.get(uri, options)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ require 'tankard/request'
2
+ require 'tankard/api/beer'
3
+ require 'tankard/api/beers'
4
+
5
+ module Tankard
6
+ class Client
7
+
8
+ def initialize(options={})
9
+ Tankard::Configuration::KEYS.each do |key|
10
+ instance_variable_set(:"@#{key}", options[key])
11
+ end
12
+
13
+ @tankard_request = Tankard::Request.new(@api_key)
14
+ end
15
+
16
+ def beer(options={})
17
+ Tankard::Api::Beer.new(@tankard_request, options)
18
+ end
19
+
20
+ def beers(options={})
21
+ Tankard::Api::Beers.new(@tankard_request, options)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ module Tankard
2
+ module Configuration
3
+ attr_writer :api_key
4
+
5
+ KEYS = [:api_key]
6
+ BREWERYDB_URL = "http://api.brewerydb.com/v2/"
7
+
8
+ def configure
9
+ yield self
10
+ validate_api_key!
11
+ self
12
+ end
13
+
14
+ def reset!
15
+ Tankard::Configuration::KEYS.each do |key|
16
+ instance_variable_set(:"@{key}", nil)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def credentials
23
+ {
24
+ api_key: @api_key
25
+ }
26
+ end
27
+
28
+ def validate_api_key!
29
+ unless @api_key.is_a?(String)
30
+ raise Tankard::Error::ConfigurationError, "api_key is not a string"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ module Tankard
2
+ module Error
3
+ ConfigurationError = Class.new(::StandardError)
4
+ NoBeerId = Class.new(::StandardError)
5
+ HttpError = Class.new(::StandardError)
6
+ LoadError = Class.new(::StandardError)
7
+ InvalidResponse = Class.new(::StandardError)
8
+ ApiKeyUnauthorized = Class.new(::StandardError)
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ require 'multi_json'
2
+ require 'httpclient'
3
+ require 'tankard/error'
4
+
5
+ module Tankard
6
+ class Request
7
+
8
+ def initialize(api_key)
9
+ @http = HTTPClient.new
10
+ @api_key = api_key
11
+ end
12
+
13
+ def get(route, params={})
14
+ params[:key] = @api_key
15
+ request = @http.get(build_request_url(route), params)
16
+ raise_if_status_not_ok(request.status)
17
+ load_json(request.body)
18
+ end
19
+
20
+ private
21
+
22
+ def raise_if_status_not_ok(status)
23
+ case status
24
+ when 200
25
+ true
26
+ when 401
27
+ raise Tankard::Error::ApiKeyUnauthorized
28
+ else
29
+ raise Tankard::Error::HttpError
30
+ end
31
+ end
32
+
33
+ def build_request_url(route)
34
+ Tankard::Configuration::BREWERYDB_URL + route
35
+ end
36
+
37
+ def load_json(json_data)
38
+ begin
39
+ MultiJson.load(json_data)
40
+ rescue MultiJson::LoadError
41
+ raise Tankard::Error::LoadError
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Tankard
2
+ VERSION = "0.0.1"
3
+ end
data/lib/tankard.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "tankard/version"
2
+ require "tankard/configuration"
3
+ require "tankard/error"
4
+ require "tankard/client"
5
+ require "atomic"
6
+
7
+ module Tankard
8
+ @client = ::Atomic.new
9
+
10
+ class << self
11
+ include Configuration
12
+
13
+ def client
14
+ @client.compare_and_swap(nil, Tankard::Client.new(credentials)) unless @client.value
15
+ @client.value
16
+ end
17
+
18
+ def respond_to?(method)
19
+ return client.respond_to?(method)
20
+ end
21
+
22
+ private
23
+
24
+ def method_missing(method_name, *args, &block)
25
+ return super unless client.respond_to?(method_name)
26
+ client.send(method_name, *args, &block)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start do
9
+ add_filter '/spec/'
10
+ end
11
+
12
+ require 'tankard'
13
+ require 'rspec'
14
+ require 'webmock/rspec'
15
+
16
+ WebMock.disable_net_connect!(allow: 'coveralls.io')
17
+
18
+ def stub_get(path)
19
+ stub_request(:get, "http://api.brewerydb.com/v2/" + path)
20
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tankard::Api::Beer do
4
+
5
+ let(:beer) { Tankard::Api::Beer.new(@request) }
6
+
7
+ before do
8
+ @request = mock("request")
9
+ end
10
+
11
+ describe "#find" do
12
+
13
+ before do
14
+ @valid_beers = ["valid1", "valid2"]
15
+ @invalid_beers = ["invalid1", "invalid2"]
16
+ @request.stub(:get).with("beer/valid1", {}).and_return({ "data" => "valid1_found"})
17
+ @request.stub(:get).with("beer/valid2", {}).and_return({ "data" => "valid2_found"})
18
+ @request.stub(:get).with("beer/invalid1", {}).and_raise(Tankard::Error::HttpError)
19
+ @request.stub(:get).with("beer/invalid2", {}).and_raise(Tankard::Error::HttpError)
20
+ end
21
+
22
+ context "when looking up a valid beer" do
23
+
24
+ it "returns data on that specific beer" do
25
+ expect(beer.find(@valid_beers.first)).to eql("valid1_found")
26
+ end
27
+ end
28
+
29
+ context "when looking up an invalid beer" do
30
+
31
+ it "returns nil when not found" do
32
+ expect(beer.find(@invalid_beers.first)).to eql(nil)
33
+ end
34
+ end
35
+
36
+ context "when looking up multiple valid beers" do
37
+
38
+ it "returns an array of data with each beer" do
39
+ expect(beer.find(@valid_beers)).to eql(["valid1_found", "valid2_found"])
40
+ end
41
+ end
42
+
43
+ context "when looking up multiple beers and one is invalid" do
44
+
45
+ it "returns an array with only the valid beers" do
46
+ beer_request = @valid_beers + @invalid_beers
47
+ expect(beer.find(beer_request)).to eql(["valid1_found", "valid2_found"])
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#id" do
53
+
54
+ it "sets the options[:id] to the beer id passed in" do
55
+ beer.id("port")
56
+ beer_options = beer.instance_variable_get(:"@options")
57
+ expect(beer_options[:id]).to eql("port")
58
+ end
59
+
60
+ it "returns itself" do
61
+ expect(beer.object_id).to eql(beer.id("port").object_id)
62
+ end
63
+ end
64
+
65
+ describe "#breweries" do
66
+
67
+ it "sets the options[:endpoint] to breweries" do
68
+ beer.breweries
69
+ beer_options = beer.instance_variable_get(:"@options")
70
+ expect(beer_options[:endpoint]).to eql("breweries")
71
+ end
72
+
73
+ it "returns itself" do
74
+ expect(beer.object_id).to eql(beer.breweries.object_id)
75
+ end
76
+ end
77
+
78
+ describe "#events" do
79
+
80
+ it "sets the options[:endpoint] to events" do
81
+ beer.events
82
+ beer_options = beer.instance_variable_get(:"@options")
83
+ expect(beer_options[:endpoint]).to eql("events")
84
+ end
85
+
86
+ it "returns itself" do
87
+ expect(beer.object_id).to eql(beer.events.object_id)
88
+ end
89
+ end
90
+
91
+ describe "#ingredients" do
92
+
93
+ it "sets the options[:endpoint] to ingredients" do
94
+ beer.ingredients
95
+ beer_options = beer.instance_variable_get(:"@options")
96
+ expect(beer_options[:endpoint]).to eql("ingredients")
97
+ end
98
+
99
+ it "returns itself" do
100
+ expect(beer.object_id).to eql(beer.ingredients.object_id)
101
+ end
102
+ end
103
+
104
+ describe "#social_accounts" do
105
+
106
+ it "sets the options[:endpoint] to socialaccounts" do
107
+ beer.social_accounts
108
+ beer_options = beer.instance_variable_get(:"@options")
109
+ expect(beer_options[:endpoint]).to eql("socialaccounts")
110
+ end
111
+
112
+ it "returns itself" do
113
+ expect(beer.object_id).to eql(beer.social_accounts.object_id)
114
+ end
115
+ end
116
+
117
+ describe "#variations" do
118
+
119
+ it "sets teh options[:endpoint] to variations" do
120
+ beer.variations
121
+ beer_options = beer.instance_variable_get(:"@options")
122
+ expect(beer_options[:endpoint]).to eql("variations")
123
+ end
124
+
125
+ it "returns itself" do
126
+ expect(beer.object_id).to eql(beer.variations.object_id)
127
+ end
128
+ end
129
+
130
+ describe "when making a request" do
131
+
132
+ context "the id for a beer is not set" do
133
+
134
+ it "raises a Tankard::Error::NoBeerId error" do
135
+ expect { beer.each { |b| p b } }.to raise_error(Tankard::Error::NoBeerId)
136
+ end
137
+ end
138
+
139
+ context "the id for a beer is set" do
140
+
141
+ before do
142
+ @request.stub(:get).with("beer/valid1", {}).and_return({ "data" => { "valid1_found" => "beer", "valid1_found_more" => "more_details" }})
143
+ end
144
+
145
+ it "uses the beer id in the uri" do
146
+ expect(beer.id("valid1").collect { |x| x }).to eql([{"valid1_found" => "beer", "valid1_found_more" => "more_details" }])
147
+ end
148
+ end
149
+
150
+ context "the endpoint is set" do
151
+
152
+ before do
153
+ @request.stub(:get).with("beer/valid1/breweries", {}).and_return({ "data" => ["valid1_found"]})
154
+ end
155
+
156
+ it "adds the endpoint to the request" do
157
+ expect(beer.id("valid1").breweries.collect { |x| x }).to eql(["valid1_found"])
158
+ end
159
+ end
160
+
161
+ context "additional options are set" do
162
+
163
+ before do
164
+ @beer_with_options = Tankard::Api::Beer.new(@request, test: "123", id: "valid1")
165
+ @request.stub(:get).with("beer/valid1", Hashie::Mash.new(test: "123")).and_return({ "data" => ["valid1_found"]})
166
+ end
167
+
168
+ it "passes them to the request" do
169
+ expect(@beer_with_options.collect { |x| x }).to eql(["valid1_found"])
170
+ end
171
+ end
172
+
173
+ context "no data is returned" do
174
+
175
+ before do
176
+ @request.stub(:get).with("beer/valid1", {}).and_return({})
177
+ end
178
+
179
+ it "gracefully fails" do
180
+ expect { beer.id("valid1").collect { |x| x} }.to raise_error(Tankard::Error::InvalidResponse)
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tankard::Api::Beers do
4
+ let(:beers) { Tankard::Api::Beers.new(@request) }
5
+
6
+ before do
7
+ @request = mock("request")
8
+ end
9
+
10
+ describe "#name" do
11
+
12
+ it "sets the options[:name] of a beer" do
13
+ beers.name("stone")
14
+ beers_options = beers.instance_variable_get(:"@options")
15
+ expect(beers_options[:name]).to eql("stone")
16
+ end
17
+
18
+ it "returns self" do
19
+ expect(beers.object_id).to eql(beers.name("stone").object_id)
20
+ end
21
+ end
22
+
23
+ describe "#page" do
24
+
25
+ it "sets the options[:p] for the page number" do
26
+ beers.page(1)
27
+ beers_options = beers.instance_variable_get(:"@options")
28
+ expect(beers_options[:p]).to eql(1)
29
+ end
30
+
31
+ it "returns self" do
32
+ expect(beers.object_id).to eql(beers.page(1).object_id)
33
+ end
34
+ end
35
+
36
+ describe "when making a request" do
37
+
38
+ context "and a page is set" do
39
+
40
+ it "only queries a single page" do
41
+ beers.should_receive(:find_on_single_page)
42
+ beers.page(1).each { |x| x }
43
+ end
44
+ end
45
+
46
+ context "and a page is not set" do
47
+
48
+ it "queries multiple pages" do
49
+ beers.should_receive(:find_on_all_pages)
50
+ beers.each { |x| x }
51
+ end
52
+ end
53
+
54
+ context "and additional options are set without a page" do
55
+
56
+ before do
57
+ @beers_with_options = Tankard::Api::Beers.new(@request, test: "123")
58
+ @request.stub(:get).with("beers", Hashie::Mash.new(test: "123", p: 1)).and_return({ "data" => ["beers"]})
59
+ end
60
+
61
+ it "passes them to the request" do
62
+ expect(@beers_with_options.collect { |x| x }).to eql(["beers"])
63
+ end
64
+ end
65
+
66
+ context "and additional options are set with a page" do
67
+
68
+ before do
69
+ @beers_with_options = Tankard::Api::Beers.new(@request, test: "123", p: 2)
70
+ @request.stub(:get).with("beers", Hashie::Mash.new(test: "123", p: 2)).and_return({ "data" => ["beers"]})
71
+ end
72
+
73
+ it "passes them to the request" do
74
+ expect(@beers_with_options.collect { |x| x }).to eql(["beers"])
75
+ end
76
+ end
77
+
78
+ context "and no data is returned on a single page request" do
79
+
80
+ before do
81
+ @beers = Tankard::Api::Beers.new(@request, p: 1)
82
+ @request.stub(:get).with("beers", Hashie::Mash.new(p: 1)).and_return({})
83
+ end
84
+
85
+ it "raises a Tankard::Error::InvalidResponse error" do
86
+ expect { @beers.collect { |x| x} }.to raise_error(Tankard::Error::InvalidResponse)
87
+ end
88
+ end
89
+
90
+ context "and no data is returned on a page in a multi page request" do
91
+
92
+ before do
93
+ @beers = Tankard::Api::Beers.new(@request)
94
+ @request.stub(:get).with("beers", Hashie::Mash.new(p: 1)).and_return({"numberOfPages" => 2, "data" => ["test1", "test2"]})
95
+ @request.stub(:get).with("beers", Hashie::Mash.new(p: 2)).and_return({})
96
+ end
97
+
98
+ it "raises a Tankard::Error::InvalidResponse error" do
99
+ expect { @beers.collect { |x| x} }.to raise_error(Tankard::Error::InvalidResponse)
100
+ end
101
+ end
102
+
103
+ context "and a page is not specified" do
104
+
105
+ before do
106
+ @beers = Tankard::Api::Beers.new(@request)
107
+ @request.stub(:get).with("beers", Hashie::Mash.new(p: 1)).and_return({"numberOfPages" => 2, "data" => ["test1", "test2"]})
108
+ @request.stub(:get).with("beers", Hashie::Mash.new(p: 2)).and_return({"numberOfPages" => 2, "data" => ["test3", "test4"]})
109
+ end
110
+
111
+ it "runs through all of the pages returned by brewerydb" do
112
+ expect(@beers.collect { |x| x}).to eql(["test1", "test2", "test3", "test4"])
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tankard::Client do
4
+
5
+ let(:client) { Tankard::Client.new({api_key: "abc123"}) }
6
+
7
+ describe "#beer" do
8
+
9
+ context "when called" do
10
+
11
+ it "does not reuse an existing beer object" do
12
+ first_beer = client.beer
13
+ expect(first_beer.object_id != client.beer.object_id).to be_true
14
+ end
15
+ end
16
+
17
+ context "when passed a hash of options" do
18
+
19
+ before do
20
+ @request = mock("request")
21
+ Tankard::Request.stub!(:new).and_return(@request)
22
+ end
23
+
24
+ it "passes the options to the beer object" do
25
+ Tankard::Api::Beer.should_receive(:new).with(@request, {test: 123})
26
+ client.beer({test: 123})
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#beers" do
32
+
33
+ context "when called" do
34
+
35
+ it "does not reuse an existing beer object" do
36
+ beers = client.beers
37
+ expect(beers.object_id != client.beers.object_id).to be_true
38
+ end
39
+ end
40
+
41
+ context "when passed a hash of options" do
42
+
43
+ before do
44
+ @request = mock("request")
45
+ Tankard::Request.stub!(:new).and_return(@request)
46
+ end
47
+
48
+ it "passes the options to the beer object" do
49
+ Tankard::Api::Beers.should_receive(:new).with(@request, {test: 123})
50
+ client.beers({test: 123})
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tankard::Request do
4
+
5
+ let(:request) { Tankard::Request.new("abc123") }
6
+
7
+ describe "#get" do
8
+
9
+ context "request status is not 200 or 401" do
10
+
11
+ it "raises a Tankard::Error::HttpError" do
12
+ stub_get("test?key=abc123").to_return(status: [404, "Not Found"])
13
+ expect { request.get("test") }.to raise_error(Tankard::Error::HttpError)
14
+ end
15
+ end
16
+
17
+ context "request status is 401" do
18
+
19
+ it "raises a Tankard::Error::ApiKeyUnauthorized error" do
20
+ stub_get("test?key=abc123").to_return(status: [401, "Unauthorized"])
21
+ expect { request.get("test") }.to raise_error(Tankard::Error::ApiKeyUnauthorized)
22
+ end
23
+ end
24
+
25
+ context "request status is 200" do
26
+
27
+ it "does not raise a Tankard::Error::HttpError" do
28
+ stub_get("test?key=abc123").to_return(status: 200)
29
+ expect { request.get("test") }.not_to raise_error(Tankard::Error::HttpError)
30
+ end
31
+ end
32
+
33
+ context "valid json response" do
34
+
35
+ it "returns the json decoded body" do
36
+ stub_get("test?key=abc123").to_return(body: '{ "beer_name": "Smoked Porter" }')
37
+ expect(request.get("test")["beer_name"]).to eql("Smoked Porter")
38
+ end
39
+ end
40
+
41
+ context "invalid json response" do
42
+
43
+ it "raises an error" do
44
+ stub_get("test?key=abc123").to_return(body: '{')
45
+ expect { request.get("test") }.to raise_error(Tankard::Error::LoadError)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tankard do
4
+
5
+ context "when delegating to a client" do
6
+
7
+ before do
8
+ Tankard::Client.any_instance.stub(:test).and_return("testing")
9
+ end
10
+
11
+ it "delegates to Tankard::Client" do
12
+ expect(Tankard.test).to eql("testing")
13
+ end
14
+
15
+ describe ".respond_to?" do
16
+
17
+ it "delegates to Tankard::Client" do
18
+ expect(Tankard.respond_to?(:test)).to be_true
19
+ end
20
+ end
21
+
22
+ describe ".client" do
23
+
24
+ it "returns a Tankard::Client" do
25
+ expect(Tankard.client).to be_kind_of(Tankard::Client)
26
+ end
27
+
28
+ it "does not create a new Tankard::Client when one is already created" do
29
+ client = Tankard.client
30
+ expect(Tankard.client).to eql(client)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe ".configuration" do
36
+
37
+ context "when invalid configuration data is provided" do
38
+
39
+ it "raises a configuration error" do
40
+ expect {
41
+ Tankard.configure do |config|
42
+ config.api_key = 1234
43
+ end
44
+ }.to raise_error(Tankard::Error::ConfigurationError)
45
+ end
46
+ end
47
+
48
+ context "when valid configuration data is provided" do
49
+
50
+ before do
51
+ Tankard.configure do |config|
52
+ config.api_key = "abc123"
53
+ end
54
+ end
55
+
56
+ it "sets the api_key" do
57
+ expect(Tankard.instance_variable_get(:"@api_key")).to eql("abc123")
58
+ end
59
+ end
60
+ end
61
+ end
data/tankard.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tankard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tankard"
8
+ spec.version = Tankard::VERSION
9
+ spec.authors = ["Matthew Shafer"]
10
+ spec.email = ["matthewshafer@mac.com"]
11
+ spec.description = %q{Connector to the BreweryDB api}
12
+ spec.summary = %q{Allows easy quering to the breweryDB api}
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.13.0"
24
+ spec.add_development_dependency "webmock", "~> 1.11.0"
25
+ spec.add_development_dependency "simplecov", "~> 0.7.1"
26
+ spec.add_development_dependency "coveralls", "~> 0.6.4"
27
+ spec.add_development_dependency "pry", "~> 0.9.12"
28
+
29
+ spec.add_dependency "atomic", "~> 1.1.0"
30
+ spec.add_dependency "httpclient", "~> 2.3.3"
31
+ spec.add_dependency "multi_json", "~> 1.7.2"
32
+ spec.add_dependency "hashie", "~> 2.0.3"
33
+ end
metadata ADDED
@@ -0,0 +1,228 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tankard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Shafer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-03 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.13.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.13.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.11.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.11.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.7.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.7.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.6.4
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.6.4
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 0.9.12
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.9.12
111
+ - !ruby/object:Gem::Dependency
112
+ name: atomic
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.1.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 1.1.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: httpclient
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 2.3.3
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 2.3.3
139
+ - !ruby/object:Gem::Dependency
140
+ name: multi_json
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: 1.7.2
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: 1.7.2
153
+ - !ruby/object:Gem::Dependency
154
+ name: hashie
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: 2.0.3
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ version: 2.0.3
167
+ description: Connector to the BreweryDB api
168
+ email:
169
+ - matthewshafer@mac.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - .gitignore
175
+ - .rspec
176
+ - .travis.yml
177
+ - CHANGELOG.md
178
+ - Gemfile
179
+ - LICENSE.txt
180
+ - README.md
181
+ - Rakefile
182
+ - lib/tankard.rb
183
+ - lib/tankard/api/beer.rb
184
+ - lib/tankard/api/beers.rb
185
+ - lib/tankard/api/request/get.rb
186
+ - lib/tankard/client.rb
187
+ - lib/tankard/configuration.rb
188
+ - lib/tankard/error.rb
189
+ - lib/tankard/request.rb
190
+ - lib/tankard/version.rb
191
+ - spec/spec_helper.rb
192
+ - spec/tankard/api/beer_spec.rb
193
+ - spec/tankard/api/beers_spec.rb
194
+ - spec/tankard/client_spec.rb
195
+ - spec/tankard/request_spec.rb
196
+ - spec/tankard_spec.rb
197
+ - tankard.gemspec
198
+ homepage: ''
199
+ licenses:
200
+ - MIT
201
+ metadata: {}
202
+ post_install_message:
203
+ rdoc_options: []
204
+ require_paths:
205
+ - lib
206
+ required_ruby_version: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - '>='
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
211
+ required_rubygems_version: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - '>='
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ requirements: []
217
+ rubyforge_project:
218
+ rubygems_version: 2.0.0
219
+ signing_key:
220
+ specification_version: 4
221
+ summary: Allows easy quering to the breweryDB api
222
+ test_files:
223
+ - spec/spec_helper.rb
224
+ - spec/tankard/api/beer_spec.rb
225
+ - spec/tankard/api/beers_spec.rb
226
+ - spec/tankard/client_spec.rb
227
+ - spec/tankard/request_spec.rb
228
+ - spec/tankard_spec.rb