diff --git a/lib/api.rb b/lib/api.rb index a8d499c..1307eb8 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -8,14 +8,21 @@ class Api def self.search_by_title(title) url = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=#{APIKEY}&q=#{URI.encode(title)}&page_limit=1" - struct = OpenStruct.new(get_url_as_json(url).fetch("movies").first) - Movie.new(id: struct.id.to_i, - title: struct.title, - year: struct.year, - score: struct.ratings["critics_score"] - ) + build_movie(get_url_as_json(url).fetch("movies").first) end + def self.build_movie(json) + struct = OpenStruct.new(json) + if struct.ratings + Movie.new(id: struct.id.to_i, + title: struct.title, + year: struct.year, + score: struct.ratings["critics_score"] + ) + else + NotFoundMovie.new + end + end def self.get_url_as_json(url) JSON.parse(open(url).read) diff --git a/lib/movie.rb b/lib/movie.rb index 167a23e..7e0b99d 100644 --- a/lib/movie.rb +++ b/lib/movie.rb @@ -8,3 +8,12 @@ def initialize(hash={}) @score = hash.fetch(:score) end end + +class NotFoundMovie + attr_reader :title, :score + + def initialize + @title = "no results" + @score = "N/A" + end +end diff --git a/lib/movie_clerk.rb b/lib/movie_clerk.rb new file mode 100644 index 0000000..1074315 --- /dev/null +++ b/lib/movie_clerk.rb @@ -0,0 +1,47 @@ +require_relative "api" + +class MovieClerk + attr_reader :welcome_message, :taste_measurement + + def initialize + @movies = [] + @welcome_message = "Welcome to The Movie Clerk!" + end + + def find_movie + puts "Add a movie you like:" + movie_title = gets + search_by_title(movie_title) + send_movie_details(@movies.last) + end + + def analyze_taste + last_two_movies = @movies.last(2) + first_movie = last_two_movies.first + last_movie = last_two_movies.last + @taste_measurement = (first_movie.score - last_movie.score).to_f / (first_movie.year - last_movie.year).to_f + if @taste_measurement < 0 + puts "Your taste is diminishing over time." + else + puts "Your taste is improving over time." + end + end + + def perform_taste_analysis? + @movies.size == 2 + end + + def search_by_title(movie_title) + @movies << Api.search_by_title(movie_title) + end + + def send_movie_details(movie) + puts "Found: #{movie.title}. Score: #{movie.score}" + puts "Average score of #{movie_score_average.round(2)} for #{@movies.count} movies on your list." + end + + def movie_score_average + scores = @movies.map {|m| m.score} + scores.inject(:+).to_f / scores.size + end +end \ No newline at end of file diff --git a/movie_json.rb b/movie_json.rb index d8a91d7..76ef7ca 100644 --- a/movie_json.rb +++ b/movie_json.rb @@ -1,21 +1,16 @@ -require_relative "lib/movie" -require_relative "lib/api" +require_relative "lib/movie_clerk" -def find_movie - puts "OH HAI. Search?" - movie_title = gets - movie = Api.search_by_title(movie_title) - puts "Found: #{movie.title}. Score: #{movie.score}" -end - -find_movie +clerk = MovieClerk.new +puts clerk.welcome_message +clerk.find_movie while true do - puts "Search Again (Y/N)" + puts "Search Again (Y/N)" answer = gets.upcase[0] - if answer == "Y" - find_movie - else + if answer == "N" break + else + clerk.find_movie + clerk.analyze_taste if clerk.perform_taste_analysis? end end diff --git a/spec/api_spec.rb b/spec/api_spec.rb index 9014106..7ccbb40 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -2,26 +2,41 @@ require "ostruct" describe Api do + describe ".search_by_title" do + context "when title found" do + let(:movie) { Api.search_by_title("Forrest Gump") } - let(:movie) { Api.search_by_title("Forrest Gump") } + before do + Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/forrest.json")) } + end - before do - Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/forrest.json")) } - end + it "should search for movies" do + movie.title.should eq("Forrest Gump") + end - it "should search for movies" do - movie.title.should eq("Forrest Gump") - end + it "should return the score" do + movie.score.should eq(71) + end - it "should return the score" do - movie.score.should eq(71) - end + it "should return the id" do + movie.id.should eq(10036) + end - it "should return the id" do - movie.id.should eq(10036) - end + it "should return the year" do + movie.year.should eq(1994) + end + end + + context "when title not found" do + let(:movie) { Api.search_by_title("asdfasdfasdf") } + + before do + Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/no_result.json")) } + end - it "should return the year" do - movie.year.should eq(1994) + it "should return a not found title" do + movie.title.should eq("no results") + end + end end end diff --git a/spec/fixtures/no_result.json b/spec/fixtures/no_result.json new file mode 100644 index 0000000..cc3e7bb --- /dev/null +++ b/spec/fixtures/no_result.json @@ -0,0 +1,8 @@ +{ + "total": 0, + "movies": [], + "links": { + "self": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=asfasffsafsafa&page_limit=1&page=1" + }, + "link_template": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}" +} \ No newline at end of file diff --git a/spec/movie_clerk_spec.rb b/spec/movie_clerk_spec.rb new file mode 100644 index 0000000..255fd1e --- /dev/null +++ b/spec/movie_clerk_spec.rb @@ -0,0 +1,34 @@ +require_relative '../lib/movie_clerk' + +describe MovieClerk do + it "finds a movie" do + clerk = MovieClerk.new + clerk.search_by_title("pulp fiction").first.title.should eq("Pulp Fiction") + end + + it "should provide the average score from the movie list" do + clerk = MovieClerk.new + clerk.search_by_title("baseketball") + clerk.search_by_title("goonies") + clerk.movie_score_average.should eq(54.5) + end + + describe "#analyze_taste" do + it "should tell the user their taste is improving over time" do + clerk = MovieClerk.new + clerk.search_by_title("fargo") + clerk.search_by_title("spaceballs") + clerk.analyze_taste + clerk.taste_measurement.should be_within(0.01).of(4.44) + end + it "should tell the user their taste is diminishing over time" do + clerk = MovieClerk.new + clerk.search_by_title("gigli") + clerk.search_by_title("fargo") + clerk.analyze_taste + clerk.taste_measurement.should be_within(0.01).of(-12.57) + end + end + + $stdout = StringIO.new +end \ No newline at end of file