trackler 2.2.1.20 → 2.2.1.21

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/csharp/config.json +11 -0
  4. data/tracks/csharp/exercises/Exercises.All.sln +15 -1
  5. data/tracks/csharp/exercises/Exercises.Default.sln +120 -106
  6. data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.cs +53 -0
  7. data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.csproj +18 -0
  8. data/tracks/csharp/exercises/complex-numbers/ComplexNumbersTest.cs +255 -0
  9. data/tracks/csharp/exercises/complex-numbers/Example.cs +78 -0
  10. data/tracks/csharp/exercises/grains/Example.cs +8 -1
  11. data/tracks/csharp/exercises/grains/GrainsTest.cs +38 -17
  12. data/tracks/csharp/generators/Exercises/ComplexNumbers.cs +119 -0
  13. data/tracks/csharp/generators/Exercises/Grains.cs +29 -0
  14. data/tracks/csharp/generators/Output/ValueFormatter.cs +2 -0
  15. data/tracks/delphi/exercises/two-fer/utwoferExample.pas +2 -5
  16. data/tracks/ecmascript/exercises/queen-attack/example.js +28 -23
  17. data/tracks/ecmascript/exercises/queen-attack/queen-attack.spec.js +10 -15
  18. data/tracks/java/config.json +1 -0
  19. data/tracks/r/exercises/perfect-numbers/example.R +1 -1
  20. data/tracks/r/exercises/perfect-numbers/perfect-numbers.R +1 -1
  21. data/tracks/r/exercises/perfect-numbers/test_perfect-numbers.R +13 -13
  22. data/tracks/ruby/docs/24pullrequests.md +1 -1
  23. data/tracks/ruby/exercises/hello-world/.meta/generator/test_template.erb +1 -1
  24. data/tracks/ruby/exercises/hello-world/hello_world_test.rb +1 -1
  25. data/tracks/ruby/test/generator/command_line/generator_optparser_test.rb +1 -1
  26. data/tracks/ruby/test/generator/command_line_test.rb +1 -1
  27. data/tracks/ruby/test/generator/files/metadata_files_test.rb +1 -1
  28. data/tracks/rust/exercises/accumulate/README.md +0 -3
  29. data/tracks/rust/exercises/beer-song/src/lib.rs +7 -0
  30. data/tracks/rust/exercises/bob/src/lib.rs +3 -0
  31. data/tracks/rust/exercises/bowling/example.rs +1 -1
  32. data/tracks/rust/exercises/difference-of-squares/src/lib.rs +11 -0
  33. data/tracks/rust/exercises/grade-school/example.rs +1 -1
  34. data/tracks/rust/exercises/leap/src/lib.rs +3 -0
  35. data/tracks/rust/exercises/proverb/src/lib.rs +3 -0
  36. data/tracks/rust/exercises/raindrops/src/lib.rs +3 -0
  37. data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +3 -0
  38. data/tracks/scala/exercises/space-age/example.scala +26 -20
  39. data/tracks/scala/exercises/space-age/src/main/scala/.keep +0 -0
  40. data/tracks/scala/exercises/space-age/src/test/scala/SpaceAgeTest.scala +19 -38
  41. data/tracks/scala/exercises/sublist/src/test/scala/SublistTest.scala +36 -44
  42. data/tracks/scala/testgen/src/main/scala/SpaceAgeTestGenerator.scala +39 -0
  43. data/tracks/scala/testgen/src/main/scala/SublistTestGenerator.scala +38 -0
  44. metadata +11 -3
  45. data/tracks/scala/exercises/space-age/src/main/scala/SpaceAge.scala +0 -10
