trackler 2.2.1.43 → 2.2.1.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/lens-person/description.md +1 -1
  4. data/problem-specifications/exercises/palindrome-products/description.md +5 -12
  5. data/problem-specifications/exercises/pascals-triangle/canonical-data.json +1 -7
  6. data/tracks/c/exercises/meetup/src/example.c +64 -60
  7. data/tracks/c/exercises/meetup/src/example.h +2 -2
  8. data/tracks/c/exercises/meetup/test/test_meetup.c +4 -4
  9. data/tracks/cfml/config.json +179 -169
  10. data/tracks/cfml/exercises/markdown/.meta/HINTS.md +0 -0
  11. data/tracks/cfml/exercises/markdown/Markdown.cfc +121 -0
  12. data/tracks/cfml/exercises/markdown/MarkdownTest.cfc +51 -0
  13. data/tracks/cfml/exercises/markdown/Solution.cfc +204 -0
  14. data/tracks/cfml/exercises/markdown/SolutionTest.cfc +7 -0
  15. data/tracks/cfml/exercises/markdown/TestRunner.cfc +103 -0
  16. data/tracks/cfml/exercises/markdown/box.json +8 -0
  17. data/tracks/cfml/exercises/markdown/index.cfm +37 -0
  18. data/tracks/csharp/exercises/dominoes/DominoesTest.cs +40 -45
  19. data/tracks/csharp/exercises/meetup/MeetupTest.cs +761 -83
  20. data/tracks/csharp/generators/Exercises/Dominoes.cs +33 -0
  21. data/tracks/csharp/generators/Exercises/Meetup.cs +46 -0
  22. data/tracks/csharp/generators/Output/FormattingExtensions.cs +11 -1
  23. data/tracks/csharp/generators/Output/TypesExtensions.cs +23 -0
  24. data/tracks/csharp/generators/Output/ValueFormatter.cs +70 -69
  25. data/tracks/dart/config.json +15 -3
  26. data/tracks/dart/exercises/word-count/README.md +18 -0
  27. data/tracks/dart/exercises/word-count/lib/example.dart +26 -0
  28. data/tracks/dart/exercises/word-count/lib/word_count.dart +3 -0
  29. data/tracks/dart/exercises/word-count/pubspec.lock +293 -0
  30. data/tracks/dart/exercises/word-count/pubspec.yaml +3 -0
  31. data/tracks/dart/exercises/word-count/test/word_count_test.dart +64 -0
  32. data/tracks/ecmascript/docs/INSTALLATION.md +4 -7
  33. data/tracks/elixir/exercises/hello-world/README.md +1 -26
  34. data/tracks/elixir/exercises/hello-world/example.exs +3 -7
  35. data/tracks/elixir/exercises/hello-world/hello_world.exs +3 -25
  36. data/tracks/elixir/exercises/hello-world/hello_world_test.exs +2 -13
  37. data/tracks/elixir/mix.lock +1 -1
  38. data/tracks/elm/config.json +11 -0
  39. data/tracks/elm/exercises/pascals-triangle/README.md +51 -0
  40. data/tracks/elm/exercises/pascals-triangle/Triangle.elm +1 -0
  41. data/tracks/elm/exercises/pascals-triangle/Triangle.example.elm +23 -0
  42. data/tracks/elm/exercises/pascals-triangle/elm-package.json +14 -0
  43. data/tracks/elm/exercises/pascals-triangle/package.json +14 -0
  44. data/tracks/elm/exercises/pascals-triangle/tests/Tests.elm +34 -0
  45. data/tracks/elm/exercises/pascals-triangle/tests/elm-package.json +16 -0
  46. data/tracks/fsharp/exercises/grade-school/GradeSchool.fs +2 -2
  47. data/tracks/fsharp/exercises/grade-school/GradeSchoolTest.fs +3 -2
  48. data/tracks/java/CONTRIBUTING.md +34 -0
  49. data/tracks/java/config.json +42 -6
  50. data/tracks/java/exercises/largest-series-product/src/main/java/LargestSeriesProductCalculator.java +7 -3
  51. data/tracks/java/exercises/matrix/src/main/java/Matrix.java +23 -0
  52. data/tracks/julia/config.json +11 -2
  53. data/tracks/julia/exercises/grains/README.md +33 -0
  54. data/tracks/julia/exercises/grains/example.jl +23 -0
  55. data/tracks/julia/exercises/grains/grains.jl +9 -0
  56. data/tracks/julia/exercises/grains/runtests.jl +27 -0
  57. data/tracks/lua/README.md +1 -1
  58. data/tracks/mips/exercises/octal/README.md +3 -8
  59. data/tracks/ocaml/exercises/palindrome-products/README.md +8 -14
  60. data/tracks/perl6/.travis.yml +7 -3
  61. data/tracks/perl6/bin/exercise-gen.pl6 +5 -1
  62. data/tracks/perl6/exercises/accumulate/README.md +0 -3
  63. data/tracks/perl6/exercises/accumulate/accumulate.t +9 -3
  64. data/tracks/perl6/exercises/all-your-base/README.md +1 -1
  65. data/tracks/perl6/exercises/all-your-base/all-your-base.t +23 -11
  66. data/tracks/perl6/exercises/all-your-base/example.yaml +1 -1
  67. data/tracks/perl6/exercises/allergies/README.md +0 -1
  68. data/tracks/perl6/exercises/allergies/allergies.t +22 -10
  69. data/tracks/perl6/exercises/anagram/anagram.t +22 -10
  70. data/tracks/perl6/exercises/atbash-cipher/README.md +2 -1
  71. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +22 -10
  72. data/tracks/perl6/exercises/binary/README.md +2 -0
  73. data/tracks/perl6/exercises/bob/bob.t +24 -11
  74. data/tracks/perl6/exercises/bob/example.yaml +2 -2
  75. data/tracks/perl6/exercises/clock/clock.t +22 -10
  76. data/tracks/perl6/exercises/flatten-array/README.md +1 -2
  77. data/tracks/perl6/exercises/flatten-array/example.yaml +1 -1
  78. data/tracks/perl6/exercises/flatten-array/flatten-array.t +23 -11
  79. data/tracks/perl6/exercises/grade-school/README.md +0 -1
  80. data/tracks/perl6/exercises/grade-school/grade-school.t +9 -3
  81. data/tracks/perl6/exercises/grains/README.md +0 -1
  82. data/tracks/perl6/exercises/grains/grains.t +22 -10
  83. data/tracks/perl6/exercises/hello-world/example.yaml +3 -3
  84. data/tracks/perl6/exercises/hello-world/hello-world.t +25 -12
  85. data/tracks/perl6/exercises/leap/README.md +1 -1
  86. data/tracks/perl6/exercises/leap/example.yaml +1 -1
  87. data/tracks/perl6/exercises/leap/leap.t +23 -11
  88. data/tracks/perl6/exercises/linked-list/README.md +10 -10
  89. data/tracks/perl6/exercises/linked-list/linked-list.t +9 -3
  90. data/tracks/perl6/exercises/luhn/README.md +7 -7
  91. data/tracks/perl6/exercises/luhn/luhn.t +22 -10
  92. data/tracks/perl6/exercises/phone-number/README.md +3 -2
  93. data/tracks/perl6/exercises/phone-number/phone-number.t +22 -10
  94. data/tracks/perl6/exercises/raindrops/raindrops.t +22 -10
  95. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +22 -10
  96. data/tracks/perl6/exercises/robot-name/robot-name.t +9 -3
  97. data/tracks/perl6/exercises/scrabble-score/README.md +3 -1
  98. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +22 -10
  99. data/tracks/perl6/exercises/space-age/README.md +2 -1
  100. data/tracks/perl6/exercises/space-age/space-age.t +22 -10
  101. data/tracks/perl6/exercises/trinary/README.md +1 -1
  102. data/tracks/perl6/exercises/word-count/README.md +1 -2
  103. data/tracks/perl6/exercises/word-count/word-count.t +22 -10
  104. data/tracks/perl6/exercises/wordy/README.md +0 -5
  105. data/tracks/perl6/exercises/wordy/wordy.t +22 -10
  106. data/tracks/perl6/templates/test.mustache +26 -15
  107. data/tracks/python/config.json +10 -0
  108. data/tracks/python/exercises/book-store/book_store.py +1 -1
  109. data/tracks/python/exercises/flatten-array/flatten_array.py +1 -1
  110. data/tracks/python/exercises/matrix/matrix.py +1 -1
  111. data/tracks/python/exercises/palindrome-products/palindrome_products.py +2 -2
  112. data/tracks/python/exercises/perfect-numbers/perfect_numbers.py +2 -2
  113. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet.py +3 -3
  114. data/tracks/python/exercises/raindrops/raindrops.py +1 -1
  115. data/tracks/python/exercises/scale-generator/scale_generator.py +1 -1
  116. data/tracks/python/exercises/sieve/sieve.py +1 -1
  117. data/tracks/python/exercises/sublist/sublist.py +1 -1
  118. data/tracks/python/exercises/transpose/transpose.py +1 -1
  119. data/tracks/python/exercises/triangle/triangle.py +4 -1
  120. data/tracks/python/exercises/two-bucket/example.py +59 -0
  121. data/tracks/python/exercises/two-bucket/two_bucket.py +2 -0
  122. data/tracks/python/exercises/two-bucket/two_bucket_test.py +32 -0
  123. data/tracks/scheme/config.json +59 -89
  124. data/tracks/scheme/config/maintainers.json +11 -11
  125. data/tracks/sml/exercises/allergies/README.md +20 -5
  126. data/tracks/sml/exercises/allergies/allergies.sml +11 -14
  127. data/tracks/sml/exercises/allergies/example.sml +9 -9
  128. data/tracks/sml/exercises/allergies/test.sml +65 -129
  129. data/tracks/sml/exercises/allergies/testlib.sml +159 -0
  130. data/tracks/sml/exercises/hamming/README.md +21 -5
  131. data/tracks/sml/exercises/hamming/example.sml +14 -10
  132. data/tracks/sml/exercises/hamming/hamming.sml +4 -3
  133. data/tracks/sml/exercises/hamming/test.sml +55 -64
  134. data/tracks/sml/exercises/hamming/testlib.sml +159 -0
  135. data/tracks/typescript/config.json +15 -0
  136. data/tracks/typescript/exercises/linked-list/linked-list.test.ts +11 -11
  137. data/tracks/typescript/exercises/nth-prime/README.md +36 -0
  138. data/tracks/typescript/exercises/nth-prime/nth-prime.example.ts +28 -0
  139. data/tracks/typescript/exercises/nth-prime/nth-prime.test.ts +25 -0
  140. data/tracks/typescript/exercises/nth-prime/nth-prime.ts +0 -0
  141. data/tracks/typescript/exercises/nth-prime/package.json +36 -0
  142. data/tracks/typescript/exercises/nth-prime/tsconfig.json +22 -0
  143. data/tracks/typescript/exercises/nth-prime/tslint.json +127 -0
  144. data/tracks/typescript/exercises/nth-prime/yarn.lock +2305 -0
  145. data/tracks/typescript/exercises/prime-factors/README.md +1 -1
  146. data/tracks/typescript/exercises/prime-factors/prime-factors.test.ts +11 -11
  147. data/tracks/typescript/exercises/series/README.md +1 -1
  148. data/tracks/typescript/exercises/series/series.test.ts +11 -11
  149. data/tracks/typescript/img/icon.png +0 -0
  150. data/tracks/typescript/img/icon.svg +3 -8
  151. metadata +44 -2
