Skip to content

Commit 3a81a4e

Browse files
Converting templates to Scriban
1 parent 7dc6a88 commit 3a81a4e

File tree

35 files changed

+496
-483
lines changed

35 files changed

+496
-483
lines changed

docs/GENERATORS.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ To generate a practice exercise's tests, the test generator:
1515

1616
### Step 1: read `canonical-data.json` file
1717

18-
The test generator parses the test cases from the exercise's `canonical-data.json` using the [JSON.net library](https://www.newtonsoft.com/json).
18+
The test generator parses the test cases from the exercise's `canonical-data.json` using the [System.Text.Json namespace](https://learn.microsoft.com/en-us/dotnet/api/system.text.json).
1919

2020
Since some canonical data uses nesting, the parsed test case includes an additional `path` field that contains the `description` properties of any parent elements, as well as the test case's own `description` property.
2121

22-
Note: the JSON is parsed to an `ExpandoObject` instance, which makes dealing with dynamic data easier.
23-
2422
### Step 2: omit excluded tests from `tests.toml` file
2523

2624
Each exercise has a `tests.toml` file, in which individual tests can be excluded/disabled.
@@ -44,7 +42,7 @@ Finally, the output of the rendered template is written to the exercise's test f
4442

4543
## Templates
4644

47-
The templates are rendered using the [Handlebars.Net library](https://github.com/Handlebars-Net/Handlebars.Net), which supports [handlebars syntax](https://handlebarsjs.com/).
45+
The templates are rendered using the [Scriban library](https://github.com/scriban/scriban/).
4846

4947
## Command-line interface
5048

exercises/practice/acronym/.meta/Generator.tpl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ using Xunit;
22

33
public class AcronymTests
44
{
5-
{{#test_cases}}
6-
[Fact{{#unless @first}}(Skip = "Remove this Skip property to run this test"){{/unless}}]
7-
public void {{test_method_name}}()
5+
{{for testCase in testCases}}
6+
[Fact{{if !for.first}}(Skip = "Remove this Skip property to run this test"){{end}}]
7+
public void {{testCase.testMethodName}}()
88
{
9-
Assert.Equal({{lit expected}}, Acronym.Abbreviate({{lit input.phrase}}));
9+
Assert.Equal({{testCase.expected | string.literal}}, Acronym.Abbreviate({{testCase.input.phrase | string.literal}}));
1010
}
11-
{{/test_cases}}
11+
{{end}}
1212
}

exercises/practice/affine-cipher/.meta/Generator.tpl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,27 @@ using Xunit;
33

44
public class AffineCipherTests
55
{
6-
{{#test_cases_by_property.encode}}
7-
[Fact{{#unless @first}}(Skip = "Remove this Skip property to run this test"){{/unless}}]
8-
public void {{short_test_method_name}}()
6+
{{for testCase in testCasesByProperty.encode}}
7+
[Fact{{if !for.first}}(Skip = "Remove this Skip property to run this test"){{end}}]
8+
public void {{testCase.shortTestMethodName}}()
99
{
10-
{{#if expected.error}}
11-
Assert.Throws<ArgumentException>(() => AffineCipher.Encode({{lit input.phrase}}, {{input.key.a}}, {{input.key.b}}));
10+
{{if testCase.expected.error}}
11+
Assert.Throws<ArgumentException>(() => AffineCipher.Encode({{testCase.input.phrase | string.literal}}, {{testCase.input.key.a}}, {{testCase.input.key.b}}));
1212
{{else}}
13-
Assert.Equal({{lit expected}}, AffineCipher.Encode({{lit input.phrase}}, {{input.key.a}}, {{input.key.b}}));
14-
{{/if}}
13+
Assert.Equal({{testCase.expected | string.literal}}, AffineCipher.Encode({{testCase.input.phrase | string.literal}}, {{testCase.input.key.a}}, {{testCase.input.key.b}}));
14+
{{end}}
1515
}
16-
{{/test_cases_by_property.encode}}
16+
{{end}}
1717

18-
{{#test_cases_by_property.decode}}
18+
{{for testCase in testCasesByProperty.decode}}
1919
[Fact(Skip = "Remove this Skip property to run this test")]
20-
public void {{short_test_method_name}}()
20+
public void {{testCase.shortTestMethodName}}()
2121
{
22-
{{#if expected.error}}
23-
Assert.Throws<ArgumentException>(() => AffineCipher.Decode({{lit input.phrase}}, {{input.key.a}}, {{input.key.b}}));
22+
{{if testCase.expected.error}}
23+
Assert.Throws<ArgumentException>(() => AffineCipher.Decode({{testCase.input.phrase | string.literal}}, {{testCase.input.key.a}}, {{testCase.input.key.b}}));
2424
{{else}}
25-
Assert.Equal({{lit expected}}, AffineCipher.Decode({{lit input.phrase}}, {{input.key.a}}, {{input.key.b}}));
26-
{{/if}}
25+
Assert.Equal({{testCase.expected | string.literal}}, AffineCipher.Decode({{testCase.input.phrase}}, {{testCase.input.key.a}}, {{testCase.input.key.b}}));
26+
{{end}}
2727
}
28-
{{/test_cases_by_property.decode}}
28+
{{end}}
2929
}

exercises/practice/affine-cipher/AffineCipherTests.cs

Lines changed: 92 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -4,98 +4,96 @@
44
public class AffineCipherTests
55
{
66
[Fact]
7-
public void Encode_yes()
8-
{
9-
Assert.Equal("xbt", AffineCipher.Encode("yes", 5, 7));
10-
}
11-
12-
[Fact(Skip = "Remove this Skip property to run this test")]
13-
public void Encode_no()
14-
{
15-
Assert.Equal("fu", AffineCipher.Encode("no", 15, 18));
16-
}
17-
18-
[Fact(Skip = "Remove this Skip property to run this test")]
19-
public void Encode_omg()
20-
{
21-
Assert.Equal("lvz", AffineCipher.Encode("OMG", 21, 3));
22-
}
23-
24-
[Fact(Skip = "Remove this Skip property to run this test")]
25-
public void Encode_o_m_g()
26-
{
27-
Assert.Equal("hjp", AffineCipher.Encode("O M G", 25, 47));
28-
}
29-
30-
[Fact(Skip = "Remove this Skip property to run this test")]
31-
public void Encode_mindblowingly()
32-
{
33-
Assert.Equal("rzcwa gnxzc dgt", AffineCipher.Encode("mindblowingly", 11, 15));
34-
}
35-
36-
[Fact(Skip = "Remove this Skip property to run this test")]
37-
public void Encode_numbers()
38-
{
39-
Assert.Equal("jqgjc rw123 jqgjc rw", AffineCipher.Encode("Testing,1 2 3, testing.", 3, 4));
40-
}
41-
42-
[Fact(Skip = "Remove this Skip property to run this test")]
43-
public void Encode_deep_thought()
44-
{
45-
Assert.Equal("iynia fdqfb ifje", AffineCipher.Encode("Truth is fiction.", 5, 17));
46-
}
47-
48-
[Fact(Skip = "Remove this Skip property to run this test")]
49-
public void Encode_all_the_letters()
50-
{
51-
Assert.Equal("swxtj npvyk lruol iejdc blaxk swxmh qzglf", AffineCipher.Encode("The quick brown fox jumps over the lazy dog.", 17, 33));
52-
}
53-
54-
[Fact(Skip = "Remove this Skip property to run this test")]
55-
public void Encode_with_a_not_coprime_to_m()
56-
{
57-
Assert.Throws<ArgumentException>(() => AffineCipher.Encode("This is a test.", 6, 17));
58-
}
59-
60-
[Fact(Skip = "Remove this Skip property to run this test")]
61-
public void Decode_exercism()
62-
{
63-
Assert.Equal("exercism", AffineCipher.Decode("tytgn fjr", 3, 7));
64-
}
65-
66-
[Fact(Skip = "Remove this Skip property to run this test")]
67-
public void Decode_a_sentence()
68-
{
69-
Assert.Equal("anobstacleisoftenasteppingstone", AffineCipher.Decode("qdwju nqcro muwhn odqun oppmd aunwd o", 19, 16));
70-
}
71-
72-
[Fact(Skip = "Remove this Skip property to run this test")]
73-
public void Decode_numbers()
74-
{
75-
Assert.Equal("testing123testing", AffineCipher.Decode("odpoz ub123 odpoz ub", 25, 7));
76-
}
77-
78-
[Fact(Skip = "Remove this Skip property to run this test")]
79-
public void Decode_all_the_letters()
80-
{
81-
Assert.Equal("thequickbrownfoxjumpsoverthelazydog", AffineCipher.Decode("swxtj npvyk lruol iejdc blaxk swxmh qzglf", 17, 33));
82-
}
83-
84-
[Fact(Skip = "Remove this Skip property to run this test")]
85-
public void Decode_with_no_spaces_in_input()
86-
{
87-
Assert.Equal("thequickbrownfoxjumpsoverthelazydog", AffineCipher.Decode("swxtjnpvyklruoliejdcblaxkswxmhqzglf", 17, 33));
88-
}
89-
90-
[Fact(Skip = "Remove this Skip property to run this test")]
91-
public void Decode_with_too_many_spaces()
92-
{
93-
Assert.Equal("jollygreengiant", AffineCipher.Decode("vszzm cly yd cg qdp", 15, 16));
94-
}
95-
96-
[Fact(Skip = "Remove this Skip property to run this test")]
97-
public void Decode_with_a_not_coprime_to_m()
98-
{
99-
Assert.Throws<ArgumentException>(() => AffineCipher.Decode("Test", 13, 5));
100-
}
7+
public void () {
8+
Assert.Equal( "xbt" , AffineCipher.Encode( "yes" , 5 , 7 ) ) ; }
9+
10+
[Fact(Skip = "Remove this Skip property to run this test")]
11+
public void ()
12+
{
13+
Assert.Equal("fu", AffineCipher.Encode("no", 15, 18));
14+
}
15+
16+
[Fact(Skip = "Remove this Skip property to run this test")]
17+
public void ()
18+
{
19+
Assert.Equal("lvz", AffineCipher.Encode("OMG", 21, 3));
20+
}
21+
22+
[Fact(Skip = "Remove this Skip property to run this test")]
23+
public void ()
24+
{
25+
Assert.Equal("hjp", AffineCipher.Encode("O M G", 25, 47));
26+
}
27+
28+
[Fact(Skip = "Remove this Skip property to run this test")]
29+
public void ()
30+
{
31+
Assert.Equal("rzcwa gnxzc dgt", AffineCipher.Encode("mindblowingly", 11, 15));
32+
}
33+
34+
[Fact(Skip = "Remove this Skip property to run this test")]
35+
public void ()
36+
{
37+
Assert.Equal("jqgjc rw123 jqgjc rw", AffineCipher.Encode("Testing,1 2 3, testing.", 3, 4));
38+
}
39+
40+
[Fact(Skip = "Remove this Skip property to run this test")]
41+
public void ()
42+
{
43+
Assert.Equal("iynia fdqfb ifje", AffineCipher.Encode("Truth is fiction.", 5, 17));
44+
}
45+
46+
[Fact(Skip = "Remove this Skip property to run this test")]
47+
public void ()
48+
{
49+
Assert.Equal("swxtj npvyk lruol iejdc blaxk swxmh qzglf", AffineCipher.Encode("The quick brown fox jumps over the lazy dog.", 17, 33));
50+
}
51+
52+
[Fact(Skip = "Remove this Skip property to run this test")]
53+
public void ()
54+
{
55+
Assert.Throws<ArgumentException>(() => AffineCipher.Encode("This is a test.", 6, 17));
56+
}
57+
58+
[Fact(Skip = "Remove this Skip property to run this test")]
59+
public void ()
60+
{
61+
Assert.Equal("exercism", AffineCipher.Decode(tytgn fjr, 3, 7));
62+
}
63+
64+
[Fact(Skip = "Remove this Skip property to run this test")]
65+
public void ()
66+
{
67+
Assert.Equal("anobstacleisoftenasteppingstone", AffineCipher.Decode(qdwju nqcro muwhn odqun oppmd aunwd o, 19, 16));
68+
}
69+
70+
[Fact(Skip = "Remove this Skip property to run this test")]
71+
public void ()
72+
{
73+
Assert.Equal("testing123testing", AffineCipher.Decode(odpoz ub123 odpoz ub, 25, 7));
74+
}
75+
76+
[Fact(Skip = "Remove this Skip property to run this test")]
77+
public void ()
78+
{
79+
Assert.Equal("thequickbrownfoxjumpsoverthelazydog", AffineCipher.Decode(swxtj npvyk lruol iejdc blaxk swxmh qzglf, 17, 33));
80+
}
81+
82+
[Fact(Skip = "Remove this Skip property to run this test")]
83+
public void ()
84+
{
85+
Assert.Equal("thequickbrownfoxjumpsoverthelazydog", AffineCipher.Decode(swxtjnpvyklruoliejdcblaxkswxmhqzglf, 17, 33));
10186
}
87+
88+
[Fact(Skip = "Remove this Skip property to run this test")]
89+
public void ()
90+
{
91+
Assert.Equal("jollygreengiant", AffineCipher.Decode(vszzm cly yd cg qdp, 15, 16));
92+
}
93+
94+
[Fact(Skip = "Remove this Skip property to run this test")]
95+
public void ()
96+
{
97+
Assert.Throws<ArgumentException>(() => AffineCipher.Decode("Test", 13, 5));
98+
} }
99+

exercises/practice/allergies/.meta/Generator.tpl

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,30 @@ using Xunit;
22

33
public class AllergiesTests
44
{
5-
{{#test_cases_by_property.allergicTo}}
6-
[Fact{{#unless @first}}(Skip = "Remove this Skip property to run this test"){{/unless}}]
7-
public void {{test_method_name}}()
5+
{{for testCase in testCasesByProperty.allergicTo}}
6+
[Fact{{if !for.first}}(Skip = "Remove this Skip property to run this test"){{end}}]
7+
public void {{testCase.testMethodName}}()
88
{
9-
var sut = new Allergies({{input.score}});
10-
Assert.{{expected}}(sut.IsAllergicTo(Allergen.{{Capitalize input.item}}));
9+
var sut = new Allergies({{testCase.input.score}});
10+
Assert.{{testCase.expected ? "True" : "False"}}(sut.IsAllergicTo({{testCase.input.item | enum type: "Allergen"}}));
1111
}
12-
{{/test_cases_by_property.allergicTo}}
12+
{{end}}
1313

14-
{{#test_cases_by_property.list}}
14+
{{for testCase in testCasesByProperty.list}}
1515
[Fact(Skip = "Remove this Skip property to run this test")]
16-
public void {{test_method_name}}()
16+
public void {{testCase.testMethodName}}()
1717
{
18-
var sut = new Allergies({{input.score}});
19-
{{#isempty expected}}
18+
var sut = new Allergies({{testCase.input.score}});
19+
{{if testCase.expected.empty?}}
2020
Assert.Empty(sut.List());
2121
{{else}}
22-
Allergen[] expected = [{{#each ../expected}}Allergen.{{Capitalize .}}{{#unless @last}},{{/unless}}{{/each}}];
22+
Allergen[] expected = [
23+
{{for expected in testCase.expected}}
24+
{{testCase.expected | enum type: "Allergen"}}{{if !for.last}},{{end}}
25+
{{end}}
26+
];
2327
Assert.Equal(expected, sut.List());
24-
{{/isempty}}
28+
{{end}}
2529
}
26-
{{/test_cases_by_property.list}}
30+
{{end}}
2731
}

exercises/practice/allergies/AllergiesTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,71 +293,71 @@ public void List_when_no_allergies()
293293
public void List_when_just_eggs()
294294
{
295295
var sut = new Allergies(1);
296-
Allergen[] expected = [Allergen.Eggs];
296+
Allergen[] expected = [Allergen.["eggs"]];
297297
Assert.Equal(expected, sut.List());
298298
}
299299

300300
[Fact(Skip = "Remove this Skip property to run this test")]
301301
public void List_when_just_peanuts()
302302
{
303303
var sut = new Allergies(2);
304-
Allergen[] expected = [Allergen.Peanuts];
304+
Allergen[] expected = [Allergen.["peanuts"]];
305305
Assert.Equal(expected, sut.List());
306306
}
307307

308308
[Fact(Skip = "Remove this Skip property to run this test")]
309309
public void List_when_just_strawberries()
310310
{
311311
var sut = new Allergies(8);
312-
Allergen[] expected = [Allergen.Strawberries];
312+
Allergen[] expected = [Allergen.["strawberries"]];
313313
Assert.Equal(expected, sut.List());
314314
}
315315

316316
[Fact(Skip = "Remove this Skip property to run this test")]
317317
public void List_when_eggs_and_peanuts()
318318
{
319319
var sut = new Allergies(3);
320-
Allergen[] expected = [Allergen.Eggs, Allergen.Peanuts];
320+
Allergen[] expected = [Allergen.["eggs", "peanuts"], Allergen.["eggs", "peanuts"]];
321321
Assert.Equal(expected, sut.List());
322322
}
323323

324324
[Fact(Skip = "Remove this Skip property to run this test")]
325325
public void List_when_more_than_eggs_but_not_peanuts()
326326
{
327327
var sut = new Allergies(5);
328-
Allergen[] expected = [Allergen.Eggs, Allergen.Shellfish];
328+
Allergen[] expected = [Allergen.["eggs", "shellfish"], Allergen.["eggs", "shellfish"]];
329329
Assert.Equal(expected, sut.List());
330330
}
331331

332332
[Fact(Skip = "Remove this Skip property to run this test")]
333333
public void List_when_lots_of_stuff()
334334
{
335335
var sut = new Allergies(248);
336-
Allergen[] expected = [Allergen.Strawberries, Allergen.Tomatoes, Allergen.Chocolate, Allergen.Pollen, Allergen.Cats];
336+
Allergen[] expected = [Allergen.["strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["strawberries", "tomatoes", "chocolate", "pollen", "cats"]];
337337
Assert.Equal(expected, sut.List());
338338
}
339339

340340
[Fact(Skip = "Remove this Skip property to run this test")]
341341
public void List_when_everything()
342342
{
343343
var sut = new Allergies(255);
344-
Allergen[] expected = [Allergen.Eggs, Allergen.Peanuts, Allergen.Shellfish, Allergen.Strawberries, Allergen.Tomatoes, Allergen.Chocolate, Allergen.Pollen, Allergen.Cats];
344+
Allergen[] expected = [Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]];
345345
Assert.Equal(expected, sut.List());
346346
}
347347

348348
[Fact(Skip = "Remove this Skip property to run this test")]
349349
public void List_when_no_allergen_score_parts()
350350
{
351351
var sut = new Allergies(509);
352-
Allergen[] expected = [Allergen.Eggs, Allergen.Shellfish, Allergen.Strawberries, Allergen.Tomatoes, Allergen.Chocolate, Allergen.Pollen, Allergen.Cats];
352+
Allergen[] expected = [Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"], Allergen.["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]];
353353
Assert.Equal(expected, sut.List());
354354
}
355355

356356
[Fact(Skip = "Remove this Skip property to run this test")]
357357
public void List_when_no_allergen_score_parts_without_highest_valid_score()
358358
{
359359
var sut = new Allergies(257);
360-
Allergen[] expected = [Allergen.Eggs];
360+
Allergen[] expected = [Allergen.["eggs"]];
361361
Assert.Equal(expected, sut.List());
362362
}
363363
}

0 commit comments

Comments
 (0)