beer_list 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +44 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/beer_list.gemspec +19 -0
- data/lib/beer_list/establishments/edina_grill.rb +15 -0
- data/lib/beer_list/establishments/establishment.rb +24 -0
- data/lib/beer_list/establishments/groveland_tap.rb +15 -0
- data/lib/beer_list/establishments/longfellow_grill.rb +42 -0
- data/lib/beer_list/establishments/muddy_waters.rb +30 -0
- data/lib/beer_list/establishments/three_squares.rb +15 -0
- data/lib/beer_list/establishments.rb +12 -0
- data/lib/beer_list/exceptions.rb +16 -0
- data/lib/beer_list/list.rb +20 -0
- data/lib/beer_list/scraper.rb +28 -0
- data/lib/beer_list.rb +76 -0
- data/spec/lib/beer_list/establishments/establishment_spec.rb +52 -0
- data/spec/lib/beer_list/list_spec.rb +26 -0
- data/spec/lib/beer_list_spec.rb +111 -0
- data/spec/spec_helper.rb +12 -0
- metadata +119 -0
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
beer_list (0.0.1)
|
5
|
+
mechanize (= 2.6.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.3)
|
10
|
+
domain_name (0.5.9)
|
11
|
+
unf (>= 0.0.5, < 1.0.0)
|
12
|
+
mechanize (2.6.0)
|
13
|
+
domain_name (~> 0.5, >= 0.5.1)
|
14
|
+
mime-types (~> 1.17, >= 1.17.2)
|
15
|
+
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
16
|
+
net-http-persistent (~> 2.5, >= 2.5.2)
|
17
|
+
nokogiri (~> 1.4)
|
18
|
+
ntlm-http (~> 0.1, >= 0.1.1)
|
19
|
+
webrobots (>= 0.0.9, < 0.2)
|
20
|
+
mime-types (1.22)
|
21
|
+
net-http-digest_auth (1.3)
|
22
|
+
net-http-persistent (2.8)
|
23
|
+
nokogiri (1.5.9)
|
24
|
+
ntlm-http (0.1.1)
|
25
|
+
rspec (2.12.0)
|
26
|
+
rspec-core (~> 2.12.0)
|
27
|
+
rspec-expectations (~> 2.12.0)
|
28
|
+
rspec-mocks (~> 2.12.0)
|
29
|
+
rspec-core (2.12.2)
|
30
|
+
rspec-expectations (2.12.1)
|
31
|
+
diff-lcs (~> 1.1.3)
|
32
|
+
rspec-mocks (2.12.2)
|
33
|
+
unf (0.1.1)
|
34
|
+
unf_ext
|
35
|
+
unf_ext (0.0.6)
|
36
|
+
webrobots (0.1.1)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
beer_list!
|
43
|
+
bundler (~> 1.3)
|
44
|
+
rspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Dan Olson
|
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,74 @@
|
|
1
|
+
# Beer List
|
2
|
+
|
3
|
+
A utility for retrieving the beer list from various establishments
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
`require 'beer_list'`
|
8
|
+
|
9
|
+
### Getting a List
|
10
|
+
|
11
|
+
See what's on tap:
|
12
|
+
|
13
|
+
```
|
14
|
+
# An array-like object
|
15
|
+
list = BeerList.groveland_tap
|
16
|
+
|
17
|
+
# As a hash
|
18
|
+
list.to_hash
|
19
|
+
|
20
|
+
# As JSON
|
21
|
+
list.to_json
|
22
|
+
```
|
23
|
+
|
24
|
+
You may want to get lists for more than one establishment at a time. To do so, register
|
25
|
+
the desired establishments in BeerList.establishments:
|
26
|
+
|
27
|
+
```
|
28
|
+
three_squares = BeerList::Establishments::ThreeSquares.new
|
29
|
+
muddy_waters = BeerList::Establishments::MuddyWaters.new
|
30
|
+
|
31
|
+
BeerList.establishments << three_squares
|
32
|
+
BeerList.establishments << muddy_waters
|
33
|
+
|
34
|
+
# Array of BeerList::List objects
|
35
|
+
BeerList.lists
|
36
|
+
|
37
|
+
# As a hash
|
38
|
+
BeerList.list_as_hash
|
39
|
+
|
40
|
+
# As JSON
|
41
|
+
BeerList.list_as_json
|
42
|
+
```
|
43
|
+
|
44
|
+
The Lists will be memoized until the content of BeerList.establishments changes so that
|
45
|
+
The establishments don't have to be re-scraped each time the list is requested.
|
46
|
+
|
47
|
+
### Extending BeerList with More Establishments
|
48
|
+
|
49
|
+
BeerList ships with a limited number of establishments, but it's easy to write your own.
|
50
|
+
Your establishment class must inherit from BeerList::Establishments::Establishment,
|
51
|
+
and provide two instance methods: `get_list` and `url`. `url` should be the url of the beer list on your establishment's website. `get_list` should handle parsing and
|
52
|
+
manipulating a Mechanize::Page object in order to scrape the contents of your beer list.
|
53
|
+
|
54
|
+
For example:
|
55
|
+
|
56
|
+
```
|
57
|
+
module BeerList
|
58
|
+
module Establishments
|
59
|
+
class Applebirds
|
60
|
+
URL = 'http://applebirds.com/beers'
|
61
|
+
|
62
|
+
def get_list
|
63
|
+
page.search('p.beer').map(&:text)
|
64
|
+
end
|
65
|
+
|
66
|
+
def url
|
67
|
+
URL
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Checkout [This link](http://mechanize.rubyforge.org/) for more on Mechanize
|
data/beer_list.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = 'beer_list'
|
3
|
+
spec.version = '0.0.1'
|
4
|
+
spec.authors = ['Dan Olson']
|
5
|
+
spec.email = ['olson_dan@yahoo.com']
|
6
|
+
spec.description = 'A utility for retrieving the beer list from various establishments'
|
7
|
+
spec.summary = 'A beer list scraper'
|
8
|
+
spec.homepage = 'https://github.com/DanOlson/beer_list'
|
9
|
+
spec.license = 'MIT'
|
10
|
+
|
11
|
+
spec.files = `git ls-files`.split($/)
|
12
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
13
|
+
spec.test_files = spec.files.grep(%r{^(spec)/})
|
14
|
+
spec.require_paths = ['lib']
|
15
|
+
|
16
|
+
spec.add_dependency 'mechanize', '2.6.0'
|
17
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
18
|
+
spec.add_development_dependency 'rspec'
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module BeerList
|
2
|
+
module Establishments
|
3
|
+
class Establishment
|
4
|
+
attr_accessor :scraper, :page
|
5
|
+
|
6
|
+
def list
|
7
|
+
raise BeerList::NoScraperError unless @scraper
|
8
|
+
@list ||= BeerList::List.new get_list, short_class_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_list
|
12
|
+
raise "#{__method__} is not implemented in #{self.class.name}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def url
|
16
|
+
raise "#{__method__} is not implemented in #{self.class.name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def short_class_name
|
20
|
+
self.class.name.split('::').last
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module BeerList
|
2
|
+
module Establishments
|
3
|
+
class LongfellowGrill < Establishment
|
4
|
+
URL = 'http://www.longfellowgrill.com/beer_taps.php'
|
5
|
+
STATE_AND_PRICE_REGEX = /\s*(?:\([A-Z]*\))*\s*\**\s*\d+\.\d{2}$/
|
6
|
+
|
7
|
+
def get_list
|
8
|
+
get_base_list
|
9
|
+
process_base_list
|
10
|
+
@my_list
|
11
|
+
end
|
12
|
+
|
13
|
+
def url
|
14
|
+
URL
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def get_base_list
|
20
|
+
@my_list = page.search('li span').map(&:text)
|
21
|
+
end
|
22
|
+
|
23
|
+
def process_base_list
|
24
|
+
remove_not_applicable
|
25
|
+
remove_special_chars
|
26
|
+
trim_list_items
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_not_applicable
|
30
|
+
@my_list = @my_list.reject{ |e| e.match(/\A\s+\Z|\A\((.*)\)/) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_special_chars
|
34
|
+
@my_list = @my_list.map(&:strip).map{ |e| e.gsub(/\u00a0/, '') }
|
35
|
+
end
|
36
|
+
|
37
|
+
def trim_list_items
|
38
|
+
@my_list = @my_list.map{ |e| e.gsub(STATE_AND_PRICE_REGEX, '') }.uniq
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module BeerList
|
2
|
+
module Establishments
|
3
|
+
class MuddyWaters < Establishment
|
4
|
+
URL = 'http://muddywatersmpls.com/booze.html'
|
5
|
+
|
6
|
+
def get_list
|
7
|
+
get_processed_list
|
8
|
+
end
|
9
|
+
|
10
|
+
def url
|
11
|
+
URL
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_processed_list
|
15
|
+
all = page.search('div.graphic_textbox_layout_style_default p').map(&:text)
|
16
|
+
|
17
|
+
all.pop get_wine_count(all.reverse)
|
18
|
+
all
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_wine_count(ary=[])
|
22
|
+
count = 0
|
23
|
+
ary.each do |e|
|
24
|
+
count += 1
|
25
|
+
break count if e.empty?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module BeerList
|
4
|
+
module Establishments
|
5
|
+
require 'establishments/establishment'
|
6
|
+
require 'establishments/three_squares'
|
7
|
+
require 'establishments/groveland_tap'
|
8
|
+
require 'establishments/edina_grill'
|
9
|
+
require 'establishments/longfellow_grill'
|
10
|
+
require 'establishments/muddy_waters'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module BeerList
|
2
|
+
|
3
|
+
class NoEstablishmentsError < StandardError
|
4
|
+
def initialize(msg=nil)
|
5
|
+
msg ||= "No establishments are registered"
|
6
|
+
super msg
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class NoScraperError < StandardError
|
11
|
+
def initialize(msg=nil)
|
12
|
+
msg ||= "No scraper is registered"
|
13
|
+
super msg
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module BeerList
|
2
|
+
class List < Array
|
3
|
+
attr_reader :establishment
|
4
|
+
|
5
|
+
def initialize(ary, establishment)
|
6
|
+
@establishment = establishment
|
7
|
+
super ary
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_hash
|
11
|
+
Hash[establishment, self.to_a]
|
12
|
+
end
|
13
|
+
|
14
|
+
alias :old_to_json :to_json
|
15
|
+
|
16
|
+
def to_json
|
17
|
+
to_hash.to_json
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BeerList
|
2
|
+
class Scraper
|
3
|
+
attr_reader :agent, :url, :page
|
4
|
+
|
5
|
+
USER_AGENT = 'Mac Safari'
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@agent = Mechanize.new
|
9
|
+
set_user_agent
|
10
|
+
end
|
11
|
+
|
12
|
+
def beer_list(establishment)
|
13
|
+
establishment.scraper = self
|
14
|
+
visit_site establishment
|
15
|
+
establishment.list
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def visit_site(establishment)
|
21
|
+
establishment.page = agent.get(establishment.url)
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_user_agent
|
25
|
+
agent.user_agent_alias = USER_AGENT
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/beer_list.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module BeerList
|
5
|
+
require 'beer_list/scraper'
|
6
|
+
require 'beer_list/establishments'
|
7
|
+
require 'beer_list/list'
|
8
|
+
require 'beer_list/exceptions'
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def establishments
|
13
|
+
return [] if @establishments.nil?
|
14
|
+
@establishments.dup
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear_establishments!
|
18
|
+
@establishments.clear if @establishments
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_establishment(*args)
|
22
|
+
args.each do |e|
|
23
|
+
_establishments << e if e.respond_to?(:get_list)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
alias :add_establishments :add_establishment
|
27
|
+
|
28
|
+
def lists
|
29
|
+
raise NoEstablishmentsError if establishments.empty?
|
30
|
+
|
31
|
+
return @lists unless update_necessary?
|
32
|
+
@lists = establishments.map do |e|
|
33
|
+
scraper.beer_list e
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def lists_as_hash
|
38
|
+
lists.inject({}) do |hsh, list|
|
39
|
+
hsh.merge! list.to_hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def lists_as_json
|
44
|
+
lists_as_hash.to_json
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def scraper
|
50
|
+
@scraper ||= Scraper.new
|
51
|
+
end
|
52
|
+
|
53
|
+
def update_necessary?
|
54
|
+
!@lists || !establishments_eq_lists?
|
55
|
+
end
|
56
|
+
|
57
|
+
def _establishments
|
58
|
+
@establishments ||= []
|
59
|
+
end
|
60
|
+
|
61
|
+
def establishments_eq_lists?
|
62
|
+
list_names = @lists.map(&:establishment)
|
63
|
+
establishments.map(&:short_class_name).all? { |name| list_names.include? name }
|
64
|
+
end
|
65
|
+
|
66
|
+
def method_missing(method, *args, &block)
|
67
|
+
class_name = method.to_s.split('_').map(&:capitalize).join
|
68
|
+
begin
|
69
|
+
klass = ['BeerList', 'Establishments', class_name].compact.inject(Object){ |o, name| o.const_get(name) }
|
70
|
+
scraper.beer_list klass.new
|
71
|
+
rescue NameError
|
72
|
+
super method, *args, &block
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BeerList
|
4
|
+
module Establishments
|
5
|
+
|
6
|
+
describe Establishment do
|
7
|
+
let(:establishment){ BeerList::Establishments::Establishment.new }
|
8
|
+
|
9
|
+
describe '#list' do
|
10
|
+
context "when it doesn't have a scraper" do
|
11
|
+
it "raises an exception" do
|
12
|
+
expect { establishment.list }.to raise_error(NoScraperError)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when it has a scraper' do
|
17
|
+
|
18
|
+
before do
|
19
|
+
establishment.scraper = stub
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns a BeerList::List' do
|
23
|
+
establishment.stub(:get_list){ [] }
|
24
|
+
establishment.list.should be_an_instance_of BeerList::List
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#get_list' do
|
30
|
+
context 'when it is not implemented in a subclass' do
|
31
|
+
it 'raises an exception' do
|
32
|
+
expect { establishment.get_list }.to raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#url' do
|
38
|
+
it 'raises an exception unless it is implemented in a subclass' do
|
39
|
+
expect { establishment.get_list }.to raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#short_class_name' do
|
44
|
+
let(:establishment){ BeerList::Establishments::MuddyWaters.new }
|
45
|
+
|
46
|
+
it 'returns a usable name' do
|
47
|
+
establishment.short_class_name.should == 'MuddyWaters'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BeerList
|
4
|
+
describe List do
|
5
|
+
let(:est_name){ 'MuddyWaters' }
|
6
|
+
let(:list){ List.new [], est_name}
|
7
|
+
|
8
|
+
it 'knows its establishent' do
|
9
|
+
list.establishment.should == est_name
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#to_hash' do
|
13
|
+
it 'hashes its establishment name with its content' do
|
14
|
+
expected = { est_name => [] }
|
15
|
+
list.to_hash.should == expected
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#to_json' do
|
20
|
+
it 'returns the list as json' do
|
21
|
+
expected = "{\"MuddyWaters\":[]}"
|
22
|
+
list.to_json.should == expected
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BeerList do
|
4
|
+
let(:establishment){ BeerList::Establishments::ThreeSquares.new }
|
5
|
+
|
6
|
+
describe '.establishments' do
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
BeerList.clear_establishments!
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns an array' do
|
13
|
+
BeerList.establishments.should be_an_instance_of Array
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.add_establishment' do
|
18
|
+
let(:muddy_waters){ BeerList::Establishments::MuddyWaters.new }
|
19
|
+
|
20
|
+
after(:each) do
|
21
|
+
BeerList.clear_establishments!
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'appends to establishments' do
|
25
|
+
BeerList.add_establishment establishment
|
26
|
+
BeerList.establishments.should include establishment
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'accepts multiple establishments' do
|
30
|
+
BeerList.add_establishment establishment, muddy_waters
|
31
|
+
BeerList.establishments.size.should == 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'rejects invalid input' do
|
35
|
+
BeerList.add_establishment muddy_waters, Object.new
|
36
|
+
BeerList.establishments.size.should == 1
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'can be called multiple times' do
|
40
|
+
BeerList.add_establishment muddy_waters
|
41
|
+
BeerList.add_establishment establishment
|
42
|
+
BeerList.establishments.size.should == 2
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.clear_establishments!' do
|
47
|
+
|
48
|
+
shared_examples_for 'clear_establishments!' do
|
49
|
+
it 'should empty the collection' do
|
50
|
+
BeerList.clear_establishments!
|
51
|
+
BeerList.establishments.should be_empty
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when establishments are registered' do
|
56
|
+
before do
|
57
|
+
BeerList.add_establishment establishment
|
58
|
+
end
|
59
|
+
|
60
|
+
it_behaves_like 'clear_establishments!'
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when no establishments are registered' do
|
64
|
+
it_behaves_like 'clear_establishments!'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.lists' do
|
69
|
+
context 'when no establishments are registered' do
|
70
|
+
it 'should raise an error' do
|
71
|
+
BeerList.clear_establishments!
|
72
|
+
expect { BeerList.lists }.to raise_error(BeerList::NoEstablishmentsError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when establishments are registered' do
|
77
|
+
before(:all) do
|
78
|
+
BeerList.add_establishments establishment
|
79
|
+
end
|
80
|
+
|
81
|
+
after(:all) do
|
82
|
+
BeerList.clear_establishments!
|
83
|
+
end
|
84
|
+
|
85
|
+
before do
|
86
|
+
establishment.stub(:get_list){ ['Darkness', 'Pliney the Elder'] }
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns an array of lists' do
|
90
|
+
BeerList.lists.all?{ |l| l.is_a? BeerList::List }.should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'contains lists for the registered establishments' do
|
94
|
+
BeerList.lists.first.establishment.should == 'ThreeSquares'
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.lists_as_hash' do
|
98
|
+
it 'returns a hash' do
|
99
|
+
BeerList.lists_as_hash.should be_an_instance_of Hash
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '.lists_as_json' do
|
104
|
+
it 'returns JSON' do
|
105
|
+
expect { JSON.parse(BeerList.lists_as_json) }.to_not raise_error
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'beer_list'
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
5
|
+
config.run_all_when_everything_filtered = true
|
6
|
+
|
7
|
+
# Run specs in random order to surface order dependencies. If you find an
|
8
|
+
# order dependency and want to debug it, you can fix the order by providing
|
9
|
+
# the seed, which is printed after each run.
|
10
|
+
# --seed 1234
|
11
|
+
config.order = 'random'
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: beer_list
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Olson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mechanize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.6.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.6.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: A utility for retrieving the beer list from various establishments
|
63
|
+
email:
|
64
|
+
- olson_dan@yahoo.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .rspec
|
70
|
+
- Gemfile
|
71
|
+
- Gemfile.lock
|
72
|
+
- LICENSE.txt
|
73
|
+
- README.md
|
74
|
+
- beer_list.gemspec
|
75
|
+
- lib/beer_list.rb
|
76
|
+
- lib/beer_list/establishments.rb
|
77
|
+
- lib/beer_list/establishments/edina_grill.rb
|
78
|
+
- lib/beer_list/establishments/establishment.rb
|
79
|
+
- lib/beer_list/establishments/groveland_tap.rb
|
80
|
+
- lib/beer_list/establishments/longfellow_grill.rb
|
81
|
+
- lib/beer_list/establishments/muddy_waters.rb
|
82
|
+
- lib/beer_list/establishments/three_squares.rb
|
83
|
+
- lib/beer_list/exceptions.rb
|
84
|
+
- lib/beer_list/list.rb
|
85
|
+
- lib/beer_list/scraper.rb
|
86
|
+
- spec/lib/beer_list/establishments/establishment_spec.rb
|
87
|
+
- spec/lib/beer_list/list_spec.rb
|
88
|
+
- spec/lib/beer_list_spec.rb
|
89
|
+
- spec/spec_helper.rb
|
90
|
+
homepage: https://github.com/DanOlson/beer_list
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 1.8.24
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: A beer list scraper
|
115
|
+
test_files:
|
116
|
+
- spec/lib/beer_list/establishments/establishment_spec.rb
|
117
|
+
- spec/lib/beer_list/list_spec.rb
|
118
|
+
- spec/lib/beer_list_spec.rb
|
119
|
+
- spec/spec_helper.rb
|