trackler 2.2.1.12 → 2.2.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/space-age/description.md +2 -1
  4. data/problem-specifications/exercises/two-fer/canonical-data.json +4 -4
  5. data/tracks/csharp/.gitignore +2 -1
  6. data/tracks/csharp/config/maintainers.json +3 -3
  7. data/tracks/csharp/exercises/collatz-conjecture/CollatzConjecture.cs +1 -1
  8. data/tracks/csharp/exercises/collatz-conjecture/CollatzConjectureTest.cs +8 -8
  9. data/tracks/csharp/exercises/collatz-conjecture/Example.cs +6 -6
  10. data/tracks/csharp/exercises/gigasecond/Example.cs +1 -1
  11. data/tracks/csharp/exercises/gigasecond/Gigasecond.cs +1 -1
  12. data/tracks/csharp/exercises/gigasecond/GigasecondTest.cs +21 -10
  13. data/tracks/csharp/exercises/hamming/Example.cs +6 -1
  14. data/tracks/csharp/exercises/hamming/Hamming.cs +1 -1
  15. data/tracks/csharp/exercises/hamming/HammingTest.cs +69 -12
  16. data/tracks/csharp/exercises/pangram/PangramTest.cs +15 -20
  17. data/tracks/csharp/exercises/phone-number/Example.cs +15 -42
  18. data/tracks/csharp/exercises/phone-number/PhoneNumber.cs +2 -17
  19. data/tracks/csharp/exercises/phone-number/PhoneNumberTest.cs +57 -20
  20. data/tracks/csharp/exercises/prime-factors/Example.cs +1 -1
  21. data/tracks/csharp/exercises/prime-factors/PrimeFactors.cs +1 -1
  22. data/tracks/csharp/exercises/prime-factors/PrimeFactorsTest.cs +16 -38
  23. data/tracks/csharp/exercises/rail-fence-cipher/RailFenceCipherTest.cs +21 -19
  24. data/tracks/csharp/exercises/rna-transcription/Example.cs +7 -2
  25. data/tracks/csharp/exercises/rna-transcription/RnaTranscription.cs +2 -2
  26. data/tracks/csharp/exercises/rna-transcription/RnaTranscriptionTest.cs +26 -6
  27. data/tracks/csharp/exercises/rotational-cipher/RotationalCipherTest.cs +7 -7
  28. data/tracks/csharp/exercises/run-length-encoding/RunLengthEncodingTest.cs +53 -29
  29. data/tracks/csharp/exercises/scrabble-score/Example.cs +2 -2
  30. data/tracks/csharp/exercises/scrabble-score/ScrabbleScore.cs +1 -1
  31. data/tracks/csharp/exercises/scrabble-score/ScrabbleScoreTest.cs +33 -19
  32. data/tracks/csharp/exercises/secret-handshake/SecretHandshake.cs +0 -1
  33. data/tracks/csharp/exercises/secret-handshake/SecretHandshakeTest.cs +36 -10
  34. data/tracks/csharp/exercises/two-fer/Example.cs +1 -1
  35. data/tracks/csharp/exercises/two-fer/TwoFer.cs +1 -1
  36. data/tracks/csharp/exercises/two-fer/TwoFerTest.cs +19 -19
  37. data/tracks/csharp/generators/.gitignore +1 -1
  38. data/tracks/csharp/generators/Exercise.cs +85 -10
  39. data/tracks/csharp/generators/Exercises/AllYourBase.cs +3 -14
  40. data/tracks/csharp/generators/Exercises/Allergies.cs +21 -18
  41. data/tracks/csharp/generators/Exercises/Alphametics.cs +6 -7
  42. data/tracks/csharp/generators/Exercises/Anagram.cs +4 -4
  43. data/tracks/csharp/generators/Exercises/BeerSong.cs +4 -2
  44. data/tracks/csharp/generators/Exercises/BinarySearch.cs +3 -3
  45. data/tracks/csharp/generators/Exercises/BookStore.cs +3 -3
  46. data/tracks/csharp/generators/Exercises/BracketPush.cs +4 -2
  47. data/tracks/csharp/generators/Exercises/CollatzConjecture.cs +16 -0
  48. data/tracks/csharp/generators/Exercises/ConvertExtensions.cs +12 -0
  49. data/tracks/csharp/generators/Exercises/CryptoSquare.cs +3 -2
  50. data/tracks/csharp/generators/Exercises/FoodChain.cs +3 -3
  51. data/tracks/csharp/generators/Exercises/Gigasecond.cs +38 -0
  52. data/tracks/csharp/generators/Exercises/Hamming.cs +16 -0
  53. data/tracks/csharp/generators/Exercises/Leap.cs +4 -2
  54. data/tracks/csharp/generators/Exercises/Luhn.cs +3 -1
  55. data/tracks/csharp/generators/Exercises/NthPrime.cs +2 -10
  56. data/tracks/csharp/generators/Exercises/Pangram.cs +17 -0
  57. data/tracks/csharp/generators/Exercises/PerfectNumbers.cs +2 -9
  58. data/tracks/csharp/generators/Exercises/PhoneNumber.cs +15 -0
  59. data/tracks/csharp/generators/Exercises/PrimeFactors.cs +6 -0
  60. data/tracks/csharp/generators/Exercises/RailFenceCipher.cs +23 -0
  61. data/tracks/csharp/generators/Exercises/RnaTranscription.cs +6 -0
  62. data/tracks/csharp/generators/Exercises/RomanNumerals.cs +4 -2
  63. data/tracks/csharp/generators/Exercises/RunLengthEncoding.cs +40 -0
  64. data/tracks/csharp/generators/Exercises/ScrabbleScore.cs +6 -0
  65. data/tracks/csharp/generators/Exercises/SecretHandshake.cs +15 -0
  66. data/tracks/csharp/generators/Exercises/Transpose.cs +4 -4
  67. data/tracks/csharp/generators/Exercises/TwoFer.cs +6 -0
  68. data/tracks/csharp/generators/Exercises/Wordy.cs +2 -10
  69. data/tracks/csharp/generators/Generators.csproj +1 -3
  70. data/tracks/csharp/generators/Input/CanonicalDataFile.cs +48 -11
  71. data/tracks/csharp/generators/Input/CanonicalDataOptions.cs +8 -0
  72. data/tracks/csharp/generators/Input/CanonicalDataParser.cs +11 -3
  73. data/tracks/csharp/generators/Options.cs +8 -0
  74. data/tracks/csharp/generators/Output/{TestClassFile.cs → ExerciseWriter.cs} +4 -3
  75. data/tracks/csharp/generators/Output/FormattingExtensions.cs +14 -0
  76. data/tracks/csharp/generators/Output/IndentFilter.cs +13 -0
  77. data/tracks/csharp/generators/Output/TemplateRenderer.cs +23 -0
  78. data/tracks/csharp/generators/Output/Templates/_Act.liquid +1 -0
  79. data/tracks/csharp/generators/Output/Templates/_Arrange.liquid +3 -0
  80. data/tracks/csharp/generators/Output/Templates/_AssertBoolean.liquid +1 -0
  81. data/tracks/csharp/generators/Output/Templates/_AssertEqual.liquid +1 -0
  82. data/tracks/csharp/generators/Output/Templates/_AssertEqual_Empty.liquid +1 -0
  83. data/tracks/csharp/generators/Output/Templates/_AssertNull.liquid +1 -0
  84. data/tracks/csharp/generators/Output/Templates/_AssertThrowsException.liquid +1 -0
  85. data/tracks/csharp/generators/Output/{TestClass.liquid → Templates/_TestClass.liquid} +2 -8
  86. data/tracks/csharp/generators/Output/Templates/_TestMethod.liquid +5 -0
  87. data/tracks/csharp/generators/Output/Templates/_TestMethodBody.liquid +3 -0
  88. data/tracks/csharp/generators/Output/TestClass.cs +5 -2
  89. data/tracks/csharp/generators/Output/TestMethod.cs +6 -6
  90. data/tracks/csharp/generators/Output/TestMethodBody.cs +49 -0
  91. data/tracks/csharp/generators/Output/TestMethodBodyData.cs +85 -0
  92. data/tracks/csharp/generators/Output/TestMethodBodyWithBooleanCheck.cs +16 -0
  93. data/tracks/csharp/generators/Output/TestMethodBodyWithEqualityCheck.cs +21 -0
  94. data/tracks/csharp/generators/Output/TestMethodBodyWithExceptionCheck.cs +18 -0
  95. data/tracks/csharp/generators/Output/TestMethodBodyWithNullCheck.cs +13 -0
  96. data/tracks/csharp/generators/Output/UnescapedValue.cs +6 -2
  97. data/tracks/csharp/generators/Output/ValueFormatter.cs +1 -10
  98. data/tracks/csharp/generators/Program.cs +34 -8
  99. data/tracks/delphi/config/maintainers.json +1 -1
  100. data/tracks/delphi/docs/{Getting_Started_Guide.md → GETTING_STARTED_GUIDE.md} +0 -0
  101. data/tracks/fsharp/config.json +16 -5
  102. data/tracks/fsharp/config/maintainers.json +3 -3
  103. data/tracks/fsharp/exercises/two-fer/Example.fs +4 -0
  104. data/tracks/fsharp/exercises/two-fer/README.md +28 -0
  105. data/tracks/fsharp/exercises/two-fer/TwoFerTest.fs +19 -0
  106. data/tracks/groovy/CONTRIBUTING.md +19 -0
  107. data/tracks/groovy/README.md +10 -2
  108. data/tracks/java/exercises/allergies/src/example/java/Allergies.java +1 -1
  109. data/tracks/r/bin/run_tests.R +1 -4
  110. data/tracks/r/docs/{snippet.txt → SNIPPET.txt} +0 -0
  111. data/tracks/r/exercises/hamming/example.R +1 -1
  112. data/tracks/ruby/exercises/flatten-array/README.md +1 -1
  113. data/tracks/scala/exercises/gigasecond/example.scala +3 -3
  114. data/tracks/scala/exercises/gigasecond/src/main/scala/Gigasecond.scala +2 -2
  115. data/tracks/scala/exercises/gigasecond/src/test/scala/GigasecondTest.scala +12 -21
  116. data/tracks/scala/exercises/house/example.scala +6 -3
  117. data/tracks/scala/exercises/house/src/test/scala/HouseTest.scala +289 -97
  118. data/tracks/scala/exercises/isogram/src/main/scala/{Isogram.scala → .keep} +0 -0
  119. data/tracks/scala/exercises/isogram/src/test/scala/IsogramTest.scala +16 -19
  120. data/tracks/scala/testgen/src/main/scala/GigasecondTestGenerator.scala +49 -0
  121. data/tracks/scala/testgen/src/main/scala/HouseTestGenerator.scala +47 -0
  122. data/tracks/scala/testgen/src/main/scala/IsogramTestGenerator.scala +10 -31
  123. data/tracks/scala/testgen/src/main/scala/testgen/TestSuiteBuilder.scala +3 -3
  124. data/tracks/scala/testgen/src/main/twirl/funSuiteTemplate.scala.txt +5 -1
  125. data/tracks/swift/config.json +11 -0
  126. data/tracks/swift/exercises/rotational-cipher/.gitignore +4 -0
  127. data/tracks/swift/exercises/rotational-cipher/Package.swift +5 -0
  128. data/tracks/swift/exercises/rotational-cipher/Sources/RotationalCipher.swift +1 -0
  129. data/tracks/swift/exercises/rotational-cipher/Sources/RotationalCipherExample.swift +30 -0
  130. data/tracks/swift/exercises/rotational-cipher/Tests/LinuxMain.swift +6 -0
  131. data/tracks/swift/exercises/rotational-cipher/Tests/RotationalCipherTests/RotationalCipherTests.swift +70 -0
  132. metadata +51 -17
  133. data/tracks/csharp/generators/Output/BooleanTestMethodGenerator.cs +0 -13
  134. data/tracks/csharp/generators/Output/EqualityTestMethodGenerator.cs +0 -27
  135. data/tracks/csharp/generators/Output/ExceptionTestMethodGenerator.cs +0 -15
  136. data/tracks/csharp/generators/Output/TestClassGenerator.cs +0 -30
  137. data/tracks/csharp/generators/Output/TestClassRenderer.cs +0 -26
  138. data/tracks/csharp/generators/Output/TestMethodGenerator.cs +0 -94
  139. data/tracks/java/docs/img/eclipse-help-dropdown.png +0 -0
  140. data/tracks/java/docs/img/eclipse-mp-search-buildship-gradle.png +0 -0
  141. data/tracks/java/docs/img/mac-osx--idea-ce-run-unit-tests.png +0 -0
  142. data/tracks/java/docs/img/mac-osx--install-java-dialog.png +0 -0
