tomato_power 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +57 -0
- data/Rakefile +1 -0
- data/lib/tomato_power/api/api.rb +97 -0
- data/lib/tomato_power/api/tomato_methods.rb +82 -0
- data/lib/tomato_power/client.rb +35 -0
- data/lib/tomato_power/helpers/helpers.rb +12 -0
- data/lib/tomato_power/helpers/parsers.rb +28 -0
- data/lib/tomato_power/movie/actor.rb +12 -0
- data/lib/tomato_power/movie/clip.rb +10 -0
- data/lib/tomato_power/movie/movie.rb +56 -0
- data/lib/tomato_power/movie/review.rb +15 -0
- data/lib/tomato_power/version.rb +3 -0
- data/lib/tomato_power.rb +22 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/sample_data/no_results +1 -0
- data/spec/support/sample_data/sample_actor +5 -0
- data/spec/support/sample_data/sample_actors +186 -0
- data/spec/support/sample_data/sample_alias +64 -0
- data/spec/support/sample_data/sample_clip +6 -0
- data/spec/support/sample_data/sample_clips +147 -0
- data/spec/support/sample_data/sample_movie +1 -0
- data/spec/support/sample_data/sample_movies +46 -0
- data/spec/support/sample_data/sample_review +8 -0
- data/spec/support/sample_data/sample_reviews +191 -0
- data/spec/support/vcr/TomatoPower_API/API_Methods/valid_methods/should_create_methods.yml +598 -0
- data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_consider_0_options_valid.yml +306 -0
- data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_not_raise_error.yml +101 -0
- data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_return_a_list_of_movie_objects.yml +101 -0
- data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_url_encode_search_string_before_sending.yml +102 -0
- data/spec/support/vcr/TomatoPower_API/List_request/should_return_a_list_of_movie_objects.yml +101 -0
- data/spec/support/vcr/TomatoPower_API/List_request/should_url_encode_search_string_before_sending.yml +102 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/cast/should_return_cast_of_movie.yml +356 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/clips/should_return_clips_of_movie.yml +638 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/no_results/should_return_error_string_if_no_results_are_found.yml +49 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/reviews/should_return_reviews.yml +271 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/should_return_single_movie.yml +161 -0
- data/spec/support/vcr/TomatoPower_API/Movie_request/similar/should_return_similar_movies.yml +121 -0
- data/spec/support/vcr/TomatoPower_Client/box_office_movies/should_return_list_of_movies.yml +396 -0
- data/spec/support/vcr/TomatoPower_Client/current_release_dvds/should_return_list_of_movies.yml +427 -0
- data/spec/support/vcr/TomatoPower_Client/in_theaters_movies/should_return_list_of_movies.yml +380 -0
- data/spec/support/vcr/TomatoPower_Client/new_release_dvds/should_return_list_of_movies.yml +392 -0
- data/spec/support/vcr/TomatoPower_Client/opening_movies/should_return_list_of_movies.yml +213 -0
- data/spec/support/vcr/TomatoPower_Client/search_by_id/should_return_list_of_movies_by_id.yml +88 -0
- data/spec/support/vcr/TomatoPower_Client/search_by_title/should_return_list_of_movies_by_title.yml +89 -0
- data/spec/support/vcr/TomatoPower_Client/top_rentals/should_return_list_of_movies.yml +409 -0
- data/spec/support/vcr/TomatoPower_Client/upcoming_dvds/should_return_list_of_movies.yml +359 -0
- data/spec/support/vcr/TomatoPower_Client/upcoming_movies/should_return_list_of_movies.yml +341 -0
- data/spec/support/vcr/TomatoPower_Movie/clips/should_return_clips.yml +250 -0
- data/spec/support/vcr/TomatoPower_Movie/full_cast/should_return_cast.yml +279 -0
- data/spec/support/vcr/TomatoPower_Movie/reviews/should_return_reviews.yml +205 -0
- data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similar_movies.yml +231 -0
- data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similars.yml +81 -0
- data/spec/support/vcr.rb +13 -0
- data/spec/unit_specs/actor_spec.rb +16 -0
- data/spec/unit_specs/api_spec.rb +126 -0
- data/spec/unit_specs/client_spec.rb +73 -0
- data/spec/unit_specs/clip_spec.rb +14 -0
- data/spec/unit_specs/helpers.rb +50 -0
- data/spec/unit_specs/helpers_spec.rb +4 -0
- data/spec/unit_specs/movie_spec.rb +75 -0
- data/spec/unit_specs/parsers_spec.rb +55 -0
- data/spec/unit_specs/review_spec.rb +17 -0
- data/spec/unit_specs/tomato_power_spec.rb +6 -0
- data/tomato_power.gemspec +29 -0
- metadata +295 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sean Kay
|
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,57 @@
|
|
1
|
+
# TomatoPower
|
2
|
+
|
3
|
+
TomatoPower is a wrapper for the
|
4
|
+
[Rotten Tomatoes API](http://developer.rottentomatoes.com/).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'tomato_power'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install tomato_power
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
1. Create an instance of the `TomatoPower` client.
|
23
|
+
|
24
|
+
client = TomatoPower.new <your_rotten_tomatoes_api_key>
|
25
|
+
|
26
|
+
2. Start using the gem!
|
27
|
+
|
28
|
+
## Examples
|
29
|
+
Searching for a movie returns an array of `TomatoPower::Movie` objects.
|
30
|
+
|
31
|
+
>> movies = client.search_by_title("The Dark Knight")
|
32
|
+
>> movies[0].title
|
33
|
+
=> "The Dark Knight"
|
34
|
+
|
35
|
+
Easily access information from movies and cast members.
|
36
|
+
|
37
|
+
>> actors = movie.full_cast
|
38
|
+
>> actor = actors[0]
|
39
|
+
>> actor.name
|
40
|
+
=> "Christian Bale"
|
41
|
+
>> actor.characters
|
42
|
+
=> ["Batman/Bruce Wayne"]
|
43
|
+
|
44
|
+
Search for similar movies
|
45
|
+
|
46
|
+
>> movies = client.search_by_title("The Dark Knight")
|
47
|
+
>> similar_movies = movies[0].similar
|
48
|
+
>> similar_movies[0].title
|
49
|
+
=> "Batman Begins"
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module TomatoPower
|
6
|
+
class API
|
7
|
+
API_VERSION = 'v1.0'
|
8
|
+
MAX_PAGE_LIMIT = 50
|
9
|
+
BASE_URL = "http://api.rottentomatoes.com/api/public/#{API_VERSION}"
|
10
|
+
MOVIE_URL = "#{ BASE_URL }/movies/"
|
11
|
+
|
12
|
+
def initialize api_key
|
13
|
+
@api_key = api_key
|
14
|
+
end
|
15
|
+
|
16
|
+
#Defines methods in `TOMATO_METHODS`
|
17
|
+
# ==Parameters:
|
18
|
+
# options:
|
19
|
+
# Hash of options allowed (#see tomato_methods.rb).
|
20
|
+
#
|
21
|
+
def method_missing method, options={}
|
22
|
+
if TOMATO_METHODS.keys.include?(method)
|
23
|
+
self.class.send(:define_method, method) do |options={}|
|
24
|
+
if options_valid? method, options
|
25
|
+
fetch api_url TOMATO_METHODS[method][:url], options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
self.send method, options
|
32
|
+
end
|
33
|
+
|
34
|
+
def respond_to? method
|
35
|
+
if TOMATO_METHODS.keys.include? method
|
36
|
+
true
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def fetch url
|
45
|
+
tomato = get url
|
46
|
+
payload = TomatoPower::Parser::parse JSON.parse(tomato)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get url
|
50
|
+
open(url) do |f|
|
51
|
+
f.read
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def options_valid? method, options={}
|
56
|
+
options.keys.each do |option|
|
57
|
+
if option == :page_limit && options[:page_limit] > MAX_PAGE_LIMIT
|
58
|
+
options[:pagelimit] = MAX_PAGE_LIMIT
|
59
|
+
end
|
60
|
+
unless TOMATO_METHODS[method][:whitelist].include?(option)
|
61
|
+
raise ArgumentError.new(
|
62
|
+
"Invalid key: #{option} for #{method}.
|
63
|
+
Valid keys are #{TOMATO_METHODS[method][:whitelist]}."
|
64
|
+
)
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def api_url endpoint, options={}
|
72
|
+
if movie_id = options[:movie_id]
|
73
|
+
options.delete :movie_id
|
74
|
+
movie_url endpoint, movie_id, options
|
75
|
+
else
|
76
|
+
list_url endpoint, options
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def movie_url endpoint, movie_id, options={}
|
81
|
+
url = "#{MOVIE_URL}#{movie_id}#{endpoint}apikey=#{@api_key}#{request_params(options)}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def list_url endpoint, options={}
|
85
|
+
url = "#{BASE_URL}#{endpoint}apikey=#{@api_key}#{request_params(options)}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def request_params options ={}
|
89
|
+
params = ""
|
90
|
+
options.each_key do |key|
|
91
|
+
options[key] = URI.escape(options[key]) if options[key].is_a?(String)
|
92
|
+
params << "&#{key}=#{options[key]}"
|
93
|
+
end
|
94
|
+
params
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# List of methods and whitelist of allowed options for the corresponding
|
2
|
+
# RottenTomatoes API call.
|
3
|
+
# ==
|
4
|
+
# rotten_tomatoes_api_method =>
|
5
|
+
# {
|
6
|
+
# :url => "resource_url",
|
7
|
+
# :whitelist => [allowed options]
|
8
|
+
# }
|
9
|
+
module TomatoPower
|
10
|
+
TOMATO_METHODS = {
|
11
|
+
:movies_search =>
|
12
|
+
{
|
13
|
+
:url => "/movies.json?",
|
14
|
+
:whitelist => [:q, :page, :page_limit],
|
15
|
+
},
|
16
|
+
:box_office_movies =>
|
17
|
+
{
|
18
|
+
:url => "/lists/movies/box_office.json?",
|
19
|
+
:whitelist => [:limit, :country]
|
20
|
+
},
|
21
|
+
:in_theaters_movies =>
|
22
|
+
{
|
23
|
+
:url => "/lists/movies/in_theaters.json?",
|
24
|
+
:whitelist => [:page, :page_limit, :country]
|
25
|
+
},
|
26
|
+
:opening_movies =>
|
27
|
+
{
|
28
|
+
:url => "/lists/movies/opening.json?",
|
29
|
+
:whitelist => [:limit, :country]
|
30
|
+
},
|
31
|
+
:upcoming_movies =>
|
32
|
+
{
|
33
|
+
:url => "/lists/movies/upcoming.json?",
|
34
|
+
:whitelist => [:page, :page_limit, :country]
|
35
|
+
},
|
36
|
+
:top_rentals =>
|
37
|
+
{
|
38
|
+
:url => "/lists/dvds/top_rentals.json?",
|
39
|
+
:whitelist => [:limit, :country]
|
40
|
+
},
|
41
|
+
:current_release_dvds =>
|
42
|
+
{
|
43
|
+
:url => "/lists/dvds/current_releases.json?",
|
44
|
+
:whitelist => [:page, :page_limit,:country]
|
45
|
+
},
|
46
|
+
:new_release_dvds =>
|
47
|
+
{
|
48
|
+
:url => "/lists/dvds/new_releases.json?",
|
49
|
+
:whitelist => [:page, :page_limit, :country]
|
50
|
+
},
|
51
|
+
:upcoming_dvds =>
|
52
|
+
{
|
53
|
+
:url => "/lists/dvds/upcoming.json?",
|
54
|
+
:whitelist => [:page, :page_limit, :country]
|
55
|
+
},
|
56
|
+
:movie_cast =>
|
57
|
+
{
|
58
|
+
:url => "/cast.json?",
|
59
|
+
:whitelist => [:movie_id]
|
60
|
+
},
|
61
|
+
:movie_clips =>
|
62
|
+
{
|
63
|
+
:url => "/clips.json?",
|
64
|
+
:whitelist => [:movie_id]
|
65
|
+
},
|
66
|
+
:movie_reviews =>
|
67
|
+
{
|
68
|
+
:url => "/reviews.json?",
|
69
|
+
:whitelist => [:movie_id, :review_type, :page_limit, :page, :country]
|
70
|
+
},
|
71
|
+
:movie_similar =>
|
72
|
+
{
|
73
|
+
:url => "/similar.json?",
|
74
|
+
:whitelist => [:movie_id]
|
75
|
+
},
|
76
|
+
:movie_alias =>
|
77
|
+
{
|
78
|
+
:url => "/movie_alias.json?",
|
79
|
+
:whitelist => [:type, :id]
|
80
|
+
},
|
81
|
+
}
|
82
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module TomatoPower
|
4
|
+
class Client
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@api = TomatoPower::api
|
10
|
+
end
|
11
|
+
|
12
|
+
def_delegators :@api,
|
13
|
+
:box_office_movies,
|
14
|
+
:opening_movies,
|
15
|
+
:upcoming_movies,
|
16
|
+
:top_rentals,
|
17
|
+
:current_release_dvds,
|
18
|
+
:new_release_dvds,
|
19
|
+
:upcoming_dvds
|
20
|
+
def_delegator :@api, :in_theaters_movies, :movies_in_theaters
|
21
|
+
|
22
|
+
def search_by_title(movie_title, options={})
|
23
|
+
options[:q] = movie_title
|
24
|
+
@api.movies_search(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def search_by_id(movie_id)
|
28
|
+
options = {}
|
29
|
+
options[:type] = 'imdb' #current only supports 'imdb' type
|
30
|
+
options[:id] = movie_id
|
31
|
+
@api.movie_alias(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module TomatoPower
|
2
|
+
module Parser
|
3
|
+
def self.parse json={}
|
4
|
+
payload =[]
|
5
|
+
if json["movies"]
|
6
|
+
json["movies"].each do |movie|
|
7
|
+
payload << Movie.new(movie)
|
8
|
+
end
|
9
|
+
elsif json["cast"]
|
10
|
+
json["cast"].each do |actor|
|
11
|
+
payload << Actor.new(actor)
|
12
|
+
end
|
13
|
+
elsif json["clips"]
|
14
|
+
json["clips"].each do |clip|
|
15
|
+
payload << Clip.new(clip)
|
16
|
+
end
|
17
|
+
elsif json["reviews"]
|
18
|
+
json["reviews"].each do |review|
|
19
|
+
payload << Review.new(review)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
payload << Movie.new(json)
|
23
|
+
end
|
24
|
+
payload << "No Results" if payload.length < 1
|
25
|
+
payload
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module TomatoPower
|
2
|
+
class Movie
|
3
|
+
|
4
|
+
attr_reader :id, :info, :abridged_cast, :title, :ratings, :mpaa_rating,
|
5
|
+
:runtime,:release_dates, :synopsis, :posters, :alternate_ids, :links,
|
6
|
+
:studio, :abridged_directors
|
7
|
+
|
8
|
+
def initialize movie={}
|
9
|
+
@api = TomatoPower::api
|
10
|
+
|
11
|
+
@info = movie
|
12
|
+
@id = movie["id"]
|
13
|
+
@title = movie["title"]
|
14
|
+
@mpaa_rating = movie["mpaa_rating"]
|
15
|
+
@runtime = movie["runtime"]
|
16
|
+
@release_dates = movie["release_dates"]
|
17
|
+
@ratings = movie["ratings"]
|
18
|
+
@synopsis = movie["synopsis"]
|
19
|
+
@posters = movie["posters"]
|
20
|
+
@abridged_cast = movie["abridged_cast"]
|
21
|
+
@alternate_ids = movie["alternate_ids"]
|
22
|
+
@links = movie["links"]
|
23
|
+
@abridged_directors = movie["abridged_directors"]
|
24
|
+
@studio = movie["studio"]
|
25
|
+
end
|
26
|
+
|
27
|
+
MOVIE_METHOD_ALIAS = {
|
28
|
+
:full_cast => :movie_cast,
|
29
|
+
:clips => :movie_clips,
|
30
|
+
:reviews => :movie_reviews,
|
31
|
+
:similar => :movie_similar,
|
32
|
+
:alias => :movie_alias
|
33
|
+
}
|
34
|
+
|
35
|
+
def method_missing method, options={}
|
36
|
+
if MOVIE_METHOD_ALIAS.keys.include?(method)
|
37
|
+
method = MOVIE_METHOD_ALIAS[method]
|
38
|
+
self.class.send(:define_method, method) do |options={}|
|
39
|
+
options[:movie_id] = @id
|
40
|
+
@api.send(method, options )
|
41
|
+
end
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
self.send method
|
46
|
+
end
|
47
|
+
|
48
|
+
def respond_to? method
|
49
|
+
if MOVIE_METHOD_ALIAS.keys.include? method
|
50
|
+
true
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module TomatoPower
|
2
|
+
class Review
|
3
|
+
|
4
|
+
attr_reader :critic, :date, :freshness, :publication, :quote, :links
|
5
|
+
def initialize review={}
|
6
|
+
@critic = review["critic"]
|
7
|
+
@date = review["date"]
|
8
|
+
@freshness = review["freshness"]
|
9
|
+
@publication = review["publication"]
|
10
|
+
@quote = review["quote"]
|
11
|
+
@links = review["links"]
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
data/lib/tomato_power.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "tomato_power/version"
|
2
|
+
|
3
|
+
module TomatoPower
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'client')
|
5
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'api')
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'tomato_methods')
|
7
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','movie', 'actor')
|
8
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','clip')
|
9
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','movie')
|
10
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','review')
|
11
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','helpers', 'helpers')
|
12
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'helpers','parsers')
|
13
|
+
|
14
|
+
def self.new api_key=ENV.fetch("ROTTEN_TOMATOES_API_KEY")
|
15
|
+
self.api = API.new api_key
|
16
|
+
Client.new
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_accessor :api
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"total":0,"movies":[]}
|