import unittest
from datetime import date
from loans import due_date, late_fee, can_borrow
class TestDueDate(unittest.TestCase):
def test_normal(self):
self.assertEqual(due_date(date(2027, 1, 4)), date(2027, 1, 18))
def test_across_month_end(self):
self.assertEqual(due_date(date(2027, 1, 25)), date(2027, 2, 8))
class TestLateFee(unittest.TestCase):
def setUp(self):
self.due = date(2027, 1, 18) # runs before every test
def test_on_due_date(self):
self.assertEqual(late_fee(self.due, date(2027, 1, 18)), 0.0)
def test_early(self):
self.assertEqual(late_fee(self.due, date(2027, 1, 10)), 0.0)
def test_three_days_late(self):
self.assertAlmostEqual(late_fee(self.due, date(2027, 1, 21)), 0.75)
def test_exactly_at_cap(self):
self.assertAlmostEqual(late_fee(self.due, date(2027, 2, 7)), 5.00)
def test_past_cap(self):
self.assertAlmostEqual(late_fee(self.due, date(2027, 2, 17)), 5.00)
class TestCanBorrow(unittest.TestCase):
def loan(self, member, returned=None):
return {"item_id": "SS-01", "member_no": member, "returned": returned}
def test_two_out(self):
self.assertTrue(can_borrow(1042, [self.loan(1042), self.loan(1042)]))
def test_three_out(self):
self.assertFalse(can_borrow(1042, [self.loan(1042)] * 3))
def test_returned_loans_do_not_count(self):
loans = [self.loan(1042), self.loan(1042), self.loan(1042, date(2027, 1, 10))]
self.assertTrue(can_borrow(1042, loans))
def test_other_members_do_not_count(self):
self.assertTrue(can_borrow(1042, [self.loan(7)] * 3))
if __name__ == "__main__":
unittest.main(verbosity=2)
test_loans.py. Each class groups the tests for one function. unittest.main(verbosity=2) runs every test and lists each one by name.