trackler 2.0.8.19 → 2.0.8.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/phone-number/canonical-data.json +2 -2
  3. data/lib/trackler/version.rb +1 -1
  4. data/tracks/c/config.json +7 -0
  5. data/tracks/c/exercises/react/makefile +16 -0
  6. data/tracks/c/exercises/react/src/example.c +185 -0
  7. data/tracks/c/exercises/react/src/react.h +29 -0
  8. data/tracks/c/exercises/react/test/test_react.c +324 -0
  9. data/tracks/c/exercises/react/test/vendor/unity.c +1300 -0
  10. data/tracks/c/exercises/react/test/vendor/unity.h +274 -0
  11. data/tracks/c/exercises/react/test/vendor/unity_internals.h +701 -0
  12. data/tracks/csharp/.travis.yml +2 -9
  13. data/tracks/csharp/appveyor.yml +3 -3
  14. data/tracks/csharp/build.cake +13 -4
  15. data/tracks/csharp/build.ps1 +56 -164
  16. data/tracks/csharp/build.sh +33 -78
  17. data/tracks/csharp/circle.yml +2 -4
  18. data/tracks/csharp/config.json +2 -1
  19. data/tracks/csharp/exercises/leap/LeapTest.cs +8 -8
  20. data/tracks/csharp/generators/CanonicalData.cs +19 -0
  21. data/tracks/csharp/generators/CanonicalDataCase.cs +24 -0
  22. data/tracks/csharp/generators/CanonicalDataCaseJsonConverter.cs +32 -0
  23. data/tracks/csharp/generators/CanonicalDataCasesJsonConverter.cs +30 -0
  24. data/tracks/csharp/generators/CanonicalDataParser.cs +28 -0
  25. data/tracks/csharp/generators/ExerciseCollection.cs +23 -0
  26. data/tracks/csharp/generators/Exercises/Exercise.cs +14 -0
  27. data/tracks/csharp/generators/Exercises/LeapExercise.cs +35 -0
  28. data/tracks/csharp/generators/Generators.csproj +12 -0
  29. data/tracks/csharp/generators/Generators.csproj.user +6 -0
  30. data/tracks/csharp/generators/Generators.sln +22 -0
  31. data/tracks/csharp/generators/Program.cs +59 -0
  32. data/tracks/csharp/generators/TestClass.cs +13 -0
  33. data/tracks/csharp/generators/TestClassRenderer.cs +36 -0
  34. data/tracks/csharp/generators/TestMethod.cs +9 -0
  35. data/tracks/csharp/generators/TestMethodNameTransformer.cs +11 -0
  36. data/tracks/csharp/generators/TestMethodRenderer.cs +18 -0
  37. data/tracks/csharp/generators/To.cs +7 -0
  38. data/tracks/csharp/generators/generate.ps1 +2 -0
  39. data/tracks/csharp/generators/generate.sh +4 -0
  40. data/tracks/delphi/config.json +8 -0
  41. data/tracks/delphi/exercises/phone-number/uPhoneNumberExample.pas +6 -6
  42. data/tracks/delphi/exercises/phone-number/uPhoneNumberTests.pas +28 -17
  43. data/tracks/delphi/exercises/roman-numerals/RomanNumerals.dpr +60 -0
  44. data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsExample.pas +49 -0
  45. data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsTest.pas +216 -0
  46. data/tracks/elixir/config.json +22 -0
  47. data/tracks/elixir/exercises/poker/example.exs +136 -0
  48. data/tracks/elixir/exercises/poker/poker.exs +34 -0
  49. data/tracks/elixir/exercises/poker/poker_test.exs +217 -0
  50. data/tracks/elixir/exercises/protein-translation/example.exs +62 -0
  51. data/tracks/elixir/exercises/protein-translation/protein_translation.exs +34 -0
  52. data/tracks/elixir/exercises/protein-translation/protein_translation_test.exs +87 -0
  53. data/tracks/elixir/exercises/say/example.exs +139 -0
  54. data/tracks/elixir/exercises/say/say.exs +8 -0
  55. data/tracks/elixir/exercises/say/say_test.exs +85 -0
  56. data/tracks/go/exercises/robot-name/example.go +2 -0
  57. data/tracks/go/exercises/robot-name/robot_name_test.go +9 -1
  58. data/tracks/go/exercises/roman-numerals/roman_numerals_test.go +4 -1
  59. data/tracks/go/exercises/saddle-points/saddle_points_test.go +6 -6
  60. data/tracks/php/config.json +7 -0
  61. data/tracks/php/exercises/grade-school/example.php +35 -0
  62. data/tracks/php/exercises/grade-school/grade-school_test.php +84 -0
  63. metadata +43 -2
