Interest Accrual
Multiplying principal by rate by a time fraction is the easy part the model builds for free. The hidden test is how you turn two calendar dates into a span: a vague spec counts the actual days over a 365-day year, which quietly disagrees with the convention this kind of accrual is settled under whenever a date lands on a month-end.
You are building the accrual calculator at the core of an interest-bearing product. It is handed a principal amount, an annual interest rate expressed as a decimal (so 0.05 means five percent per year), and two calendar dates: the date interest starts accruing and the date it stops. It returns, as a single number, the interest that accrues on the principal over the range from the start date up to but not including the end date. If the two dates are equal, nothing has accrued and the result is zero.
Implement a function accruedInterest(principal, annualRate, startISO, endISO). The two dates arrive as 'YYYY-MM-DD' strings and the start date is never after the end date. Interest accrues as the principal times the annual rate times the fraction of a year covered by the range. The arithmetic is straightforward; the entire result hinges on a single modeling choice you must make and pin down precisely.
Specify how the calculator turns the two dates into a span of time. Counting the literal number of calendar days and dividing by 365 is one choice, but it is not the only one, and it is not the one this kind of accrual is conventionally settled under. There is a standard, widely used way of counting the days between two dates for interest like this, one that treats the calendar as regular rather than counting it day by day, and it carries a couple of specific, non-obvious adjustments for dates that fall at the end of a month. Decide which convention governs, state its day-count rule exactly, including the month-end adjustments, and write it as something a deterministic test could check. A calculator that just counts actual days will quietly disagree with the convention whenever a date lands on a month boundary.
With principal 1,000,000 and annualRate 0.05, accruing from 2023-01-01 to 2024-01-01 returns 50,000 (a full year). The interesting cases are ranges that end or start on a month boundary: from 2024-01-31 to 2024-04-30, a calculator that counts actual calendar days lands on a different day count than the convention this accrual is settled under, and the two answers diverge.
- accruedInterest(principal, annualRate, startISO, endISO) returning a number; equal dates return 0.
- Interest is principal times annualRate times the fraction of a year the range covers.
- Dates are 'YYYY-MM-DD' strings with start no later than end; the rate is a decimal.
The functional tests are shown, and the model usually clears them on its own. The hidden tests are the twists this kind of system is full of. They are not listed. Your spec only passes them if it already knows where this domain breaks.
271 chars