trackler 2.0.8.19 → 2.0.8.20

Sign up to get free protection for your applications and to get access to all the features.
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
+ }