@@ -0,0 +1,119 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Linq;
4
+ using Generators.Input;
5
+ using Generators.Output;
6
+ using Newtonsoft.Json.Linq;
7
+
8
+ namespace Generators.Exercises
9
+ {
10
+ public class ComplexNumbers : Exercise
11
+ {
12
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
13
+ {
14
+ canonicalData.Exercise = "complex-number";
15
+
16
+ // Ensure the Real and Imaginary methods are tested first as they're used later to assert equality between complex numbers
17
+ canonicalData.Cases = canonicalData.Cases.OrderBy(c => c.Property == "real" || c.Property == "imaginary" ? 0 : 1).ToArray();
18
+
19
+ foreach (var canonicalDataCase in canonicalData.Cases)
20
+ {
21
+ canonicalDataCase.TestedMethodType = TestedMethodType.Instance;
22
+
23
+ // Process expected
24
+ if (IsComplexNumber(canonicalDataCase.Expected))
25
+ {
26
+ canonicalDataCase.UseVariableForExpected = true;
27
+ }
28
+
29
+ canonicalDataCase.Expected = ConvertToType(canonicalDataCase.Expected);
30
+
31
+ // Process constructor param
32
+ var constructorParamName = canonicalDataCase.Input.ContainsKey("input") ? "input" : "z1";
33
+
34
+ var constructorParamValues = canonicalDataCase.Input[constructorParamName]
35
+ .ConvertToEnumerable<string>()
36
+ .Select(v => ConvertMathDouble(v))
37
+ .ToArray();
38
+
39
+ canonicalDataCase.ConstructorInput = new Dictionary<string, object>
40
+ {
41
+ ["real"] = constructorParamValues[0],
42
+ ["imaginary"] = constructorParamValues[1]
43
+ };
44
+
45
+ canonicalDataCase.Input.Remove(constructorParamName);
46
+
47
+ // Process function param
48
+ var keys = canonicalDataCase.Input.Keys.ToArray();
49
+
50
+ foreach (var key in keys)
51
+ {
52
+ canonicalDataCase.Input[key] = ConvertToType(canonicalDataCase.Input[key]);
53
+ }
54
+ }
55
+ }
56
+
57
+ protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody)
58
+ {
59
+ if (testMethodBody.UseVariableForExpected)
60
+ return RenderComplexNumberAssert(testMethodBody);
61
+
62
+ return base.RenderTestMethodBodyAssert(testMethodBody);
63
+ }
64
+
65
+ private static string RenderComplexNumberAssert(TestMethodBody testMethodBody)
66
+ {
67
+ var tmeplate = "Assert.Equal({{ ExpectedParameter }}.Real(), {{ TestedValue }}.Real(), 15);\r\nAssert.Equal({{ ExpectedParameter }}.Imaginary(), {{ TestedValue }}.Imaginary(), 15);";
68
+
69
+ return TemplateRenderer.RenderInline(tmeplate, testMethodBody.AssertTemplateParameters);
70
+ }
71
+
72
+ protected override HashSet<string> GetUsingNamespaces()
73
+ {
74
+ var usingNamespaces = base.GetUsingNamespaces();
75
+ usingNamespaces.Add(typeof(Math).Namespace);
76
+
77
+ return usingNamespaces;
78
+ }
79
+
80
+ private object ConvertToType(object rawValue)
81
+ {
82
+ if (IsComplexNumber(rawValue))
83
+ {
84
+ var array = rawValue
85
+ .ConvertToEnumerable<string>()
86
+ .Select(rv => ConvertToType(rv))
87
+ .ToArray();
88
+
89
+ return new UnescapedValue($"new ComplexNumber({array[0]}, {array[1]})");
90
+ }
91
+ else if (rawValue is string)
92
+ {
93
+ return ConvertMathDouble((string)rawValue);
94
+ }
95
+ else
96
+ {
97
+ return rawValue;
98
+ }
99
+ }
100
+
101
+ private bool IsComplexNumber(object rawValue)
102
+ {
103
+ return rawValue is JArray;
104
+ }
105
+
106
+ private object ConvertMathDouble(string value)
107
+ {
108
+ switch (value)
109
+ {
110
+ case "e":
111
+ return new UnescapedValue("Math.E");
112
+ case "pi":
113
+ return new UnescapedValue("Math.PI");
114
+ default:
115
+ return double.Parse(value);
116
+ }
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,29 @@
1
+ using System;
2
+ using Generators.Input;
3
+
4
+ namespace Generators.Exercises
5
+ {
6
+ public class Grains : Exercise
7
+ {
8
+ protected override void UpdateCanonicalData(CanonicalData canonicalData)
9
+ {
10
+ foreach (var canonicalDataCase in canonicalData.Cases)
11
+ {
12
+ if (ShouldThrowException(canonicalDataCase.Expected))
13
+ {
14
+ canonicalDataCase.ExceptionThrown = typeof(ArgumentOutOfRangeException);
15
+ }
16
+ else
17
+ {
18
+ canonicalDataCase.Expected = ulong.Parse(canonicalDataCase.Expected.ToString());
19
+ }
20
+ }
21
+ }
22
+
23
+ private static bool ShouldThrowException(object value)
24
+ {
25
+ return int.TryParse(value.ToString(), out int result)
26
+ && result == -1;
27
+ }
28
+ }
29
+ }
@@ -32,6 +32,8 @@ public static object Format(object val)
32
32
  return dbl.ToString(CultureInfo.InvariantCulture);
33
33
  case float flt:
34
34
  return flt.ToString(CultureInfo.InvariantCulture);
35
+ case ulong ulng:
36
+ return $"{ulng}UL";
35
37
  case char c:
36
38
  return $"'{c}'";
37
39
  default:
@@ -2,15 +2,12 @@ unit utwofer;
2
2
 
3
3
  interface
4
4
 
5
- function twoFer(aName: string=''): string;
5
+ function twoFer(aName: string='you'): string;
6
6
 
7
7
  implementation
8
- uses SysUtils;
9
8
 
10
- function twoFer(aName: string=''): string;
9
+ function twoFer(aName: string='you'): string;
11
10
  begin
12
- if trim(aName).IsEmpty then
13
- aName := 'you';
14
11
  result := 'One for ' + aName + ', one for me.';
15
12
  end;
16
13
 
@@ -1,10 +1,34 @@
1
- const W = 8,
2
- H = 8,
3
- STARTING = { black: [7, 3], white: [0, 3] };
1
+ const W = 8;
2
+ const H = 8;
3
+ const STARTING = { black: [7, 3], white: [0, 3] };
4
+
5
+ function samePosition({ white, black }) {
6
+ return white[0] === black[0] && white[1] === black[1];
7
+ }
8
+
9
+ function buildRow(cell, colCount) {
10
+ return Array(...Array(colCount)).map(() => cell);
11
+ }
12
+
13
+ function concatRows(row, rowCount) {
14
+ return [...Array.prototype.concat.apply(buildRow(row, rowCount)).join('')];
15
+ }
16
+
17
+ function constructBoard() {
18
+ let row = buildRow('_ ', W).join('');
19
+ row = `${row.substring(0, row.length - 1)}\n`;
20
+ return concatRows(row, H);
21
+ }
22
+
23
+ function placePieces(self) {
24
+ const board = self.board;
25
+ board[(self.black[0] * W * 2) + (self.black[1] * 2)] = 'B';
26
+ board[(self.white[0] * W * 2) + (self.white[1] * 2)] = 'W';
27
+ }
4
28
 
5
29
  const QueenAttack = (params = STARTING) => {
6
30
  const self = this instanceof QueenAttack ? this : Object.getPrototypeOf(QueenAttack);
7
- if (params && params.white === params.black) {
31
+ if (samePosition(params)) {
8
32
  throw new Error('Queens cannot share the same space');
9
33
  }
10
34
 
@@ -25,23 +49,4 @@ const QueenAttack = (params = STARTING) => {
25
49
  return self;
26
50
  };
27
51
 
28
- function constructBoard() {
29
- let row = buildRow('_ ', W).join('');
30
- row = `${row.substring(0, row.length - 1)}\n`;
31
- return concatRows(row, H);
32
- }
33
-
34
- function placePieces(self) {
35
- self.board[self.black[0] * W * 2 + self.black[1] * 2] = 'B';
36
- self.board[self.white[0] * W * 2 + self.white[1] * 2] = 'W';
37
- }
38
-
39
- function buildRow(cell, colCount) {
40
- return Array(...Array(colCount)).map(() => cell);
41
- }
42
-
43
- function concatRows(row, rowCount) {
44
- return [...Array.prototype.concat.apply(buildRow(row, rowCount)).join('')];
45
- }
46
-
47
52
  export default QueenAttack;
@@ -15,26 +15,21 @@ describe('Queens', () => {
15
15
 
16
16
  xtest('cannot occupy the same space', () => {
17
17
  const positioning = { white: [2, 4], black: [2, 4] };
18
-
19
- try {
20
- new Queens(positioning);
21
- } catch (error) {
22
- expect(error).toEqual('Queens cannot share the same space');
23
- }
18
+ const expectedError = 'Queens cannot share the same space';
19
+ expect(() => new Queens(positioning)).toThrow(expectedError);
24
20
  });
25
21
 
26
22
  xtest('toString representation', () => {
27
23
  const positioning = { white: [2, 4], black: [6, 6] };
28
24
  const queens = new Queens(positioning);
29
- const board = '_ _ _ _ _ _ _ _\n\
30
- _ _ _ _ _ _ _ _\n\
31
- _ _ _ _ W _ _ _\n\
32
- _ _ _ _ _ _ _ _\n\
33
- _ _ _ _ _ _ _ _\n\
34
- _ _ _ _ _ _ _ _\n\
35
- _ _ _ _ _ _ B _\n\
36
- _ _ _ _ _ _ _ _\n\
37
- ';
25
+ const board = ['_ _ _ _ _ _ _ _',
26
+ '_ _ _ _ _ _ _ _',
27
+ '_ _ _ _ W _ _ _',
28
+ '_ _ _ _ _ _ _ _',
29
+ '_ _ _ _ _ _ _ _',
30
+ '_ _ _ _ _ _ _ _',
31
+ '_ _ _ _ _ _ B _',
32
+ '_ _ _ _ _ _ _ _\n'].join('\n');
38
33
  expect(queens.toString()).toEqual(board);
39
34
  });
40
35
 
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "language": "Java",
3
3
  "active": true,
4
+ "blurb": "Java is a very widely used Object Oriented programming language. It's safe, simple to use and portable so that you can \"write once, run anywhere\".",
4
5
  "exercises": [
5
6
  {
6
7
  "uuid": "f77dc7e3-35a8-4300-a7c8-2c1765e9644d",
@@ -1,4 +1,4 @@
1
- is_perfect <- function(n){
1
+ number_type <- function(n){
2
2
 
3
3
  # catch invalid input
4
4
  if (n <= 0)
@@ -1,3 +1,3 @@
1
- is_perfect <- function(n){
1
+ number_type <- function(n){
2
2
 
3
3
  }
@@ -3,73 +3,73 @@ library(testthat)
3
3
 
4
4
  test_that("Smallest perfect number is classified correctly", {
5
5
  n <- 6
6
- expect_equal(is_perfect(n), "perfect")
6
+ expect_equal(number_type(n), "perfect")
7
7
  })
8
8
 
9
9
  test_that("Medium perfect number is classified correctly", {
10
10
  n <- 28
11
- expect_equal(is_perfect(n), "perfect")
11
+ expect_equal(number_type(n), "perfect")
12
12
  })
13
13
 
14
14
  test_that("Large perfect number is classified correctly", {
15
15
  n <- 33550336
16
- expect_equal(is_perfect(n), "perfect")
16
+ expect_equal(number_type(n), "perfect")
17
17
  })
18
18
 
19
19
 
20
20
 
21
21
  test_that("Smallest abundant number is classified correctly", {
22
22
  n <- 12
23
- expect_equal(is_perfect(n), "abundant")
23
+ expect_equal(number_type(n), "abundant")
24
24
  })
25
25
 
26
26
  test_that("Medium abundant number is classified correctly", {
27
27
  n <- 30
28
- expect_equal(is_perfect(n), "abundant")
28
+ expect_equal(number_type(n), "abundant")
29
29
  })
30
30
 
31
31
  test_that("Large abundant number is classified correctly", {
32
32
  n <- 33550335
33
- expect_equal(is_perfect(n), "abundant")
33
+ expect_equal(number_type(n), "abundant")
34
34
  })
35
35
 
36
36
 
37
37
 
38
38
  test_that("Smallest prime deficient number is classified correctly", {
39
39
  n <- 2
40
- expect_equal(is_perfect(n), "deficient")
40
+ expect_equal(number_type(n), "deficient")
41
41
  })
42
42
 
43
43
  test_that("Smallest non-prime deficient number is classified correctly", {
44
44
  n <- 4
45
- expect_equal(is_perfect(n), "deficient")
45
+ expect_equal(number_type(n), "deficient")
46
46
  })
47
47
 
48
48
  test_that("Medium deficient number is classified correctly", {
49
49
  n <- 32
50
- expect_equal(is_perfect(n), "deficient")
50
+ expect_equal(number_type(n), "deficient")
51
51
  })
52
52
 
53
53
  test_that("Large deficient number is classified correctly", {
54
54
  n <- 33550337
55
- expect_equal(is_perfect(n), "deficient")
55
+ expect_equal(number_type(n), "deficient")
56
56
  })
57
57
 
58
58
  test_that("Edge case (no factors other than itself) is classified correctly", {
59
59
  n <- 1
60
- expect_equal(is_perfect(n), "deficient")
60
+ expect_equal(number_type(n), "deficient")
61
61
  })
62
62
 
63
63
 
64
64
 
65
65
  test_that("Zero is rejected (not a natural number)", {
66
66
  n <- 0
67
- expect_error(is_perfect(n))
67
+ expect_error(number_type(n))
68
68
  })
69
69
 
70
70
  test_that("Negative integer is rejected (not a natural number)", {
71
71
  n <- -1
72
- expect_error(is_perfect(n))
72
+ expect_error(number_type(n))
73
73
  })
74
74
 
75
75
 
@@ -18,4 +18,4 @@ Something missing? Create a pull request!
18
18
 
19
19
  Check out the [Getting Involved in a Track](https://github.com/exercism/exercism.io/blob/master/docs/getting-involved-in-a-track.md) documentation, and some [ideas for things we are looking for](http://exercism.io/languages/ruby/todo) for exercises that are needed to be implemented.
20
20
 
21
- We are available to answer questions in the [![Join the chat at https://gitter.im/exercism/ruby](https://badges.gitter.im/exercism/ruby.svg)](https://gitter.im/exercism/ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge).
21
+ We are available to answer questions in the [![Join the chat at https://gitter.im/exercism/ruby](https://badges.gitter.im/exercism/ruby.svg)](https://gitter.im/exercism/ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge).
@@ -4,7 +4,7 @@ begin
4
4
  require_relative 'hello_world'
5
5
  rescue Gem::LoadError => e
6
6
  puts "\nMissing Dependency:\n#{e.backtrace.first} #{e.message}"
7
- puts 'Minitest 5.0 gem must be installed for the xRuby track.'
7
+ puts 'Minitest 5.0 gem must be installed for the Ruby track.'
8
8
  rescue LoadError => e
9
9
  puts "\nError:\n#{e.backtrace.first} #{e.message}"
10
10
  puts DATA.read
@@ -4,7 +4,7 @@ begin
4
4
  require_relative 'hello_world'
5
5
  rescue Gem::LoadError => e
6
6
  puts "\nMissing Dependency:\n#{e.backtrace.first} #{e.message}"
7
- puts 'Minitest 5.0 gem must be installed for the xRuby track.'
7
+ puts 'Minitest 5.0 gem must be installed for the Ruby track.'
8
8
  rescue LoadError => e
9
9
  puts "\nError:\n#{e.backtrace.first} #{e.message}"
10
10
  puts DATA.read
@@ -4,7 +4,7 @@ module Generator
4
4
  class GeneratorOptparserTest < Minitest::Test
5
5
  FixturePaths = Paths.new(
6
6
  metadata: 'test/fixtures/metadata',
7
- track: 'test/fixtures/xruby'
7
+ track: 'test/fixtures/ruby'
8
8
  )
9
9
 
10
10
  def default_options
@@ -4,7 +4,7 @@ module Generator
4
4
  class CommandLineTest < Minitest::Test
5
5
  FixturePaths = Paths.new(
6
6
  metadata: 'test/fixtures/metadata',
7
- track: 'test/fixtures/xruby'
7
+ track: 'test/fixtures/ruby'
8
8
  )
9
9
 
10
10
  def test_parse
@@ -4,7 +4,7 @@ module Generator
4
4
  class MetadataFilesTest < Minitest::Test
5
5
  FixturePaths = Paths.new(
6
6
  metadata: 'test/fixtures/metadata',
7
- track: 'test/fixtures/xruby'
7
+ track: 'test/fixtures/ruby'
8
8
  )
9
9
 
10
10
  class TestMetadataFiles