diff --git a/exercises/practice/bank-account/.meta/src/reference/java/BankAccount.java b/exercises/practice/bank-account/.meta/src/reference/java/BankAccount.java index 8f762cf1d..9146d0a5c 100644 --- a/exercises/practice/bank-account/.meta/src/reference/java/BankAccount.java +++ b/exercises/practice/bank-account/.meta/src/reference/java/BankAccount.java @@ -2,11 +2,18 @@ class BankAccount { private int balance = 0; private boolean isClosed = true; - void open() { + void open() throws BankAccountActionInvalidException { + if (!isClosed) { + throw new BankAccountActionInvalidException("Account already open"); + } isClosed = false; + balance = 0; } - void close() { + void close() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account not open"); + } isClosed = true; } diff --git a/exercises/practice/bank-account/.meta/tests.toml b/exercises/practice/bank-account/.meta/tests.toml new file mode 100644 index 000000000..4e42d4dcb --- /dev/null +++ b/exercises/practice/bank-account/.meta/tests.toml @@ -0,0 +1,61 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[983a1528-4ceb-45e5-8257-8ce01aceb5ed] +description = "Newly opened account has zero balance" + +[e88d4ec3-c6bf-4752-8e59-5046c44e3ba7] +description = "Single deposit" + +[3d9147d4-63f4-4844-8d2b-1fee2e9a2a0d] +description = "Multiple deposits" + +[08f1af07-27ae-4b38-aa19-770bde558064] +description = "Withdraw once" + +[6f6d242f-8c31-4ac6-8995-a90d42cad59f] +description = "Withdraw twice" + +[45161c94-a094-4c77-9cec-998b70429bda] +description = "Can do multiple operations sequentially" + +[f9facfaa-d824-486e-8381-48832c4bbffd] +description = "Cannot check balance of closed account" + +[7a65ba52-e35c-4fd2-8159-bda2bde6e59c] +description = "Cannot deposit into closed account" + +[a0a1835d-faae-4ad4-a6f3-1fcc2121380b] +description = "Cannot deposit into unopened account" + +[570dfaa5-0532-4c1f-a7d3-0f65c3265608] +description = "Cannot withdraw from closed account" + +[c396d233-1c49-4272-98dc-7f502dbb9470] +description = "Cannot close an account that was not opened" + +[c06f534f-bdc2-4a02-a388-1063400684de] +description = "Cannot open an already opened account" + +[0722d404-6116-4f92-ba3b-da7f88f1669c] +description = "Reopened account does not retain balance" + +[ec42245f-9361-4341-8231-a22e8d19c52f] +description = "Cannot withdraw more than deposited" + +[4f381ef8-10ef-4507-8e1d-0631ecc8ee72] +description = "Cannot withdraw negative" + +[d45df9ea-1db0-47f3-b18c-d365db49d938] +description = "Cannot deposit negative" + +[ba0c1e0b-0f00-416f-8097-a7dfc97871ff] +description = "Can handle concurrent transactions" diff --git a/exercises/practice/bank-account/src/main/java/BankAccount.java b/exercises/practice/bank-account/src/main/java/BankAccount.java index 61625bd6d..0538b3611 100644 --- a/exercises/practice/bank-account/src/main/java/BankAccount.java +++ b/exercises/practice/bank-account/src/main/java/BankAccount.java @@ -1,10 +1,10 @@ class BankAccount { - void open() { + void open() throws BankAccountActionInvalidException { throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } - void close() { + void close() throws BankAccountActionInvalidException { throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } diff --git a/exercises/practice/bank-account/src/main/java/BankAccountActionInvalidException.java b/exercises/practice/bank-account/src/main/java/BankAccountActionInvalidException.java index 4b06fa845..a4fa24c81 100644 --- a/exercises/practice/bank-account/src/main/java/BankAccountActionInvalidException.java +++ b/exercises/practice/bank-account/src/main/java/BankAccountActionInvalidException.java @@ -1,6 +1,6 @@ -class BankAccountActionInvalidException extends Exception { +public class BankAccountActionInvalidException extends Exception { - BankAccountActionInvalidException(String message) { + public BankAccountActionInvalidException(String message) { super(message); } } diff --git a/exercises/practice/bank-account/src/test/java/BankAccountTest.java b/exercises/practice/bank-account/src/test/java/BankAccountTest.java index ba0982893..77770297d 100644 --- a/exercises/practice/bank-account/src/test/java/BankAccountTest.java +++ b/exercises/practice/bank-account/src/test/java/BankAccountTest.java @@ -1,14 +1,18 @@ -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.fail; - +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import java.util.Random; +import static org.assertj.core.api.Assertions.*; + public class BankAccountTest { - private BankAccount bankAccount = new BankAccount(); + private BankAccount bankAccount; + + @Before + public void setUp() { + bankAccount = new BankAccount(); + } @Test public void newlyOpenedAccountHasEmptyBalance() throws BankAccountActionInvalidException { @@ -19,136 +23,162 @@ public void newlyOpenedAccountHasEmptyBalance() throws BankAccountActionInvalidE @Ignore("Remove to run test") @Test - public void canDepositMoney() throws BankAccountActionInvalidException { + public void singleDeposit() throws BankAccountActionInvalidException { bankAccount.open(); + bankAccount.deposit(100); - bankAccount.deposit(10); - - assertThat(bankAccount.getBalance()).isEqualTo(10); + assertThat(bankAccount.getBalance()).isEqualTo(100); } @Ignore("Remove to run test") @Test - public void canDepositMoneySequentially() throws BankAccountActionInvalidException { + public void multipleDeposits() throws BankAccountActionInvalidException { bankAccount.open(); + bankAccount.deposit(100); + bankAccount.deposit(50); - bankAccount.deposit(5); - bankAccount.deposit(23); - - assertThat(bankAccount.getBalance()).isEqualTo(28); + assertThat(bankAccount.getBalance()).isEqualTo(150); } @Ignore("Remove to run test") @Test - public void canWithdrawMoney() throws BankAccountActionInvalidException { + public void withdrawOnce() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(10); - - bankAccount.withdraw(5); + bankAccount.deposit(100); + bankAccount.withdraw(75); - assertThat(bankAccount.getBalance()).isEqualTo(5); + assertThat(bankAccount.getBalance()).isEqualTo(25); } @Ignore("Remove to run test") @Test - public void canWithdrawMoneySequentially() throws BankAccountActionInvalidException { + public void withdrawTwice() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(23); - - bankAccount.withdraw(10); - bankAccount.withdraw(13); + bankAccount.deposit(100); + bankAccount.withdraw(80); + bankAccount.withdraw(20); assertThat(bankAccount.getBalance()).isEqualTo(0); } @Ignore("Remove to run test") @Test - public void cannotWithdrawMoneyFromEmptyAccount() { + public void canDoMultipleOperationsSequentially() throws BankAccountActionInvalidException { bankAccount.open(); + bankAccount.deposit(100); + bankAccount.deposit(110); + bankAccount.withdraw(200); + bankAccount.deposit(60); + bankAccount.withdraw(50); - assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.withdraw(5)) - .withMessage("Cannot withdraw money from an empty account"); + assertThat(bankAccount.getBalance()).isEqualTo(20); } @Ignore("Remove to run test") @Test - public void cannotWithdrawMoreMoneyThanYouHave() throws BankAccountActionInvalidException { + public void cannotCheckBalanceOfClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(6); + bankAccount.close(); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.withdraw(7)) - .withMessage("Cannot withdraw more money than is currently in the account"); + .isThrownBy(bankAccount::getBalance) + .withMessage("Account closed"); } @Ignore("Remove to run test") @Test - public void cannotDepositNegativeAmount() { + public void cannotDepositIntoClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); + bankAccount.close(); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.deposit(-1)) - .withMessage("Cannot deposit or withdraw negative amount"); + .isThrownBy(() -> bankAccount.deposit(50)) + .withMessage("Account closed"); } @Ignore("Remove to run test") @Test - public void cannotWithdrawNegativeAmount() throws BankAccountActionInvalidException { + public void cannotDepositIntoUnopenedAccount() { + assertThatExceptionOfType(BankAccountActionInvalidException.class) + .isThrownBy(() -> bankAccount.deposit(50)) + .withMessage("Account closed"); + } + + @Ignore("Remove to run test") + @Test + public void cannotWithdrawFromClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(105); + bankAccount.close(); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.withdraw(-5)) - .withMessage("Cannot deposit or withdraw negative amount"); + .isThrownBy(() -> bankAccount.withdraw(50)) + .withMessage("Account closed"); } @Ignore("Remove to run test") @Test - public void cannotGetBalanceOfClosedAccount() throws BankAccountActionInvalidException { + public void cannotCloseAnAccountThatWasNotOpened() { + assertThatExceptionOfType(BankAccountActionInvalidException.class) + .isThrownBy(bankAccount::close) + .withMessage("Account not open"); + } + + @Ignore("Remove to run test") + @Test + public void cannotOpenAnAlreadyOpenedAccount() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(10); - bankAccount.close(); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(bankAccount::getBalance) - .withMessage("Account closed"); + .isThrownBy(bankAccount::open) + .withMessage("Account already open"); } @Ignore("Remove to run test") @Test - public void cannotDepositMoneyIntoClosedAccount() { + public void reopenedAccountDoesNotRetainBalance() throws BankAccountActionInvalidException { bankAccount.open(); + bankAccount.deposit(50); bankAccount.close(); + bankAccount.open(); + + assertThat(bankAccount.getBalance()).isEqualTo(0); + } + + @Ignore("Remove to run test") + @Test + public void cannotWithdrawMoreThanWasDeposited() throws BankAccountActionInvalidException { + bankAccount.open(); + bankAccount.deposit(25); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.deposit(5)) - .withMessage("Account closed"); + .isThrownBy(() -> bankAccount.withdraw(50)) + .withMessage("Cannot withdraw more money than is currently in the account"); } @Ignore("Remove to run test") @Test - public void cannotWithdrawMoneyFromClosedAccount() throws BankAccountActionInvalidException { + public void cannotWithdrawNegativeAmount() throws BankAccountActionInvalidException { bankAccount.open(); - bankAccount.deposit(20); - bankAccount.close(); + bankAccount.deposit(100); assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(() -> bankAccount.withdraw(5)) - .withMessage("Account closed"); + .isThrownBy(() -> bankAccount.withdraw(-50)) + .withMessage("Cannot deposit or withdraw negative amount"); } @Ignore("Remove to run test") @Test - public void bankAccountIsClosedBeforeItIsOpened() { + public void cannotDepositNegativeAmount() throws BankAccountActionInvalidException { + bankAccount.open(); + assertThatExceptionOfType(BankAccountActionInvalidException.class) - .isThrownBy(bankAccount::getBalance) - .withMessage("Account closed"); + .isThrownBy(() -> bankAccount.deposit(-50)) + .withMessage("Cannot deposit or withdraw negative amount"); } @Ignore("Remove to run test") @Test - public void canAdjustBalanceConcurrently() throws BankAccountActionInvalidException, InterruptedException { + public void canHandleConcurrentTransactions() throws BankAccountActionInvalidException, InterruptedException { bankAccount.open(); bankAccount.deposit(1000); @@ -158,7 +188,7 @@ public void canAdjustBalanceConcurrently() throws BankAccountActionInvalidExcept } } - private void adjustBalanceConcurrently() throws BankAccountActionInvalidException, InterruptedException { + private void adjustBalanceConcurrently() throws InterruptedException { Random random = new Random(); Thread[] threads = new Thread[1000];