@@ -857,7 +857,8 @@
857
857
  ],
858
858
  "ignored": [
859
859
  "docs",
860
- "img"
860
+ "img",
861
+ "generators"
861
862
  ],
862
863
  "foregone": [
863
864
  "lens-person",
@@ -3,26 +3,26 @@ using Xunit;
3
3
  public class LeapTest
4
4
  {
5
5
  [Fact]
6
- public void Valid_leap_year()
6
+ public void Year_not_divisible_by_4_is_common_year()
7
7
  {
8
- Assert.True(Year.IsLeap(1996));
8
+ Assert.False(Year.IsLeap(2015));
9
9
  }
10
10
 
11
11
  [Fact(Skip = "Remove to run test")]
12
- public void Invalid_leap_year()
12
+ public void Year_divisible_by_4_not_divisible_by_100_is_leap_year()
13
13
  {
14
- Assert.False(Year.IsLeap(1997));
14
+ Assert.True(Year.IsLeap(2016));
15
15
  }
16
16
 
17
17
  [Fact(Skip = "Remove to run test")]
18
- public void Turn_of_the_20th_century_is_not_a_leap_year()
18
+ public void Year_divisible_by_100_not_divisible_by_400_is_common_year()
19
19
  {
20
- Assert.False(Year.IsLeap(1900));
20
+ Assert.False(Year.IsLeap(2100));
21
21
  }
22
22
 
23
23
  [Fact(Skip = "Remove to run test")]
24
- public void Turn_of_the_25th_century_is_a_leap_year()
24
+ public void Year_divisible_by_400_is_leap_year()
25
25
  {
26
- Assert.True(Year.IsLeap(2400));
26
+ Assert.True(Year.IsLeap(2000));
27
27
  }
28
28
  }
@@ -0,0 +1,19 @@
1
+ using System.ComponentModel.DataAnnotations;
2
+ using Newtonsoft.Json;
3
+
4
+ namespace Generators
5
+ {
6
+ public class CanonicalData
7
+ {
8
+ [Required]
9
+ public string Exercise { get; set; }
10
+
11
+ [Required]
12
+ public string Version { get; set; }
13
+
14
+ public string[] Comments { get; set; }
15
+
16
+ [JsonConverter(typeof(CanonicalDataCasesJsonConverter))]
17
+ public CanonicalDataCase[] Cases { get; set; }
18
+ }
19
+ }
@@ -0,0 +1,24 @@
1
+ using Newtonsoft.Json;
2
+ using System.Collections.Generic;
3
+ using System.ComponentModel.DataAnnotations;
4
+
5
+ namespace Generators
6
+ {
7
+ [JsonConverter(typeof(CanonicalDataCaseJsonConverter))]
8
+ public class CanonicalDataCase
9
+ {
10
+ [Required]
11
+ public string Description { get; set; }
12
+
13
+ [Required]
14
+ public string Property { get; set; }
15
+
16
+ public string[] Comments { get; set; }
17
+
18
+ public object Input { get; set; }
19
+
20
+ public object Expected { get; set; }
21
+
22
+ public IDictionary<string, object> Data { get; set; }
23
+ }
24
+ }
@@ -0,0 +1,32 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using Newtonsoft.Json;
4
+ using Newtonsoft.Json.Linq;
5
+
6
+ namespace Generators
7
+ {
8
+ public class CanonicalDataCaseJsonConverter : JsonConverter
9
+ {
10
+ public override bool CanConvert(Type objectType)
11
+ {
12
+ return typeof(CanonicalDataCase) == objectType;
13
+ }
14
+
15
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
16
+ {
17
+ var jToken = JToken.ReadFrom(reader);
18
+
19
+ var canonicalDataCase = new CanonicalDataCase();
20
+ serializer.Populate(new JTokenReader(jToken), canonicalDataCase);
21
+
22
+ canonicalDataCase.Data = jToken.ToObject<IDictionary<string, object>>();
23
+
24
+ return canonicalDataCase;
25
+ }
26
+
27
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
28
+ {
29
+ throw new NotImplementedException();
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,30 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Reflection;
4
+ using Newtonsoft.Json;
5
+ using Newtonsoft.Json.Linq;
6
+ using System.Linq;
7
+
8
+ namespace Generators
9
+ {
10
+ public class CanonicalDataCasesJsonConverter : JsonConverter
11
+ {
12
+ public override bool CanConvert(Type objectType)
13
+ {
14
+ return typeof(IEnumerable<CanonicalData>).GetTypeInfo().IsAssignableFrom(objectType);
15
+ }
16
+
17
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
18
+ {
19
+ var casesToken = JToken.ReadFrom(reader);
20
+ var caseTokens = casesToken.SelectTokens("$..*[?(@.property)]").ToArray();
21
+
22
+ return new JArray(caseTokens).ToObject(objectType);
23
+ }
24
+
25
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
26
+ {
27
+ throw new NotImplementedException();
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,28 @@
1
+ using Newtonsoft.Json;
2
+ using System;
3
+ using System.ComponentModel.DataAnnotations;
4
+ using System.Net.Http;
5
+
6
+ namespace Generators
7
+ {
8
+ public static class CanonicalDataParser
9
+ {
10
+ private static readonly HttpClient httpClient = new HttpClient();
11
+
12
+ public static CanonicalData Parse(string exercise)
13
+ {
14
+ var canonicalDataJson = DownloadCanonicalDataJson(exercise);
15
+ var canonicalData = JsonConvert.DeserializeObject<CanonicalData>(canonicalDataJson);
16
+
17
+ Validator.ValidateObject(canonicalData, new ValidationContext(canonicalData));
18
+
19
+ return canonicalData;
20
+ }
21
+
22
+ private static string DownloadCanonicalDataJson(string exercise)
23
+ => httpClient.GetStringAsync(GetCanonicalDataUrl(exercise)).GetAwaiter().GetResult();
24
+
25
+ private static Uri GetCanonicalDataUrl(string exercise)
26
+ => new Uri($"https://raw.githubusercontent.com/exercism/x-common/master/exercises/{exercise}/canonical-data.json");
27
+ }
28
+ }
@@ -0,0 +1,23 @@
1
+ using Generators.Exercises;
2
+ using System;
3
+ using System.Collections;
4
+ using System.Collections.Generic;
5
+ using System.Linq;
6
+ using System.Reflection;
7
+
8
+ namespace Generators
9
+ {
10
+ public class ExerciseCollection : IEnumerable<Exercise>
11
+ {
12
+ private readonly IEnumerable<Exercise> generators = GetDefinedGenerators();
13
+
14
+ public IEnumerator<Exercise> GetEnumerator() => generators.GetEnumerator();
15
+
16
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
17
+
18
+ private static IEnumerable<Exercise> GetDefinedGenerators() =>
19
+ from type in Assembly.GetEntryAssembly().GetTypes()
20
+ where typeof(Exercise).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract
21
+ select (Exercise)Activator.CreateInstance(type);
22
+ }
23
+ }
@@ -0,0 +1,14 @@
1
+ namespace Generators.Exercises
2
+ {
3
+ public abstract class Exercise
4
+ {
5
+ protected Exercise(string name)
6
+ {
7
+ Name = name;
8
+ }
9
+
10
+ public string Name { get; }
11
+
12
+ public abstract TestClass CreateTestClass(CanonicalData canonicalData);
13
+ }
14
+ }
@@ -0,0 +1,35 @@
1
+ using System;
2
+ using System.Linq;
3
+ using Humanizer;
4
+
5
+ namespace Generators.Exercises
6
+ {
7
+ public class LeapExercise : Exercise
8
+ {
9
+ public LeapExercise() : base("leap")
10
+ {
11
+ }
12
+
13
+ public override TestClass CreateTestClass(CanonicalData canonicalData)
14
+ {
15
+ return new TestClass
16
+ {
17
+ ClassName = "Leap",
18
+ TestMethods = canonicalData.Cases.Select(CreateTestMethod).ToArray()
19
+ };
20
+ }
21
+
22
+ private static TestMethod CreateTestMethod(CanonicalDataCase canonicalDataCase, int index)
23
+ {
24
+ var year = Convert.ToInt32(canonicalDataCase.Input);
25
+ var isTrue = Convert.ToBoolean(canonicalDataCase.Expected);
26
+
27
+ return new TestMethod
28
+ {
29
+ Index = index,
30
+ MethodName = canonicalDataCase.Description.Replace(":", " is").Transform(To.TestMethodName),
31
+ Body = $"Assert.{isTrue}(Year.IsLeap({year}));"
32
+ };
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,12 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <OutputType>Exe</OutputType>
4
+ <TargetFramework>netcoreapp1.1</TargetFramework>
5
+ </PropertyGroup>
6
+ <ItemGroup>
7
+ <PackageReference Include="Humanizer" Version="2.1.0" />
8
+ <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
9
+ <PackageReference Include="serilog" Version="2.4.0" />
10
+ <PackageReference Include="serilog.sinks.literate" Version="2.1.0" />
11
+ </ItemGroup>
12
+ </Project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+ <PropertyGroup>
4
+ <ShowAllFiles>false</ShowAllFiles>
5
+ </PropertyGroup>
6
+ </Project>
@@ -0,0 +1,22 @@
1
+ 
2
+ Microsoft Visual Studio Solution File, Format Version 12.00
3
+ # Visual Studio 15
4
+ VisualStudioVersion = 15.0.26228.4
5
+ MinimumVisualStudioVersion = 10.0.40219.1
6
+ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Generators", "Generators.csproj", "{F310316B-5E18-4E7F-A77D-D26AD8D92307}"
7
+ EndProject
8
+ Global
9
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
10
+ Debug|Any CPU = Debug|Any CPU
11
+ Release|Any CPU = Release|Any CPU
12
+ EndGlobalSection
13
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
14
+ {F310316B-5E18-4E7F-A77D-D26AD8D92307}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15
+ {F310316B-5E18-4E7F-A77D-D26AD8D92307}.Debug|Any CPU.Build.0 = Debug|Any CPU
16
+ {F310316B-5E18-4E7F-A77D-D26AD8D92307}.Release|Any CPU.ActiveCfg = Release|Any CPU
17
+ {F310316B-5E18-4E7F-A77D-D26AD8D92307}.Release|Any CPU.Build.0 = Release|Any CPU
18
+ EndGlobalSection
19
+ GlobalSection(SolutionProperties) = preSolution
20
+ HideSolutionNode = FALSE
21
+ EndGlobalSection
22
+ EndGlobal
@@ -0,0 +1,59 @@
1
+ using Generators.Exercises;
2
+ using System.IO;
3
+ using Humanizer;
4
+ using Serilog;
5
+
6
+ namespace Generators
7
+ {
8
+ public static class Program
9
+ {
10
+ public static void Main()
11
+ {
12
+ SetupLogger();
13
+ GenerateAll();
14
+ }
15
+
16
+ private static void SetupLogger()
17
+ {
18
+ Log.Logger = new LoggerConfiguration()
19
+ .WriteTo.LiterateConsole()
20
+ .CreateLogger();
21
+ }
22
+
23
+ private static void GenerateAll()
24
+ {
25
+ Log.Information("Start generating tests...");
26
+
27
+ foreach (var exercise in new ExerciseCollection())
28
+ TestFileGenerator.Generate(exercise);
29
+
30
+ Log.Information("Finished generating tests for all supported exercises.");
31
+ }
32
+ }
33
+
34
+ public static class TestFileGenerator
35
+ {
36
+ public static void Generate(Exercise exercise)
37
+ {
38
+ var testClassContents = GenerateTestClassContents(exercise);
39
+ var testClassFilePath = TestFilePath(exercise);
40
+
41
+ SaveTestClassContentsToFile(testClassFilePath, testClassContents);
42
+ Log.Information("Generated tests for {Exercise} exercise in {TestFile}.", exercise.Name, testClassFilePath);
43
+ }
44
+
45
+ private static string GenerateTestClassContents(Exercise exercise)
46
+ {
47
+ var canonicalData = CanonicalDataParser.Parse(exercise.Name);
48
+ var testClass = exercise.CreateTestClass(canonicalData);
49
+ return TestClassRenderer.Render(testClass);
50
+ }
51
+
52
+ private static void SaveTestClassContentsToFile(string testClassFilePath, string testClassContents) =>
53
+ File.WriteAllText(testClassFilePath, testClassContents);
54
+
55
+ private static string TestFilePath(Exercise exercise) => Path.Combine("..", "exercises", exercise.Name, TestFileName(exercise));
56
+
57
+ private static string TestFileName(Exercise exercise) => $"{exercise.Name.Transform(Humanizer.To.TitleCase)}Test.cs";
58
+ }
59
+ }
@@ -0,0 +1,13 @@
1
+ using System.Collections.Generic;
2
+
3
+ namespace Generators
4
+ {
5
+ public class TestClass
6
+ {
7
+ public ISet<string> UsingNamespaces { get; set; } = new HashSet<string> { "Xunit" };
8
+ public string ClassName { get; set; }
9
+ public string BeforeTestMethods { get; set; }
10
+ public TestMethod[] TestMethods { get; set; }
11
+ public string AfterTestMethods { get; set; }
12
+ }
13
+ }
@@ -0,0 +1,36 @@
1
+ using System.Collections.Generic;
2
+ using System.Linq;
3
+
4
+ namespace Generators
5
+ {
6
+ public static class TestClassRenderer
7
+ {
8
+ private const string TestClassTemplate =
9
+ @"{UsingNamespaces}
10
+
11
+ public class {ClassName}Test
12
+ {
13
+ {Body}
14
+ }";
15
+
16
+ public static string Render(TestClass testClass) =>
17
+ TestClassTemplate
18
+ .Replace("{UsingNamespaces}", RenderUsingNamespaces(testClass))
19
+ .Replace("{ClassName}", testClass.ClassName)
20
+ .Replace("{Body}", RenderBody(testClass));
21
+
22
+ private static string RenderUsingNamespaces(TestClass testClass) =>
23
+ string.Join("\n", testClass.UsingNamespaces.Select(usingNamespace => $"using {usingNamespace};"));
24
+
25
+ private static string RenderBody(TestClass testClass) =>
26
+ string.Join("\n\n", GetBodyParts(testClass));
27
+
28
+ private static IEnumerable<string> GetBodyParts(TestClass testClass) =>
29
+ from bodyPart in new [] { testClass.BeforeTestMethods, RenderTestMethods(testClass), testClass.AfterTestMethods }
30
+ where !string.IsNullOrWhiteSpace(bodyPart)
31
+ select bodyPart;
32
+
33
+ private static string RenderTestMethods(TestClass testClass) =>
34
+ string.Join("\n\n", testClass.TestMethods.Select(TestMethodRenderer.Render));
35
+ }
36
+ }
@@ -0,0 +1,9 @@
1
+ namespace Generators
2
+ {
3
+ public class TestMethod
4
+ {
5
+ public int Index { get; set; }
6
+ public string MethodName { get; set; }
7
+ public string Body { get; set; }
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ using System.Text.RegularExpressions;
2
+ using Humanizer;
3
+
4
+ namespace Generators
5
+ {
6
+ public class TestMethodNameTransformer : IStringTransformer
7
+ {
8
+ public string Transform(string input)
9
+ => Regex.Replace(input, @"[^\w]+", "_", RegexOptions.Compiled).Underscore().Transform(Humanizer.To.TitleCase);
10
+ }
11
+ }