Skip to content

Commit c652ff3

Browse files
meatball133BethanyG
authored andcommitted
Updated bank account
1 parent f333803 commit c652ff3

5 files changed

Lines changed: 397 additions & 69 deletions

File tree

bin/githelp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Iterator, Union
77

88

9-
GITHUB_EXERCISM = f"https://github.com/exercism"
9+
GITHUB_EXERCISM = f"https://github.com/meatball133"
1010

1111

1212
class Repo(Enum):
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{%- import "generator_macros.j2" as macros with context -%}
2+
{% macro test_case(case) -%}
3+
def test_{{ case["description"] | to_snake }}(self):
4+
account = BankAccount()
5+
{%- set inputs = case["input"]["operations"] -%}
6+
{%- if case["expected"] -%}
7+
{%- set error_case = true -%}
8+
{%- set error_msg = case["expected"]["error"] -%}
9+
{%- set error_operation = inputs[-1]["operation"] -%}
10+
{%- set final_value = inputs[-1]["value"] -%}
11+
{% endif %}
12+
{%- if case["expected"] and inputs|length > 1 -%}
13+
{%- set inputs = inputs[:-1] -%}
14+
{%- endif -%}
15+
{%- for input in inputs -%}
16+
{%- set operation = input["operation"] -%}
17+
{%- set value = input["value"] -%}
18+
{%- set expected = input["expected"] %}
19+
{%- if operation and value %}
20+
account.{{ operation }}({{ value }})
21+
{%- elif operation == "amount" %}
22+
self.assertEqual(account.get_balance(), {{ expected }})
23+
{%- elif operation and not value %}
24+
account.{{ operation }}()
25+
{%- endif %}
26+
{%- endfor %}
27+
{%- if error_case %}
28+
with self.assertRaises(ValueError) as err:
29+
account.{{ error_operation }}({{ final_value if final_value else "" }})
30+
self.assertEqual(type(err.exception), ValueError)
31+
self.assertEqual(err.exception.args[0], "{{ error_msg }}")
32+
{%- endif %}
33+
{% endmacro %}
34+
35+
{{ macros.header(["BankAccount"]) }}
36+
37+
class {{ exercise | camel_case }}Test(unittest.TestCase):
38+
{% for case in cases -%}
39+
{{ test_case(case) }}
40+
{% endfor %}
41+
{% if additional_cases | length -%}
42+
43+
# Additional tests for this track
44+
{% for case in additional_cases -%}
45+
{{ test_case(case) }}
46+
{% endfor %}
47+
{%- endif %}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# This is an auto-generated file. Regular comments will be removed when this
2+
# file is regenerated. Regenerating will not touch any manually added keys,
3+
# so comments can be added in a "comment" key.
4+
5+
[983a1528-4ceb-45e5-8257-8ce01aceb5ed]
6+
description = "encode yes"
7+
8+
[e88d4ec3-c6bf-4752-8e59-5046c44e3ba7]
9+
description = "encode no"
10+
11+
[08f1af07-27ae-4b38-aa19-770bde558064]
12+
description = "encode OMG"
13+
14+
[6f6d242f-8c31-4ac6-8995-a90d42cad59f]
15+
description = "encode spaces"
16+
17+
[f9facfaa-d824-486e-8381-48832c4bbffd]
18+
description = "encode mindblowingly"
19+
20+
[7a65ba52-e35c-4fd2-8159-bda2bde6e59c]
21+
description = "encode numbers"
22+
23+
[570dfaa5-0532-4c1f-a7d3-0f65c3265608]
24+
description = "encode deep thought"
25+
26+
[c396d233-1c49-4272-98dc-7f502dbb9470]
27+
description = "encode all the letters"
28+
29+
[c06f534f-bdc2-4a02-a388-1063400684de]
30+
description = "decode exercism"
31+
32+
[0722d404-6116-4f92-ba3b-da7f88f1669c]
33+
description = "decode a sentence"
34+
35+
[ec42245f-9361-4341-8231-a22e8d19c52f]
36+
description = "decode numbers"
37+
38+
[4f381ef8-10ef-4507-8e1d-0631ecc8ee72]
39+
description = "decode all the letters"
40+
41+
[d45df9ea-1db0-47f3-b18c-d365db49d938]
42+
description = "decode with too many spaces"
43+
Lines changed: 21 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,112 @@
1-
import sys
2-
import threading
3-
import time
41
import unittest
52

6-
from bank_account import BankAccount
3+
from bank_account import (
4+
BankAccount,
5+
)
6+
7+
# Tests adapted from `problem-specifications//canonical-data.json`
78

89

910
class BankAccountTest(unittest.TestCase):
10-
def test_newly_opened_account_has_zero_balance(self):
11+
def test_using_pop_raises_an_error_if_the_list_is_empty(self):
1112
account = BankAccount()
1213
account.open()
1314
self.assertEqual(account.get_balance(), 0)
1415

15-
def test_can_deposit_money(self):
16+
def test_can_return_with_pop_and_then_raise_an_error_if_empty(self):
1617
account = BankAccount()
1718
account.open()
1819
account.deposit(100)
1920
self.assertEqual(account.get_balance(), 100)
2021

