hungry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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