@@ -1,17 +1,14 @@
1
1
  datatype allergen = Eggs
2
- | Peanuts
3
- | Shellfish
4
- | Strawberries
5
- | Tomatoes
6
- | Chocolate
7
- | Pollen
8
- | Cats
2
+ | Peanuts
3
+ | Shellfish
4
+ | Strawberries
5
+ | Tomatoes
6
+ | Chocolate
7
+ | Pollen
8
+ | Cats
9
9
 
10
- (* given a code generate a list of all allergens this code represents *)
11
- fun list (code: int): allergen list =
12
- raise Fail "'list' has not been implemented"
10
+ fun allergicTo (score: int) (a: allergen) : bool =
11
+ raise Fail "'allergicTo' is not implemented"
13
12
 
14
- (* given a code and an allergen return true or false
15
- whether the specified allergen is represented by the code *)
16
- fun allergic_to (code: int) (a: allergen): bool =
17
- raise Fail "'allergic_to' has not been implemented"
13
+ fun list (score: int): allergen list =
14
+ raise Fail "'list' is not implemented"
@@ -25,12 +25,12 @@ fun valueOf a =
25
25
  | Cats => 7
26
26
 
27
27
  (* allergic_to = fn : int -> allergen -> bool
28
- Given a code (integer) and an allergen returns true if the person
29
- represented by the code is allergic to the specified allergen
28
+ Given a score (integer) and an allergen returns true if the person
29
+ represented by the score is allergic to the specified allergen
30
30
  *)
