diff --git a/.gitignore b/.gitignore index 5e1422c..c0ac3dc 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ build-iPhoneSimulator/ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc +coverage diff --git a/README.md b/README.md index 7530093..4c4167b 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ A `Rental` will contain an `initialize` method and the following attributes: * movie: The movie being rented * customer: The name of the customer making the rental -A `Rental` will have the follwing methods: +A `Rental` will have the following methods: * `cost`: This method will return the cost of the rental. A movie rental will cost $3.0 per night. The customer is **not** charged for the day the movie is checked in. So a movie checked out on August 8th and checked in August 10th would cost $3.00 * 2 days = $6.00 @@ -102,7 +102,7 @@ This class will contain an `initialize` method and the following attributes: * movies: The list of movies available in the system * rentals: A list of all the rentals which have occurred. -The `RentalManager` will be able to perform the following actions (methods): +The `MovieReserver` will be able to perform the following actions (methods): * `self.load_movies`: This method will open the csv file `movies.csv` and read in the movies and return an array of the given movies. Note the actors are separated by the `:` character. You will need to break up that field. - The `initialize` method should use `self.load_movies` to read in the movie list for the application @@ -114,4 +114,4 @@ The `RentalManager` will be able to perform the following actions (methods): ## Optional Enhancements You can add the following methods along with tests to further enhance this project: -- movies_staring(actor_name, date_range): This method will list all movies available in the given date range and with the provied actor. +- movies_staring(actor_name, date_range): This method will list all movies available in the given date range and with the provided actor. diff --git a/lib/date_range.rb b/lib/date_range.rb index b6009b4..8ccbaf9 100644 --- a/lib/date_range.rb +++ b/lib/date_range.rb @@ -1,7 +1,46 @@ require 'time' +require_relative 'movie_reserver' module GreenBox + # When a movie is being rented you need to understand when that rental occurs. To represent that interval of time, you will create a `DateRange` class. class DateRange + attr_reader :start_date , :end_date, :nights + def initialize(start_date, end_date) + @start_date = start_date + @end_date = end_date + + if start_date > end_date + raise ArgumentError.new "The end date is before the start date" + end + end + +# `contains(date)` - This method returns true if the date occurs on or after the start date and before the end date. + def contains(date) + if (date >= @start_date) && (date < @end_date) + return true + else + date < @start_date || date >= @end_date + return false + end + end + + +# `overlaps(other_date_range)` - This method takes another date range as a parameter and returns `true` if the date ranges overlap. + def overlaps(other_date_range) + if contains(other_date_range.start_date) || contains(other_date_range.end_date) + true + elsif other_date_range.contains(@start_date) && other_date_range.contains(@end_date) + true + else + false + end + end + +# `nights` - This method will return the number of nights included in the given `DateRange. + def nights + count = (@end_date - @start_date)/(60*60*24) + return count + end end end diff --git a/lib/movie.rb b/lib/movie.rb index f28fa85..55a01bc 100644 --- a/lib/movie.rb +++ b/lib/movie.rb @@ -1,5 +1,28 @@ +require 'csv' + module GreenBox + #A 'movie class' represents a film in our system database class Movie + attr_reader :id, :title, :publisher, :actors + + def initialize(id,title,publisher, actors:[]) + @id = id + @title = title + @publisher = publisher + @actors = actors + end + + movie = GreenBox::Movie.new(4,'Happiness','Fox',actors:['Denzel Washington', 'LL Cool J']) + + #This method will return true if the given actor does appear in the movie. + def stars_actor(actor_name) + actors.each do |actor| + if actor_name == actor + return true + end + end + return false + end end end diff --git a/lib/movie_reserver.rb b/lib/movie_reserver.rb index a151bc5..bfaf477 100644 --- a/lib/movie_reserver.rb +++ b/lib/movie_reserver.rb @@ -1,7 +1,121 @@ require 'csv' +require 'pry' +require_relative 'date_range' +require_relative 'movie' +require_relative 'rental' + module GreenBox class MovieReserver + attr_accessor :movies, :rentals, :date_range + # :reserver, :date_range + + def initialize + @movies = MovieReserver.load_movies + @rentals = [] + @date_range = GreenBox::DateRange.new(Time.parse('2018-08-08'),Time.parse('2018-08-09')) + end + + # `self.load_movies`: This method will open the csv file `movies.csv` and read in the movies and return an array of the given movies. Note the actors are separated by the `:` character. You will need to break up that field. + def self.load_movies + showtime_movies = [] + + CSV.read('data/movies.csv', headers: false).each do |line| + movie_id = line[0].to_i + title = line[1] + publisher = line[2] + all_actors = line[3] + actors_names = all_actors.split(':') + actors = {actors: actors_names} + + showtime_movies << GreenBox::Movie.new(movie_id, title, publisher, actors) + end + return showtime_movies + end + + + # `available_movies(date_range)`: This method will take a `DateRange` instance and return a list of + # movies available (not rented yet) in that range. + def available_movies(date_range) + + # @movies = available_movies + # If @rentals = [] - is empty, + if @rentals.empty? + # then all the movies are available + return @movies + else + # @movies is a MovieReserver object that contains movies. + available_movies = [] + @movies.each do |movie| + if @rentals.date_range == date_range + available_movies << movie + end + end + return @rentals + end + end + #PSEUDOCODE + # If there is a movie in rentals + ##### Want to check what movies are in rentals + # that fall into that date date_range + # and remove that movie only + # will need to use a data structure to only use the ID that are in the date_range + #use data structure to store those and match + # them with the ones in the movie list + # + + # if @rentals.length > 0 + # @rentals.each do |movies| + # date_range + # if @movies.include(date_range) + # available_movies = @movies.delete(date_range) + # end + # @rentals.each do |movie| + # movie.id + # if @movies.include(movie.id) + # available_movies = @movies.delete(movie.id) + # end + + # end + + # end + + # * `rent_movie(movie_title, date_range, customer_name)`: This method will attempt to reserve a movie with the given title for the given date range. If the movie is not available in that range the method should raise a `StandardError`. + + def rent_movie(movie_title, date_range, customer_name) + @movies.each do |movie| + if movie.title == movie_title + @rentals << movie + return @rentals + end + end + # If we finish the loop and nothing is found, raise an error here. + raise ArgumentError.new("No movies found!") + end end + end + + + +# available_movies = @rentals.map do |movie| +# if @rentals.date_range.contains(movie.id) +# return available_movies +# else +# @rentals << movie +# end +# end +# movies not rented yet = showtime_movies +# movies rented = rentals +# +# available_movies << GreenBox::Rental.new(movie,date_range) +# +# available_movies = MovieReserver.load_movies +# +# @rentals = available_movies.each do |date_range| +# if @rentals.date_range <= 0 +# @rentals << movie +# end +# end +# return available_movies diff --git a/lib/rental.rb b/lib/rental.rb index 432dbc9..fef36af 100644 --- a/lib/rental.rb +++ b/lib/rental.rb @@ -1,6 +1,28 @@ +require_relative 'date_range' +require 'time' +require_relative 'movie' + + module GreenBox + # A `Rental` represents a movie rental in the system. class Rental + attr_accessor :movie, :date_range, :customer + def initialize(movie, date_range, customer) + if date_range.nights <= 0 + raise ArgumentError.new "This is an illegal date range" + end + @movie = movie + @date_range = date_range + # * customer: The name of the customer making the rental + @customer = customer + end +# * `cost`: This method will return the cost of the rental. A movie rental will cost $3.0 per night. The customer is **not** charged for the day the movie is checked in. So a movie checked out on August 8th and checked in August 10th would cost $3.00 * 2 days = $6.00 + def cost + rent = @date_range.nights + cost = rent * 3.0 + return cost.round(2) + end end end diff --git a/specs/date_range_spec.rb b/specs/date_range_spec.rb index 75153d4..335ed33 100644 --- a/specs/date_range_spec.rb +++ b/specs/date_range_spec.rb @@ -2,7 +2,7 @@ require_relative 'spec_helper' -xdescribe 'GreenBox::DateRange' do +describe 'GreenBox::DateRange' do describe 'initialization' do it 'can be created' do diff --git a/specs/movie_reserver_spec.rb b/specs/movie_reserver_spec.rb index bd6282c..7c07bb4 100644 --- a/specs/movie_reserver_spec.rb +++ b/specs/movie_reserver_spec.rb @@ -2,17 +2,17 @@ MOVIES_IN_CSV = 11 -xdescribe 'GreenBox::MovieReserver' do +describe 'GreenBox::MovieReserver' do let (:reserver) { GreenBox::MovieReserver.new } let (:date_range) { GreenBox::DateRange.new(Time.parse('2018-08-08'), Time.parse('2018-08-09')) } describe 'initialization' do - xit 'can be instantiated' do + it 'can be instantiated' do expect(reserver).must_be_instance_of GreenBox::MovieReserver end - xit 'has the proper number of movies' do + it 'has the proper number of movies' do expect(reserver.movies.length).must_equal MOVIES_IN_CSV end end @@ -20,11 +20,11 @@ describe 'load_movies' do let (:movie_list) { GreenBox::MovieReserver.load_movies } - xit 'loads the right number of movies' do + it 'loads the right number of movies' do expect(movie_list.length).must_equal MOVIES_IN_CSV end - xit 'loads the 1st movie' do + it 'loads the 1st movie' do first_movie = movie_list.first expect(first_movie.title).must_equal 'Green Lantern' @@ -32,7 +32,7 @@ expect(first_movie.publisher).must_equal 'Fox' end - xit 'loads the last movie' do + it 'loads the last movie' do last_movie = movie_list.last expect(last_movie.title).must_equal 'Crazy Rich Asians' @@ -40,7 +40,7 @@ expect(last_movie.publisher).must_equal 'Warner Bros' end - xit 'loads the right actors' do + it 'loads the right actors' do first_movie = movie_list.first expect(first_movie.actors).must_include 'Blake Lively' @@ -53,18 +53,18 @@ describe 'movies available' do - xit 'will list the available movies' do + it 'will list the available movies' do available_movies = reserver.available_movies(date_range) expect(available_movies.length).must_equal 11 end - xit 'will not include rented movies' do + it 'will not include rented movies' do date_range = GreenBox::DateRange.new(Time.parse('2018-08-08'), Time.parse('2018-08-09')) reserver.rent_movie('Crazy Rich Asians', date_range, 'Ada Lovelace') available_movies = reserver.available_movies(date_range) - expect(available_movies.length).must_equal 10 + expect(available_movies).must_equal 10 movie_id = 2 movie_id_2 = available_movies.find do |movie| @@ -75,27 +75,77 @@ end end - xdescribe 'rent_movie' do + describe 'rent_movie' do it 'returns a rental for a successfully rented movie' do - # TODO Your Code goes here + #Setup + movie_reserver = GreenBox::MovieReserver.new + title = 'Crazy Rich Asians' + date_range = GreenBox::DateRange.new(Time.parse('2018-08-08'),Time.parse('2018-08-09')) + customer_name = ' Sabine ' + #Method under testn(call the things that I am verifying) + rental = movie_reserver.rent_movie(title, date_range, customer_name) + + #Assertions - something that has changed that tells + #us we have the expected result + expect(rental).wont_be_nil end + it 'can rent multiple movies with the same title' do - # TODO Your Code goes here + movie_reserver = GreenBox::MovieReserver.new + title = 'Crazy Rich Asians' + + date_range_a = GreenBox::DateRange.new(Time.parse('2018-08-09'),Time.parse('2018-08-10')) + customer_name_a = ' Andrew ' + + date_range_b = GreenBox::DateRange.new(Time.parse('2018-08-08'),Time.parse('2018-08-09')) + customer_name_b = ' Sabine ' + + rental_a = movie_reserver.rent_movie(title, date_range_a, customer_name_a) + + rental_b = movie_reserver.rent_movie(title, date_range_b, customer_name_b) + + expect(rental_a).wont_be_nil + expect(rental_b).wont_be_nil + expect(rental_a).wont_equal(rental_b) end - xit 'cannot rent a movie already rented' do - # TODO Your Code goes here + it 'cannot rent a movie already rented' do + + movie_reserver = GreenBox::MovieReserver.new + title = 'Crazy Rich Asians' + date_range = GreenBox::DateRange.new(Time.parse('2018-08-08'),Time.parse('2018-08-09')) + customer_name = ' Sabine ' + + #Method under test(call the things that I am verifying) + rental_a = movie_reserver.rent_movie(title, date_range, customer_name) + rental_b = movie_reserver.rent_movie(title, date_range, customer_name) + #Assertions/Expectation - something that has changed that tells + #us we have the expected result + expect(rental_a).wont_be_nil + expect(rental_b).must_be_nil + # expect(rental_a).must_equal(rental_b) end - xit 'raises an error if a movie is requested that does not appear in the list' do - # TODO Your Code goes here + it 'raises an error if a movie is requested that does not appear in the list' do + + movie_reserver = GreenBox::MovieReserver.new + title = 'Blackklansman' + date_range = GreenBox::DateRange.new(Time.parse('2018-08-08'),Time.parse('2018-08-09')) + customer_name = ' Sabine ' + + # checking for errors + expect { + movie_reserver.rent_movie(title, date_range, customer_name) + + # (the "method under test" section goes inside!) + }.must_raise StandardError end end diff --git a/specs/movie_spec.rb b/specs/movie_spec.rb index 679d630..c7a1f72 100644 --- a/specs/movie_spec.rb +++ b/specs/movie_spec.rb @@ -1,6 +1,6 @@ require_relative 'spec_helper' -xdescribe 'GreenBox::Movie' do +describe 'GreenBox::Movie' do let (:movie) { GreenBox::Movie.new(3, 'Green Lantern', 'Fox', actors: ['Ryan Reynolds', 'Blake Lively']) } @@ -34,7 +34,7 @@ end end - xdescribe 'stars_actor' do + describe 'stars_actor' do it 'returns true if the movie does feature the actor' do expect(movie.stars_actor('Ryan Reynolds')).must_equal true end diff --git a/specs/rental_spec.rb b/specs/rental_spec.rb index ab67eb2..caf72c8 100644 --- a/specs/rental_spec.rb +++ b/specs/rental_spec.rb @@ -1,7 +1,7 @@ require 'time' require_relative 'spec_helper' -xdescribe 'GreenBox::Rental' do +describe 'GreenBox::Rental' do let (:date_range) do GreenBox::DateRange.new(Time.parse('2018-08-09'), Time.parse('2018-08-11')) end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 906c711..03f66f8 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -1,12 +1,14 @@ -require 'time' require 'minitest' require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' require 'awesome_print' -# Add simplecov +require 'simplecov' +SimpleCov.start Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -# Require_relative your lib files here! +require_relative '../lib/rental' +require_relative '../lib/movie' require_relative '../lib/date_range' +require_relative '../lib/movie_reserver'