@@ -0,0 +1,15 @@
1
+ using Generators.Input;
2
+
3
+ namespace Generators.Exercises
4
+ {
5
+ public class PhoneNumber : Exercise
6
+ {
7
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
8
+ {
9
+ foreach (var canonicalDataCase in CanonicalData.Cases)
10
+ {
11
+ canonicalDataCase.UseVariablesForInput = true;
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,6 @@
1
+ namespace Generators.Exercises
2
+ {
3
+ public class PrimeFactors : Exercise
4
+ {
5
+ }
6
+ }
@@ -0,0 +1,23 @@
1
+ using System.Collections.Generic;
2
+ using Generators.Input;
3
+
4
+ namespace Generators.Exercises
5
+ {
6
+ public class RailFenceCipher : Exercise
7
+ {
8
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
9
+ {
10
+ foreach (var canonicalDataCase in CanonicalData.Cases)
11
+ {
12
+ canonicalDataCase.ConstructorInput = new Dictionary<string, object>
13
+ {
14
+ ["rails"] = canonicalDataCase.Properties["rails"]
15
+ };
16
+ canonicalDataCase.Input.Remove("rails");
17
+ canonicalDataCase.TestedMethodType = TestedMethodType.Instance;
18
+ canonicalDataCase.UseVariablesForInput = true;
19
+ canonicalDataCase.UseVariableForExpected = true;
20
+ }
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,6 @@
1
+ namespace Generators.Exercises
2
+ {
3
+ public class RnaTranscription : Exercise
4
+ {
5
+ }
6
+ }
@@ -1,8 +1,10 @@
1
- namespace Generators.Exercises
1
+ using Generators.Input;
2
+
3
+ namespace Generators.Exercises
2
4
  {
3
5
  public class RomanNumerals : Exercise
4
6
  {
5
- public RomanNumerals()
7
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
6
8
  {
7
9
  foreach (var canonicalDataCase in CanonicalData.Cases)
8
10
  {
@@ -0,0 +1,40 @@
1
+ using Generators.Input;
2
+ using Generators.Output;
3
+
4
+ namespace Generators.Exercises
5
+ {
6
+ public class RunLengthEncoding : Exercise
7
+ {
8
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
9
+ {
10
+ foreach (var canonicalDataCase in CanonicalData.Cases)
11
+ {
12
+ // Prefix the test name with encode/decode because both functions are tested with the same cases
13
+ canonicalDataCase.Description = $"{canonicalDataCase.Property} {canonicalDataCase.Description}";
14
+ }
15
+ }
16
+
17
+ protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody)
18
+ {
19
+ if (testMethodBody.CanonicalDataCase.Property == "consistency")
20
+ {
21
+ return RenderConsistencyToAssert(testMethodBody);
22
+ }
23
+
24
+ return base.RenderTestMethodBodyAssert(testMethodBody);
25
+ }
26
+
27
+ private static string RenderConsistencyToAssert(TestMethodBody testMethodBody)
28
+ {
29
+ const string template = @"Assert.Equal(""{{ExpectedOutput}}"", {{ExerciseName}}.Decode({{ExerciseName}}.Encode(""{{ExpectedOutput}}"")));";
30
+
31
+ var templateParameters = new
32
+ {
33
+ ExpectedOutput = testMethodBody.CanonicalDataCase.Expected,
34
+ ExerciseName = testMethodBody.CanonicalData.Exercise.ToTestedClassName()
35
+ };
36
+
37
+ return TemplateRenderer.RenderInline(template, templateParameters);
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,6 @@
1
+ namespace Generators.Exercises
2
+ {
3
+ public class ScrabbleScore : Exercise
4
+ {
5
+ }
6
+ }
@@ -0,0 +1,15 @@
1
+ using Generators.Input;
2
+
3
+ namespace Generators.Exercises
4
+ {
5
+ public class SecretHandshake : Exercise
6
+ {
7
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
8
+ {
9
+ foreach (var canonicalDataCase in CanonicalData.Cases)
10
+ {
11
+ canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertToEnumerable<string>();
12
+ }
13
+ }
14
+ }
15
+ }
@@ -1,20 +1,20 @@
1
1
  using System.Collections.Generic;
2
- using Newtonsoft.Json.Linq;
2
+ using Generators.Input;
3
3
 
4
4
  namespace Generators.Exercises
5
5
  {
6
6
  public class Transpose : Exercise
7
7
  {
8
- public Transpose()
8
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
9
9
  {
10
10
  foreach (var canonicalDataCase in CanonicalData.Cases)
11
11
  {
12
12
  canonicalDataCase.Property = "String";
13
13
  canonicalDataCase.Input = new Dictionary<string, object>
14
14
  {
15
- ["input"] = string.Join("\n", (JArray)canonicalDataCase.Input["input"])
15
+ ["input"] = canonicalDataCase.Input["input"].ConvertMultiLineString()
16
16
  };
17
- canonicalDataCase.Expected = string.Join("\n", (JArray)canonicalDataCase.Expected);
17
+ canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertMultiLineString();
18
18
  canonicalDataCase.UseVariablesForInput = true;
19
19
  canonicalDataCase.UseVariableForExpected = true;
20
20
  }
@@ -0,0 +1,6 @@
1
+ namespace Generators.Exercises
2
+ {
3
+ public class TwoFer : Exercise
4
+ {
5
+ }
6
+ }
@@ -1,22 +1,14 @@
1
1
  using System;
2
- using Generators.Output;
2
+ using Generators.Input;
3
3
 
4
4
  namespace Generators.Exercises
5
5
  {
6
6
  public class Wordy : Exercise
7
7
  {
8
- public Wordy()
8
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
9
9
  {
10
10
  foreach (var canonicalDataCase in CanonicalData.Cases)
11
11
  canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is bool ? typeof(ArgumentException) : null;
12
12
  }
13
-
14
- protected override TestClass CreateTestClass()
15
- {
16
- var testClass = base.CreateTestClass();
17
- testClass.UsingNamespaces.Add(typeof(ArgumentException).Namespace);
18
-
19
- return testClass;
20
- }
21
13
  }
22
14
  }
@@ -13,8 +13,6 @@
13
13
  <PackageReference Include="serilog.sinks.literate" Version="2.1.0" />
14
14
  </ItemGroup>
15
15
  <ItemGroup>
16
- <None Update="Output\*.liquid">
17
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
18
- </None>
16
+ <EmbeddedResource Include="Output\Templates\*.liquid" />
19
17
  </ItemGroup>
20
18
  </Project>
@@ -1,28 +1,65 @@
1
1
  using System.IO;
2
2
  using System.Linq;
3
3
  using LibGit2Sharp;
4
+ using Serilog;
4
5
 
5
6
  namespace Generators.Input
6
7
  {
7
- public static class CanonicalDataFile
8
+ public class CanonicalDataFile
8
9
  {
9
- private const string CacheDir = "./.cache";
10
10
  private const string ProblemSpecificationsGitUrl = "https://github.com/exercism/problem-specifications.git";
11
- private const string RemoteName = "origin";
11
+ private const string ProblemSpecificationsBranch = "master";
12
+ private const string ProblemSpecificationsRemote = "origin";
13
+ private const string ProblemSpecificationsRemoteBranch = ProblemSpecificationsRemote + "/" + ProblemSpecificationsBranch;
12
14
 
13
- static CanonicalDataFile()
15
+ private readonly CanonicalDataOptions _options;
16
+
17
+ public CanonicalDataFile(CanonicalDataOptions options)
18
+ {
19
+ _options = options;
20
+ }
21
+
22
+ public string Contents(string exercise)
14
23
  {
15
- if (!Directory.Exists(CacheDir))
16
- Repository.Clone(ProblemSpecificationsGitUrl, CacheDir);
24
+ var exerciseCanonicalDataPath = Path.Combine(_options.CanonicalDataDirectory, "exercises", exercise, "canonical-data.json");
25
+ return File.ReadAllText(exerciseCanonicalDataPath);
26
+ }
17
27
 
18
- using (var repository = new Repository(CacheDir))
19
- Commands.Fetch(repository, RemoteName, Enumerable.Empty<string>(), new FetchOptions(), null);
28
+ public void DownloadData()
29
+ {
30
+ CloneRepository();
31
+
32
+ if (_options.CacheCanonicalData)
33
+ return;
34
+
35
+ UpdateToLatestVersion();
20
36
  }
21
37
 
22
- public static string Contents(string exercise)
38
+ private void CloneRepository()
23
39
  {
24
- var exerciseCanonicalDataPath = Path.Combine(CacheDir, "exercises", exercise, "canonical-data.json");
25
- return File.ReadAllText(exerciseCanonicalDataPath);
40
+ if (Directory.Exists(_options.CanonicalDataDirectory))
41
+ return;
42
+
43
+ Log.Information("Cloning repository...");
44
+
45
+ Repository.Clone(ProblemSpecificationsGitUrl, _options.CanonicalDataDirectory);
46
+
47
+ Log.Information("Repository cloned.");
48
+ }
49
+
50
+ private void UpdateToLatestVersion()
51
+ {
52
+ Log.Information("Updating repository to latest version...");
53
+
54
+ using (var repository = new Repository(_options.CanonicalDataDirectory))
55
+ {
56
+ Commands.Fetch(repository, ProblemSpecificationsRemote, Enumerable.Empty<string>(), new FetchOptions(), null);
57
+
58
+ var remoteBranch = repository.Branches[ProblemSpecificationsRemoteBranch];
59
+ repository.Reset(ResetMode.Hard, remoteBranch.Tip);
60
+ }
61
+
62
+ Log.Information("Updated repository to latest version.");
26
63
  }
27
64
  }
28
65
  }
@@ -0,0 +1,8 @@
1
+ namespace Generators.Input
2
+ {
3
+ public class CanonicalDataOptions
4
+ {
5
+ public string CanonicalDataDirectory { get; set; }
6
+ public bool CacheCanonicalData { get; set; }
7
+ }
8
+ }
@@ -3,11 +3,19 @@
3
3
 
4
4
  namespace Generators.Input
5
5
  {
6
- public static class CanonicalDataParser
6
+ public class CanonicalDataParser
7
7
  {
8
- public static CanonicalData Parse(string exercise)
8
+ private readonly CanonicalDataFile _canonicalDataFile;
9
+
10
+ public CanonicalDataParser(CanonicalDataOptions options)
11
+ {
12
+ _canonicalDataFile = new CanonicalDataFile(options);
13
+ _canonicalDataFile.DownloadData();
14
+ }
15
+
16
+ public CanonicalData Parse(Exercise exercise)
9
17
  {
10
- var canonicalDataJson = CanonicalDataFile.Contents(exercise);
18
+ var canonicalDataJson = _canonicalDataFile.Contents(exercise.Name);
11
19
  var canonicalData = JsonConvert.DeserializeObject<CanonicalData>(canonicalDataJson);
12
20
 
13
21
  Validator.ValidateObject(canonicalData, new ValidationContext(canonicalData));
@@ -8,5 +8,13 @@ public class Options
8
8
  [Option('e', "exercises", Required = false,
9
9
  HelpText = "Exercises to generate (if not specified, defaults to all exercises).")]
10
10
  public IEnumerable<string> Exercises { get; set; }
11
+
12
+ [Option('d', "canonicaldatadirectory", Required = false, Default = "./.problem-specifications",
13
+ HelpText = "Canonical data directory. If the directory does not exist, the canonical data will be downloaded.")]
14
+ public string CanonicalDataDirectory { get; set; }
15
+
16
+ [Option('c', "cachecanonicaldata", Required = false, Default = false,
17
+ HelpText = "Use the cached canonical data and don't update the data.")]
18
+ public bool CacheCanonicalData { get; set; }
11
19
  }
12
20
  }
@@ -3,14 +3,15 @@
3
3
 
4
4
  namespace Generators.Output
5
5
  {
6
- public static class TestClassFile
6
+ public class ExerciseWriter
7
7
  {
8
- public static void Write(Exercise exercise, string contents)
8
+ public virtual void WriteToFile(Exercise exercise)
9
9
  {
10
10
  var testClassFilePath = TestClassFilePath(exercise);
11
+ var testClassContents = exercise.Render();
11
12
 
12
13
  Directory.CreateDirectory(Path.GetDirectoryName(testClassFilePath));
13
- File.WriteAllText(testClassFilePath, contents);
14
+ File.WriteAllText(testClassFilePath, testClassContents);
14
15
 
15
16
  Log.Information("Generated tests for {Exercise} exercise in {TestFile}", exercise.Name, testClassFilePath);
16
17
  }
@@ -0,0 +1,14 @@
1
+ namespace Generators.Output
2
+ {
3
+ public static class FormattingExtensions
4
+ {
5
+ public static string Indent(this string str, int level = 1) => $"{new string(' ', 4 * level)}{str}";
6
+
7
+ public static string EscapeControlCharacters(this string s)
8
+ => s.Replace("\n", "\\n")
9
+ .Replace("\t", "\\t")
10
+ .Replace("\r", "\\r");
11
+
12
+ public static string Quote(this string s) => $"\"{s}\"";
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ using System;
2
+ using System.Linq;
3
+
4
+ namespace Generators.Output
5
+ {
6
+ public class IndentFilter
7
+ {
8
+ public static string Indent(string input)
9
+ => string.Join(Environment.NewLine, input
10
+ .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
11
+ .Select(x => x.Indent()));
12
+ }
13
+ }
@@ -0,0 +1,23 @@
1
+ using System.Reflection;
2
+ using DotLiquid;
3
+ using DotLiquid.FileSystems;
4
+
5
+ namespace Generators.Output
6
+ {
7
+ public static class TemplateRenderer
8
+ {
9
+ private static readonly string EmbeddedTemplatesNamespace = $"{typeof(TemplateRenderer).Namespace}.Templates";
10
+
11
+ static TemplateRenderer()
12
+ {
13
+ Template.RegisterFilter(typeof(IndentFilter));
14
+ Template.FileSystem = new EmbeddedFileSystem(Assembly.GetEntryAssembly(), EmbeddedTemplatesNamespace);
15
+ }
16
+
17
+ public static string RenderInline(string template, object parameters)
18
+ => Template.Parse(template).Render(Hash.FromAnonymousObject(parameters));
19
+
20
+ public static string RenderPartial(string template, object parameters)
21
+ => Template.Parse($"{{% include \"{template}\" %}}").Render(Hash.FromAnonymousObject(parameters));
22
+ }
23
+ }
@@ -0,0 +1,3 @@
1
+ {%- for variable in Variables -%}
2
+ {{ variable }}
3
+ {%- endfor -%}
@@ -0,0 +1 @@
1
+ Assert.{{ BooleanAssertMethod}}({{ TestedValue }});
@@ -0,0 +1 @@
1
+ Assert.Equal({{ ExpectedParameter }}, {{ TestedValue }});
@@ -0,0 +1 @@
1
+ Assert.Empty({{ TestedValue }});
@@ -0,0 +1 @@
1
+ Assert.Null({{ TestedValue }});
@@ -0,0 +1 @@
1
+ Assert.Throws<{{ ExceptionType }}>(() => {{ TestedValue }});
@@ -6,14 +6,8 @@ using {{ namespace }};
6
6
 
7
7
  public class {{ClassName}}
8
8
  {
9
- {%- for testMethod in TestMethods -%}
10
- [Fact{% if forloop.first == false %}(Skip = "Remove to run test"){% endif %}]
11
- public void {{testMethod.Name}}()
12
- {
13
- {%- for line in testMethod.Body -%}
14
- {{ line }}
15
- {%- endfor -%}
16
- }
9
+ {%- for method in Methods -%}
10
+ {{ method | indent }}
17
11
  {%- if forloop.last == false %}
18
12
  {% endif -%}
19
13
  {%- endfor -%}