Skip to content

Commit 0717f2c

Browse files
Mooore (#2379)
* rest-api: add generator * bank-account: add generator * pov: add generator * grade-school: add generator * zipper: add generator * zipper: add generator * list-ops: add generator [no important files changed]
1 parent 5c937a9 commit 0717f2c

File tree

13 files changed

+569
-140
lines changed

13 files changed

+569
-140
lines changed

exercises/practice/bank-account/.meta/Example.cs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ public class BankAccount
99

1010
public void Open()
1111
{
12+
if (isOpen)
13+
{
14+
throw new InvalidOperationException("Cannot open an account that is already open");
15+
}
16+
1217
lock(_lock)
1318
{
1419
isOpen = true;
@@ -17,9 +22,15 @@ public void Open()
1722

1823
public void Close()
1924
{
25+
if (!isOpen)
26+
{
27+
throw new InvalidOperationException("Cannot close an account that isn't open");
28+
}
29+
2030
lock(_lock)
2131
{
2232
isOpen = false;
33+
balance = 0;
2334
}
2435
}
2536

@@ -39,16 +50,44 @@ public decimal Balance
3950
}
4051
}
4152

42-
public void UpdateBalance(decimal change)
53+
public void Deposit(decimal change)
4354
{
55+
if (change < 0)
56+
{
57+
throw new InvalidOperationException("Cannot deposit a negative amount");
58+
}
59+
4460
lock(_lock)
4561
{
4662
if (!isOpen)
4763
{
48-
throw new InvalidOperationException("Cannot update balance on an account that isn't open");
64+
throw new InvalidOperationException("Cannot deposit in account that isn't open");
4965
}
5066

5167
balance += change;
5268
}
5369
}
70+
71+
public void Withdraw(decimal change)
72+
{
73+
if (change < 0)
74+
{
75+
throw new InvalidOperationException("Cannot deposit a negative amount");
76+
}
77+
78+
lock(_lock)
79+
{
80+
if (!isOpen)
81+
{
82+
throw new InvalidOperationException("Cannot withdraw from account that isn't open");
83+
}
84+
85+
if (balance < change)
86+
{
87+
throw new InvalidOperationException("Cannot withdraw more than the balance");
88+
}
89+
90+
balance -= change;
91+
}
92+
}
5493
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{{ func to_tested_method
2+
string.capitalize $0.operation
3+
end }}
4+
5+
{{ func to_amount
6+
if $0.amount
7+
ret $"{$0.amount}m"
8+
end
9+
10+
ret ""
11+
end }}
12+
13+
{{ func to_call
14+
if $0.operation == "balance"
15+
ret "Balance"
16+
end
17+
18+
ret $"{to_tested_method $0}({ to_amount $0 })"
19+
end }}
20+
21+
22+
using System;
23+
using System.Collections.Generic;
24+
using System.Threading.Tasks;
25+
using Xunit;
26+
27+
public class {{ testClass }}
28+
{
29+
{{- for test in tests }}
30+
[Fact{{ if !for.first }}(Skip = "Remove this Skip property to run this test"){{ end }}]
31+
public void {{ test.testMethod }}()
32+
{
33+
var account = new {{ testedClass }}();
34+
{{- for op in test.input.operations }}
35+
{{- if for.last }}
36+
{{- if test.expected.error }}
37+
Assert.Throws<InvalidOperationException>(() => account.{{ op | to_call }});
38+
{{- else }}
39+
Assert.Equal({{ test.expected }}m, account.{{ op | to_call }});
40+
{{ end -}}
41+
{{- else if op.operation == "concurrent" }}
42+
for (int i = 0; i < 500; i++)
43+
{
44+
var tasks = new List<Task>();
45+
tasks.Add(Task.Factory.StartNew(() =>
46+
{
47+
for (int j = 0; j < 100; j++)
48+
{
49+
{{- for nested_op in op.operations }}
50+
account.{{ nested_op | to_call }};
51+
{{- end -}}
52+
}
53+
}));
54+
Task.WaitAll(tasks.ToArray());
55+
}
56+
{{- else }}
57+
account.{{ op | to_call }};
58+
{{- end -}}
59+
{{ end -}}
60+
}
61+
{{ end -}}
62+
}

exercises/practice/bank-account/BankAccount.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ public decimal Balance
2020
}
2121
}
2222