31
- fun allergic_to code a =
32
- let fun testAllergy code n =
33
- let val codeWord = Word.fromInt(code)
31
+ fun allergicTo score a =
32
+ let fun testAllergy score n =
33
+ let val codeWord = Word.fromInt(score)
34
34
  val nWord = Word.fromInt(n)
35
35
  val oneWord = Word.fromInt(1)
36
36
  in (* ((code >> n) & 1) == 1 *)
@@ -40,12 +40,12 @@ fun allergic_to code a =
40
40
  )
41
41
  end
42
42
  in
43
- testAllergy code (valueOf a)
43
+ testAllergy score (valueOf a)
44
44
  end
45
45
 
46
46
  (* allergies = fn: int -> allergen list
47
- Given a code that represents a person's allergies
47
+ Given a score that represents a person's allergies
48
48
  return a list of all allergens that they are allergic to
49
49
  *)
50
- fun list code =
51
- List.filter (allergic_to code) [Eggs, Peanuts, Shellfish, Strawberries, Tomatoes, Chocolate, Pollen, Cats]
50
+ fun list score =
51
+ List.filter (allergicTo score) [Eggs, Peanuts, Shellfish, Strawberries, Tomatoes, Chocolate, Pollen, Cats]
@@ -1,132 +1,68 @@
1
+ (* version 1.0.0 *)
2
+
3
+ use "testlib.sml";
1
4
  use "allergies.sml";