21-
def test_can_deposit_money_sequentially(self):
22-
account = BankAccount()
23-
account.open()
24-
account.deposit(100)
25-
account.deposit(50)
26-
27-
self.assertEqual(account.get_balance(), 150)
28-
29-
def test_can_withdraw_money(self):
22+
def test_using_shift_raises_an_error_if_the_list_is_empty(self):
3023
account = BankAccount()
3124
account.open()
3225
account.deposit(100)
3326
account.withdraw(50)
34-
3527
self.assertEqual(account.get_balance(), 50)
3628

37-
def test_can_withdraw_money_sequentially(self):
29+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
3830
account = BankAccount()
3931
account.open()
4032
account.deposit(100)
41-
account.withdraw(20)
4233
account.withdraw(80)
43-
34+
account.withdraw(20)
4435
self.assertEqual(account.get_balance(), 0)
4536

46-
def test_checking_balance_of_closed_account_throws_error(self):
37+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
4738
account = BankAccount()
4839
account.open()
4940
account.close()
50-
5141
with self.assertRaises(ValueError) as err:
52-
account.get_balance()
42+
account.amount()
5343
self.assertEqual(type(err.exception), ValueError)
5444
self.assertEqual(err.exception.args[0], "account not open")
5545

56-
def test_deposit_into_closed_account(self):
46+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
5747
account = BankAccount()
5848
account.open()
5949
account.close()
60-
6150
with self.assertRaises(ValueError) as err:
6251
account.deposit(50)
6352
self.assertEqual(type(err.exception), ValueError)
6453
self.assertEqual(err.exception.args[0], "account not open")
6554

66-
67-
def test_withdraw_from_closed_account(self):
55+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
6856
account = BankAccount()
6957
account.open()
7058
account.close()
71-
7259
with self.assertRaises(ValueError) as err:
7360
account.withdraw(50)
7461
self.assertEqual(type(err.exception), ValueError)
7562
self.assertEqual(err.exception.args[0], "account not open")
7663

77-
def test_close_already_closed_account(self):
64+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
7865
account = BankAccount()
66+
account.close()
7967
with self.assertRaises(ValueError) as err:
8068
account.close()
8169
self.assertEqual(type(err.exception), ValueError)
8270
self.assertEqual(err.exception.args[0], "account not open")
8371

84-
def test_open_already_opened_account(self):
72+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
8573
account = BankAccount()
8674
account.open()
8775
with self.assertRaises(ValueError) as err:
8876
account.open()
8977
self.assertEqual(type(err.exception), ValueError)
9078
self.assertEqual(err.exception.args[0], "account already open")
9179

92-
def test_reopened_account_does_not_retain_balance(self):
80+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
9381
account = BankAccount()
9482
account.open()
9583
account.deposit(50)
9684
account.close()
9785
account.open()
9886
self.assertEqual(account.get_balance(), 0)
9987

100-
def test_cannot_withdraw_more_than_deposited(self):
88+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
10189
account = BankAccount()
10290
account.open()
10391
account.deposit(25)
104-
10592
with self.assertRaises(ValueError) as err:
10693
account.withdraw(50)
10794
self.assertEqual(type(err.exception), ValueError)
10895
self.assertEqual(err.exception.args[0], "amount must be less than balance")
10996

110-
def test_cannot_withdraw_negative(self):
97+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
11198
account = BankAccount()
11299
account.open()
113100
account.deposit(100)
114-
115101
with self.assertRaises(ValueError) as err:
116102
account.withdraw(-50)
117103
self.assertEqual(type(err.exception), ValueError)
118104
self.assertEqual(err.exception.args[0], "amount must be greater than 0")
119105

120-
def test_cannot_deposit_negative(self):
106+
def test_can_return_with_shift_and_then_raise_an_error_if_empty(self):
121107
account = BankAccount()
122108
account.open()
123-
124109
with self.assertRaises(ValueError) as err:
125110
account.deposit(-50)
126111
self.assertEqual(type(err.exception), ValueError)
127112
self.assertEqual(err.exception.args[0], "amount must be greater than 0")
128-
129-
def test_can_handle_concurrent_transactions(self):
130-
account = BankAccount()
131-
account.open()
132-
account.deposit(1000)
133-
134-
self.adjust_balance_concurrently(account)
135-
136-
self.assertEqual(account.get_balance(), 1000)
137-
138-
def adjust_balance_concurrently(self, account):
139-
def transact():
140-
account.deposit(5)
141-
time.sleep(0.001)
142-
account.withdraw(5)
143-
144-
# Greatly improve the chance of an operation being interrupted
145-
# by thread switch, thus testing synchronization effectively
146-
try:
147-
sys.setswitchinterval(1e-12)
148-
except AttributeError:
149-
# For Python 2 compatibility
150-
sys.setcheckinterval(1)
151-
152-
threads = [threading.Thread(target=transact) for _ in range(1000)]
153-
for thread in threads:
154-
thread.start()
155-
for thread in threads:
156-
thread.join()
157-
158-
if __name__ == '__main__':
159-
unittest.main()

0 commit comments

Comments
 (0)