23-
public void UpdateBalance(decimal change)
23+
public void Deposit(decimal change)
24+
{
25+
throw new NotImplementedException("You need to implement this method.");
26+
}
27+
28+
public void Withdraw(decimal change)
2429
{
2530
throw new NotImplementedException("You need to implement this method.");
2631
}

exercises/practice/bank-account/BankAccountTests.cs

Lines changed: 119 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,80 +6,170 @@
66
public class BankAccountTests
77
{
88
[Fact]
9-
public void Returns_empty_balance_after_opening()
9+
public void Newly_opened_account_has_zero_balance()
1010
{
1111
var account = new BankAccount();
1212
account.Open();
13-
1413
Assert.Equal(0m, account.Balance);
1514
}
1615

1716
[Fact(Skip = "Remove this Skip property to run this test")]
18-
public void Check_basic_balance()
17+
public void Single_deposit()
1918
{
2019
var account = new BankAccount();
2120
account.Open();
21+
account.Deposit(100m);
22+
Assert.Equal(100m, account.Balance);
23+
}
2224

23-
var openingBalance = account.Balance;
25+
[Fact(Skip = "Remove this Skip property to run this test")]
26+
public void Multiple_deposits()
27+
{
28+
var account = new BankAccount();
29+
account.Open();
30+
account.Deposit(100m);
31+
account.Deposit(50m);
32+
Assert.Equal(150m, account.Balance);
33+
}
2434

25-
account.UpdateBalance(10m);
26-
var updatedBalance = account.Balance;
35+
[Fact(Skip = "Remove this Skip property to run this test")]
36+
public void Withdraw_once()
37+
{
38+
var account = new BankAccount();
39+
account.Open();
40+
account.Deposit(100m);
41+
account.Withdraw(75m);
42+
Assert.Equal(25m, account.Balance);
43+
}
2744

28-
Assert.Equal(0m, openingBalance);
29-
Assert.Equal(10m, updatedBalance);
45+
[Fact(Skip = "Remove this Skip property to run this test")]
46+
public void Withdraw_twice()
47+
{
48+
var account = new BankAccount();
49+
account.Open();
50+
account.Deposit(100m);
51+
account.Withdraw(80m);
52+
account.Withdraw(20m);
53+
Assert.Equal(0m, account.Balance);
3054
}
3155

3256
[Fact(Skip = "Remove this Skip property to run this test")]
33-
public void Balance_can_increment_and_decrement()
57+
public void Can_do_multiple_operations_sequentially()
3458
{
3559
var account = new BankAccount();
3660
account.Open();
37-
var openingBalance = account.Balance;
61+
account.Deposit(100m);
62+
account.Deposit(110m);
63+
account.Withdraw(200m);
64+
account.Deposit(60m);
65+
account.Withdraw(50m);
66+
Assert.Equal(20m, account.Balance);
67+
}
3868

39-
account.UpdateBalance(10m);
40-
var addedBalance = account.Balance;
69+
[Fact(Skip = "Remove this Skip property to run this test")]
70+
public void Cannot_check_balance_of_closed_account()
71+
{
72+
var account = new BankAccount();
73+
account.Open();
74+
account.Close();
75+
Assert.Throws<InvalidOperationException>(() => account.Balance);
76+
}
4177

42-
account.UpdateBalance(-15m);
43-
var subtractedBalance = account.Balance;
78+
[Fact(Skip = "Remove this Skip property to run this test")]
79+
public void Cannot_deposit_into_closed_account()
80+
{
81+
var account = new BankAccount();
82+
account.Open();
83+
account.Close();
84+
Assert.Throws<InvalidOperationException>(() => account.Deposit(50m));
85+
}
4486

45-
Assert.Equal(0m, openingBalance);
46-
Assert.Equal(10m, addedBalance);
47-
Assert.Equal(-5m, subtractedBalance);
87+
[Fact(Skip = "Remove this Skip property to run this test")]
88+
public void Cannot_deposit_into_unopened_account()
89+
{
90+
var account = new BankAccount();
91+
Assert.Throws<InvalidOperationException>(() => account.Deposit(50m));
4892
}
4993

5094
[Fact(Skip = "Remove this Skip property to run this test")]
51-
public void Closed_account_throws_exception_when_checking_balance()
95+
public void Cannot_withdraw_from_closed_account()
5296
{
5397
var account = new BankAccount();
5498
account.Open();
5599
account.Close();
100+
Assert.Throws<InvalidOperationException>(() => account.Withdraw(50m));
101+
}
56102

57-
Assert.Throws<InvalidOperationException>(() => account.Balance);
103+
[Fact(Skip = "Remove this Skip property to run this test")]
104+
public void Cannot_close_an_account_that_was_not_opened()
105+
{
106+
var account = new BankAccount();
107+
Assert.Throws<InvalidOperationException>(() => account.Close());
58108
}
59109

60110
[Fact(Skip = "Remove this Skip property to run this test")]
61-
public void Change_account_balance_from_multiple_threads()
111+
public void Cannot_open_an_already_opened_account()
62112
{
63113
var account = new BankAccount();
64-
var tasks = new List<Task>();
114+
account.Open();
115+
Assert.Throws<InvalidOperationException>(() => account.Open());
116+
}
65117

66-
var threads = 500;
67-
var iterations = 100;
118+
[Fact(Skip = "Remove this Skip property to run this test")]
119+
public void Reopened_account_does_not_retain_balance()
120+
{
121+
var account = new BankAccount();
122+
account.Open();
123+
account.Deposit(50m);
124+
account.Close();
125+
account.Open();
126+
Assert.Equal(0m, account.Balance);
127+
}
68128

129+
[Fact(Skip = "Remove this Skip property to run this test")]
130+
public void Cannot_withdraw_more_than_deposited()
131+
{
132+
var account = new BankAccount();
69133
account.Open();
70-
for (int i = 0; i < threads; i++)
134+
account.Deposit(25m);
135+
Assert.Throws<InvalidOperationException>(() => account.Withdraw(50m));
136+
}
137+
138+
[Fact(Skip = "Remove this Skip property to run this test")]
139+
public void Cannot_withdraw_negative()
140+
{
141+
var account = new BankAccount();
142+
account.Open();
143+
account.Deposit(100m);
144+
Assert.Throws<InvalidOperationException>(() => account.Withdraw(-50m));
145+
}
146+
147+
[Fact(Skip = "Remove this Skip property to run this test")]
148+
public void Cannot_deposit_negative()
149+
{
150+
var account = new BankAccount();
151+
account.Open();
152+
Assert.Throws<InvalidOperationException>(() => account.Deposit(-50m));
153+
}
154+
155+
[Fact(Skip = "Remove this Skip property to run this test")]
156+
public void Can_handle_concurrent_transactions()
157+
{
158+
var account = new BankAccount();
159+
account.Open();
160+
for (int i = 0; i < 500; i++)
71161
{
162+
var tasks = new List<Task>();
72163
tasks.Add(Task.Factory.StartNew(() =>
73164
{
74-
for (int j = 0; j < iterations; j++)
165+
for (int j = 0; j < 100; j++)
75166
{
76-
account.UpdateBalance(1m);
77-
account.UpdateBalance(-1m);
167+
account.Deposit(1m);
168+
account.Withdraw(1m);
78169
}
79170
}));
171+
Task.WaitAll(tasks.ToArray());
80172
}
81-
Task.WaitAll(tasks.ToArray());
82-
83173
Assert.Equal(0m, account.Balance);
84174
}
85175
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using Xunit;
3+
4+
public class {{ testClass }}
5+
{
6+
{{- for test in tests }}
7+
[Fact{{ if !for.first }}(Skip = "Remove this Skip property to run this test"){{ end }}]
8+
public void {{ test.testMethod }}()
9+
{
10+
var sut = new GradeSchool();
11+
{{- if test.property == "add" }}
12+
{{ for i in 0..((array.size test.input.students) - 1) -}}
13+
Assert.{{ test.expected[i] ? "True" : "False" }}(sut.Add({{test.input.students[i][0] | string.literal }}, {{test.input.students[i][1]}}));
14+
{{ end -}}
15+
{{- else }}
16+
{{ for student in test.input.students -}}
17+
sut.Add({{ student[0] | string.literal }}, {{ student[1] }});
18+
{{ end -}}
19+
string[] expected = {{ test.expected }};
20+
Assert.Equal(expected, sut.{{ test.testedMethod }}({{ test.input.desiredGrade }}));
21+
{{ end -}}
22+
}
23+
{{ end -}}
24+
}

0 commit comments

Comments
 (0)