2
5
 
3
- val test_cases = {
4
- list = [
5
- {
6
- description = "Code = 0 returns no allergies",
7
- input = 0,
8
- expected = []
9
- },
10
- {
11
- description = "Code = 1 returns allergen list of [Eggs]",
12
- input = 1,
13
- expected = [Eggs]
14
- },
15
- {
16
- description = "Code = 2 returns allergen list of [Peanuts]",
17
- input = 2,
18
- expected = [Peanuts]
19
- },
20
- {
21
- description = "Code = 4 returns allergen list of [Shellfish]",
22
- input = 4,
23
- expected = [Shellfish]
24
- },
25
- {
26
- description = "Code = 8 returns allergen list of [Strawberries]",
27
- input = 8,
28
- expected = [Strawberries]
29
- },
30
- {
31
- description = "Code = 16 returns allergen list of [Tomatoes]",
32
- input = 16,
33
- expected = [Tomatoes]
34
- },
35
- {
36
- description = "Code = 32 returns allergen list of [Chocolate]",
37
- input = 32,
38
- expected = [Chocolate]
39
- },
40
- {
41
- description = "Code = 64 returns allergen list of [Pollen]",
42
- input = 64,
43
- expected = [Pollen]
44
- },
45
- {
46
- description = "Code = 128 returns allergen list of [Cats]",
47
- input = 128,
48
- expected = [Cats]
49
- },
50
- {
51
- description = "Code = 256 returns an empty allergen list",
52
- input = 256,
53
- expected = []
54
- },
55
- (* compound tests *)
56
- {
57
- description = "Code = 3 returns allergen list of [Eggs, Peanuts]",
58
- input = 3,
59
- expected = [Eggs, Peanuts]
60
- },
61
- {
62
- description = "Code = 20 returns allergen list of [Shellfish, Tomatoes]",
63
- input = 20,
64
- expected = [Shellfish, Tomatoes]
65
- },
66
- {
67
- description = "Code = 192 returns allergen list of [Pollen, Cats]",
68
- input = 192,
69
- expected = [Pollen, Cats]
70
- },
71
- {
72
- description = "Code = 255 returns all allergens",
73
- input = 255,
74
- expected = [Eggs, Peanuts, Shellfish, Strawberries,Tomatoes, Chocolate, Pollen, Cats]
75
- }
76
- ],
77
- allergic_to = [
78
- {
79
- description = "Code = 1 is allergic to Eggs",
80
- input = 1,
81
- allergen = Eggs,
82
- expected = true
83
- },
84
- {
85
- description = "Code = 1 is not allergic to Pollen",
86
- input = 1,
87
- allergen = Pollen,
88
- expected = false
89
- },
90
- {
91
- description = "Code = 2 is allergic to Peanuts",
92
- input = 2,
93
- allergen = Peanuts,
94
- expected = true
95
- },
96
- {
97
- description = "Code = 255 is allergic to Cats",
98
- input = 255,
99
- allergen = Cats,
100
- expected = true
101
- }
6
+ infixr |>
7
+ fun x |> f = f x
8
+
9
+ val testsuite =
10
+ describe "allergies" [
11
+ describe "allergicTo" [
12
+ describe "no allergies means not allergic" [
13
+ test "is not allergic to Peanuts"
14
+ (fn _ => allergicTo 0 Peanuts |> Expect.falsy),
15
+
16
+ test "is not allergic to Cats"
17
+ (fn _ => allergicTo 0 Cats |> Expect.falsy),
18
+
19
+ test "is not allergic to Strawberries"
20
+ (fn _ => allergicTo 0 Strawberries |> Expect.falsy)
21
+ ],
22
+
23
+ test "is allergic to eggs"
24
+ (fn _ => allergicTo 1 Eggs |> Expect.truthy),
25
+
26
+ describe "allergic to eggs in addition to other stuff" [
27
+ test "is allergic to Eggs"
28
+ (fn _ => allergicTo 5 Eggs |> Expect.truthy),
29
+
30
+ test "is allergic to Shellfish"
31
+ (fn _ => allergicTo 5 Shellfish |> Expect.truthy),
32
+
33
+ test "is allergic to Strawberries"
34
+ (fn _ => allergicTo 5 Strawberries |> Expect.falsy)
35
+ ]
36
+ ],
37
+
38
+ describe "list" [
39
+ test "no allergies at all"
40
+ (fn _ => list (0) |> Expect.equalTo []),
41
+
42
+ test "allergic to just eggs"
43
+ (fn _ => list (1) |> Expect.equalTo [Eggs]),
44
+
45
+ test "allergic to just peanuts"
46
+ (fn _ => list (2) |> Expect.equalTo [Peanuts]),
47
+
48
+ test "allergic to just strawberries"
49
+ (fn _ => list (8) |> Expect.equalTo [Strawberries]),
50
+
51
+ test "allergic to eggs and peanuts"
52
+ (fn _ => list (3) |> Expect.equalTo [Eggs, Peanuts]),
53
+
54
+ test "allergic to more than eggs but not peanuts"
55
+ (fn _ => list (5) |> Expect.equalTo [Eggs, Shellfish]),
56
+
57
+ test "allergic to lots of stuff"
58
+ (fn _ => list (248) |> Expect.equalTo [Strawberries, Tomatoes, Chocolate, Pollen, Cats]),
59
+
60
+ test "allergic to everything"
61
+ (fn _ => list (255) |> Expect.equalTo [Eggs, Peanuts, Shellfish, Strawberries, Tomatoes, Chocolate, Pollen, Cats]),
62
+
63
+ test "ignore non allergen score parts"
64
+ (fn _ => list (509) |> Expect.equalTo [Eggs, Shellfish, Strawberries, Tomatoes, Chocolate, Pollen, Cats])
65
+ ]
102
66
  ]
103
- };
104
-
105
- fun run_tests _ [] = []
106
- | run_tests f (x :: xs) =
107
- let
108
- fun aux { description, is_correct } =
109
- let
110
- val expl = description ^ ": " ^
111
- (if is_correct then "PASSED" else "FAILED") ^ "\n"
112
- in
113
- (print (expl); is_correct)
114
- end
115
- in
116
- (aux x) :: run_tests f xs
117
- end
118
-
119
- fun evaluateList f { description, input, expected } =
120
- { description = description, is_correct = (f input) = expected }
121
-
122
- fun evaluateAllergicTo f { description, input, allergen, expected } =
123
- { description = description, is_correct = (f input allergen) = expected }
124
-
125
- val testResults = run_tests list (List.map (evaluateList list) (#list test_cases))
126
- @ run_tests list (List.map (evaluateAllergicTo allergic_to) (#allergic_to test_cases));
127
- val passedTests = List.filter (fn x => x) testResults;
128
- val failedTests = List.filter (fn x => not x) testResults;
129
-
130
- if (List.length testResults) = (List.length passedTests)
131
- then (print "ALL TESTS PASSED")
132
- else (print (Int.toString (List.length failedTests) ^ " TEST(S) FAILED"));
67
+
68
+ val _ = Test.run testsuite
@@ -0,0 +1,159 @@
1
+ structure Expect =
2
+ struct
3
+ datatype expectation = Pass | Fail of string * string
4
+
5
+ local
6
+ fun failEq b a =
7
+ Fail ("Expected: " ^ b, "Got: " ^ a)
8
+
9
+ fun failExn b a =
10
+ Fail ("Expected: " ^ b, "Raised: " ^ a)
11
+
12
+ fun exnName (e: exn): string = General.exnName e
13
+ in
14
+ fun truthy a =
15
+ if a
16
+ then Pass
17
+ else failEq "true" "false"
18
+
19
+ fun falsy a =
20
+ if a
21
+ then failEq "false" "true"
22
+ else Pass
23
+
24
+ fun equalTo b a =
25
+ if a = b
26
+ then Pass
27
+ else failEq (PolyML.makestring b) (PolyML.makestring a)
28
+
29
+ fun nearTo b a =
30
+ if Real.== (a, b)
31
+ then Pass
32
+ else failEq (Real.toString b) (Real.toString a)
33
+
34
+ fun anyError f =
35
+ (
36
+ f ();
37
+ failExn "an exception" "Nothing"
38
+ ) handle _ => Pass
39
+
40
+ fun error e f =
41
+ (
42
+ f ();
43
+ failExn (exnName e) "Nothing"
44
+ ) handle e' => if exnMessage e' = exnMessage e
45
+ then Pass
46
+ else failExn (exnMessage e) (exnMessage e')
47
+ end
48
+ end
49
+
50
+ structure TermColor =
51
+ struct
52
+ datatype color = Red | Green | Yellow | Normal
53
+
54
+ fun f Red = "\027[31m"
55
+ | f Green = "\027[32m"
56
+ | f Yellow = "\027[33m"
57
+ | f Normal = "\027[0m"
58
+
59
+ fun colorize color s = (f color) ^ s ^ (f Normal)
60
+
61
+ val redit = colorize Red
62
+
63
+ val greenit = colorize Green
64
+
65
+ val yellowit = colorize Yellow
66
+ end
67
+
68
+ structure Test =
69
+ struct
70
+ datatype testnode = TestGroup of string * testnode list
71
+ | Test of string * (unit -> Expect.expectation)
72
+
73
+ local
74
+ datatype evaluation = Success of string
75
+ | Failure of string * string * string
76
+ | Error of string * string
77
+
78
+ fun indent n s = (implode (List.tabulate (n, fn _ => #" "))) ^ s
79
+
80
+ fun fmt indentlvl ev =
81
+ let
82
+ val check = TermColor.greenit "\226\156\148 " (* ✔ *)
83
+ val cross = TermColor.redit "\226\156\150 " (* ✖ *)
84
+ val indentlvl = indentlvl * 2
85
+ in
86
+ case ev of
87
+ Success descr => indent indentlvl (check ^ descr)
88
+ | Failure (descr, exp, got) =>
89
+ String.concatWith "\n" [indent indentlvl (cross ^ descr),
90
+ indent (indentlvl + 2) exp,
91
+ indent (indentlvl + 2) got]
92
+ | Error (descr, reason) =>
93
+ String.concatWith "\n" [indent indentlvl (cross ^ descr),
94
+ indent (indentlvl + 2) (TermColor.redit reason)]
95
+ end
96
+
97
+ fun eval (TestGroup _) = raise Fail "Only a 'Test' can be evaluated"
98
+ | eval (Test (descr, thunk)) =
99
+ (
100
+ case thunk () of
101
+ Expect.Pass => ((1, 0, 0), Success descr)
102
+ | Expect.Fail (s, s') => ((0, 1, 0), Failure (descr, s, s'))
103
+ )
104
+ handle e => ((0, 0, 1), Error (descr, "Unexpected error: " ^ exnMessage e))
105
+
106
+ fun flatten depth testnode =
107
+ let
108
+ fun sum (x, y, z) (a, b, c) = (x + a, y + b, z + c)
109
+
110
+ fun aux (t, (counter, acc)) =
111
+ let
112
+ val (counter', texts) = flatten (depth + 1) t
113
+ in
114
+ (sum counter' counter, texts :: acc)
115
+ end
116
+ in
117
+ case testnode of
118
+ TestGroup (descr, ts) =>
119
+ let
120
+ val (counter, texts) = foldr aux ((0, 0, 0), []) ts
121
+ in
122
+ (counter, (indent (depth * 2) descr) :: List.concat texts)
123
+ end
124
+ | Test _ =>
125
+ let
126
+ val (counter, evaluation) = eval testnode
127
+ in
128
+ (counter, [fmt depth evaluation])
129
+ end
130
+ end
131
+
132
+ fun println s = print (s ^ "\n")
133
+ in
134
+ fun run suite =
135
+ let
136
+ val ((succeeded, failed, errored), texts) = flatten 0 suite
137
+
138
+ val summary = String.concatWith ", " [
139
+ TermColor.greenit ((Int.toString succeeded) ^ " passed"),
140
+ TermColor.redit ((Int.toString failed) ^ " failed"),
141
+ TermColor.redit ((Int.toString errored) ^ " errored"),
142
+ (Int.toString (succeeded + failed + errored)) ^ " total"
143
+ ]
144
+
145
+ val status = if failed = 0 andalso errored = 0
146
+ then OS.Process.success
147
+ else OS.Process.failure
148
+
149
+ in
150
+ List.app println texts;
151
+ println "";
152
+ println ("Tests: " ^ summary);
153
+ OS.Process.exit status
154
+ end
155
+ end
156
+ end
157
+
158
+ fun describe description tests = Test.TestGroup (description, tests)
159
+ fun test description thunk = Test.Test (description, thunk)
@@ -35,19 +35,35 @@ The Hamming distance is only defined for sequences of equal length. This means
35
35
  that based on the definition, each language could deal with getting sequences
36
36
  of equal length differently.
37
37
 
38
- ## Running the tests
38
+ ## Loading your exercise implementation in PolyML
39
39
 
40
- Even though there are multiple implementations, we encourage to use Poly/ML.
40
+ ```
41
+ $ poly --use {exercise}.sml
42
+ ```
43
+
44
+ Or:
41
45
 
42
46
  ```
43
- $ poly -q < test_{ exercise }.sml
47
+ $ poly
48
+ > use "{exercise}.sml";
44
49
  ```
45
50
 
46
- If you want to start an interactive session:
51
+ **Note:** You have to replace {exercise}.
52
+
53
+ ## Running the tests
54
+
47
55
  ```
48
- $ poly --use test_{ exercise }.sml
56
+ $ poly -q --use test.sml
49
57
  ```
50
58
 
59
+ ## Feedback, Issues, Pull Requests
60
+
61
+ The [exercism/sml](https://github.com/exercism/sml) repository on
62
+ GitHub is the home for all of the Standard ML exercises.
63
+
64
+ If you have feedback about an exercise, or want to help implementing a new
65
+ one, head over there and create an issue. We'll do our best to help you!
66
+
51
67
  ## Source
52
68
 
53
69
  The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/)