コード例 #1
0
def test_dont_overpay_small_balance_loan(current_date):
    """
  If a loan has only a small balance left, and the
  HighestInterestFirstPayer's amount is greater than that balance
  do not overpay.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    init_loan_balance = Money(100.00)
    bill_info = BillInfo(
        day=10, amount=Money(1.00))  # days after dates covered in this test
    loan_info = LoanInfo(init_loan_balance, interest=1.00)

    loans = [Loan(loan_info, bill_info)]

    # pay day after current_date (5)
    pay_amount = Money(200.00)
    payer = HighestInterestFirstPayer(loans, account,
                                      next_day(current_date.date), pay_amount)
    init_total_owed = payer.total_owed

    current_date.register(payer)
    current_date.increment_day()

    assert account.balance + init_loan_balance == init_account_balance
    assert loans[0].total_owed == Money(0.00)
コード例 #2
0
def test_order_observers_regiester():
    """
  The order in which two observers are registered should not affect
  the update cycle.
  """
    start = datetime.date(2020, 7, 4)
    date = DateSubject(start)
    end = date.date + datetime.timedelta(days=10)
    bill_info = BillInfo(day=end.day, amount=Money(10.00))
    loan_info = LoanInfo(Money(1000.00), interest=1.00)

    loan = Loan(loan_info, bill_info)
    loan_copy = copy.deepcopy(loan)

    account = Account(Money(10000.00))  # a reserve of money

    date.register(MinPaymentPayer(loan, account))
    date.register(InterestAccruer(loan))

    date.register(InterestAccruer(loan_copy))
    date.register(MinPaymentPayer(loan_copy, account))

    for d in date_range(start, end):
        date.increment_day()

    # \todo These are off by a penny. Is that acceptable?
    assert almost_equal(loan.balance, loan_copy.balance, 0.01)
    assert almost_equal(loan.total_owed, loan_copy.total_owed, 0.01)
コード例 #3
0
def test_highest_interest_first(current_date):
    """
  If there are 2+ loans, the loan with highest interest 
  receives the payment.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    init_loans = []
    init_loan_balance = Money(100.00)
    bill_info = BillInfo(
        day=10, amount=Money(1.00))  # days after dates covered in this test
    loan_info = LoanInfo(init_loan_balance, interest=1.00)
    init_loans.append(Loan(loan_info, bill_info))

    loan_info = LoanInfo(init_loan_balance, interest=loan_info.interest + 1.00)
    init_loans.append(Loan(loan_info, bill_info))

    loans = copy.deepcopy(init_loans)

    payer = HighestInterestFirstPayer(loans, account,
                                      next_day(current_date.date),
                                      Money(100.00))

    current_date.register(payer)
    current_date.increment_day()

    # second loan, the higher interest one, should have a different balance
    assert init_loans[1].balance != loans[1].balance

    # but lower interest one should be unchanged in this test
    assert init_loans[0].balance == loans[0].balance
コード例 #4
0
def test_account_loan_balance_adjusts(current_date):
    """
  The total_owed on a loan and change in account balance should 
  be changed in a specific way.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    init_loan_balance = Money(100.00)
    bill_info = BillInfo(
        day=10, amount=Money(1.00))  # days after dates covered in this test
    loan_info = LoanInfo(init_loan_balance, interest=1.00)

    loans = [Loan(loan_info, bill_info)]

    # pay day after current_date (5)
    pay_amount = Money(10.00)
    payer = HighestInterestFirstPayer(loans, account,
                                      next_day(current_date.date), pay_amount)
    init_total_owed = payer.total_owed

    current_date.register(payer)
    current_date.increment_day()

    assert account.balance + pay_amount == init_account_balance
    assert loans[0].total_owed + pay_amount == init_loan_balance
コード例 #5
0
def test_highest_interest_accruing(current_date):
    """
  If there are multiple loans, it's the highest interest loans who
  are accruing that are addressed first.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    init_loans = []
    init_loan_balance = Money(100.00)
    bill_info = BillInfo(
        day=10, amount=Money(1.00))  # days after dates covered in this test
    accrue_start_date = current_date.date + datetime.timedelta(days=100)
    loan_info = LoanInfo(init_loan_balance, 1.00, accrue_start_date)
    init_loans.append(Loan(loan_info, bill_info))

    loan_info = LoanInfo(init_loan_balance, 1.00)
    init_loans.append(Loan(loan_info, bill_info))

    loans = copy.deepcopy(init_loans)

    payer = HighestInterestFirstPayer(loans, account,
                                      next_day(current_date.date),
                                      Money(50.00))

    current_date.register(payer)
    current_date.increment_day()

    # first loan, nonaccruing, should not have a changed balance
    assert loans[0].balance == init_loans[0].balance

    # second loan should have a decreased balance
    assert loans[1].balance + Money(50.00) == init_loans[1].balance
