Refactor a PaymentRegister whose gift-card implementation weakens the meaning of success.
All payment methods share one contract: charge(amount) returns true only after charging exactly amount. The starter's gift card charges whatever balance remains and still returns true, so client code cannot trust the result.
addCard(name) adds a card with no spending limit in this exercise.addGiftCard(name, balance) adds a gift card with a fixed starting balance.pay(index, amount) returns true only after charging the full positive amount.chargedTotal(index) returns the total charged, or -1 for an invalid index.describe(index) returns "Card <name> charged <total>", "Gift <name> remaining <balance> charged <total>", or "UNKNOWN".A refused payment must leave every value unchanged.
charge(amount) may be called with any integer. A nonpositive amount returns false without mutation.true means the charged total increased by exactly amount.false means the charged total and every implementation-specific value, including gift-card balance, are unchanged.This exercise focuses on a weakened postcondition: the starter reports full success after performing only part of the promised operation.
Operations | Results |
|---|---|
|
|
|
|
For the refused gift-card payment above, the description remains "Gift small remaining 30 charged 0".
Full marks when every PaymentMethod charges exactly amount before returning true. Lose points heavily when GiftCard charges a partial amount, reports success without the full charge, or changes state before returning false.
Full marks when PaymentRegister calls the same charge contract for card and gift card without checking their concrete types. Lose points for gift-card logic in the register or a type switch.
Full marks when nonpositive amounts and insufficient gift-card balances return false without mutation, totals accumulate correctly, and invalid indexes return the required sentinels. Lose points for incorrect descriptions or printed output.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new PaymentRegister() | null |
| addCard("main") | 0 |
| pay(0, 25) | true |
| chargedTotal(0) | 25 |
| describe(0) | "Card main charged 25" |
A successful card payment records the complete requested amount.
Run checks these cases. Submit also runs a larger hidden set.

