Permalink
Browse files

Add test cases for #statement

    - I had to assume that the statement worked as it is
    - I asserted against whatever statement returned as of now
    - I tried to cover all the cases and conditionals
  • Loading branch information...
edgenard committed Jul 29, 2018
1 parent f03969b commit 7a45e9baff1e3e67b6ba28d87fc62600389a1011
Showing with 196 additions and 0 deletions.
  1. +2 −0 a_first_example/Gemfile
  2. +12 −0 a_first_example/Gemfile.lock
  3. +68 −0 a_first_example/first_example.rb
  4. +114 −0 a_first_example/first_example_spec.rb
@@ -0,0 +1,2 @@

gem 'minitest'
@@ -0,0 +1,12 @@
GEM
specs:
minitest (5.11.3)

PLATFORMS
ruby

DEPENDENCIES
minitest

BUNDLED WITH
1.16.2
@@ -0,0 +1,68 @@
# Ruby Refactoring A first example

This comment has been minimized.

@bbimeredithedwards

bbimeredithedwards Jul 31, 2018

Can you summarize the objects here and their responsibilities?

class Movie
CHILDRENS = 2
REGULAR = 0
NEW_RELEASE = 1

attr_reader :title
attr_accessor :price_code

def initialize(title, price_code)
@title, @price_code = title, price_code
end
end


class Rental
attr_reader :movie, :days_rented

def initialize(movie, days_rented)
@movie, @days_rented = movie, days_rented
end
end

class Customer
attr_reader :name

def initialize(name)
@name = name
@rentals = []
end

def add_rental(arg)
@rentals << arg
end

def statement
total_amount, frequent_renter_points = 0, 0
result = "Rental Record for #{@name}\n"
@rentals.each do |element|
this_amount = 0

# determine amounts for each line
case element.movie.price_code
when Movie::REGULAR
this_amount += 2
this_amount += (element.days_rented - 2) * 1.5 if element.days_rented > 2
when Movie::NEW_RELEASE
this_amount += element.days_rented * 3
when Movie::CHILDRENS
this_amount += 1.5
this_amount += (element.days_rented - 3) * 1.5 if element.days_rented > 3
end

# add frequent renter points
frequent_renter_points += 1
# add bonus for a two day new release rental
frequent_renter_points += 1 if element.movie.price_code == Movie::NEW_RELEASE && element.days_rented > 1

# show figures for this rental
result += "\t" + element.movie.title + "\t" + this_amount.to_s + "\n"
total_amount += this_amount
end
# add footer lines
result += "Amount owed is #{total_amount.to_s}\n"
result += "You earned #{frequent_renter_points.to_s} frequent renter points"
result
end
end
@@ -0,0 +1,114 @@
require "minitest/autorun"

This comment has been minimized.

@bbimeredithedwards

bbimeredithedwards Jul 31, 2018

Curious. Why did you choose minitest over rspec?

require_relative 'first_example.rb'

class TestFirstExample < Minitest::Test
def setup
@joe = Customer.new('Joe')
@child_movie = Movie.new('Cars', Movie::CHILDRENS)
@reg_movie = Movie.new('Jaws', Movie::REGULAR)
@new_movie = Movie.new('Tag', Movie::NEW_RELEASE)
end

def test_3day_child
@joe.add_rental(Rental.new(@child_movie, 3))

This comment has been minimized.

@bbimeredithedwards

bbimeredithedwards Jul 31, 2018

I'm noticing some patterns.
In #setup, you create your Customer and 3 instances of Movie. #setup is the only place that directly class those classes.
Later, you use @joe in every single test. Cool. You then pass a movie object to the Rental on the first line -- for example: Rental.new(@child_movie, 3) and then add the rental to @joe.


assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Cars\t1.5\nAmount owed is 1.5\n" +
"You earned 1 frequent renter points")
end

def test_5day_child
@joe.add_rental(Rental.new(@child_movie, 5))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Cars\t4.5\n" +
"Amount owed is 4.5\n" +
"You earned 1 frequent renter points")
end

def test_1day_new
@joe.add_rental(Rental.new(@new_movie, 1))

assert_equal(@joe.statement,

This comment has been minimized.

@bbimeredithedwards

bbimeredithedwards Jul 31, 2018

Each test calls #add_rental then looks at @joe.statement.
How do you feel about this? Is it a good test pattern to call one method (#add_rental) and test its correctness by calling another method (#statement)?

"Rental Record for Joe\n\t" +
"Tag\t3\n" +
"Amount owed is 3\n" +
"You earned 1 frequent renter points")
end

def test_2day_new
@joe.add_rental(Rental.new(@new_movie, 2))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Tag\t6\n" +
"Amount owed is 6\n" +
"You earned 2 frequent renter points")
end

def test_3day_reg
@joe.add_rental(Rental.new(@reg_movie, 3))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Jaws\t3.5\n" +
"Amount owed is 3.5\n" +
"You earned 1 frequent renter points")
end

def test_3day_reg_3day_new
@joe.add_rental(Rental.new(@reg_movie, 3))
@joe.add_rental(Rental.new(@new_movie, 3))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Jaws\t3.5\n\t" +
"Tag\t9\n" +
"Amount owed is 12.5\n" +
"You earned 3 frequent renter points")
end

def test_3day_reg_4day_child
@joe.add_rental(Rental.new(@reg_movie, 3))
@joe.add_rental(Rental.new(@child_movie, 4))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Jaws\t3.5\n\t" +
"Cars\t3.0\n" +
"Amount owed is 6.5\n" +
"You earned 2 frequent renter points")
end

def test_2day_new_4day_child
@joe.add_rental(Rental.new(@new_movie, 2))
@joe.add_rental(Rental.new(@child_movie, 4))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Tag\t6\n\t" +
"Cars\t3.0\n" +
"Amount owed is 9.0\n" +
"You earned 3 frequent renter points")
end

def test_2day_new_4day_child_3day_reg

This comment has been minimized.

@bbimeredithedwards

bbimeredithedwards Jul 31, 2018

What do the test names mean? test_2day_new_4day_child_3day_reg

@joe.add_rental(Rental.new(@new_movie, 2))
@joe.add_rental(Rental.new(@child_movie, 4))
@joe.add_rental(Rental.new(@reg_movie, 3))

assert_equal(@joe.statement,
"Rental Record for Joe\n\t" +
"Tag\t6\n\t" +
"Cars\t3.0\n\t" +
"Jaws\t3.5\n" +
"Amount owed is 12.5\n" +
"You earned 4 frequent renter points")
end

end



0 comments on commit 7a45e9b

Please sign in to comment.