コード例 #6
0
def test_payment_reduces_balance(current_date, min_payment):
    """
  When bill day is hit, loan total_owed reduces to zero
  when minimum payment exceed amount owed on loan.
  """
    initial_balance = Money(100.00)
    loan = create_loan(initial_balance, min_payment)

    initial_amount = Money(1000.00)
    account = Account(initial_amount)  # a reserve of money
    payer = MinPaymentPayer(loan, account)

    current_date.register(payer)
    current_date.increment_day()
    assert account.balance == initial_amount - initial_balance
    assert loan.total_owed == Money(0.00)
コード例 #7
0
def test_payment_reduces_balance(current_date, min_payment):
    """
  When bill day is hit, loan total_owed reduces 
  by the minimum payment amount. Same with account balance.
  """
    initial_balance = Money(100.00)
    loan = create_loan(initial_balance, min_payment)

    initial_amount = Money(1000.00)
    account = Account(initial_amount)  # a reserve of money
    payer = MinPaymentPayer(loan, account)

    current_date.register(payer)
    current_date.increment_day()
    assert account.balance == initial_amount - min_payment
    assert loan.total_owed == initial_balance - min_payment
コード例 #8
0
def test_in_progress(current_date):
    """
  If min payments are in progress account balance should change, and
  loan balance should change.
  """
    initial_balance = Money(100.00)
    loan = create_loan(initial_balance, Money(10.00))

    initial_amount = Money(1000.00)
    account = Account(initial_amount)  # a reserve of money
    payer = MinPaymentPayer(loan, account)

    current_date.register(payer)
    current_date.increment_day()
    assert account.balance != initial_amount
    assert loan.total_owed != initial_balance
コード例 #9
0
def test_not_in_progress(current_date):
    """
  If min payments are not in progress hitting bill date should
  not change account balance or total owed on loan.
  """
    initial_balance = Money(100.00)
    bill_start_date = current_date.date + datetime.timedelta(days=100)
    loan = create_loan(initial_balance, Money(10.00), bill_start_date)

    initial_amount = Money(1000.00)
    account = Account(initial_amount)  # a reserve of money
    payer = MinPaymentPayer(loan, account)

    current_date.register(payer)
    current_date.increment_day()
    assert account.balance == initial_amount
    assert loan.total_owed == initial_balance
コード例 #10
0
def test_nonzero_balance_loan(current_date):
    """
  If there is a nonzero balance loan total owed of highinterestpayer
  should change, and account amount should change.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    bill_info = BillInfo(day=10, amount=Money(1.00))
    loan_info = LoanInfo(Money(100.00), interest=1.00)

    loans = [Loan(loan_info, bill_info)]

    payer = HighestInterestFirstPayer(loans, account, 8, Money(10.00))
    init_total_owed = payer.total_owed

    current_date.register(payer)
    for i in range(31):
        current_date.increment_day()

    assert init_account_balance != account.balance
    assert init_total_owed != payer.total_owed
コード例 #11
0
def test_multiple_loans_highest_interest_first(current_date):
    """
  If there are 2+ loans, where payer's amount covers at least one of the
  loan's remaining balance, and then some, the second highest interest
  loan is the loan whose balance gets paid down.
  """
    init_account_balance = Money(10000.00)
    account = Account(init_account_balance)

    init_loans = []
    init_loan_balance = Money(100.00)
    bill_info = BillInfo(
        day=10, amount=Money(1.00))  # days after dates covered in this test
    loan_info = LoanInfo(init_loan_balance, interest=1.00)
    init_loans.append(Loan(loan_info, bill_info))

    loan_info = LoanInfo(init_loan_balance, interest=loan_info.interest + 1.00)
    init_loans.append(Loan(loan_info, bill_info))

    loan_info = LoanInfo(init_loan_balance, interest=loan_info.interest - 0.50)
    init_loans.append(Loan(loan_info, bill_info))

    loans = copy.deepcopy(init_loans)

    payer = HighestInterestFirstPayer(loans, account,
                                      next_day(current_date.date),
                                      init_loan_balance + Money(50.00))

    current_date.register(payer)
    current_date.increment_day()

    # first loan in this test should remain unchanged.
    assert loans[0].balance == init_loans[0].balance

    # Second loan should have zero money left
    assert loans[1].balance == Money(0.00)

    # Third loan should have a reduced balance
    assert loans[2].balance == init_loans[2].balance - Money(50.00)