trackler 2.0.8.24 → 2.0.8.26
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/c/config.json +9 -0
- data/tracks/c/exercises/nucleotide-count/makefile +15 -0
- data/tracks/c/exercises/nucleotide-count/src/example.c +43 -0
- data/tracks/c/exercises/nucleotide-count/src/example.h +6 -0
- data/tracks/c/exercises/nucleotide-count/test/test_nucleotide_count.c +58 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/nucleotide-count/test/vendor/unity_internals.h +701 -0
- data/tracks/ceylon/README.md +2 -2
- data/tracks/csharp/.gitattributes +11 -0
- data/tracks/csharp/appveyor.yml +1 -4
- data/tracks/csharp/exercises/acronym/AcronymTest.cs +1 -1
- data/tracks/csharp/exercises/atbash-cipher/AtbashCipher.cs +8 -3
- data/tracks/csharp/exercises/atbash-cipher/AtbashCipherTest.cs +76 -0
- data/tracks/csharp/exercises/atbash-cipher/Example.cs +22 -23
- data/tracks/csharp/exercises/isogram/Example.cs +2 -2
- data/tracks/csharp/exercises/isogram/IsogramTest.cs +47 -15
- data/tracks/csharp/exercises/nth-prime/Example.cs +4 -1
- data/tracks/csharp/exercises/nth-prime/NthPrime.cs +1 -1
- data/tracks/csharp/exercises/nth-prime/NthPrimeTest.cs +29 -15
- data/tracks/csharp/exercises/perfect-numbers/Example.cs +14 -16
- data/tracks/csharp/exercises/perfect-numbers/PerfectNumbers.cs +2 -2
- data/tracks/csharp/exercises/perfect-numbers/PerfectNumbersTest.cs +78 -26
- data/tracks/csharp/exercises/pig-latin/PigLatinTest.cs +69 -24
- data/tracks/csharp/exercises/raindrops/Example.cs +1 -1
- data/tracks/csharp/exercises/raindrops/RaindropsTest.cs +93 -31
- data/tracks/csharp/exercises/roman-numerals/HINTS.md +2 -0
- data/tracks/csharp/exercises/roman-numerals/RomanNumeralsTest.cs +106 -23
- data/tracks/csharp/exercises/word-search/HINTS.md +6 -0
- data/tracks/csharp/generators/{TestClass.cs → Classes/TestClass.cs} +2 -1
- data/tracks/csharp/generators/{TestClassNameTransformer.cs → Classes/TestClassNameTransformer.cs} +1 -1
- data/tracks/csharp/generators/{TestClassRenderer.cs → Classes/TestClassRenderer.cs} +2 -1
- data/tracks/csharp/generators/Classes/TestedClassNameTransformer.cs +9 -0
- data/tracks/csharp/generators/{CanonicalData.cs → Data/CanonicalData.cs} +1 -1
- data/tracks/csharp/generators/{CanonicalDataCase.cs → Data/CanonicalDataCase.cs} +3 -3
- data/tracks/csharp/generators/{CanonicalDataCaseJsonConverter.cs → Data/CanonicalDataCaseJsonConverter.cs} +1 -1
- data/tracks/csharp/generators/{CanonicalDataCasesJsonConverter.cs → Data/CanonicalDataCasesJsonConverter.cs} +2 -2
- data/tracks/csharp/generators/{CanonicalDataParser.cs → Data/CanonicalDataParser.cs} +5 -5
- data/tracks/csharp/generators/{ExerciseCollection.cs → Data/ExerciseCollection.cs} +3 -3
- data/tracks/csharp/generators/Exercises/AcronymExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/AtbashCipherExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/BooleanExercise.cs +14 -0
- data/tracks/csharp/generators/Exercises/EqualityExercise.cs +14 -0
- data/tracks/csharp/generators/Exercises/Exercise.cs +59 -4
- data/tracks/csharp/generators/Exercises/IsogramExercise.cs +9 -0
- data/tracks/csharp/generators/Exercises/LeapExercise.cs +1 -4
- data/tracks/csharp/generators/Exercises/NthPrimeExercise.cs +25 -0
- data/tracks/csharp/generators/Exercises/PerfectNumbersExercise.cs +29 -0
- data/tracks/csharp/generators/Exercises/PigLatinExercise.cs +9 -0
- data/tracks/csharp/generators/Exercises/RaindropsExercise.cs +20 -0
- data/tracks/csharp/generators/Exercises/RomanNumeralsExercise.cs +30 -0
- data/tracks/csharp/generators/Helpers/StringExtensions.cs +8 -0
- data/tracks/csharp/generators/{To.cs → Helpers/To.cs} +4 -1
- data/tracks/csharp/generators/Methods/BooleanTestMethodGenerator.cs +32 -0
- data/tracks/csharp/generators/Methods/EqualityTestMethodGenerator.cs +25 -0
- data/tracks/csharp/generators/Methods/ExceptionTestMethodGenerator.cs +30 -0
- data/tracks/csharp/generators/{TestMethod.cs → Methods/TestMethod.cs} +6 -3
- data/tracks/csharp/generators/Methods/TestMethodData.cs +12 -0
- data/tracks/csharp/generators/Methods/TestMethodGenerator.cs +64 -0
- data/tracks/csharp/generators/Methods/TestMethodNameTransformer.cs +23 -0
- data/tracks/csharp/generators/Methods/TestMethodOptions.cs +13 -0
- data/tracks/csharp/generators/{TestMethodRenderer.cs → Methods/TestMethodRenderer.cs} +1 -1
- data/tracks/csharp/generators/{TestedMethodNameTransformer.cs → Methods/TestedMethodNameTransformer.cs} +1 -1
- data/tracks/csharp/generators/Methods/TestedMethodType.cs +9 -0
- data/tracks/csharp/generators/Program.cs +2 -0
- data/tracks/elixir/config.json +7 -0
- data/tracks/elixir/exercises/diffie-hellman/HINTS.md +10 -0
- data/tracks/elixir/exercises/diffie-hellman/diffie_hellman.exs +61 -0
- data/tracks/elixir/exercises/diffie-hellman/diffie_hellman_test.exs +99 -0
- data/tracks/elixir/exercises/diffie-hellman/example.exs +64 -0
- data/tracks/haskell/exercises/pov/src/POV.hs +2 -2
- data/tracks/haskell/exercises/pythagorean-triplet/src/Triplet.hs +6 -3
- data/tracks/haskell/exercises/queen-attack/src/Queens.hs +1 -1
- data/tracks/haskell/exercises/raindrops/src/Raindrops.hs +2 -1
- data/tracks/haskell/exercises/robot-name/src/Robot.hs +2 -2
- data/tracks/haskell/exercises/robot-simulator/src/Robot.hs +6 -6
- data/tracks/haskell/exercises/roman-numerals/src/Roman.hs +2 -1
- data/tracks/haskell/exercises/run-length-encoding/src/RunLength.hs +2 -2
- data/tracks/haskell/exercises/saddle-points/src/Matrix.hs +2 -1
- data/tracks/haskell/exercises/say/src/Say.hs +2 -1
- data/tracks/haskell/exercises/scrabble-score/src/Scrabble.hs +4 -2
- data/tracks/haskell/exercises/secret-handshake/src/SecretHandshake.hs +1 -1
- data/tracks/haskell/exercises/sgf-parsing/src/Sgf.hs +1 -1
- data/tracks/java/exercises/acronym/src/example/java/Acronym.java +11 -1
- data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +8 -9
- data/tracks/java/exercises/grade-school/src/test/java/SchoolTest.java +8 -2
- data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +20 -13
- data/tracks/java/exercises/robot-name/src/test/java/RobotTest.java +6 -1
- data/tracks/javascript/README.md +1 -1
- data/tracks/javascript/docs/TESTS.md +9 -1
- data/tracks/kotlin/exercises/luhn/src/example/kotlin/Luhn.kt +18 -26
- data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +40 -38
- data/tracks/php/README.md +1 -1
- data/tracks/php/config.json +5 -0
- data/tracks/php/exercises/perfect-numbers/example.php +23 -0
- data/tracks/php/exercises/perfect-numbers/perfect-numbers_test.php +99 -0
- data/tracks/purescript/.travis.yml +1 -0
- data/tracks/purescript/bin/test.sh +33 -8
- data/tracks/purescript/config.json +7 -0
- data/tracks/purescript/exercises/meetup/bower.json +17 -0
- data/tracks/purescript/exercises/meetup/examples/src/Meetup.purs +37 -0
- data/tracks/purescript/exercises/meetup/src/Meetup.purs +11 -0
- data/tracks/purescript/exercises/meetup/test/Main.purs +395 -0
- data/tracks/python/README.md +7 -6
- data/tracks/python/docs/TOOLS.md +3 -3
- data/tracks/python/exercises/bracket-push/bracket_push_test.py +32 -15
- data/tracks/python/exercises/hamming/hamming_test.py +2 -0
- data/tracks/python/exercises/luhn/luhn_test.py +2 -0
- data/tracks/python/test/check-exercises.py +7 -1
- metadata +56 -20
- data/tracks/csharp/exercises/atbash-cipher/AtbashTest.cs +0 -17
- data/tracks/csharp/generators/BooleanTestMethod.cs +0 -36
- data/tracks/csharp/generators/TestMethodNameTransformer.cs +0 -11
- data/tracks/csharp/generators/TestedClassNameTransformer.cs +0 -11
- data/tracks/java/exercises/allergies/src/main/java/.keep +0 -0
@@ -1,10 +1,20 @@
|
|
1
|
-
using System.
|
1
|
+
using System.Collections.Generic;
|
2
|
+
using System.Linq;
|
3
|
+
using Generators.Classes;
|
4
|
+
using Generators.Data;
|
5
|
+
using Generators.Methods;
|
2
6
|
using Humanizer;
|
7
|
+
using Newtonsoft.Json.Linq;
|
8
|
+
using To = Generators.Helpers.To;
|
3
9
|
|
4
10
|
namespace Generators.Exercises
|
5
11
|
{
|
6
12
|
public abstract class Exercise
|
7
13
|
{
|
14
|
+
private static readonly BooleanTestMethodGenerator BooleanTestMethodGenerator = new BooleanTestMethodGenerator();
|
15
|
+
private static readonly EqualityTestMethodGenerator EqualityTestMethodGenerator = new EqualityTestMethodGenerator();
|
16
|
+
private static readonly ExceptionTestMethodGenerator ExceptionTestMethodGenerator = new ExceptionTestMethodGenerator();
|
17
|
+
|
8
18
|
protected Exercise(string name)
|
9
19
|
{
|
10
20
|
Name = name;
|
@@ -14,12 +24,57 @@ namespace Generators.Exercises
|
|
14
24
|
|
15
25
|
public TestClass CreateTestClass(CanonicalData canonicalData)
|
16
26
|
{
|
17
|
-
|
27
|
+
var testClass = new TestClass
|
18
28
|
{
|
19
29
|
ClassName = Name.Transform(To.TestClassName),
|
20
|
-
TestMethods =
|
30
|
+
TestMethods = CreateTestMethods(canonicalData).ToArray()
|
21
31
|
};
|
32
|
+
|
33
|
+
AddTestMethodUsingNamespaces(testClass);
|
34
|
+
|
35
|
+
return testClass;
|
36
|
+
}
|
37
|
+
|
38
|
+
private static void AddTestMethodUsingNamespaces(TestClass testClass)
|
39
|
+
{
|
40
|
+
foreach (var testMethod in testClass.TestMethods)
|
41
|
+
testClass.UsingNamespaces.UnionWith(testMethod.UsingNamespaces);
|
42
|
+
}
|
43
|
+
|
44
|
+
protected abstract TestMethod CreateTestMethod(TestMethodData testMethodData);
|
45
|
+
|
46
|
+
protected virtual IEnumerable<TestMethod> CreateTestMethods(CanonicalData canonicalData)
|
47
|
+
=> canonicalData.Cases.Select((t, i) => CreateTestMethod(canonicalData, t, i));
|
48
|
+
|
49
|
+
protected virtual TestMethod CreateTestMethod(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
50
|
+
{
|
51
|
+
var testMethodData = CreateTestMethodData(canonicalData, canonicalDataCase, index);
|
52
|
+
|
53
|
+
if (testMethodData.CanonicalDataCase.Expected is JObject jObject)
|
54
|
+
return CreateExceptionTestMethod(testMethodData);
|
55
|
+
|
56
|
+
return CreateTestMethod(testMethodData);
|
22
57
|
}
|
23
|
-
|
58
|
+
|
59
|
+
protected virtual TestMethodData CreateTestMethodData(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
60
|
+
=> new TestMethodData
|
61
|
+
{
|
62
|
+
CanonicalData = canonicalData,
|
63
|
+
CanonicalDataCase = canonicalDataCase,
|
64
|
+
Index = index,
|
65
|
+
Options = CreateTestMethodOptions(canonicalData, canonicalDataCase, index)
|
66
|
+
};
|
67
|
+
|
68
|
+
protected virtual TestMethodOptions CreateTestMethodOptions(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
69
|
+
=> new TestMethodOptions();
|
70
|
+
|
71
|
+
protected virtual TestMethod CreateBooleanTestMethod(TestMethodData testMethodData)
|
72
|
+
=> BooleanTestMethodGenerator.Create(testMethodData);
|
73
|
+
|
74
|
+
protected virtual TestMethod CreateEqualityTestMethod(TestMethodData testMethodData)
|
75
|
+
=> EqualityTestMethodGenerator.Create(testMethodData);
|
76
|
+
|
77
|
+
protected virtual TestMethod CreateExceptionTestMethod(TestMethodData testMethodData)
|
78
|
+
=> ExceptionTestMethodGenerator.Create(testMethodData);
|
24
79
|
}
|
25
80
|
}
|
@@ -1,12 +1,9 @@
|
|
1
1
|
namespace Generators.Exercises
|
2
2
|
{
|
3
|
-
public class LeapExercise :
|
3
|
+
public class LeapExercise : BooleanExercise
|
4
4
|
{
|
5
5
|
public LeapExercise() : base("leap")
|
6
6
|
{
|
7
7
|
}
|
8
|
-
|
9
|
-
protected override TestMethod CreateTestMethod(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
10
|
-
=> new BooleanTestMethod(canonicalData, canonicalDataCase, index);
|
11
8
|
}
|
12
9
|
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
using System;
|
2
|
+
using Generators.Data;
|
3
|
+
using Generators.Methods;
|
4
|
+
using Humanizer;
|
5
|
+
|
6
|
+
namespace Generators.Exercises
|
7
|
+
{
|
8
|
+
public class NthPrimeExercise : EqualityExercise
|
9
|
+
{
|
10
|
+
public NthPrimeExercise() : base("nth-prime")
|
11
|
+
{
|
12
|
+
}
|
13
|
+
|
14
|
+
protected override TestMethod CreateTestMethod(TestMethodData testMethodData)
|
15
|
+
{
|
16
|
+
if (testMethodData.CanonicalDataCase.Expected is bool b)
|
17
|
+
{
|
18
|
+
testMethodData.Options.ExceptionType = typeof(ArgumentOutOfRangeException);
|
19
|
+
return CreateExceptionTestMethod(testMethodData);
|
20
|
+
}
|
21
|
+
|
22
|
+
return CreateEqualityTestMethod(testMethodData);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
using System;
|
2
|
+
using Generators.Data;
|
3
|
+
using Generators.Methods;
|
4
|
+
using Humanizer;
|
5
|
+
|
6
|
+
namespace Generators.Exercises
|
7
|
+
{
|
8
|
+
public class PerfectNumbersExercise : EqualityExercise
|
9
|
+
{
|
10
|
+
public PerfectNumbersExercise() : base("perfect-numbers")
|
11
|
+
{
|
12
|
+
}
|
13
|
+
|
14
|
+
protected override TestMethodData CreateTestMethodData(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
15
|
+
{
|
16
|
+
var testMethodData = base.CreateTestMethodData(canonicalData, canonicalDataCase, index);
|
17
|
+
testMethodData.Options.ExceptionType = typeof(ArgumentOutOfRangeException);
|
18
|
+
testMethodData.Options.FormatExpected = false;
|
19
|
+
|
20
|
+
if (testMethodData.CanonicalDataCase.Expected is string classificationType)
|
21
|
+
testMethodData.CanonicalDataCase.Expected = GetClassification(classificationType);
|
22
|
+
|
23
|
+
return testMethodData;
|
24
|
+
}
|
25
|
+
|
26
|
+
private static string GetClassification(string classificationType)
|
27
|
+
=> $"Classification.{classificationType.Transform(Humanizer.To.TitleCase)}";
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
using Generators.Data;
|
2
|
+
using Generators.Methods;
|
3
|
+
|
4
|
+
namespace Generators.Exercises
|
5
|
+
{
|
6
|
+
public class RaindropsExercise : EqualityExercise
|
7
|
+
{
|
8
|
+
public RaindropsExercise() : base("raindrops")
|
9
|
+
{
|
10
|
+
}
|
11
|
+
|
12
|
+
protected override TestMethodOptions CreateTestMethodOptions(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
13
|
+
{
|
14
|
+
var testMethodOptions = base.CreateTestMethodOptions(canonicalData, canonicalDataCase, index);
|
15
|
+
testMethodOptions.InputProperty = "number";
|
16
|
+
|
17
|
+
return testMethodOptions;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
using Generators.Data;
|
2
|
+
using Generators.Methods;
|
3
|
+
|
4
|
+
namespace Generators.Exercises
|
5
|
+
{
|
6
|
+
public class RomanNumeralsExercise : EqualityExercise
|
7
|
+
{
|
8
|
+
public RomanNumeralsExercise() : base("roman-numerals")
|
9
|
+
{
|
10
|
+
}
|
11
|
+
|
12
|
+
protected override TestMethodData CreateTestMethodData(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
13
|
+
{
|
14
|
+
var testMethodData = base.CreateTestMethodData(canonicalData, canonicalDataCase, index);
|
15
|
+
testMethodData.CanonicalDataCase.Property = "ToRoman";
|
16
|
+
testMethodData.CanonicalDataCase.Description = "Number_" + testMethodData.CanonicalDataCase.Description;
|
17
|
+
|
18
|
+
return testMethodData;
|
19
|
+
}
|
20
|
+
|
21
|
+
protected override TestMethodOptions CreateTestMethodOptions(CanonicalData canonicalData, CanonicalDataCase canonicalDataCase, int index)
|
22
|
+
{
|
23
|
+
var testMethodOptions = new TestMethodOptions();
|
24
|
+
testMethodOptions.InputProperty = "number";
|
25
|
+
testMethodOptions.TestedMethodType = TestedMethodType.Extension;
|
26
|
+
|
27
|
+
return testMethodOptions;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
using System;
|
2
|
+
using Generators.Helpers;
|
3
|
+
|
4
|
+
namespace Generators.Methods
|
5
|
+
{
|
6
|
+
public class BooleanTestMethodGenerator : TestMethodGenerator
|
7
|
+
{
|
8
|
+
protected override string Body
|
9
|
+
{
|
10
|
+
get
|
11
|
+
{
|
12
|
+
switch (TestMethodData.Options.TestedMethodType)
|
13
|
+
{
|
14
|
+
case TestedMethodType.Static:
|
15
|
+
return $"{Assertion}({TestedClassName}.{TestedMethod}({Input}));";
|
16
|
+
case TestedMethodType.Instance:
|
17
|
+
return $"var sut = new {TestedClassName}();\n {Assertion}(sut.{TestedMethod}({Input}));";
|
18
|
+
case TestedMethodType.Extension:
|
19
|
+
return $"{Assertion}({Input}.{TestedMethod}());";
|
20
|
+
default:
|
21
|
+
throw new ArgumentOutOfRangeException();
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
private string Assertion
|
27
|
+
=> $"Assert.{Convert.ToBoolean(TestMethodData.CanonicalDataCase.Expected)}";
|
28
|
+
|
29
|
+
protected override string TestedMethod
|
30
|
+
=> base.TestedMethod.EnsureStartsWith("Is");
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
using System;
|
2
|
+
|
3
|
+
namespace Generators.Methods
|
4
|
+
{
|
5
|
+
public class EqualityTestMethodGenerator : TestMethodGenerator
|
6
|
+
{
|
7
|
+
protected override string Body
|
8
|
+
{
|
9
|
+
get
|
10
|
+
{
|
11
|
+
switch (TestMethodData.Options.TestedMethodType)
|
12
|
+
{
|
13
|
+
case TestedMethodType.Static:
|
14
|
+
return $"Assert.Equal({Expected}, {TestedClassName}.{TestedMethod}({Input}));";
|
15
|
+
case TestedMethodType.Instance:
|
16
|
+
return $"var sut = new {TestedClassName}();\n Assert.Equal({Expected}, sut.{TestedMethod}({Input}));";
|
17
|
+
case TestedMethodType.Extension:
|
18
|
+
return $"Assert.Equal({Expected}, {Input}.{TestedMethod}());";
|
19
|
+
default:
|
20
|
+
throw new ArgumentOutOfRangeException();
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Collections.Generic;
|
3
|
+
|
4
|
+
namespace Generators.Methods
|
5
|
+
{
|
6
|
+
public class ExceptionTestMethodGenerator : TestMethodGenerator
|
7
|
+
{
|
8
|
+
protected override string Body
|
9
|
+
{
|
10
|
+
get
|
11
|
+
{
|
12
|
+
switch (TestMethodData.Options.TestedMethodType)
|
13
|
+
{
|
14
|
+
case TestedMethodType.Static:
|
15
|
+
return $"Assert.Throws<{ExceptionType}>(() => {TestedClassName}.{TestedMethod}({Input}));";
|
16
|
+
case TestedMethodType.Instance:
|
17
|
+
return $"var sut = new {TestedClassName}();\n Assert.Throws<{ExceptionType}>(() => sut.{TestedMethod}({Input}));;";
|
18
|
+
case TestedMethodType.Extension:
|
19
|
+
return $"Assert.Throws<{ExceptionType}>(() => {Input}.{TestedMethod}());";
|
20
|
+
default:
|
21
|
+
throw new ArgumentOutOfRangeException();
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
protected override ISet<string> UsingNamespaces => new HashSet<string> { TestMethodData.Options.ExceptionType.Namespace };
|
27
|
+
|
28
|
+
protected virtual string ExceptionType => TestMethodData.Options.ExceptionType.Name;
|
29
|
+
}
|
30
|
+
}
|
@@ -1,9 +1,12 @@
|
|
1
|
-
|
1
|
+
using System.Collections.Generic;
|
2
|
+
|
3
|
+
namespace Generators.Methods
|
2
4
|
{
|
3
5
|
public class TestMethod
|
4
6
|
{
|
5
|
-
public
|
7
|
+
public ISet<string> UsingNamespaces { get; set; } = new HashSet<string>();
|
6
8
|
public string MethodName { get; set; }
|
7
9
|
public string Body { get; set; }
|
10
|
+
public int Index { get; set; }
|
8
11
|
}
|
9
|
-
}
|
12
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
using Generators.Data;
|
2
|
+
|
3
|
+
namespace Generators.Methods
|
4
|
+
{
|
5
|
+
public class TestMethodData
|
6
|
+
{
|
7
|
+
public CanonicalData CanonicalData { get; set; }
|
8
|
+
public CanonicalDataCase CanonicalDataCase { get; set;}
|
9
|
+
public int Index { get; set; }
|
10
|
+
public TestMethodOptions Options { get; set; } = new TestMethodOptions();
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
using System.Collections.Generic;
|
2
|
+
using Humanizer;
|
3
|
+
using To = Generators.Helpers.To;
|
4
|
+
|
5
|
+
namespace Generators.Methods
|
6
|
+
{
|
7
|
+
public abstract class TestMethodGenerator
|
8
|
+
{
|
9
|
+
public TestMethod Create(TestMethodData testMethodData)
|
10
|
+
{
|
11
|
+
TestMethodData = testMethodData;
|
12
|
+
|
13
|
+
return new TestMethod
|
14
|
+
{
|
15
|
+
MethodName = MethodName,
|
16
|
+
Body = Body,
|
17
|
+
Index = TestMethodData.Index,
|
18
|
+
UsingNamespaces = UsingNamespaces
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
protected TestMethodData TestMethodData { get; private set; }
|
23
|
+
|
24
|
+
protected abstract string Body { get; }
|
25
|
+
|
26
|
+
protected virtual ISet<string> UsingNamespaces
|
27
|
+
=> new HashSet<string>();
|
28
|
+
|
29
|
+
protected virtual string MethodName
|
30
|
+
=> TestMethodData.CanonicalDataCase.Description.Replace(":", " is").Transform(To.TestMethodName);
|
31
|
+
|
32
|
+
protected virtual string TestedClassName
|
33
|
+
=> TestMethodData.CanonicalData.Exercise.Transform(To.TestedClassName);
|
34
|
+
|
35
|
+
protected virtual string TestedMethod
|
36
|
+
=> TestMethodData.CanonicalDataCase.Property.Transform(To.TestedMethodName);
|
37
|
+
|
38
|
+
protected virtual object Input =>
|
39
|
+
TestMethodData.Options.FormatInput
|
40
|
+
? FormatValue(InputValue)
|
41
|
+
: InputValue;
|
42
|
+
|
43
|
+
protected virtual object Expected =>
|
44
|
+
TestMethodData.Options.FormatExpected
|
45
|
+
? FormatValue(TestMethodData.CanonicalDataCase.Expected)
|
46
|
+
: TestMethodData.CanonicalDataCase.Expected;
|
47
|
+
|
48
|
+
protected virtual object InputValue
|
49
|
+
=> TestMethodData.Options.InputProperty == null
|
50
|
+
? TestMethodData.CanonicalDataCase.Input
|
51
|
+
: TestMethodData.CanonicalDataCase.Data[TestMethodData.Options.InputProperty];
|
52
|
+
|
53
|
+
protected virtual object FormatValue(object val)
|
54
|
+
{
|
55
|
+
switch (val)
|
56
|
+
{
|
57
|
+
case string s:
|
58
|
+
return $"\"{s}\"";
|
59
|
+
default:
|
60
|
+
return val;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
using System.Text.RegularExpressions;
|
2
|
+
using Humanizer;
|
3
|
+
|
4
|
+
namespace Generators.Methods
|
5
|
+
{
|
6
|
+
public class TestMethodNameTransformer : IStringTransformer
|
7
|
+
{
|
8
|
+
public string Transform(string input)
|
9
|
+
{
|
10
|
+
var methodName = Regex.Replace(input, @"[^\w]+", "_", RegexOptions.Compiled)
|
11
|
+
.Underscore()
|
12
|
+
.Transform(To.TitleCase);
|
13
|
+
|
14
|
+
if (char.IsDigit(methodName[0]))
|
15
|
+
return "Number_" + methodName;
|
16
|
+
|
17
|
+
if (!char.IsLetter(methodName[0]))
|
18
|
+
return "Test_";
|
19
|
+
|
20
|
+
return methodName;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
using System;
|
2
|
+
|
3
|
+
namespace Generators.Methods
|
4
|
+
{
|
5
|
+
public class TestMethodOptions
|
6
|
+
{
|
7
|
+
public string InputProperty { get; set; }
|
8
|
+
public bool FormatInput { get; set; } = true;
|
9
|
+
public bool FormatExpected { get; set; } = true;
|
10
|
+
public Type ExceptionType { get; set; } = typeof(ArgumentException);
|
11
|
+
public TestedMethodType TestedMethodType { get; set; } = TestedMethodType.Static;
|
12
|
+
}
|
13
|
+
}
|
data/tracks/elixir/config.json
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
For generating random numbers, Erlang's `:rand.uniform` or `Enum.random` are
|
2
|
+
good places to start.
|
3
|
+
|
4
|
+
`:math.pow |> round` can be used to find the power of a number, and `rem` for
|
5
|
+
the modulus.
|
6
|
+
|
7
|
+
Neither of those works particularly well (or quickly) for very large integers.
|
8
|
+
Cryptography generally makes use of numbers larger than 1024 bits. Erlang's
|
9
|
+
:crypto module has a useful function for finding the modulus of a power,
|
10
|
+
particularly for enormous integers, but you might need :binary to decode it.
|
@@ -0,0 +1,61 @@
|
|
1
|
+
defmodule DiffieHellman do
|
2
|
+
@moduledoc """
|
3
|
+
Diffie-Hellman is a method of securely exchanging keys in a public-key
|
4
|
+
cryptosystem. Two users, Alice and Bob, want to share a secret between
|
5
|
+
themselves, while ensuring nobody else can read it.
|
6
|
+
|
7
|
+
Step 0: Alice and Bob agree on two prime numbers, P and G. An attacker, Eve,
|
8
|
+
can intercept these numbers, but without one of Alice or Bob's private keys,
|
9
|
+
we'll see Eve can't do anything useful with them.
|
10
|
+
|
11
|
+
Step 1: Alice and Bob each generate a private key between 1 and P-1.
|
12
|
+
P).
|
13
|
+
|
14
|
+
Step 2: Using the initial primes P and G, Alice and Bob calculate their
|
15
|
+
public keys by raising G to the power of their private key, then calculating
|
16
|
+
the modulus of that number by P. ((G**private_key) % P)
|
17
|
+
|
18
|
+
Step 3: Alice and Bob exchange public keys. Alice and Bob calculate a secret
|
19
|
+
shared key by raising the other's public key to the power of their private
|
20
|
+
key, then doing a modulus of the result by P. Due to the way modulus math
|
21
|
+
works, they should both generate the same shared key.
|
22
|
+
|
23
|
+
Alice calculates: (bob_public ** alice_private) % P
|
24
|
+
Bob calculates: (alice_public ** bob_private) % P
|
25
|
+
|
26
|
+
As long as their private keys are never lost or transmitted, only they know
|
27
|
+
their private keys, so even if Eve has P, G, and both public keys, she can't
|
28
|
+
do anything with them.
|
29
|
+
|
30
|
+
A video example is available at:
|
31
|
+
https://www.khanacademy.org/computing/computer-science/cryptography/modern-crypt/v/diffie-hellman-key-exchange-part-2
|
32
|
+
"""
|
33
|
+
|
34
|
+
@doc """
|
35
|
+
Given a prime integer `prime_p`, return a random integer between 1 and `prime_p` - 1
|
36
|
+
"""
|
37
|
+
@spec generate_private_key(prime_p :: integer) :: integer
|
38
|
+
def generate_private_key(prime_p) do
|
39
|
+
end
|
40
|
+
|
41
|
+
@doc """
|
42
|
+
Given two prime integers as generators (`prime_p` and `prime_g`), and a private key,
|
43
|
+
generate a public key using the mathematical formula:
|
44
|
+
|
45
|
+
(prime_g ** private_key) % prime_p
|
46
|
+
"""
|
47
|
+
@spec generate_public_key(prime_p :: integer, prime_g :: integer, private_key :: integer) :: integer
|
48
|
+
def generate_public_key(prime_p, prime_g, private_key) do
|
49
|
+
end
|
50
|
+
|
51
|
+
@doc """
|
52
|
+
Given a prime integer `prime_p`, user B's public key, and user A's private key,
|
53
|
+
generate a shared secret using the mathematical formula:
|
54
|
+
|
55
|
+
(public_key_b ** private_key_a) % prime_p
|
56
|
+
"""
|
57
|
+
@spec generate_shared_secret(prime_p :: integer, public_key_b :: integer, private_key_a :: integer) :: integer
|
58
|
+
def generate_shared_secret(prime_p, public_key_b, private_key_a) do
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|