hungry 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.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ .rvmrc
4
+ Gemfile.lock
5
+ pkg/*
6
+ tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format s
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in eet.nu.gemspec
4
+ gemspec
5
+
6
+ # Support for guard:
7
+ gem 'guard'
8
+ gem 'guard-bundler'
9
+ gem 'guard-rspec'
10
+ gem 'guard-spork'
11
+ gem 'rb-fsevent'
12
+ gem 'rb-readline'
13
+ gem 'fuubar'
@@ -0,0 +1,11 @@
1
+ require 'rb-readline'
2
+
3
+ guard 'bundler' do
4
+ watch('Gemfile')
5
+ end
6
+
7
+ guard 'rspec', version: 2, cli: '--format Fuubar --colour' do
8
+ watch(%r{^spec/.+_spec\.rb})
9
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
10
+ watch('spec/spec_helper.rb') { "spec" }
11
+ end
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'hungry'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'hungry'
7
+ s.version = Hungry::VERSION
8
+ s.authors = ['Tom-Eric Gerritsen']
9
+ s.email = ['tomeric@eet.nu']
10
+ s.homepage = 'http://github.com/eet-nu/hungry'
11
+ s.summary = %q{An interface to the Eet.nu API.}
12
+ s.description = %q{An interface to the Eet.nu API.}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ['lib']
18
+
19
+ # specify any dependencies here:
20
+ s.add_dependency 'httparty'
21
+ s.add_dependency 'rack'
22
+
23
+ # specify any development dependencies here:
24
+ s.add_development_dependency 'rspec'
25
+ s.add_development_dependency 'fakeweb'
26
+ end
@@ -0,0 +1,37 @@
1
+ $LOAD_PATH << File.expand_path('..', __FILE__)
2
+
3
+ require 'support/presence'
4
+ require 'support/symbolize_keys'
5
+
6
+ module Hungry
7
+ VERSION = '0.0.1'
8
+
9
+ class << self
10
+ attr_accessor :api_url
11
+ end
12
+
13
+ self.api_url = 'http://api.eet.nu/'
14
+
15
+ ### LIBRARY:
16
+
17
+ autoload :City, 'hungry/city'
18
+ autoload :Collection, 'hungry/collection'
19
+ autoload :Country, 'hungry/country'
20
+ autoload :Geolocation, 'hungry/geolocation'
21
+ autoload :Location, 'hungry/location'
22
+ autoload :Region, 'hungry/region'
23
+ autoload :Resource, 'hungry/resource'
24
+ autoload :Review, 'hungry/review'
25
+ autoload :Site, 'hungry/site'
26
+ autoload :Tag, 'hungry/tag'
27
+ autoload :Util, 'hungry/util'
28
+ autoload :Venue, 'hungry/venue'
29
+
30
+ ### EXCEPTIONS:
31
+
32
+ # Exception raised when a geolocation is required, but it is not given:
33
+ class GeolocationNotGiven < StandardError; end
34
+
35
+ # Exception raised when an endpoint is not specified for a resource:
36
+ class EndpointNotSpecified < StandardError; end
37
+ end
@@ -0,0 +1,7 @@
1
+ module Hungry
2
+ class City < Location
3
+
4
+ self.default_criteria = { type: 'City' }
5
+
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ require 'httparty'
2
+ require 'cgi'
3
+
4
+ module Hungry
5
+ class Collection
6
+ include Enumerable
7
+ include HTTParty
8
+
9
+ autoload :Pagination, 'hungry/collection/pagination'
10
+
11
+ attr_reader :klass, :endpoint, :criteria
12
+
13
+ ### CLASS METHODS:
14
+
15
+ def self.get(*args)
16
+ puts "[Collection]: GET #{args.map(&:inspect).join(', ')}"
17
+ self.base_uri Hungry.api_url
18
+ super
19
+ end
20
+
21
+ ### INSTANCE METHODS:
22
+
23
+ def initialize(klass, endpoint, criteria = {})
24
+ @klass = klass
25
+ @endpoint = endpoint
26
+ @criteria = criteria.symbolize_keys
27
+ end
28
+
29
+ def from_url(url)
30
+ uri = URI.parse(url)
31
+ options = Util.params_from_uri(uri) || klass.default_criteria
32
+
33
+ self.class.new(klass, uri.path, options)
34
+ end
35
+
36
+ def all(new_criteria = {})
37
+ self.class.new(klass, endpoint, criteria.merge(new_criteria))
38
+ end
39
+
40
+ def count(*args)
41
+ if args.present?
42
+ super
43
+ else
44
+ response['results'].count
45
+ end
46
+ end
47
+
48
+ def each(&block)
49
+ response['results'].each do |result|
50
+ yield klass.new(result)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def response
57
+ raise NoEndpointSpecified unless endpoint
58
+
59
+ @response ||= begin
60
+ uri = Util.uri_with_params(endpoint, criteria)
61
+ self.class.get uri
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,71 @@
1
+ module Hungry
2
+ class Collection
3
+ module Pagination
4
+ class NotPaginatedError < StandardError; end
5
+
6
+ def paginate(page, options = {})
7
+ all options.merge(page: page)
8
+ end
9
+
10
+ def paginated?
11
+ pagination.present?
12
+ end
13
+
14
+ def per_page
15
+ if paginated?
16
+ pagination['per_page'].to_i
17
+ else
18
+ response['results'].length
19
+ end
20
+ end
21
+
22
+ def total_entries
23
+ if paginated?
24
+ pagination['total_entries'].to_i
25
+ else
26
+ response['results'].length
27
+ end
28
+ end
29
+
30
+ def total_pages
31
+ if paginated?
32
+ pagination['total_pages'].to_i
33
+ else
34
+ 1
35
+ end
36
+ end
37
+
38
+ def current_page
39
+ if paginated?
40
+ pagination['current_page'].to_i
41
+ else
42
+ 1
43
+ end
44
+ end
45
+
46
+ def previous_page
47
+ current_page - 1 if paginated? && current_page > 1
48
+ end
49
+
50
+ def next_page
51
+ current_page + 1 if paginated? && current_page < total_pages
52
+ end
53
+
54
+ def previous
55
+ raise NotPaginatedError unless paginated?
56
+ all page: previous_page if previous_page
57
+ end
58
+
59
+ def next
60
+ raise NotPaginatedError unless paginated?
61
+ all page: next_page if next_page
62
+ end
63
+
64
+ private
65
+
66
+ def pagination
67
+ response['pagination']
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,7 @@
1
+ module Hungry
2
+ class Country < Location
3
+
4
+ self.default_criteria = { type: 'Country' }
5
+
6
+ end
7
+ end
@@ -0,0 +1,63 @@
1
+ module Hungry
2
+ class Geolocation
3
+ attr_accessor :latitude, :longitude
4
+
5
+ def self.parse(input)
6
+ # input is already a Geolocation, so we can return it early:
7
+ return input if input.is_a?(self)
8
+
9
+ if input.respond_to?(:geolocation)
10
+ # input has a geolocation attribute, so try to use that one first:
11
+ geolocation = parse(input.geolocation)
12
+ return geolocation if geolocation
13
+ end
14
+
15
+ coordinates = []
16
+
17
+ if input.respond_to?(:latitude) && input.respond_to?(:longitude)
18
+ # input has latitude and longitude attributes, so use those:
19
+ coordinates = [input.latitude, input.longitude]
20
+
21
+ elsif input.respond_to?(:lat) && input.respond_to?(:lng)
22
+ # input has lat and lng attributes, so use those:
23
+ coordinates = [input.lat, input.lng]
24
+
25
+ elsif input.respond_to?(:match)
26
+ # Example: "50.8469397,5.6927505"
27
+ #
28
+ # input is a String, so we can use a regular expression to extract
29
+ # latitude and longitude:
30
+ if match = input.match(/^(?<latitude>[0-9\.]+),\s?(?<longitude>[0-9\.]+)$/)
31
+ coordinates = [match[:latitude], match[:longitude]]
32
+ end
33
+
34
+ elsif input.respond_to?(:keys)
35
+ # Example: { latitude: 50.8469397, longitude: 5.6927505 }
36
+ #
37
+ # input is a Hash, so we can extract values with the keys:
38
+ coordinates = [input[:latitude] || input[:lat], input[:longitude] || input[:lng]]
39
+
40
+ elsif input.respond_to?(:[])
41
+ # Example: [50.8469397, 5.6927505]
42
+ #
43
+ # input is an Array, so we need the first and second value:
44
+ coordinates = input[0], input[1]
45
+ end
46
+
47
+ coordinates = coordinates.map(&:presence).compact
48
+
49
+ if coordinates.length == 2 && coordinates.all? { |coordinate| Util.is_numeric?(coordinate) }
50
+ new(*coordinates)
51
+ end
52
+ end
53
+
54
+ def initialize(latitude, longitude)
55
+ self.latitude = latitude.to_f
56
+ self.longitude = longitude.to_f
57
+ end
58
+
59
+ def to_s
60
+ [latitude, longitude].join(',')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ module Hungry
2
+ class Location < Resource
3
+
4
+ self.endpoint = '/locations'
5
+
6
+ ### ATTRIBUTES:
7
+
8
+ ### Location:
9
+ attr_accessor :id, :name, :type, :url, :geolocation,
10
+
11
+ ### Utility:
12
+ :resources, :counters
13
+
14
+ ### RESOURCES:
15
+
16
+ has_many :venues, Venue
17
+
18
+ has_many :nearby_venues, Venue
19
+
20
+ has_many :tags, Tag
21
+
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Hungry
2
+ class Region < Location
3
+
4
+ self.default_criteria = { type: 'Region' }
5
+
6
+ end
7
+ end
@@ -0,0 +1,93 @@
1
+ require 'httparty'
2
+
3
+ module Hungry
4
+ class Resource
5
+ include HTTParty
6
+
7
+ attr_accessor :attributes
8
+
9
+ ### CLASS METHODS:
10
+
11
+ def self.get(*args)
12
+ puts "[Resource]: GET #{args.map(&:inspect).join(', ')}"
13
+ self.base_uri Hungry.api_url
14
+ super
15
+ end
16
+
17
+ def self.belongs_to(resource, klass = Resource)
18
+ define_method resource do
19
+ if url = resources[resource]
20
+ attributes = self.class.get url
21
+ klass.new(attributes)
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.has_many(resource, klass = Resource)
27
+ define_method resource do
28
+ if url = resources[resource]
29
+ klass.collection.from_url(url)
30
+ end
31
+ end
32
+ end
33
+
34
+ class << self
35
+ include Enumerable
36
+
37
+ attr_writer :endpoint
38
+ attr_writer :default_criteria
39
+
40
+ def endpoint
41
+ @endpoint || (superclass.respond_to?(:endpoint) ? superclass.endpoint : nil)
42
+ end
43
+
44
+ def default_criteria
45
+ if @default_criteria.respond_to?(:call)
46
+ @default_criteria.call
47
+ else
48
+ @default_criteria || {}
49
+ end
50
+ end
51
+
52
+ def collection
53
+ Collection.new(self, endpoint, default_criteria)
54
+ end
55
+
56
+ def find(id)
57
+ raise NoEndpointSpecified unless endpoint
58
+
59
+ response = get "#{endpoint}/#{id}"
60
+
61
+ if response.code == 200
62
+ new(response)
63
+ end
64
+ end
65
+
66
+ def all(criteria = {})
67
+ collection.all(criteria)
68
+ end
69
+
70
+ def each(&block)
71
+ all.each(&block)
72
+ end
73
+ end
74
+
75
+ ### INSTANCE METHODS:
76
+
77
+ def initialize(new_attributes = {})
78
+ self.attributes = {}
79
+
80
+ new_attributes.each do |key, value|
81
+ if value.respond_to?(:symbolize_keys)
82
+ value = value.symbolize_keys
83
+ end
84
+
85
+ attributes[key] = value
86
+
87
+ if respond_to?("#{key}=")
88
+ send("#{key}=", value)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,19 @@
1
+ require 'httparty'
2
+
3
+ module Hungry
4
+ class Review < Resource
5
+
6
+ ### ATTRIBUTES:
7
+
8
+ ### Review:
9
+ attr_accessor :id, :body, :rating, :scores, :author,
10
+
11
+ ### Utility:
12
+ :created_at, :updated_at
13
+
14
+ ### RESOURCES:
15
+
16
+ belongs_to :venue, Venue
17
+
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module Hungry
2
+ class Site < Resource
3
+
4
+ self.endpoint = '/sites'
5
+
6
+ ### ATTRIBUTES:
7
+
8
+ ### Preview:
9
+ attr_accessor :id, :name, :title, :subtitle, :identifier, :default, :locale,
10
+ :url, :timezone, :country, :applications,
11
+
12
+ ### Utility:
13
+ :resources, :counters
14
+
15
+ ### FINDERS:
16
+
17
+ def self.with_hostname(hostname)
18
+ collection.all(hostname: hostname).first
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Hungry
2
+ class Tag < Resource
3
+
4
+ self.endpoint = '/tags'
5
+
6
+ ### ATTRIBUTES:
7
+
8
+ ### Tag:
9
+ attr_accessor :id, :name, :context,
10
+
11
+ ### Utility:
12
+ :resources, :counters
13
+
14
+ ### RESOURCES:
15
+
16
+ has_many :venues, Venue
17
+
18
+ has_many :tags, Tag
19
+
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'cgi'
2
+ require 'rack/utils'
3
+
4
+ module Hungry
5
+ module Util
6
+ extend self
7
+
8
+ def params_from_uri(uri)
9
+ uri = URI.parse(uri) unless uri.is_a?(URI)
10
+ Rack::Utils.parse_query(uri.query) if uri.query.present?
11
+ end
12
+
13
+ def uri_with_params(uri, params = {})
14
+ params = params.map { |k,v| "#{k}=#{CGI.escape(v.to_s)}" }
15
+ .join('&')
16
+ .presence
17
+
18
+ [uri, params].compact
19
+ .join('?')
20
+ end
21
+
22
+ def is_numeric?(value)
23
+ value.to_s =~ /^[+-]?[\d]+(\.[\d]+){0,1}$/
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ module Hungry
2
+ class Venue < Resource
3
+ autoload :Collection, 'hungry/venue/collection'
4
+
5
+ self.endpoint = '/venues'
6
+
7
+ ### RESOURCES:
8
+
9
+ has_many :reviews, Review
10
+
11
+ belongs_to :country, Country
12
+
13
+ belongs_to :region, Region
14
+
15
+ belongs_to :city, City
16
+
17
+ ### ATTRIBUTES:
18
+
19
+ ### Preview:
20
+ attr_accessor :id, :name, :category, :telephone, :fax, :website_url,
21
+ :tagline, :rating, :url, :address, :geolocation, :relevance,
22
+ :distance, :plan,
23
+
24
+ ### Full:
25
+ :reachability, :staff, :prices, :capacity, :description,
26
+ :tags, :menus, :images, :maintainers, :awards, :opening_hours,
27
+
28
+ ### Utility:
29
+ :resources, :counters, :created_at, :updated_at
30
+
31
+ ### FINDERS:
32
+
33
+ def self.collection
34
+ Collection.new(self, endpoint, default_criteria)
35
+ end
36
+
37
+ def self.search(query)
38
+ collection.search(query)
39
+ end
40
+
41
+ def self.nearby(geolocation, options = {})
42
+ collection.nearby(geolocation, options)
43
+ end
44
+
45
+ def self.tagged_with(*tags)
46
+ collection.tagged_with(*tags)
47
+ end
48
+
49
+ def self.sort_by(sortable)
50
+ collection.sort_by(sortable)
51
+ end
52
+
53
+ def self.paginate(page, options = {})
54
+ collection.paginate(page, options)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,37 @@
1
+ module Hungry
2
+ class Venue
3
+ class Collection < Hungry::Collection
4
+ include Pagination
5
+
6
+ def search(query)
7
+ all query: query
8
+ end
9
+
10
+ def nearby(location, options = {})
11
+ options[:geolocation] = Geolocation.parse(location)
12
+ options[:sort_by] ||= 'distance'
13
+
14
+ all options
15
+ end
16
+
17
+ def tagged_with(*tags)
18
+ all tags: (current_tags + tags.flatten).compact.join(',')
19
+ end
20
+
21
+ def sort_by(subject)
22
+ all sort_by: subject
23
+ end
24
+
25
+ private
26
+
27
+ def current_tags
28
+ if criteria[:tags].is_a?(String)
29
+ criteria[:tags].gsub(/\s+/, '')
30
+ .split(',')
31
+ else
32
+ criteria[:tags] || []
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ begin
2
+ # Add support for Object#presence:
3
+ require 'active_support/core_ext/object/blank'
4
+
5
+ rescue LoadError => e
6
+ Object.class_eval do
7
+ unless respond_to?(:present?)
8
+ def present?
9
+ !!presence
10
+ end
11
+ end
12
+
13
+ unless respond_to?(:presence)
14
+ def presence
15
+ return nil if respond_to?(:empty?) ? empty? : !self
16
+ self
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ begin
2
+ # Add support for Hash#symbolize_keys:
3
+ require 'active_support/core_ext/hash/keys'
4
+
5
+ rescue LoadError => e
6
+ Hash.class_eval do
7
+ unless respond_to?(:symbolize_keys)
8
+ def symbolize_keys
9
+ inject({}) do |options, (key, value)|
10
+ options[(key.to_sym rescue key) || key] = value
11
+ options
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hungry::Geolocation do
4
+ let(:geo) { Hungry::Geolocation.new(50.8469397, 5.6927505) }
5
+
6
+ describe '.parse' do
7
+ context 'with a Geolocation' do
8
+ it 'returns the given Geolocation' do
9
+ Hungry::Geolocation.parse(geo).should == geo
10
+ end
11
+ end
12
+
13
+ context 'with an Object' do
14
+ it 'returns a Geolocation object for objects with a latitude and longitude' do
15
+ object = Class.new do
16
+ def latitude; 50.8469397; end
17
+ def longitude; 5.6927505; end
18
+ end.new
19
+
20
+ geo = Hungry::Geolocation.parse(object)
21
+ geo.latitude.should == 50.8469397
22
+ geo.longitude.should == 5.6927505
23
+ end
24
+
25
+ it 'returns a Geolocation object for objects with a lat and lng' do
26
+ object = Class.new do
27
+ def lat; 50.8469397; end
28
+ def lng; 5.6927505; end
29
+ end.new
30
+
31
+ geo = Hungry::Geolocation.parse(object)
32
+ geo.latitude.should == 50.8469397
33
+ geo.longitude.should == 5.6927505
34
+ end
35
+
36
+ it 'returns a Geolocation object for objects that have a valid geolocation' do
37
+ object = Class.new do
38
+ def geolocation; Hungry::Geolocation.new(50.8469397, 5.6927505); end
39
+ end.new
40
+
41
+ geo = Hungry::Geolocation.parse(object)
42
+ geo.latitude.should == 50.8469397
43
+ geo.longitude.should == 5.6927505
44
+ end
45
+
46
+ it 'returns nil for objects without geo information' do
47
+ geo = Hungry::Geolocation.parse(Object.new)
48
+ geo.should be_nil
49
+ end
50
+
51
+ it 'returns nil for objects that have an invalid geolocation' do
52
+ object = Class.new do
53
+ def geolocation; "just a string"; end
54
+ end.new
55
+
56
+ geo = Hungry::Geolocation.parse(object)
57
+ geo.should be_nil
58
+ end
59
+ end
60
+
61
+ context 'with a String' do
62
+ it 'returns a Geolocation object' do
63
+ geo = Hungry::Geolocation.parse('50.8469397,5.6927505')
64
+ geo.latitude.should == 50.8469397
65
+ geo.longitude.should == 5.6927505
66
+ end
67
+
68
+ it 'returns nil if the string can not be parsed' do
69
+ geo = Hungry::Geolocation.parse('not-a,geolocation')
70
+ geo.should be_nil
71
+ end
72
+ end
73
+
74
+ context 'with an Array' do
75
+ it 'returns a Geolocation object' do
76
+ geo = Hungry::Geolocation.parse([50.8469397, 5.6927505])
77
+ geo.latitude.should == 50.8469397
78
+ geo.longitude.should == 5.6927505
79
+ end
80
+
81
+ it 'returns nil if the array can not be parsed' do
82
+ geo = Hungry::Geolocation.parse(['not a', 'geolocation'])
83
+ geo.should be_nil
84
+ end
85
+ end
86
+
87
+ context 'with a Hash' do
88
+ it 'returns a Geolocation object' do
89
+ geo = Hungry::Geolocation.parse(latitude: 50.8469397, longitude: 5.6927505)
90
+ geo.latitude.should == 50.8469397
91
+ geo.longitude.should == 5.6927505
92
+ end
93
+
94
+ it 'supports abbreviated keys' do
95
+ geo = Hungry::Geolocation.parse(lat: 50.8469397, lng: 5.6927505)
96
+ geo.latitude.should == 50.8469397
97
+ geo.longitude.should == 5.6927505
98
+ end
99
+
100
+ it 'returns nil if the hash can not be parsed' do
101
+ geo = Hungry::Geolocation.parse(a: 'b', c: 'd')
102
+ geo.should be_nil
103
+ end
104
+ end
105
+ end
106
+
107
+ describe '#initialize' do
108
+ it 'sets latitude' do
109
+ geo.latitude.should == 50.8469397
110
+ end
111
+
112
+ it 'sets longitude' do
113
+ geo.longitude.should == 5.6927505
114
+ end
115
+ end
116
+
117
+ describe '#to_s' do
118
+ it 'joins latitude and longitude with a ","' do
119
+ geo.to_s.should == "50.8469397,5.6927505"
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hungry::Util do
4
+ describe '#params_from_uri' do
5
+ it 'returns a hash representing the params in the given URL' do
6
+ hash = Hungry::Util.params_from_uri 'http://www.google.com/search?q=ruby&lang=en'
7
+ hash.should == { 'q' => 'ruby', 'lang' => 'en' }
8
+ end
9
+ end
10
+
11
+ describe '#uri_with_params' do
12
+ it 'returns a clean URL if there no hash is given' do
13
+ url = Hungry::Util.uri_with_params('http://www.google.com/')
14
+ url.should == 'http://www.google.com/'
15
+ end
16
+
17
+ it 'returns an URL with params representing the given hash' do
18
+ url = Hungry::Util.uri_with_params('http://www.google.com/search', 'q' => 'ruby', 'lang' => 'en')
19
+ url.should == 'http://www.google.com/search?q=ruby&lang=en'
20
+ end
21
+ end
22
+
23
+ describe '#is_numeric?' do
24
+ it 'returns true for integers' do
25
+ Hungry::Util.is_numeric?(100).should be_true
26
+ end
27
+
28
+ it 'returns true for floats' do
29
+ Hungry::Util.is_numeric?(10.0).should be_true
30
+ end
31
+
32
+ it 'returns true for integers in strings' do
33
+ Hungry::Util.is_numeric?('100').should be_true
34
+ end
35
+
36
+ it 'returns true for floats in strings' do
37
+ Hungry::Util.is_numeric?('10.0').should be_true
38
+ end
39
+
40
+ it 'returns true for negative integers in strings' do
41
+ Hungry::Util.is_numeric?('-100').should be_true
42
+ end
43
+
44
+ it 'returns true for negative floats in strings' do
45
+ Hungry::Util.is_numeric?('-10.0').should be_true
46
+ end
47
+
48
+ it 'returns false for non numeric values' do
49
+ Hungry::Util.is_numeric?('abc').should be_false
50
+ Hungry::Util.is_numeric?('1a3').should be_false
51
+ Hungry::Util.is_numeric?('1.0.0').should be_false
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path('../../lib/hungry', __FILE__)
2
+
3
+ require 'fakeweb'
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hungry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tom-Eric Gerritsen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
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
+ - !ruby/object:Gem::Dependency
63
+ name: fakeweb
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: An interface to the Eet.nu API.
79
+ email:
80
+ - tomeric@eet.nu
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .rspec
87
+ - Gemfile
88
+ - Guardfile
89
+ - Rakefile
90
+ - hungry.gemspec
91
+ - lib/hungry.rb
92
+ - lib/hungry/city.rb
93
+ - lib/hungry/collection.rb
94
+ - lib/hungry/collection/pagination.rb
95
+ - lib/hungry/country.rb
96
+ - lib/hungry/geolocation.rb
97
+ - lib/hungry/location.rb
98
+ - lib/hungry/region.rb
99
+ - lib/hungry/resource.rb
100
+ - lib/hungry/review.rb
101
+ - lib/hungry/site.rb
102
+ - lib/hungry/tag.rb
103
+ - lib/hungry/util.rb
104
+ - lib/hungry/venue.rb
105
+ - lib/hungry/venue/collection.rb
106
+ - lib/support/presence.rb
107
+ - lib/support/symbolize_keys.rb
108
+ - spec/hungry/geolocation_spec.rb
109
+ - spec/hungry/util_spec.rb
110
+ - spec/spec_helper.rb
111
+ homepage: http://github.com/eet-nu/hungry
112
+ licenses: []
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.24
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: An interface to the Eet.nu API.
135
+ test_files:
136
+ - spec/hungry/geolocation_spec.rb
137
+ - spec/hungry/util_spec.rb
138
+ - spec/spec_helper.rb