trackler 2.2.1.162 → 2.2.1.163
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/bash/config.json +2 -1
- data/tracks/c/docs/ABOUT.md +3 -3
- data/tracks/c/docs/SNIPPET.txt +3 -4
- data/tracks/common-lisp/docs/RESOURCES.md +1 -1
- data/tracks/cpp/config.json +1 -0
- data/tracks/csharp/exercises/pov/Example.cs +49 -53
- data/tracks/csharp/exercises/pov/Pov.cs +5 -25
- data/tracks/csharp/exercises/pov/PovTest.cs +127 -110
- data/tracks/csharp/exercises/react/Example.cs +3 -5
- data/tracks/csharp/exercises/react/React.csproj +1 -0
- data/tracks/csharp/exercises/react/ReactTest.cs +167 -78
- data/tracks/csharp/exercises/simple-cipher/Example.cs +18 -21
- data/tracks/csharp/exercises/simple-cipher/SimpleCipher.cs +3 -3
- data/tracks/csharp/exercises/simple-cipher/SimpleCipherTest.cs +43 -79
- data/tracks/csharp/generators/Exercises/Pov.cs +54 -0
- data/tracks/csharp/generators/Exercises/React.cs +136 -0
- data/tracks/csharp/generators/Exercises/SimpleCipher.cs +67 -0
- data/tracks/elixir/config/maintainers.json +16 -16
- data/tracks/elixir/config.json +370 -369
- data/tracks/java/config.json +1 -1
- data/tracks/racket/docs/LEARNING.md +1 -1
- data/tracks/sml/config/maintainers.json +8 -8
- data/tracks/sml/config.json +57 -103
- data/tracks/sml/exercises/nth-prime/.meta/hints.md +1 -1
- metadata +5 -2
@@ -1,115 +1,204 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
// This file was auto-generated based on version 2.0.0 of the canonical data.
|
2
|
+
|
3
|
+
using Xunit;
|
4
|
+
using System;
|
5
|
+
using FakeItEasy;
|
3
6
|
|
4
7
|
public class ReactTest
|
5
8
|
{
|
6
9
|
[Fact]
|
7
|
-
public void
|
10
|
+
public void Input_cells_have_a_value()
|
8
11
|
{
|
9
|
-
var
|
10
|
-
var
|
11
|
-
|
12
|
-
Assert.Equal(1, inputCell1.Value);
|
13
|
-
inputCell1.Value = 2;
|
14
|
-
Assert.Equal(2, inputCell1.Value);
|
12
|
+
var sut = new Reactor();
|
13
|
+
var input = sut.CreateInputCell(10);
|
14
|
+
Assert.Equal(10, input.Value);
|
15
15
|
}
|
16
16
|
|
17
17
|
[Fact(Skip = "Remove to run test")]
|
18
|
-
public void
|
18
|
+
public void An_input_cells_value_can_be_set()
|
19
19
|
{
|
20
|
-
var
|
21
|
-
var
|
22
|
-
|
23
|
-
|
24
|
-
Assert.Equal(2, computeCell1.Value);
|
25
|
-
inputCell1.Value = 2;
|
26
|
-
Assert.Equal(3, computeCell1.Value);
|
20
|
+
var sut = new Reactor();
|
21
|
+
var input = sut.CreateInputCell(4);
|
22
|
+
input.Value = 20;
|
23
|
+
Assert.Equal(20, input.Value);
|
27
24
|
}
|
28
25
|
|
29
26
|
[Fact(Skip = "Remove to run test")]
|
30
|
-
public void
|
27
|
+
public void Compute_cells_calculate_initial_value()
|
31
28
|
{
|
32
|
-
var
|
33
|
-
var
|
34
|
-
var
|
35
|
-
|
36
|
-
var computeCell3 = reactor.CreateComputeCell(new[] { computeCell1, computeCell2 }, (values) => values[0] * values[1]);
|
37
|
-
|
38
|
-
Assert.Equal(0, computeCell3.Value);
|
39
|
-
inputCell1.Value = 3;
|
40
|
-
Assert.Equal(8, computeCell3.Value);
|
29
|
+
var sut = new Reactor();
|
30
|
+
var input = sut.CreateInputCell(1);
|
31
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
32
|
+
Assert.Equal(2, output.Value);
|
41
33
|
}
|
42
34
|
|
43
35
|
[Fact(Skip = "Remove to run test")]
|
44
|
-
public void
|
36
|
+
public void Compute_cells_take_inputs_in_the_right_order()
|
45
37
|
{
|
46
|
-
var
|
47
|
-
var
|
48
|
-
var
|
49
|
-
var
|
50
|
-
|
51
|
-
|
52
|
-
Assert.Empty(observed);
|
53
|
-
inputCell1.Value = 2;
|
54
|
-
Assert.Equal(new[] { 3 }, observed);
|
38
|
+
var sut = new Reactor();
|
39
|
+
var one = sut.CreateInputCell(1);
|
40
|
+
var two = sut.CreateInputCell(2);
|
41
|
+
var output = sut.CreateComputeCell(new[] { one, two }, inputs => inputs[0] + inputs[1] * 10);
|
42
|
+
Assert.Equal(21, output.Value);
|
55
43
|
}
|
56
44
|
|
57
45
|
[Fact(Skip = "Remove to run test")]
|
58
|
-
public void
|
46
|
+
public void Compute_cells_update_value_when_dependencies_are_changed()
|
59
47
|
{
|
60
|
-
var
|
61
|
-
var
|
62
|
-
var
|
63
|
-
|
64
|
-
|
48
|
+
var sut = new Reactor();
|
49
|
+
var input = sut.CreateInputCell(1);
|
50
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
51
|
+
input.Value = 3;
|
52
|
+
Assert.Equal(4, output.Value);
|
53
|
+
}
|
65
54
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
55
|
+
[Fact(Skip = "Remove to run test")]
|
56
|
+
public void Compute_cells_can_depend_on_other_compute_cells()
|
57
|
+
{
|
58
|
+
var sut = new Reactor();
|
59
|
+
var input = sut.CreateInputCell(1);
|
60
|
+
var timesTwo = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] * 2);
|
61
|
+
var timesThirty = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] * 30);
|
62
|
+
var output = sut.CreateComputeCell(new[] { timesTwo, timesThirty }, inputs => inputs[0] + inputs[1]);
|
63
|
+
Assert.Equal(32, output.Value);
|
64
|
+
input.Value = 3;
|
65
|
+
Assert.Equal(96, output.Value);
|
72
66
|
}
|
73
67
|
|
74
68
|
[Fact(Skip = "Remove to run test")]
|
75
|
-
public void
|
69
|
+
public void Compute_cells_fire_callbacks()
|
76
70
|
{
|
77
|
-
var
|
78
|
-
var
|
79
|
-
var
|
80
|
-
var
|
81
|
-
|
71
|
+
var sut = new Reactor();
|
72
|
+
var input = sut.CreateInputCell(1);
|
73
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
74
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
75
|
+
output.Changed += callback1;
|
76
|
+
input.Value = 3;
|
77
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 4)).MustHaveHappenedOnceExactly();
|
78
|
+
Fake.ClearRecordedCalls(callback1);
|
79
|
+
}
|
82
80
|
|
83
|
-
|
84
|
-
|
81
|
+
[Fact(Skip = "Remove to run test")]
|
82
|
+
public void Callback_cells_only_fire_on_change()
|
83
|
+
{
|
84
|
+
var sut = new Reactor();
|
85
|
+
var input = sut.CreateInputCell(1);
|
86
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] < 3 ? 111 : 222);
|
87
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
88
|
+
output.Changed += callback1;
|
89
|
+
input.Value = 2;
|
90
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
91
|
+
input.Value = 4;
|
92
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 222)).MustHaveHappenedOnceExactly();
|
93
|
+
Fake.ClearRecordedCalls(callback1);
|
94
|
+
}
|
85
95
|
|
86
|
-
|
87
|
-
|
96
|
+
[Fact(Skip = "Remove to run test")]
|
97
|
+
public void Callbacks_do_not_report_already_reported_values()
|
98
|
+
{
|
99
|
+
var sut = new Reactor();
|
100
|
+
var input = sut.CreateInputCell(1);
|
101
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
102
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
103
|
+
output.Changed += callback1;
|
104
|
+
input.Value = 2;
|
105
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 3)).MustHaveHappenedOnceExactly();
|
106
|
+
Fake.ClearRecordedCalls(callback1);
|
107
|
+
input.Value = 3;
|
108
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 4)).MustHaveHappenedOnceExactly();
|
109
|
+
Fake.ClearRecordedCalls(callback1);
|
110
|
+
}
|
88
111
|
|
89
|
-
|
90
|
-
|
91
|
-
|
112
|
+
[Fact(Skip = "Remove to run test")]
|
113
|
+
public void Callbacks_can_fire_from_multiple_cells()
|
114
|
+
{
|
115
|
+
var sut = new Reactor();
|
116
|
+
var input = sut.CreateInputCell(1);
|
117
|
+
var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
118
|
+
var minusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1);
|
119
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
120
|
+
plusOne.Changed += callback1;
|
121
|
+
var callback2 = A.Fake<EventHandler<int>>();
|
122
|
+
minusOne.Changed += callback2;
|
123
|
+
input.Value = 10;
|
124
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 11)).MustHaveHappenedOnceExactly();
|
125
|
+
Fake.ClearRecordedCalls(callback1);
|
126
|
+
A.CallTo(() => callback2.Invoke(A<object>._, 9)).MustHaveHappenedOnceExactly();
|
127
|
+
Fake.ClearRecordedCalls(callback2);
|
128
|
+
}
|
92
129
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
130
|
+
[Fact(Skip = "Remove to run test")]
|
131
|
+
public void Callbacks_can_be_added_and_removed()
|
132
|
+
{
|
133
|
+
var sut = new Reactor();
|
134
|
+
var input = sut.CreateInputCell(11);
|
135
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
136
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
137
|
+
output.Changed += callback1;
|
138
|
+
var callback2 = A.Fake<EventHandler<int>>();
|
139
|
+
output.Changed += callback2;
|
140
|
+
input.Value = 31;
|
141
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 32)).MustHaveHappenedOnceExactly();
|
142
|
+
Fake.ClearRecordedCalls(callback1);
|
143
|
+
A.CallTo(() => callback2.Invoke(A<object>._, 32)).MustHaveHappenedOnceExactly();
|
144
|
+
Fake.ClearRecordedCalls(callback2);
|
145
|
+
output.Changed -= callback1;
|
146
|
+
var callback3 = A.Fake<EventHandler<int>>();
|
147
|
+
output.Changed += callback3;
|
148
|
+
input.Value = 41;
|
149
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
97
150
|
}
|
98
151
|
|
99
152
|
[Fact(Skip = "Remove to run test")]
|
100
|
-
public void
|
153
|
+
public void Removing_a_callback_multiple_times_doesnt_interfere_with_other_callbacks()
|
101
154
|
{
|
102
|
-
var
|
103
|
-
var
|
104
|
-
var
|
105
|
-
var
|
106
|
-
|
107
|
-
var
|
155
|
+
var sut = new Reactor();
|
156
|
+
var input = sut.CreateInputCell(1);
|
157
|
+
var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
158
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
159
|
+
output.Changed += callback1;
|
160
|
+
var callback2 = A.Fake<EventHandler<int>>();
|
161
|
+
output.Changed += callback2;
|
162
|
+
output.Changed -= callback1;
|
163
|
+
output.Changed -= callback1;
|
164
|
+
output.Changed -= callback1;
|
165
|
+
input.Value = 2;
|
166
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
167
|
+
}
|
108
168
|
|
109
|
-
|
110
|
-
|
169
|
+
[Fact(Skip = "Remove to run test")]
|
170
|
+
public void Callbacks_should_only_be_called_once_even_if_multiple_dependencies_change()
|
171
|
+
{
|
172
|
+
var sut = new Reactor();
|
173
|
+
var input = sut.CreateInputCell(1);
|
174
|
+
var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
175
|
+
var minusOne1 = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1);
|
176
|
+
var minusOne2 = sut.CreateComputeCell(new[] { minusOne1 }, inputs => inputs[0] - 1);
|
177
|
+
var output = sut.CreateComputeCell(new[] { plusOne, minusOne2 }, inputs => inputs[0] * inputs[1]);
|
178
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
179
|
+
output.Changed += callback1;
|
180
|
+
input.Value = 4;
|
181
|
+
A.CallTo(() => callback1.Invoke(A<object>._, 10)).MustHaveHappenedOnceExactly();
|
182
|
+
Fake.ClearRecordedCalls(callback1);
|
183
|
+
}
|
111
184
|
|
112
|
-
|
113
|
-
|
185
|
+
[Fact(Skip = "Remove to run test")]
|
186
|
+
public void Callbacks_should_not_be_called_if_dependencies_change_but_output_value_doesnt_change()
|
187
|
+
{
|
188
|
+
var sut = new Reactor();
|
189
|
+
var input = sut.CreateInputCell(1);
|
190
|
+
var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1);
|
191
|
+
var minusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1);
|
192
|
+
var alwaysTwo = sut.CreateComputeCell(new[] { plusOne, minusOne }, inputs => inputs[0] - inputs[1]);
|
193
|
+
var callback1 = A.Fake<EventHandler<int>>();
|
194
|
+
alwaysTwo.Changed += callback1;
|
195
|
+
input.Value = 2;
|
196
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
197
|
+
input.Value = 3;
|
198
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
199
|
+
input.Value = 4;
|
200
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
201
|
+
input.Value = 5;
|
202
|
+
A.CallTo(() => callback1.Invoke(A<object>._, A<int>._)).MustNotHaveHappened();
|
114
203
|
}
|
115
|
-
}
|
204
|
+
}
|
@@ -3,34 +3,31 @@ using System.Linq;
|
|
3
3
|
using System.Text;
|
4
4
|
using System.Text.RegularExpressions;
|
5
5
|
|
6
|
-
public class
|
6
|
+
public class SimpleCipher
|
7
7
|
{
|
8
|
-
private const string
|
8
|
+
private const string Alphabet = "abcdefghijklmnopqrstuvwxyz";
|
9
|
+
|
9
10
|
private static readonly Random Rand = new Random();
|
10
11
|
|
11
|
-
public string Key { get;
|
12
|
+
public string Key { get; }
|
12
13
|
|
13
|
-
public
|
14
|
+
public SimpleCipher()
|
14
15
|
{
|
15
|
-
Key = new string(Enumerable.Range(0, 100).Select(x =>
|
16
|
+
Key = new string(Enumerable.Range(0, 100).Select(x => Alphabet[Rand.Next(Alphabet.Length)]).ToArray());
|
16
17
|
}
|
17
18
|
|
18
|
-
public
|
19
|
+
public SimpleCipher(string key)
|
19
20
|
{
|
20
|
-
|
21
|
-
Key = key;
|
21
|
+
Key = IsValidKey(key) ? key : throw new ArgumentException("Invalid key");
|
22
22
|
}
|
23
23
|
|
24
|
-
private static bool IsValidKey(string key)
|
25
|
-
{
|
26
|
-
return Regex.IsMatch(key, "^[a-z]+$");
|
27
|
-
}
|
24
|
+
private static bool IsValidKey(string key) => Regex.IsMatch(key, "^[a-z]+$");
|
28
25
|
|
29
26
|
public string Encode(string plaintext)
|
30
27
|
{
|
31
28
|
var ciphertext = new StringBuilder(plaintext.Length);
|
32
29
|
|
33
|
-
for (
|
30
|
+
for (var i = 0; i < plaintext.Length; i++)
|
34
31
|
ciphertext.Append(EncodeCharacter(plaintext, i));
|
35
32
|
|
36
33
|
return ciphertext.ToString();
|
@@ -38,17 +35,17 @@ public class Cipher
|
|
38
35
|
|
39
36
|
private char EncodeCharacter(string plaintext, int idx)
|
40
37
|
{
|
41
|
-
var alphabetIdx =
|
42
|
-
if (alphabetIdx >=
|
43
|
-
alphabetIdx -=
|
44
|
-
return
|
38
|
+
var alphabetIdx = Alphabet.IndexOf(plaintext[idx]) + Alphabet.IndexOf(Key[idx % Key.Length]);
|
39
|
+
if (alphabetIdx >= Alphabet.Length)
|
40
|
+
alphabetIdx -= Alphabet.Length;
|
41
|
+
return Alphabet[alphabetIdx];
|
45
42
|
}
|
46
43
|
|
47
44
|
public string Decode(string ciphertext)
|
48
45
|
{
|
49
46
|
var plaintext = new StringBuilder(ciphertext.Length);
|
50
47
|
|
51
|
-
for (
|
48
|
+
for (var i = 0; i < ciphertext.Length; i++)
|
52
49
|
plaintext.Append(DecodeCharacter(ciphertext, i));
|
53
50
|
|
54
51
|
return plaintext.ToString();
|
@@ -56,9 +53,9 @@ public class Cipher
|
|
56
53
|
|
57
54
|
private char DecodeCharacter(string ciphertext, int idx)
|
58
55
|
{
|
59
|
-
var alphabetIdx =
|
56
|
+
var alphabetIdx = Alphabet.IndexOf(ciphertext[idx]) - Alphabet.IndexOf(Key[idx % Key.Length]);
|
60
57
|
if (alphabetIdx < 0)
|
61
|
-
alphabetIdx +=
|
62
|
-
return
|
58
|
+
alphabetIdx += Alphabet.Length;
|
59
|
+
return Alphabet[alphabetIdx];
|
63
60
|
}
|
64
61
|
}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
using System;
|
2
2
|
|
3
|
-
public class
|
3
|
+
public class SimpleCipher
|
4
4
|
{
|
5
|
-
public
|
5
|
+
public SimpleCipher()
|
6
6
|
{
|
7
7
|
throw new NotImplementedException("You need to implement this function.");
|
8
8
|
}
|
9
9
|
|
10
|
-
public
|
10
|
+
public SimpleCipher(string key)
|
11
11
|
{
|
12
12
|
throw new NotImplementedException("You need to implement this function.");
|
13
13
|
}
|
@@ -1,138 +1,102 @@
|
|
1
|
-
|
1
|
+
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
2
|
+
|
2
3
|
using Xunit;
|
4
|
+
using System;
|
3
5
|
|
4
|
-
public class
|
6
|
+
public class SimpleCipherTest
|
5
7
|
{
|
6
|
-
private readonly Cipher cipher = new Cipher();
|
7
|
-
|
8
8
|
[Fact]
|
9
|
-
public void
|
9
|
+
public void Random_key_cipher_can_encode()
|
10
10
|
{
|
11
|
-
|
11
|
+
var sut = new SimpleCipher();
|
12
|
+
Assert.Equal(sut.Key.Substring(0, 10), sut.Encode("aaaaaaaaaa"));
|
12
13
|
}
|
13
14
|
|
14
15
|
[Fact(Skip = "Remove to run test")]
|
15
|
-
public void
|
16
|
+
public void Random_key_cipher_can_decode()
|
16
17
|
{
|
17
|
-
|
18
|
+
var sut = new SimpleCipher();
|
19
|
+
Assert.Equal("aaaaaaaaaa", sut.Decode(sut.Key.Substring(0, 10)));
|
18
20
|
}
|
19
21
|
|
20
22
|
[Fact(Skip = "Remove to run test")]
|
21
|
-
public void
|
23
|
+
public void Random_key_cipher_is_reversible_i_e_if_you_apply_decode_in_a_encoded_result_you_must_see_the_same_plaintext_encode_parameter_as_a_result_of_the_decode_method()
|
22
24
|
{
|
23
|
-
|
25
|
+
var sut = new SimpleCipher();
|
26
|
+
Assert.Equal("abcdefghij", sut.Decode(sut.Encode("abcdefghij")));
|
24
27
|
}
|
25
28
|
|
26
|
-
// Here we take advantage of the fact that plaintext of "aaa..." doesn't output
|
27
|
-
// the key. This is a critical problem with shift ciphers, some characters
|
28
|
-
// will always output the key verbatim.
|
29
29
|
[Fact(Skip = "Remove to run test")]
|
30
|
-
public void
|
30
|
+
public void Random_key_cipher_key_is_made_only_of_lowercase_letters()
|
31
31
|
{
|
32
|
-
|
32
|
+
var sut = new SimpleCipher();
|
33
|
+
Assert.Matches("^[a-z]+$", sut.Key);
|
33
34
|
}
|
34
35
|
|
35
36
|
[Fact(Skip = "Remove to run test")]
|
36
|
-
public void
|
37
|
+
public void Substitution_cipher_can_encode()
|
37
38
|
{
|
38
|
-
|
39
|
+
var sut = new SimpleCipher("abcdefghij");
|
40
|
+
Assert.Equal("abcdefghij", sut.Encode("aaaaaaaaaa"));
|
39
41
|
}
|
40
42
|
|
41
43
|
[Fact(Skip = "Remove to run test")]
|
42
|
-
public void
|
44
|
+
public void Substitution_cipher_can_decode()
|
43
45
|
{
|
44
|
-
|
45
|
-
Assert.Equal(
|
46
|
+
var sut = new SimpleCipher("abcdefghij");
|
47
|
+
Assert.Equal("aaaaaaaaaa", sut.Decode("abcdefghij"));
|
46
48
|
}
|
47
|
-
}
|
48
|
-
|
49
|
-
|
50
|
-
public class IncorrectKeyCipherTest
|
51
|
-
{
|
52
|
-
[Fact]
|
53
|
-
public void Cipher_throws_with_an_all_caps_key()
|
54
|
-
{
|
55
|
-
Assert.Throws<ArgumentException>(() => new Cipher("ABCDEF"));
|
56
|
-
}
|
57
|
-
|
58
|
-
[Fact(Skip = "Remove to run test")]
|
59
|
-
public void Cipher_throws_with_any_caps_key()
|
60
|
-
{
|
61
|
-
Assert.Throws<ArgumentException>(() => new Cipher("abcdEFg"));
|
62
|
-
}
|
63
|
-
|
64
|
-
[Fact(Skip = "Remove to run test")]
|
65
|
-
public void Cipher_throws_with_numeric_key()
|
66
|
-
{
|
67
|
-
Assert.Throws<ArgumentException>(() => new Cipher("12345"));
|
68
|
-
}
|
69
|
-
|
70
|
-
[Fact(Skip = "Remove to run test")]
|
71
|
-
public void Cipher_throws_with_any_numeric_key()
|
72
|
-
{
|
73
|
-
Assert.Throws<ArgumentException>(() => new Cipher("abcd345ef"));
|
74
|
-
}
|
75
|
-
|
76
|
-
[Fact(Skip = "Remove to run test")]
|
77
|
-
public void Cipher_throws_with_empty_key()
|
78
|
-
{
|
79
|
-
Assert.Throws<ArgumentException>(() => new Cipher(""));
|
80
|
-
}
|
81
|
-
}
|
82
|
-
|
83
|
-
|
84
|
-
public class SubstitutionCipherTest
|
85
|
-
{
|
86
|
-
private const string KEY = "abcdefghij";
|
87
|
-
private readonly Cipher cipher = new Cipher(KEY);
|
88
49
|
|
89
50
|
[Fact(Skip = "Remove to run test")]
|
90
|
-
public void
|
51
|
+
public void Substitution_cipher_is_reversible_i_e_if_you_apply_decode_in_a_encoded_result_you_must_see_the_same_plaintext_encode_parameter_as_a_result_of_the_decode_method()
|
91
52
|
{
|
92
|
-
|
53
|
+
var sut = new SimpleCipher("abcdefghij");
|
54
|
+
Assert.Equal("abcdefghij", sut.Decode(sut.Encode("abcdefghij")));
|
93
55
|
}
|
94
56
|
|
95
57
|
[Fact(Skip = "Remove to run test")]
|
96
|
-
public void
|
58
|
+
public void Substitution_cipher_can_double_shift_encode()
|
97
59
|
{
|
98
|
-
|
60
|
+
var sut = new SimpleCipher("iamapandabear");
|
61
|
+
Assert.Equal("qayaeaagaciai", sut.Encode("iamapandabear"));
|
99
62
|
}
|
100
63
|
|
101
64
|
[Fact(Skip = "Remove to run test")]
|
102
|
-
public void
|
65
|
+
public void Substitution_cipher_can_wrap_on_encode()
|
103
66
|
{
|
104
|
-
|
67
|
+
var sut = new SimpleCipher("abcdefghij");
|
68
|
+
Assert.Equal("zabcdefghi", sut.Encode("zzzzzzzzzz"));
|
105
69
|
}
|
106
70
|
|
107
71
|
[Fact(Skip = "Remove to run test")]
|
108
|
-
public void
|
72
|
+
public void Substitution_cipher_can_wrap_on_decode()
|
109
73
|
{
|
110
|
-
|
111
|
-
Assert.Equal(
|
74
|
+
var sut = new SimpleCipher("abcdefghij");
|
75
|
+
Assert.Equal("zzzzzzzzzz", sut.Decode("zabcdefghi"));
|
112
76
|
}
|
113
77
|
|
114
78
|
[Fact(Skip = "Remove to run test")]
|
115
|
-
public void
|
79
|
+
public void Substitution_cipher_can_handle_messages_longer_than_the_key()
|
116
80
|
{
|
117
|
-
|
118
|
-
Assert.Equal("
|
81
|
+
var sut = new SimpleCipher("abc");
|
82
|
+
Assert.Equal("iboaqcnecbfcr", sut.Encode("iamapandabear"));
|
119
83
|
}
|
120
84
|
|
121
85
|
[Fact(Skip = "Remove to run test")]
|
122
|
-
public void
|
86
|
+
public void Incorrect_key_cipher_throws_an_error_with_an_all_uppercase_key()
|
123
87
|
{
|
124
|
-
Assert.
|
88
|
+
Assert.Throws<ArgumentException>(() => new SimpleCipher("ABCDEF"));
|
125
89
|
}
|
126
90
|
|
127
91
|
[Fact(Skip = "Remove to run test")]
|
128
|
-
public void
|
92
|
+
public void Incorrect_key_cipher_throws_an_error_with_a_numeric_key()
|
129
93
|
{
|
130
|
-
Assert.
|
94
|
+
Assert.Throws<ArgumentException>(() => new SimpleCipher("12345"));
|
131
95
|
}
|
132
96
|
|
133
97
|
[Fact(Skip = "Remove to run test")]
|
134
|
-
public void
|
98
|
+
public void Incorrect_key_cipher_throws_an_error_with_empty_key()
|
135
99
|
{
|
136
|
-
Assert.
|
100
|
+
Assert.Throws<ArgumentException>(() => new SimpleCipher(""));
|
137
101
|
}
|
138
102
|
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Linq;
|
3
|
+
using System.Text;
|
4
|
+
using Generators.Input;
|
5
|
+
using Generators.Output;
|
6
|
+
using Humanizer;
|
7
|
+
using Newtonsoft.Json.Linq;
|
8
|
+
|
9
|
+
namespace Generators.Exercises
|
10
|
+
{
|
11
|
+
public class Pov : GeneratorExercise
|
12
|
+
{
|
13
|
+
protected override void UpdateCanonicalData(CanonicalData canonicalData)
|
14
|
+
{
|
15
|
+
foreach (var canonicalDataCase in canonicalData.Cases)
|
16
|
+
{
|
17
|
+
canonicalDataCase.UseVariablesForInput = true;
|
18
|
+
canonicalDataCase.UseVariableForExpected = true;
|
19
|
+
canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is null ? typeof(ArgumentException) : null;
|
20
|
+
|
21
|
+
canonicalDataCase.Input["tree"] = RenderTree(canonicalDataCase.Input["tree"]);
|
22
|
+
|
23
|
+
if (canonicalDataCase.Property == "fromPov")
|
24
|
+
{
|
25
|
+
canonicalDataCase.Expected = RenderTree(canonicalDataCase.Expected);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
private static UnescapedValue RenderTree(dynamic tree)
|
31
|
+
{
|
32
|
+
if (tree == null)
|
33
|
+
{
|
34
|
+
return null;
|
35
|
+
}
|
36
|
+
|
37
|
+
var sb = new StringBuilder();
|
38
|
+
|
39
|
+
var label = ValueFormatter.Format(tree["label"]);
|
40
|
+
|
41
|
+
if (tree.ContainsKey("children"))
|
42
|
+
{
|
43
|
+
var children = string.Join(", ", ((object[])tree["children"]).Select(RenderTree));
|
44
|
+
sb.Append($"new Tree({label}, {children})");
|
45
|
+
}
|
46
|
+
else
|
47
|
+
{
|
48
|
+
sb.Append($"new Tree({label})");
|
49
|
+
}
|
50
|
+
|
51
|
+
return new UnescapedValue(sb.ToString());
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|