Finished
33// convenience to get you started writing code faster.
44//
55
6// Simple mutex implementation for thread safety
7class Mutex {
8 constructor() {
9 this._queue = [];
10 this._locked = false;
11 }
12
13 async acquire() {
14 return new Promise((resolve) => {
15 if (!this._locked) {
16 this._locked = true;
17 resolve();
18 } else {
19 this._queue.push(resolve);
20 }
21 });
22 }
23
24 release() {
25 if (this._queue.length > 0) {
26 const nextResolve = this._queue.shift();
27 nextResolve();
28 } else {
29 this._locked = false;
30 }
31 }
32
33 async withLock(callback) {
34 await this.acquire();
35 try {
36 return await callback();
37 } finally {
38 this.release();
39 }
40 }
41}
42
643export class BankAccount {
744 constructor() {
8 throw new Error('Remove this line and implement the function');
45 this._balance = 0;
46 this._isOpen = false;
47 this._mutex = new Mutex();
948 }
1049
11 open() {
12 throw new Error('Remove this line and implement the function');
50 async open() {
51 return this._mutex.withLock(async () => {
52 // Edge Case: Attempting to open an already open account
53 if (this._isOpen) {
54 throw new ValueError();
55 }
56 this._isOpen = true;
57 this._balance = 0;
58 });
1359 }
1460
15 close() {
16 throw new Error('Remove this line and implement the function');
61 async close() {
62 return this._mutex.withLock(async () => {
63 // Edge Case: Attempting to close an already closed account
64 if (!this._isOpen) {
65 throw new ValueError();
66 }
67 this._isOpen = false;
68 });
1769 }
1870
1971 /**
2072 * @param {number} amount
2173 */
22 deposit(amount) {
23 throw new Error('Remove this line and implement the function');
74 async deposit(amount) {
75 return this._mutex.withLock(async () => {
76 // Edge Case: Attempting operations on a closed account
77 if (!this._isOpen) {
78 throw new ValueError();
79 }
80
81 // Edge Case: Negative deposit amount
82 if (amount <= 0) {
83 throw new ValueError();
84 }
85
86 this._balance += amount;
87 });
2488 }
2589
2690 /**
2791 * @param {number} amount
2892 */
29 withdraw(amount) {
30 throw new Error('Remove this line and implement the function');
93 async withdraw(amount) {
94 return this._mutex.withLock(async () => {
95 // Edge Case: Attempting operations on a closed account
96 if (!this._isOpen) {
97 throw new ValueError();
98 }
99
100 // Edge Case: Negative withdrawal amount
101 if (amount <= 0) {
102 throw new ValueError();
103 }
104
105 // Edge Case: Insufficient funds for withdrawal
106 if (amount > this._balance) {
107 throw new ValueError();
108 }
109
110 this._balance -= amount;
111 });
112 }
113
114 /**
115 * @return {number}
116 */
117 async getBalance() {
118 return this._mutex.withLock(async () => {
119 // Edge Case: Attempting to check balance of a closed account
120 if (!this._isOpen) {
121 throw new ValueError();
122 }
123
124 return this._balance;
125 });
31126 }
32127
33128 /**
34129 * @return {number}
130 * @deprecated Use getBalance() instead for async operations
35131 */
36132 get balance() {
37 throw new Error('Remove this line and implement the function');
133 // Synchronous balance access - not thread safe!
134 // This is kept for backward compatibility but should not be used in concurrent scenarios
135 if (!this._isOpen) {
136 throw new ValueError();
137 }
138 return this._balance;
38139 }
39140}
40141
43144 super('Bank account error');
44145 }
45146}
147
148// Handled Edge Cases:
149// 1. Attempting to open an already open account
150// 2. Attempting to close an already closed account
151// 3. Attempting operations on a closed account
152// 4. Negative deposit amount
153// 5. Negative withdrawal amount
154// 6. Insufficient funds for withdrawal
155// 7. Attempting to check balance of a closed account
156//
157// Thread Safety Features:
158// - All operations are protected by a mutex to prevent race conditions
159// - Concurrent deposits and withdrawals are serialized to maintain data integrity
160// - Balance reads are atomic and consistent
161// - Use async/await pattern for all operations in concurrent environments
Test NameStatus
newly opened account has zero balance
Fail
Single deposit
Fail
Multiple deposits"
Fail
Withdraw once
Fail
Withdraw twice
Fail
Can do multiple operations sequentially
Fail
Cannot deposit into closed account
Fail
Cannot deposit into unopened account
Fail
Cannot withdraw from closed account
Fail
Cannot close an account that was not opened
Fail
Cannot open an already opened account
Fail
Reopened account does not retain balance
Fail
Cannot withdraw more than deposited
Fail
Cannot withdraw negative
Fail
Cannot deposit negative
Fail
Cannot check balance of closed account
Pass
Can handle concurrent transactions
Pass
Changing balance directly throws error
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.