trackler 2.2.1.27 → 2.2.1.28
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/problem-specifications/exercises/palindrome-products/canonical-data.json +138 -0
- data/tracks/csharp/exercises/book-store/BookStoreTest.cs +26 -26
- data/tracks/csharp/exercises/complex-numbers/ComplexNumbersTest.cs +38 -38
- data/tracks/csharp/generators/Exercises/AllYourBase.cs +0 -2
- data/tracks/csharp/generators/Exercises/Allergies.cs +5 -23
- data/tracks/csharp/generators/Exercises/Alphametics.cs +6 -9
- data/tracks/csharp/generators/Exercises/Anagram.cs +1 -8
- data/tracks/csharp/generators/Exercises/BinarySearch.cs +2 -7
- data/tracks/csharp/generators/Exercises/BookStore.cs +2 -6
- data/tracks/csharp/generators/Exercises/BracketPush.cs +1 -1
- data/tracks/csharp/generators/Exercises/CollatzConjecture.cs +1 -3
- data/tracks/csharp/generators/Exercises/ComplexNumbers.cs +19 -46
- data/tracks/csharp/generators/Exercises/Convert.cs +7 -0
- data/tracks/csharp/generators/Exercises/CryptoSquare.cs +0 -4
- data/tracks/csharp/generators/Exercises/FoodChain.cs +1 -1
- data/tracks/csharp/generators/Exercises/Gigasecond.cs +5 -13
- data/tracks/csharp/generators/Exercises/Grains.cs +2 -10
- data/tracks/csharp/generators/Exercises/Hamming.cs +0 -2
- data/tracks/csharp/generators/Exercises/House.cs +1 -1
- data/tracks/csharp/generators/Exercises/PerfectNumbers.cs +2 -3
- data/tracks/csharp/generators/Exercises/Poker.cs +0 -3
- data/tracks/csharp/generators/Exercises/QueenAttack.cs +10 -21
- data/tracks/csharp/generators/Exercises/RailFenceCipher.cs +2 -7
- data/tracks/csharp/generators/Exercises/RnaTranscription.cs +0 -2
- data/tracks/csharp/generators/Exercises/SecretHandshake.cs +1 -10
- data/tracks/csharp/generators/Exercises/Sieve.cs +1 -1
- data/tracks/csharp/generators/Exercises/SpaceAge.cs +3 -8
- data/tracks/csharp/generators/Exercises/SumOfMultiples.cs +1 -17
- data/tracks/csharp/generators/Exercises/Transpose.cs +3 -6
- data/tracks/csharp/generators/Exercises/WordCount.cs +6 -9
- data/tracks/csharp/generators/Input/CanonicalDataCase.cs +26 -32
- data/tracks/csharp/generators/Input/CanonicalDataCaseJson.cs +73 -0
- data/tracks/csharp/generators/Input/CanonicalDataCaseJsonConverter.cs +7 -15
- data/tracks/csharp/generators/Input/CanonicalDataCasesJson.cs +58 -0
- data/tracks/csharp/generators/Input/CanonicalDataCasesJsonConverter.cs +3 -11
- data/tracks/csharp/generators/Output/TestMethodBodyData.cs +1 -1
- data/tracks/csharp/generators/Output/ValueFormatter.cs +2 -6
- data/tracks/ecmascript/README.md +1 -1
- data/tracks/go/README.md +3 -3
- data/tracks/go/exercises/robot-simulator/robot_simulator_step2_test.go +4 -4
- data/tracks/go/exercises/roman-numerals/example.go +2 -2
- data/tracks/go/exercises/roman-numerals/roman_numerals_test.go +3 -3
- data/tracks/ocaml/.travis-ci.sh +1 -1
- data/tracks/ocaml/config.json +432 -423
- data/tracks/ocaml/exercises/palindrome-products/.merlin +3 -0
- data/tracks/ocaml/exercises/palindrome-products/Makefile +11 -0
- data/tracks/ocaml/exercises/palindrome-products/README.md +85 -0
- data/tracks/ocaml/exercises/palindrome-products/example.ml +59 -0
- data/tracks/ocaml/exercises/palindrome-products/palindrome_products.mli +22 -0
- data/tracks/ocaml/exercises/palindrome-products/test.ml +58 -0
- data/tracks/ocaml/tools/test-generator/src/ocaml_special_cases.ml +28 -3
- data/tracks/ocaml/tools/test-generator/templates/ocaml/palindrome-products/test.ml +25 -0
- data/tracks/typescript/config.json +160 -112
- metadata +13 -3
- data/tracks/csharp/generators/Exercises/ConvertExtensions.cs +0 -12
@@ -1,5 +1,6 @@
|
|
1
1
|
using System;
|
2
2
|
using System.Collections.Generic;
|
3
|
+
using System.Linq;
|
3
4
|
using Newtonsoft.Json;
|
4
5
|
using Newtonsoft.Json.Linq;
|
5
6
|
|
@@ -7,7 +8,7 @@ namespace Generators.Input
|
|
7
8
|
{
|
8
9
|
public class CanonicalDataCaseJsonConverter : JsonConverter
|
9
10
|
{
|
10
|
-
private static readonly string[] NonInputProperties = {"description", "property", "expected", "comments"};
|
11
|
+
private static readonly string[] NonInputProperties = { "description", "property", "expected", "comments" };
|
11
12
|
|
12
13
|
public override bool CanConvert(Type objectType) => typeof(CanonicalDataCase) == objectType;
|
13
14
|
|
@@ -17,23 +18,14 @@ namespace Generators.Input
|
|
17
18
|
|
18
19
|
var canonicalDataCase = new CanonicalDataCase();
|
19
20
|
serializer.Populate(new JTokenReader(jToken), canonicalDataCase);
|
20
|
-
|
21
|
-
canonicalDataCase.Properties =
|
22
|
-
canonicalDataCase.
|
23
|
-
|
24
|
-
|
21
|
+
|
22
|
+
canonicalDataCase.Properties = CanonicalDataCaseJson.ToDictionary(jToken);
|
23
|
+
canonicalDataCase.SetInputParameters(GetInputProperties(canonicalDataCase.Properties));
|
24
|
+
|
25
25
|
return canonicalDataCase;
|
26
26
|
}
|
27
27
|
|
28
|
-
private static IDictionary<string,
|
29
|
-
{
|
30
|
-
var allProperties = jToken.ToObject<IDictionary<string, object>>();
|
31
|
-
|
32
|
-
foreach (var nonInputProperty in NonInputProperties)
|
33
|
-
allProperties.Remove(nonInputProperty);
|
34
|
-
|
35
|
-
return allProperties;
|
36
|
-
}
|
28
|
+
private static string[] GetInputProperties(IDictionary<string, dynamic> properties) => properties.Keys.Except(NonInputProperties).ToArray();
|
37
29
|
|
38
30
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
|
39
31
|
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Collections.Generic;
|
3
|
+
using System.Linq;
|
4
|
+
using Newtonsoft.Json.Linq;
|
5
|
+
|
6
|
+
namespace Generators.Input
|
7
|
+
{
|
8
|
+
public static class CanonicalDataCasesJson
|
9
|
+
{
|
10
|
+
private const string TokensPath = "$..*[?(@.property)]";
|
11
|
+
|
12
|
+
public static CanonicalDataCase[] ToArray(JToken casesToken)
|
13
|
+
{
|
14
|
+
var caseTokens = new JArray(casesToken.SelectTokens(TokensPath));
|
15
|
+
var canonicalDataCases = new JArray(caseTokens).ToObject<CanonicalDataCase[]>();
|
16
|
+
|
17
|
+
ConvertEmptyJArrayToArray(canonicalDataCases);
|
18
|
+
|
19
|
+
return canonicalDataCases;
|
20
|
+
}
|
21
|
+
|
22
|
+
private static void ConvertEmptyJArrayToArray(CanonicalDataCase[] canonicalDataCases)
|
23
|
+
{
|
24
|
+
foreach (var groupedCanonicalDataCases in canonicalDataCases.ToLookup(c => c.Property))
|
25
|
+
{
|
26
|
+
foreach (var groupedProperties in groupedCanonicalDataCases.SelectMany(x => x.Properties).ToLookup(x => x.Key))
|
27
|
+
{
|
28
|
+
var arrayType = GetArrayType(groupedProperties);
|
29
|
+
if (arrayType == null)
|
30
|
+
continue;
|
31
|
+
|
32
|
+
foreach (var groupedCanonicalDataCase in GetEmptyJArrays(groupedCanonicalDataCases, groupedProperties))
|
33
|
+
groupedCanonicalDataCase.Properties[groupedProperties.Key] = Array.CreateInstance(arrayType, 0);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
private static Type GetArrayType(IGrouping<string, KeyValuePair<string, dynamic>> groupedProperties)
|
39
|
+
{
|
40
|
+
if (groupedProperties.Any(x => x.Value is string[]))
|
41
|
+
return typeof(string);
|
42
|
+
|
43
|
+
if (groupedProperties.Any(x => x.Value is int[]))
|
44
|
+
return typeof(int);
|
45
|
+
|
46
|
+
if (groupedProperties.Any(x => x.Value is float[]))
|
47
|
+
return typeof(float);
|
48
|
+
|
49
|
+
return null;
|
50
|
+
}
|
51
|
+
|
52
|
+
private static IEnumerable<CanonicalDataCase> GetEmptyJArrays(IGrouping<string, CanonicalDataCase> groupedCanonicalDataCases, IGrouping<string, KeyValuePair<string, dynamic>> groupedProperties)
|
53
|
+
=> groupedCanonicalDataCases.Where(canonicalDataCase => IsEmptyJArray(canonicalDataCase, groupedProperties));
|
54
|
+
|
55
|
+
private static bool IsEmptyJArray(CanonicalDataCase x, IGrouping<string, KeyValuePair<string, dynamic>> groupedProperties)
|
56
|
+
=> x.Properties[groupedProperties.Key] is JArray jArray && jArray.Count == 0;
|
57
|
+
}
|
58
|
+
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
using System;
|
2
|
-
using System.Collections.Generic;
|
3
2
|
using System.Reflection;
|
4
3
|
using Newtonsoft.Json;
|
5
4
|
using Newtonsoft.Json.Linq;
|
@@ -8,17 +7,10 @@ namespace Generators.Input
|
|
8
7
|
{
|
9
8
|
public class CanonicalDataCasesJsonConverter : JsonConverter
|
10
9
|
{
|
11
|
-
|
10
|
+
public override bool CanConvert(Type objectType) => typeof(CanonicalDataCase[]).GetTypeInfo().IsAssignableFrom(objectType);
|
12
11
|
|
13
|
-
public override
|
14
|
-
|
15
|
-
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
16
|
-
{
|
17
|
-
var casesToken = JToken.ReadFrom(reader);
|
18
|
-
var caseTokens = new JArray(casesToken.SelectTokens(TokensPath));
|
19
|
-
|
20
|
-
return new JArray(caseTokens).ToObject(objectType);
|
21
|
-
}
|
12
|
+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
13
|
+
=> CanonicalDataCasesJson.ToArray(JToken.ReadFrom(reader));
|
22
14
|
|
23
15
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
|
24
16
|
}
|
@@ -19,7 +19,7 @@ namespace Generators.Output
|
|
19
19
|
}
|
20
20
|
|
21
21
|
public object TestedValue => _testMethodBody.UseVariableForTested ? TestedVariableName : TestedMethodInvocation;
|
22
|
-
public object InputParameters => _testMethodBody.UseVariablesForInput ? string.Join(", ", CanonicalDataCase.Input.Keys.Select(key =>
|
22
|
+
public object InputParameters => _testMethodBody.UseVariablesForInput ? string.Join(", ", CanonicalDataCase.Input.Keys.Select(key => key.ToVariableName())) : Input;
|
23
23
|
public object ExpectedParameter => _testMethodBody.UseVariableForExpected ? ExpectedVariableName : Expected;
|
24
24
|
public object ConstructorParameters => _testMethodBody.UseVariablesForConstructorParameters ? string.Join(", ", CanonicalDataCase.ConstructorInput.Keys.Select(key => key.ToVariableName())) : ConstructorInput;
|
25
25
|
|
@@ -41,8 +41,8 @@ namespace Generators.Output
|
|
41
41
|
}
|
42
42
|
}
|
43
43
|
|
44
|
-
public static string[] FormatVariables(
|
45
|
-
=> dict.Keys.SelectMany(
|
44
|
+
public static string[] FormatVariables(IReadOnlyDictionary<string, object> dict)
|
45
|
+
=> dict.Keys.SelectMany(key => FormatVariable(dict[key], key.ToVariableName())).ToArray();
|
46
46
|
|
47
47
|
public static string[] FormatVariable(object val, string name)
|
48
48
|
{
|
@@ -50,10 +50,6 @@ namespace Generators.Output
|
|
50
50
|
{
|
51
51
|
case string str when str.Contains("\n"):
|
52
52
|
return FormatMultiLineString(name, str);
|
53
|
-
case int[] ints when ints.Any():
|
54
|
-
return FormatMultiLineEnumerable(ints.Select(x => x.ToString(CultureInfo.InvariantCulture)), name);
|
55
|
-
case string[] strings when strings.Any():
|
56
|
-
return FormatMultiLineEnumerable(strings, name);
|
57
53
|
case IDictionary<char, int> dict:
|
58
54
|
return FormatMultiLineEnumerable(dict.Keys.Select((key, i) => $"[{Format(key)}] = {Format(dict[key])}" + (i < dict.Keys.Count - 1 ? "," : "")), name, "new Dictionary<char, int>");
|
59
55
|
case IDictionary<string, int> dict:
|
data/tracks/ecmascript/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# ECMAScript
|
2
2
|
[![Build Status](https://travis-ci.org/exercism/ecmascript.svg?branch=master)](https://travis-ci.org/exercism/ecmascript)
|
3
3
|
[![Join the chat at https://gitter.im/exercism/xecmascript](https://badges.gitter.im/exercism/xecmascript.svg)](https://gitter.im/exercism/xecmascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
4
|
|
data/tracks/go/README.md
CHANGED
@@ -49,7 +49,7 @@ $ tree -a
|
|
49
49
|
.
|
50
50
|
├── cases_test.go
|
51
51
|
├── example.go
|
52
|
-
├──
|
52
|
+
├── fizzbuzz.go
|
53
53
|
├── fizzbuzz_test.go
|
54
54
|
├── .meta
|
55
55
|
│ └── description.md
|
@@ -80,11 +80,11 @@ So let's quickly run through each file and briefly describe it:
|
|
80
80
|
by the `exercism fetch` command. See [ignored files](#ignored-files)
|
81
81
|
for details on which files are ignored.
|
82
82
|
|
83
|
-
* **
|
83
|
+
* **fizzbuzz.go** - This is a *stub file*, and will only be
|
84
84
|
present in some exercises as a way to give users a useful starting
|
85
85
|
point.
|
86
86
|
|
87
|
-
* **
|
87
|
+
* **fizzbuzz_test.go** - This is the main test file for the
|
88
88
|
exercise.
|
89
89
|
|
90
90
|
* **.meta/** - The `.meta/` directory contains files that are not
|
@@ -4,13 +4,13 @@ package robot
|
|
4
4
|
|
5
5
|
import "testing"
|
6
6
|
|
7
|
-
// For step 1 you
|
7
|
+
// For step 1 you implemented robot movements, but it's not much of a simulation.
|
8
8
|
// For example where in the source code is "the robot"? Where is "the grid"?
|
9
9
|
// Where are the computations that turn robot actions into grid positions,
|
10
|
-
// in the robot or in the grid? The physical world is different.
|
10
|
+
// in the robot, or in the grid? The physical world is different.
|
11
11
|
//
|
12
12
|
// Step 2 introduces a "room." It seems a small addition, but we'll make
|
13
|
-
// big changes to clarify the
|
13
|
+
// big changes to clarify the roles of "room", "robot", and "test program"
|
14
14
|
// and begin to clarify the physics of the simulation. You will define Room
|
15
15
|
// and Robot as functions which the test program "brings into existence" by
|
16
16
|
// launching them as goroutines. Information moves between test program,
|
@@ -34,7 +34,7 @@ import "testing"
|
|
34
34
|
// The test program then sends commands to Robot. When it is done sending
|
35
35
|
// commands, it closes the command channel. Robot must accept commands and
|
36
36
|
// inform Room of actions it is attempting. When it senses the command channel
|
37
|
-
// closing, it must shut down
|
37
|
+
// closing, it must shut itself down. The room must interpret the physical
|
38
38
|
// consequences of the robot actions. When it senses the robot shutting down,
|
39
39
|
// it sends a final report back to the test program, telling the robot's final
|
40
40
|
// position and direction.
|
@@ -5,7 +5,7 @@ import (
|
|
5
5
|
"fmt"
|
6
6
|
)
|
7
7
|
|
8
|
-
const testVersion =
|
8
|
+
const testVersion = 4
|
9
9
|
|
10
10
|
type arabicToRoman struct {
|
11
11
|
arabic int
|
@@ -15,7 +15,7 @@ type arabicToRoman struct {
|
|
15
15
|
func ToRomanNumeral(input int) (string, error) {
|
16
16
|
buffer := bytes.NewBufferString("")
|
17
17
|
|
18
|
-
if input <= 0 || input >=
|
18
|
+
if input <= 0 || input >= 3001 {
|
19
19
|
return "", fmt.Errorf("the number %d is undefined in the roman numeral system", input)
|
20
20
|
}
|
21
21
|
|
@@ -2,7 +2,7 @@ package romannumerals
|
|
2
2
|
|
3
3
|
import "testing"
|
4
4
|
|
5
|
-
const targetTestVersion =
|
5
|
+
const targetTestVersion = 4
|
6
6
|
|
7
7
|
func TestTestVersion(t *testing.T) {
|
8
8
|
if testVersion != targetTestVersion {
|
@@ -14,9 +14,9 @@ func TestRomanNumerals(t *testing.T) {
|
|
14
14
|
tc := append(romanNumeralTests, []romanNumeralTest{
|
15
15
|
{0, "", true},
|
16
16
|
{-1, "", true},
|
17
|
-
{
|
18
|
-
{3999, "MMMCMXCIX", false},
|
17
|
+
{3001, "", true},
|
19
18
|
}...)
|
19
|
+
|
20
20
|
for _, test := range tc {
|
21
21
|
actual, err := ToRomanNumeral(test.arabic)
|
22
22
|
if err == nil && test.hasError {
|
data/tracks/ocaml/.travis-ci.sh
CHANGED