diff --git a/exercises/practice/bank-account/.meta/config.json b/exercises/practice/bank-account/.meta/config.json index 23ae37c0b5..330828347b 100644 --- a/exercises/practice/bank-account/.meta/config.json +++ b/exercises/practice/bank-account/.meta/config.json @@ -3,6 +3,7 @@ "TomPradat" ], "contributors": [ + "jagdish-15", "SleeplessByte" ], "files": { diff --git a/exercises/practice/bank-account/.meta/tests.toml b/exercises/practice/bank-account/.meta/tests.toml new file mode 100644 index 0000000000..4e42d4dcb5 --- /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/bank-account.spec.js b/exercises/practice/bank-account/bank-account.spec.js index 3da7d08e6f..7b2664b6f3 100644 --- a/exercises/practice/bank-account/bank-account.spec.js +++ b/exercises/practice/bank-account/bank-account.spec.js @@ -8,14 +8,14 @@ describe('Bank Account', () => { expect(account.balance).toEqual(0); }); - xtest('can deposit money', () => { + xtest('Single deposit', () => { const account = new BankAccount(); account.open(); account.deposit(100); expect(account.balance).toEqual(100); }); - xtest('can deposit money sequentially', () => { + xtest('Multiple deposits"', () => { const account = new BankAccount(); account.open(); account.deposit(100); @@ -23,7 +23,7 @@ describe('Bank Account', () => { expect(account.balance).toEqual(150); }); - xtest('can withdraw money', () => { + xtest('Withdraw once', () => { const account = new BankAccount(); account.open(); account.deposit(100); @@ -31,7 +31,7 @@ describe('Bank Account', () => { expect(account.balance).toEqual(50); }); - xtest('can withdraw money sequentially', () => { + xtest('Withdraw twice', () => { const account = new BankAccount(); account.open(); account.deposit(100); @@ -40,14 +40,25 @@ describe('Bank Account', () => { expect(account.balance).toEqual(0); }); - xtest('checking balance of closed account throws error', () => { + xtest('Can do multiple operations sequentially', () => { + const account = new BankAccount(); + account.open(); + account.deposit(100); + account.deposit(110); + account.withdraw(200); + account.deposit(60); + account.withdraw(50); + expect(account.balance).toEqual(20); + }); + + xtest('Cannot check balance of closed account', () => { const account = new BankAccount(); account.open(); account.close(); expect(() => account.balance).toThrow(ValueError); }); - xtest('deposit into closed account throws error', () => { + xtest('Cannot deposit into closed account', () => { const account = new BankAccount(); account.open(); account.close(); @@ -56,7 +67,14 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('withdraw from closed account throws error', () => { + xtest('Cannot deposit into closed account', () => { + const account = new BankAccount(); + expect(() => { + account.deposit(50); + }).toThrow(ValueError); + }); + + xtest('Cannot withdraw from closed account', () => { const account = new BankAccount(); account.open(); account.close(); @@ -65,14 +83,14 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('close already closed account throws error', () => { + xtest('Cannot close an account that was not opened', () => { const account = new BankAccount(); expect(() => { account.close(); }).toThrow(ValueError); }); - xtest('open already opened account throws error', () => { + xtest('Cannot open an already opened account', () => { const account = new BankAccount(); account.open(); expect(() => { @@ -80,7 +98,7 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('reopened account does not retain balance', () => { + xtest('Reopened account does not retain balance', () => { const account = new BankAccount(); account.open(); account.deposit(50); @@ -89,7 +107,7 @@ describe('Bank Account', () => { expect(account.balance).toEqual(0); }); - xtest('cannot withdraw more than deposited', () => { + xtest('Cannot withdraw more than deposited', () => { const account = new BankAccount(); account.open(); account.deposit(25); @@ -98,7 +116,7 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('cannot withdraw negative amount', () => { + xtest('Cannot withdraw negative', () => { const account = new BankAccount(); account.open(); account.deposit(100); @@ -107,7 +125,7 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('cannot deposit negative amount', () => { + xtest('Cannot deposit negative', () => { const account = new BankAccount(); account.open(); expect(() => { @@ -115,7 +133,40 @@ describe('Bank Account', () => { }).toThrow(ValueError); }); - xtest('changing balance directly throws error', () => { + xtest('Can handle concurrent transactions', async () => { + const account = new BankAccount(); + account.open(); + account.deposit(1000); + + for (let i = 0; i < 10; i++) { + await adjustBalanceConcurrently(account); + expect(account.balance).toEqual(1000); + } + }); + + function adjustBalanceConcurrently(account) { + const random = () => Math.floor(Math.random() * 10); + + const tasks = Array.from( + { length: 1000 }, + () => + new Promise((resolve) => { + try { + account.deposit(5); + setTimeout(() => { + account.withdraw(5); + resolve(); + }, random()); + } catch (e) { + throw new Error(`Exception should not be thrown: ${e.message}`); + } + }), + ); + + return Promise.all(tasks); + } + + xtest('Changing balance directly throws error', () => { const account = new BankAccount(); account.open(); expect(() => {