trackler 2.0.6.9 → 2.0.6.10
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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/csharp/exercises/luhn/LuhnTest.cs +5 -5
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +5 -5
- data/tracks/fsharp/exercises/tree-building/Example.fs +6 -0
- data/tracks/fsharp/exercises/tree-building/TreeBuilding.fs +15 -0
- data/tracks/fsharp/exercises/tree-building/TreeBuildingTest.fs +97 -14
- data/tracks/go/config.json +1 -1
- data/tracks/go/exercises/TRACK_HINTS.md +1 -1
- data/tracks/ocaml/config.json +5 -0
- data/tracks/ocaml/exercises/dominoes/.merlin +3 -0
- data/tracks/ocaml/exercises/dominoes/Makefile +11 -0
- data/tracks/ocaml/exercises/dominoes/dominoes.mli +3 -0
- data/tracks/ocaml/exercises/dominoes/example.ml +51 -0
- data/tracks/ocaml/exercises/dominoes/test.ml +60 -0
- data/tracks/ruby/.travis.yml +0 -1
- data/tracks/ruby/README.md +13 -23
- data/tracks/ruby/Rakefile +19 -4
- data/tracks/ruby/bin/local-status-check +1 -1
- data/tracks/ruby/lib/tasks/exercise.rb +42 -0
- data/tracks/ruby/lib/tasks/exercise_test_tasks.rb +40 -0
- data/tracks/ruby/lib/tasks/exercise_tests_runner.rb +33 -0
- data/tracks/ruby/test/tasks/exercise_test.rb +46 -0
- data/tracks/ruby/test/tasks/exercise_test_tasks_test.rb +49 -0
- data/tracks/ruby/test/tasks/exercise_tests_runner_test.rb +64 -0
- data/tracks/ruby/test/test_helper.rb +10 -1
- data/tracks/scala/config.json +3 -0
- data/tracks/scala/exercises/luhn/build.sbt +2 -2
- data/tracks/scala/exercises/luhn/example.scala +19 -12
- data/tracks/scala/exercises/luhn/src/test/scala/LuhnTest.scala +18 -21
- metadata +13 -3
- data/tracks/ruby/Makefile +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 953233b1b3c26056a61ba8b0155589068f8a106e
|
4
|
+
data.tar.gz: 8111432be32d72c9ee0b52448735add2f6a11333
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f3b82d836515898a1a27435d01d86748105835110af07ccd8d05a542a0735e24a7112b005cda5aed1e0dc7aa96cbf7daba2b212f44ac70b9225f021d3e7ba36
|
7
|
+
data.tar.gz: 49a6dc1f57ba27a0afa3af2260caf0d8cddcf49148566f893b2434c7dd44ba25ccc2efadd51d619193f5ee8d29e7f81443da39f89b34262d74791d4ae8a2488f
|
data/lib/trackler/version.rb
CHANGED
@@ -4,11 +4,11 @@ using NUnit.Framework;
|
|
4
4
|
public class LuhnTest
|
5
5
|
{
|
6
6
|
[TestCase("1", ExpectedResult = false)] // single digit strings can not be valid
|
7
|
-
[TestCase("0", ExpectedResult = false, Ignore = "Remove to run test")] // a single zero is invalid
|
8
|
-
[TestCase("046 454 286", ExpectedResult = true, Ignore = "Remove to run test")] // valid Canadian SIN
|
9
|
-
[TestCase("046 454 287", ExpectedResult = false, Ignore = "Remove to run test")] // invalid Canadian SIN
|
10
|
-
[TestCase("8273 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test")] // invalid credit card
|
11
|
-
[TestCase("827a 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test")] // strings that contain non-digits are not valid
|
7
|
+
[TestCase("0", ExpectedResult = false, Ignore = "Remove to run test case")] // a single zero is invalid
|
8
|
+
[TestCase("046 454 286", ExpectedResult = true, Ignore = "Remove to run test case")] // valid Canadian SIN
|
9
|
+
[TestCase("046 454 287", ExpectedResult = false, Ignore = "Remove to run test case")] // invalid Canadian SIN
|
10
|
+
[TestCase("8273 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test case")] // invalid credit card
|
11
|
+
[TestCase("827a 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test case")] // strings that contain non-digits are not valid
|
12
12
|
public bool ValidateChecksum(string number)
|
13
13
|
{
|
14
14
|
return Luhn.IsValid(number);
|
@@ -4,10 +4,10 @@ open NUnit.Framework
|
|
4
4
|
open Luhn
|
5
5
|
|
6
6
|
[<TestCase("1", ExpectedResult = false)>] // single digit strings can not be valid
|
7
|
-
[<TestCase("0", ExpectedResult = false, Ignore = "Remove to run test")>] // a single zero is invalid
|
8
|
-
[<TestCase("046 454 286", ExpectedResult = true, Ignore = "Remove to run test")>] // valid Canadian SIN
|
9
|
-
[<TestCase("046 454 287", ExpectedResult = false, Ignore = "Remove to run test")>] // invalid Canadian SIN
|
10
|
-
[<TestCase("8273 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test")>] // invalid credit card
|
11
|
-
[<TestCase("827a 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test")>] // strings that contain non-digits are not valid
|
7
|
+
[<TestCase("0", ExpectedResult = false, Ignore = "Remove to run test case")>] // a single zero is invalid
|
8
|
+
[<TestCase("046 454 286", ExpectedResult = true, Ignore = "Remove to run test case")>] // valid Canadian SIN
|
9
|
+
[<TestCase("046 454 287", ExpectedResult = false, Ignore = "Remove to run test case")>] // invalid Canadian SIN
|
10
|
+
[<TestCase("8273 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test case")>] // invalid credit card
|
11
|
+
[<TestCase("827a 1232 7352 0569", ExpectedResult = false, Ignore = "Remove to run test case")>] // strings that contain non-digits are not valid
|
12
12
|
let ``Validate checksum`` number =
|
13
13
|
valid number
|
@@ -5,6 +5,12 @@ type Tree =
|
|
5
5
|
| Branch of int * Tree list
|
6
6
|
| Leaf of int
|
7
7
|
|
8
|
+
let recordId = function Branch (id, _) | Leaf id -> id
|
9
|
+
|
10
|
+
let isBranch = function Branch _ -> true | Leaf _ -> false
|
11
|
+
|
12
|
+
let children = function Branch (_, children') -> children' | Leaf _ -> []
|
13
|
+
|
8
14
|
let rootNodeRecordId = 0
|
9
15
|
|
10
16
|
let addOrAppend key value map =
|
@@ -5,6 +5,21 @@ type Tree =
|
|
5
5
|
| Branch of int * Tree list
|
6
6
|
| Leaf of int
|
7
7
|
|
8
|
+
let recordId t =
|
9
|
+
match t with
|
10
|
+
| Branch (id, c) -> id
|
11
|
+
| Leaf id -> id
|
12
|
+
|
13
|
+
let isBranch t =
|
14
|
+
match t with
|
15
|
+
| Branch (id, c) -> true
|
16
|
+
| Leaf id -> false
|
17
|
+
|
18
|
+
let children t =
|
19
|
+
match t with
|
20
|
+
| Branch (id, c) -> c
|
21
|
+
| Leaf id -> []
|
22
|
+
|
8
23
|
let buildTree records =
|
9
24
|
let records' = List.sortBy (fun x -> x.RecordId) records
|
10
25
|
|
@@ -10,8 +10,12 @@ let ``One node`` () =
|
|
10
10
|
[
|
11
11
|
{ RecordId = 0; ParentId = 0 }
|
12
12
|
]
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
let tree = buildTree input
|
15
|
+
|
16
|
+
Assert.That(isBranch tree, Is.False)
|
17
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
18
|
+
Assert.That(children tree, Is.EqualTo([]))
|
15
19
|
|
16
20
|
[<Test>]
|
17
21
|
let ``Three nodes in order`` () =
|
@@ -21,8 +25,18 @@ let ``Three nodes in order`` () =
|
|
21
25
|
{ RecordId = 1; ParentId = 0 };
|
22
26
|
{ RecordId = 2; ParentId = 0 };
|
23
27
|
]
|
24
|
-
|
25
|
-
|
28
|
+
|
29
|
+
let tree = buildTree input
|
30
|
+
|
31
|
+
Assert.That(isBranch tree, Is.True)
|
32
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
33
|
+
Assert.That(children tree |> List.length, Is.EqualTo(2))
|
34
|
+
|
35
|
+
Assert.That(children tree |> List.item 0 |> isBranch, Is.False)
|
36
|
+
Assert.That(children tree |> List.item 0 |> recordId, Is.EqualTo(1))
|
37
|
+
|
38
|
+
Assert.That(children tree |> List.item 1 |> isBranch, Is.False)
|
39
|
+
Assert.That(children tree |> List.item 1 |> recordId, Is.EqualTo(2))
|
26
40
|
|
27
41
|
[<Test>]
|
28
42
|
let ``Three nodes in reverse order`` () =
|
@@ -32,8 +46,18 @@ let ``Three nodes in reverse order`` () =
|
|
32
46
|
{ RecordId = 1; ParentId = 0 };
|
33
47
|
{ RecordId = 0; ParentId = 0 };
|
34
48
|
]
|
35
|
-
|
36
|
-
|
49
|
+
|
50
|
+
let tree = buildTree input
|
51
|
+
|
52
|
+
Assert.That(isBranch tree, Is.True)
|
53
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
54
|
+
Assert.That(children tree |> List.length, Is.EqualTo(2))
|
55
|
+
|
56
|
+
Assert.That(children tree |> List.item 0 |> isBranch, Is.False)
|
57
|
+
Assert.That(children tree |> List.item 0 |> recordId, Is.EqualTo(1))
|
58
|
+
|
59
|
+
Assert.That(children tree |> List.item 1 |> isBranch, Is.False)
|
60
|
+
Assert.That(children tree |> List.item 1 |> recordId, Is.EqualTo(2))
|
37
61
|
|
38
62
|
[<Test>]
|
39
63
|
let ``More than two children`` () =
|
@@ -44,8 +68,21 @@ let ``More than two children`` () =
|
|
44
68
|
{ RecordId = 1; ParentId = 0 };
|
45
69
|
{ RecordId = 0; ParentId = 0 };
|
46
70
|
]
|
47
|
-
|
48
|
-
|
71
|
+
|
72
|
+
let tree = buildTree input
|
73
|
+
|
74
|
+
Assert.That(isBranch tree, Is.True)
|
75
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
76
|
+
Assert.That(children tree |> List.length, Is.EqualTo(3))
|
77
|
+
|
78
|
+
Assert.That(children tree |> List.item 0 |> isBranch, Is.False)
|
79
|
+
Assert.That(children tree |> List.item 0 |> recordId, Is.EqualTo(1))
|
80
|
+
|
81
|
+
Assert.That(children tree |> List.item 1 |> isBranch, Is.False)
|
82
|
+
Assert.That(children tree |> List.item 1 |> recordId, Is.EqualTo(2))
|
83
|
+
|
84
|
+
Assert.That(children tree |> List.item 2 |> isBranch, Is.False)
|
85
|
+
Assert.That(children tree |> List.item 2 |> recordId, Is.EqualTo(3))
|
49
86
|
|
50
87
|
[<Test>]
|
51
88
|
let ``Binary tree`` () =
|
@@ -59,9 +96,32 @@ let ``Binary tree`` () =
|
|
59
96
|
{ RecordId = 0; ParentId = 0 };
|
60
97
|
{ RecordId = 6; ParentId = 2 }
|
61
98
|
]
|
62
|
-
|
63
|
-
|
64
|
-
|
99
|
+
|
100
|
+
let tree = buildTree input
|
101
|
+
|
102
|
+
Assert.That(isBranch tree, Is.True)
|
103
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
104
|
+
Assert.That(children tree |> List.length, Is.EqualTo(2))
|
105
|
+
|
106
|
+
Assert.That(children tree |> List.item 0 |> isBranch, Is.True)
|
107
|
+
Assert.That(children tree |> List.item 0 |> recordId, Is.EqualTo(1))
|
108
|
+
Assert.That(children tree |> List.item 0 |> children |> List.length, Is.EqualTo(2))
|
109
|
+
|
110
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 0 |> isBranch, Is.False)
|
111
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 0 |> recordId, Is.EqualTo(4))
|
112
|
+
|
113
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 1 |> isBranch, Is.False)
|
114
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 1 |> recordId, Is.EqualTo(5))
|
115
|
+
|
116
|
+
Assert.That(children tree |> List.item 1 |> isBranch, Is.True)
|
117
|
+
Assert.That(children tree |> List.item 1 |> recordId, Is.EqualTo(2))
|
118
|
+
Assert.That(children tree |> List.item 1 |> children |> List.length, Is.EqualTo(2))
|
119
|
+
|
120
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 0 |> isBranch, Is.False)
|
121
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 0 |> recordId, Is.EqualTo(3))
|
122
|
+
|
123
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 1 |> isBranch, Is.False)
|
124
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 1 |> recordId, Is.EqualTo(6))
|
65
125
|
|
66
126
|
[<Test>]
|
67
127
|
let ``Unbalanced tree`` () =
|
@@ -75,9 +135,32 @@ let ``Unbalanced tree`` () =
|
|
75
135
|
{ RecordId = 0; ParentId = 0 };
|
76
136
|
{ RecordId = 6; ParentId = 2 }
|
77
137
|
]
|
78
|
-
|
79
|
-
|
80
|
-
|
138
|
+
|
139
|
+
let tree = buildTree input
|
140
|
+
|
141
|
+
Assert.That(isBranch tree, Is.True)
|
142
|
+
Assert.That(recordId tree, Is.EqualTo(0))
|
143
|
+
Assert.That(children tree |> List.length, Is.EqualTo(2))
|
144
|
+
|
145
|
+
Assert.That(children tree |> List.item 0 |> isBranch, Is.True)
|
146
|
+
Assert.That(children tree |> List.item 0 |> recordId, Is.EqualTo(1))
|
147
|
+
Assert.That(children tree |> List.item 0 |> children |> List.length, Is.EqualTo(1))
|
148
|
+
|
149
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 0 |> isBranch, Is.False)
|
150
|
+
Assert.That(children tree |> List.item 0 |> children |> List.item 0 |> recordId, Is.EqualTo(4))
|
151
|
+
|
152
|
+
Assert.That(children tree |> List.item 1 |> isBranch, Is.True)
|
153
|
+
Assert.That(children tree |> List.item 1 |> recordId, Is.EqualTo(2))
|
154
|
+
Assert.That(children tree |> List.item 1 |> children |> List.length, Is.EqualTo(3))
|
155
|
+
|
156
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 0 |> isBranch, Is.False)
|
157
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 0 |> recordId, Is.EqualTo(3))
|
158
|
+
|
159
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 1 |> isBranch, Is.False)
|
160
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 1 |> recordId, Is.EqualTo(5))
|
161
|
+
|
162
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 2 |> isBranch, Is.False)
|
163
|
+
Assert.That(children tree |> List.item 1 |> children |> List.item 2 |> recordId, Is.EqualTo(6))
|
81
164
|
|
82
165
|
[<Test>]
|
83
166
|
let ``Empty input`` () =
|
data/tracks/go/config.json
CHANGED
data/tracks/ocaml/config.json
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
(* Based off the Haskell solution by Tarmean at http://exercism.io/submissions/6dc2eef7e7eb469d8657111fc4389fc0 *)
|
2
|
+
|
3
|
+
open Core.Std
|
4
|
+
|
5
|
+
type dominoe = int * int
|
6
|
+
|
7
|
+
(* Functions from Haskell that I can't find in Core! *)
|
8
|
+
|
9
|
+
let zip_with (xs: 'a list) (ys: 'b list) ~(f: 'a -> 'b -> 'c) =
|
10
|
+
let rec go xs ys acc = match (xs,ys) with
|
11
|
+
| (x::xs,y::ys) -> go xs ys @@ (f x y)::acc
|
12
|
+
| _ -> acc
|
13
|
+
in
|
14
|
+
List.rev @@ go xs ys []
|
15
|
+
|
16
|
+
let tails (xs: 'a list): ('a list) list =
|
17
|
+
let rec go acc = function
|
18
|
+
| [] -> [] :: acc
|
19
|
+
| (x::xs) as l -> go (l :: acc) xs
|
20
|
+
in
|
21
|
+
List.rev @@ go [] xs
|
22
|
+
|
23
|
+
let inits (xs: 'a list): ('a list) list =
|
24
|
+
List.rev xs |> tails |> List.map ~f:List.rev |> List.rev
|
25
|
+
|
26
|
+
let listToOption = function
|
27
|
+
| [] -> None
|
28
|
+
| (x :: _) -> Some x
|
29
|
+
|
30
|
+
(* The implementation *)
|
31
|
+
|
32
|
+
let left (ds: dominoe list): int = ds |> List.hd_exn |> fst
|
33
|
+
let right (ds: dominoe list): int = ds |> List.last_exn |> snd
|
34
|
+
let choose_from (ls: 'a list): ('a * 'a list) list =
|
35
|
+
List.zip_exn ls @@ zip_with ~f:List.append (inits ls) (List.tl_exn (tails ls))
|
36
|
+
|
37
|
+
let rec attach_to path ((a, b), rest) =
|
38
|
+
let lp = left path in
|
39
|
+
if b = lp then go rest ((a,b)::path)
|
40
|
+
else if a = lp then go rest ((b,a)::path)
|
41
|
+
else []
|
42
|
+
and go stones path = match stones with
|
43
|
+
| [] -> if left path = right path then [path] else []
|
44
|
+
| _ -> let open List.Monad_infix in choose_from stones >>= attach_to path
|
45
|
+
|
46
|
+
let chain_non_empty (first: dominoe) (rest: dominoe list): (dominoe list) option =
|
47
|
+
listToOption @@ go rest [first]
|
48
|
+
|
49
|
+
let chain = function
|
50
|
+
| [] -> Some []
|
51
|
+
| first::rest -> chain_non_empty first rest
|
@@ -0,0 +1,60 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Dominoes
|
4
|
+
|
5
|
+
let print_dominoe (d1, d2) = sprintf "(%d,%d)" d1 d2
|
6
|
+
|
7
|
+
let option_printer = function
|
8
|
+
| None -> "None"
|
9
|
+
| Some xs -> "Some [" ^ String.concat ~sep:";" (List.map xs ~f:print_dominoe) ^ "]"
|
10
|
+
|
11
|
+
let drop_1_right xs = List.rev xs |> List.tl_exn |> List.rev
|
12
|
+
|
13
|
+
let check_chain (chained: dominoe list) =
|
14
|
+
let assert_dominoes_match d1 d2 =
|
15
|
+
if snd d1 <> fst d2 then failwith @@ sprintf "%s and %s cannot be chained together" (print_dominoe d1) (print_dominoe d2) else () in
|
16
|
+
let consecutives = List.zip_exn (drop_1_right chained) (List.tl_exn chained) in
|
17
|
+
List.iter consecutives ~f:(fun (d1, d2) -> assert_dominoes_match d1 d2)
|
18
|
+
|
19
|
+
let assert_empty c = if List.is_empty c then () else failwith "Expected 0 length chain"
|
20
|
+
|
21
|
+
let assert_valid_chain input _ctxt =
|
22
|
+
match chain input with
|
23
|
+
| None -> failwith "Expecting a chain"
|
24
|
+
| Some(c) -> (if List.is_empty input then assert_empty else check_chain) c
|
25
|
+
|
26
|
+
let assert_no_chain input _ctxt =
|
27
|
+
assert_equal None (chain input) ~printer:option_printer
|
28
|
+
|
29
|
+
let assert_chain input hasChain =
|
30
|
+
if hasChain then assert_valid_chain input else assert_no_chain input
|
31
|
+
|
32
|
+
let tests = [
|
33
|
+
"empty input = empty output" >::
|
34
|
+
assert_chain [] true;
|
35
|
+
"singleton input = singleton output" >::
|
36
|
+
assert_chain [(1,1)] true;
|
37
|
+
"singleton that can't be chained" >::
|
38
|
+
assert_chain [(1,2)] false;
|
39
|
+
"three elements" >::
|
40
|
+
assert_chain [(1,2); (3,1); (2,3)] true;
|
41
|
+
"can reverse dominoes" >::
|
42
|
+
assert_chain [(1,2); (1,3); (2,3)] true;
|
43
|
+
"can't be chained" >::
|
44
|
+
assert_chain [(1,2); (4,1); (2,3)] false;
|
45
|
+
"disconnected - simple" >::
|
46
|
+
assert_chain [(1,1); (2,2)] false;
|
47
|
+
"disconnected - double loop" >::
|
48
|
+
assert_chain [(1,2); (2,1); (3,4); (4,3)] false;
|
49
|
+
"disconnected - single isolated" >::
|
50
|
+
assert_chain [(1,2); (2,3); (3,1); (4,4)] false;
|
51
|
+
"need backtrack" >::
|
52
|
+
assert_chain [(1,2); (2,3); (3,1); (2,4); (2,4)] true;
|
53
|
+
"separate loops" >::
|
54
|
+
assert_chain [(1,2); (2,3); (3,1); (1,1); (2,2); (3,3)] true;
|
55
|
+
"ten elements" >::
|
56
|
+
assert_chain [(1,2); (5,3); (3,1); (1,2); (2,4); (1,6); (2,3); (3,4); (5,6)] true;
|
57
|
+
]
|
58
|
+
|
59
|
+
let () =
|
60
|
+
run_test_tt_main ("dominoes tests" >::: tests)
|
data/tracks/ruby/.travis.yml
CHANGED
data/tracks/ruby/README.md
CHANGED
@@ -34,42 +34,32 @@ suite, you can run the file with a shim that temporarily disables them:
|
|
34
34
|
ruby -I./lib -rdisable_skip exercise/exercise/filename_test.rb
|
35
35
|
```
|
36
36
|
|
37
|
-
It is simpler to use the `
|
37
|
+
It is simpler to use the `rake` tool which is available in the project
|
38
38
|
root. It will disable the skip calls for you automatically, it does the
|
39
39
|
same thing as the above.
|
40
40
|
|
41
|
-
If you would like to use the `
|
41
|
+
If you would like to use the `rake` tool to run a single test while
|
42
42
|
developing clock, for example, you can do something like this:
|
43
43
|
|
44
44
|
```sh
|
45
|
-
|
45
|
+
rake test:clock
|
46
46
|
```
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
ARGS is where you can put additional arguments, here I am demonstrating
|
52
|
-
the `-p` argument which may give you 'pride' output.
|
53
|
-
|
54
|
-
If you use zsh, you can use the following function to make this process
|
55
|
-
simple.
|
56
|
-
|
48
|
+
To pass arguments to the test command, like `-p` for example, you can run
|
49
|
+
the following:
|
57
50
|
```sh
|
58
|
-
|
51
|
+
rake test:clock -- -p
|
59
52
|
```
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
rather than just the dots, for example:
|
67
|
-
|
68
|
-
`xtest clock -v`
|
54
|
+
To show an example of running a limited number of tests, we will use the
|
55
|
+
"hamming" exercise with a pattern of "identical" to run (currently) two tests:
|
56
|
+
```sh
|
57
|
+
rake test:hamming -- -p -n="/identical/"
|
58
|
+
```
|
69
59
|
|
70
|
-
|
60
|
+
Note that flags which have an attached value, like above, must take the form
|
61
|
+
`-flag=value` and if `value` has spaces `-flag="value with spaces"`.
|
71
62
|
|
72
|
-
`xtest robot-name -p`
|
73
63
|
|
74
64
|
### Generated Test Suites
|
75
65
|
|
data/tracks/ruby/Rakefile
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
|
-
|
5
|
-
task default: :test
|
4
|
+
require_relative 'lib/tasks/exercise_test_tasks'
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
task default: 'test'
|
7
|
+
|
8
|
+
desc 'Run individual exercises or run all development and exercise tests'
|
9
|
+
task :test do
|
10
|
+
Rake::Task['test:dev'].invoke
|
11
|
+
Rake::Task['test:exercises'].invoke
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :test do
|
15
|
+
flags = ARGV.drop_while { |e| e != '--' }.drop(1).join(' ')
|
16
|
+
|
17
|
+
desc 'Run all development tests located in the test directory'
|
18
|
+
Rake::TestTask.new :dev do |task|
|
19
|
+
task.options = flags
|
20
|
+
task.pattern = 'test/**/*_test.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
ExerciseTestTasks.new options: flags
|
9
24
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Exercise
|
2
|
+
class << self
|
3
|
+
def all
|
4
|
+
exercise_names.map { |e| new(e) }
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def exercise_names
|
10
|
+
FileList['exercises/*'].pathmap('%f').exclude('TRACK_HINTS.md')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :name
|
15
|
+
alias :to_s :name
|
16
|
+
|
17
|
+
def initialize(name)
|
18
|
+
@name = name
|
19
|
+
end
|
20
|
+
|
21
|
+
def directory
|
22
|
+
"exercises/#{name}/."
|
23
|
+
end
|
24
|
+
|
25
|
+
def example_file
|
26
|
+
'example.rb'
|
27
|
+
end
|
28
|
+
|
29
|
+
def testable_example_file
|
30
|
+
"#{base_file_name}.rb"
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_file
|
34
|
+
"#{base_file_name}_test.rb"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def base_file_name
|
40
|
+
@_base_file_name ||= name.tr('-', '_')
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rake/dsl_definition'
|
2
|
+
|
3
|
+
require_relative 'exercise'
|
4
|
+
require_relative 'exercise_tests_runner'
|
5
|
+
|
6
|
+
class ExerciseTestTasks
|
7
|
+
include Rake::DSL
|
8
|
+
|
9
|
+
def initialize(options:, test_runner: ExerciseTestsRunner)
|
10
|
+
@options = options
|
11
|
+
@test_runner = test_runner
|
12
|
+
|
13
|
+
define
|
14
|
+
end
|
15
|
+
|
16
|
+
def define
|
17
|
+
define_task_for_all_exercises
|
18
|
+
|
19
|
+
exercises.each { |exercise| define_task_for(exercise) }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :options, :test_runner
|
25
|
+
|
26
|
+
def exercises
|
27
|
+
@_exercises ||= Exercise.all
|
28
|
+
end
|
29
|
+
|
30
|
+
def define_task_for_all_exercises
|
31
|
+
desc 'Run the tests for all exercises'
|
32
|
+
task exercises: exercises
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_task_for(exercise)
|
36
|
+
task exercise do
|
37
|
+
test_runner.new(exercise: exercise, test_options: options).run
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rake/file_utils_ext"
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
class ExerciseTestsRunner
|
5
|
+
include Rake::FileUtilsExt
|
6
|
+
|
7
|
+
def initialize(exercise:, test_options: '')
|
8
|
+
@exercise = exercise
|
9
|
+
@test_options = test_options
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
puts "\n\n#{'-'*64}\nrunning tests for: #{exercise}"
|
14
|
+
|
15
|
+
Dir.mktmpdir(exercise.name) do |dir|
|
16
|
+
setup_exercise_files_in(dir)
|
17
|
+
run_exercise_tests_in(dir)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :exercise, :test_options
|
24
|
+
|
25
|
+
def setup_exercise_files_in(dir)
|
26
|
+
FileUtils.cp_r exercise.directory, dir
|
27
|
+
FileUtils.mv "#{dir}/#{exercise.example_file}", "#{dir}/#{exercise.testable_example_file}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_exercise_tests_in(dir)
|
31
|
+
ruby "-I lib -r disable_skip.rb #{dir}/#{exercise.test_file} #{test_options}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
class ExerciseTest < Minitest::Test
|
5
|
+
def test_all
|
6
|
+
Dir.mktmpdir('exercise-test') do |dir|
|
7
|
+
FileUtils.mkdir "#{dir}/test"
|
8
|
+
FileUtils.mkdir "#{dir}/test2"
|
9
|
+
FileUtils.touch "#{dir}/TRACK_HINTS.md"
|
10
|
+
|
11
|
+
FileList.stub :[], FileList["#{dir}/*"] do
|
12
|
+
assert_equal true, Exercise.all.all? { |e| e.instance_of?(Exercise) }
|
13
|
+
assert_equal ['test', 'test2'], Exercise.all.map(&:name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_name
|
19
|
+
exercise = Exercise.new('name')
|
20
|
+
assert_equal 'name', exercise.name
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_to_s
|
24
|
+
exercise = Exercise.new('name')
|
25
|
+
assert_equal 'name', exercise.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_directory
|
29
|
+
exercise = Exercise.new('exercise_name')
|
30
|
+
assert_equal 'exercises/exercise_name/.', exercise.directory
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_example_file
|
34
|
+
assert_equal 'example.rb', Exercise.new('').example_file
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_testable_example_file
|
38
|
+
exercise = Exercise.new('all-your-base')
|
39
|
+
assert_equal 'all_your_base.rb', exercise.testable_example_file
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_test_file
|
43
|
+
exercise = Exercise.new('all-your-base')
|
44
|
+
assert_equal 'all_your_base_test.rb', exercise.test_file
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class ExerciseTestTasksTest < Minitest::Test
|
4
|
+
def test_all_exercises_task
|
5
|
+
setup_rake
|
6
|
+
|
7
|
+
Exercise.stub :all, ['test1', 'test2'] do
|
8
|
+
ExerciseTestTasks.new(options: '')
|
9
|
+
|
10
|
+
assert_equal ['test1', 'test2'], Rake::Task['exercises'].prerequisites
|
11
|
+
assert_equal 'Run the tests for all exercises', Rake::Task['exercises'].comment
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_individual_exercise_tasks
|
16
|
+
setup_rake
|
17
|
+
|
18
|
+
Exercise.stub :all, ['test1', 'test2'] do
|
19
|
+
mock_test_runner_instance = Minitest::Mock.new
|
20
|
+
mock_test_runner_instance.expect :run, nil
|
21
|
+
mock_test_runner_instance.expect :run, nil
|
22
|
+
|
23
|
+
mock_test_runner = Minitest::Mock.new
|
24
|
+
mock_test_runner.expect(
|
25
|
+
:new,
|
26
|
+
mock_test_runner_instance,
|
27
|
+
[exercise: 'test1', test_options: '-p'],
|
28
|
+
)
|
29
|
+
mock_test_runner.expect(
|
30
|
+
:new,
|
31
|
+
mock_test_runner_instance,
|
32
|
+
[exercise: 'test2', test_options: '-p'],
|
33
|
+
)
|
34
|
+
|
35
|
+
ExerciseTestTasks.new(options: '-p', test_runner: mock_test_runner)
|
36
|
+
|
37
|
+
Rake::Task['test1'].invoke
|
38
|
+
Rake::Task['test2'].invoke
|
39
|
+
|
40
|
+
mock_test_runner.verify
|
41
|
+
mock_test_runner_instance.verify
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_rake
|
46
|
+
Rake.application = Rake::Application.new
|
47
|
+
Rake::TaskManager.record_task_metadata = true
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class FakeExercise
|
4
|
+
def name
|
5
|
+
'test'
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :to_s :name
|
9
|
+
|
10
|
+
def directory
|
11
|
+
'test/.'
|
12
|
+
end
|
13
|
+
|
14
|
+
def example_file
|
15
|
+
'example.rb'
|
16
|
+
end
|
17
|
+
|
18
|
+
def testable_example_file
|
19
|
+
'test.rb'
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_file
|
23
|
+
'test_test.rb'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ExerciseTestsRunnerTest < Minitest::Test
|
28
|
+
def test_run
|
29
|
+
Dir.stub :mktmpdir, nil, 'dir' do
|
30
|
+
cp_mock = Minitest::Mock.new.expect(:call, nil, ['test/.', 'dir'])
|
31
|
+
|
32
|
+
mv_mock = Minitest::Mock.new.expect(
|
33
|
+
:call,
|
34
|
+
nil,
|
35
|
+
['dir/example.rb', 'dir/test.rb'],
|
36
|
+
)
|
37
|
+
|
38
|
+
ruby_mock = Minitest::Mock.new.expect(
|
39
|
+
:call,
|
40
|
+
nil,
|
41
|
+
['-I lib -r disable_skip.rb dir/test_test.rb -p'],
|
42
|
+
)
|
43
|
+
|
44
|
+
FileUtils.stub :cp_r, cp_mock do
|
45
|
+
FileUtils.stub :mv, mv_mock do
|
46
|
+
runner = ExerciseTestsRunner.new(
|
47
|
+
exercise: FakeExercise.new,
|
48
|
+
test_options: '-p',
|
49
|
+
)
|
50
|
+
|
51
|
+
runner.stub :ruby, ruby_mock do
|
52
|
+
assert_output "\n\n#{'-'*64}\nrunning tests for: test\n" do
|
53
|
+
runner.run
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
cp_mock.verify
|
58
|
+
mv_mock.verify
|
59
|
+
ruby_mock.verify
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -6,12 +6,21 @@ unless ENV['CI']
|
|
6
6
|
require 'simplecov'
|
7
7
|
SimpleCov.start do
|
8
8
|
add_filter '/test/'
|
9
|
+
|
9
10
|
add_group 'Generator' do |file|
|
10
11
|
file.filename =~ /generator/
|
11
12
|
end
|
13
|
+
|
14
|
+
add_group 'Tasks' do |file|
|
15
|
+
file.filename =~ /tasks/
|
16
|
+
end
|
17
|
+
|
12
18
|
add_group 'Cases', '_cases.rb'
|
19
|
+
|
13
20
|
add_group 'Other' do |file|
|
14
|
-
!(file.filename =~ /_cases\.rb$/) &&
|
21
|
+
!(file.filename =~ /_cases\.rb$/) &&
|
22
|
+
file.filename !~ /generator/ &&
|
23
|
+
file.filename !~ /tasks/
|
15
24
|
end
|
16
25
|
end
|
17
26
|
end
|
data/tracks/scala/config.json
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
scalaVersion := "2.
|
1
|
+
scalaVersion := "2.12.1"
|
2
2
|
|
3
|
-
libraryDependencies += "org.scalatest"
|
3
|
+
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
|
@@ -1,23 +1,29 @@
|
|
1
|
-
|
2
|
-
lazy val checkDigit: Int = (number % 10).toInt
|
1
|
+
object Luhn {
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
def validate(numberStr: String): Boolean = {
|
4
|
+
def isCandidate(numberStr: String): Boolean =
|
5
|
+
numberStr.length > 1 &&
|
6
|
+
numberStr.forall(c => c.isDigit || c.isSpaceChar)
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
def toLong(numberStr: String): Long =
|
9
|
+
numberStr.filter(_.isDigit).toLong
|
9
10
|
|
10
|
-
|
11
|
+
val number =
|
12
|
+
Option(numberStr) filter isCandidate map toLong
|
11
13
|
|
12
|
-
|
14
|
+
number map (checksum(_) == 0) getOrElse false
|
15
|
+
}
|
13
16
|
|
14
|
-
|
15
|
-
val m = number * 10
|
16
|
-
val luhn = Luhn(m)
|
17
|
+
private def checkDigit(number: Long): Int = (number % 10).toInt
|
17
18
|
|
18
|
-
|
19
|
+
private def addends(number: Long): List[Int] = {
|
20
|
+
val zippedDigits = digits(number).zipWithIndex.reverse
|
21
|
+
|
22
|
+
zippedDigits.map{case (m, i) => if (isOdd(i)) dbl(m) else m}
|
19
23
|
}
|
20
24
|
|
25
|
+
private def checksum(number: Long): Int = addends(number).sum % 10
|
26
|
+
|
21
27
|
private def digits(n: Long): List[Int] = n match {
|
22
28
|
case 0 => Nil
|
23
29
|
case _ => List((n % 10).toInt) ++ digits(n / 10)
|
@@ -31,3 +37,4 @@ case class Luhn(number: Long) {
|
|
31
37
|
|
32
38
|
private def isOdd(i: Int) = i % 2 == 1
|
33
39
|
}
|
40
|
+
|
@@ -1,36 +1,33 @@
|
|
1
|
-
import org.scalatest.{
|
1
|
+
import org.scalatest.{FunSuite, Matchers}
|
2
2
|
|
3
|
-
class LuhnTest extends
|
4
|
-
|
5
|
-
Luhn(
|
6
|
-
Luhn(91370).checkDigit should equal(0)
|
7
|
-
Luhn(0).checkDigit should equal(0)
|
3
|
+
class LuhnTest extends FunSuite with Matchers {
|
4
|
+
test("single digit strings can not be valid") {
|
5
|
+
Luhn.validate("1") should be (false)
|
8
6
|
}
|
9
7
|
|
10
|
-
|
8
|
+
test("A single zero is invalid") {
|
11
9
|
pending
|
12
|
-
Luhn(
|
13
|
-
Luhn(8631).addends should equal(List(7, 6, 6, 1))
|
10
|
+
Luhn.validate("0") should be (false)
|
14
11
|
}
|
15
12
|
|
16
|
-
|
13
|
+
test("valid Canadian SIN") {
|
17
14
|
pending
|
18
|
-
|
19
|
-
// be mod 10 like we are testing here.
|
20
|
-
Luhn(4913).checksum should equal(2)
|
21
|
-
Luhn(201773).checksum should equal(1)
|
15
|
+
Luhn.validate("046 454 286") should be (true)
|
22
16
|
}
|
23
17
|
|
24
|
-
|
18
|
+
test("invalid Canadian SIN") {
|
25
19
|
pending
|
26
|
-
Luhn(
|
27
|
-
Luhn(8739567).isValid should be (true)
|
20
|
+
Luhn.validate("046 454 287") should be (false)
|
28
21
|
}
|
29
22
|
|
30
|
-
|
23
|
+
test("invalid credit card") {
|
31
24
|
pending
|
32
|
-
Luhn(
|
33
|
-
|
34
|
-
|
25
|
+
Luhn.validate("8273 1232 7352 0569") should be (false)
|
26
|
+
}
|
27
|
+
|
28
|
+
test("strings that contain non-digits are not valid") {
|
29
|
+
pending
|
30
|
+
Luhn.validate("827a 1232 7352 0569") should be (false)
|
35
31
|
}
|
36
32
|
}
|
33
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trackler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.6.
|
4
|
+
version: 2.0.6.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Owen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -4913,6 +4913,11 @@ files:
|
|
4913
4913
|
- tracks/ocaml/exercises/difference-of-squares/difference_of_squares.mli
|
4914
4914
|
- tracks/ocaml/exercises/difference-of-squares/example.ml
|
4915
4915
|
- tracks/ocaml/exercises/difference-of-squares/test.ml
|
4916
|
+
- tracks/ocaml/exercises/dominoes/.merlin
|
4917
|
+
- tracks/ocaml/exercises/dominoes/Makefile
|
4918
|
+
- tracks/ocaml/exercises/dominoes/dominoes.mli
|
4919
|
+
- tracks/ocaml/exercises/dominoes/example.ml
|
4920
|
+
- tracks/ocaml/exercises/dominoes/test.ml
|
4916
4921
|
- tracks/ocaml/exercises/etl/.merlin
|
4917
4922
|
- tracks/ocaml/exercises/etl/Makefile
|
4918
4923
|
- tracks/ocaml/exercises/etl/etl.mli
|
@@ -5937,7 +5942,6 @@ files:
|
|
5937
5942
|
- tracks/ruby/Gemfile
|
5938
5943
|
- tracks/ruby/HINTS.md
|
5939
5944
|
- tracks/ruby/LICENSE
|
5940
|
-
- tracks/ruby/Makefile
|
5941
5945
|
- tracks/ruby/README.md
|
5942
5946
|
- tracks/ruby/Rakefile
|
5943
5947
|
- tracks/ruby/bin/enable-executable
|
@@ -6235,6 +6239,9 @@ files:
|
|
6235
6239
|
- tracks/ruby/lib/roman_numerals_cases.rb
|
6236
6240
|
- tracks/ruby/lib/run_length_encoding_cases.rb
|
6237
6241
|
- tracks/ruby/lib/sieve_cases.rb
|
6242
|
+
- tracks/ruby/lib/tasks/exercise.rb
|
6243
|
+
- tracks/ruby/lib/tasks/exercise_test_tasks.rb
|
6244
|
+
- tracks/ruby/lib/tasks/exercise_tests_runner.rb
|
6238
6245
|
- tracks/ruby/lib/tournament_cases.rb
|
6239
6246
|
- tracks/ruby/lib/transpose_cases.rb
|
6240
6247
|
- tracks/ruby/lib/triangle_cases.rb
|
@@ -6256,6 +6263,9 @@ files:
|
|
6256
6263
|
- tracks/ruby/test/generator/template_values_test.rb
|
6257
6264
|
- tracks/ruby/test/generator_test.rb
|
6258
6265
|
- tracks/ruby/test/grains_cases_test.rb
|
6266
|
+
- tracks/ruby/test/tasks/exercise_test.rb
|
6267
|
+
- tracks/ruby/test/tasks/exercise_test_tasks_test.rb
|
6268
|
+
- tracks/ruby/test/tasks/exercise_tests_runner_test.rb
|
6259
6269
|
- tracks/ruby/test/test_helper.rb
|
6260
6270
|
- tracks/ruby/test/wordy_cases_test.rb
|
6261
6271
|
- tracks/rust/.git
|
data/tracks/ruby/Makefile
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
.PHONY: test
|
2
|
-
|
3
|
-
# assignments
|
4
|
-
ASSIGNMENT ?= ""
|
5
|
-
IGNOREDIRS := "^(\.git|bin|docs|lib|exercises)$$"
|
6
|
-
ASSIGNMENTS = $(shell find ./exercises -maxdepth 1 -mindepth 1 -type d | awk -F/ '{print $$NF}' | sort | grep -Ev $(IGNOREDIRS))
|
7
|
-
|
8
|
-
default: test
|
9
|
-
|
10
|
-
# output directories
|
11
|
-
TMPDIR ?= "/tmp/"
|
12
|
-
OUTDIR := $(shell mktemp -d "$(TMPDIR)$(ASSIGNMENT).XXXXXXXXXX")
|
13
|
-
|
14
|
-
# language specific config (tweakable per language)
|
15
|
-
FILEEXT := "rb"
|
16
|
-
EXAMPLE := "example.$(FILEEXT)"
|
17
|
-
SRCFILE := "$(shell echo $(ASSIGNMENT) | sed 's/-/_/g')"
|
18
|
-
TSTFILE := "$(SRCFILE)_test.$(FILEEXT)"
|
19
|
-
# Any additional arguments, such as -p for pretty output and others
|
20
|
-
ARGS ?= ""
|
21
|
-
|
22
|
-
# single test
|
23
|
-
test-assignment:
|
24
|
-
@echo ""
|
25
|
-
@echo ""
|
26
|
-
@echo "----------------------------------------------------------------"
|
27
|
-
@echo "running tests for: $(ASSIGNMENT)"
|
28
|
-
@cp -r ./exercises/$(ASSIGNMENT)/* $(OUTDIR)
|
29
|
-
@cp ./exercises/$(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(SRCFILE).$(FILEEXT)
|
30
|
-
@ruby -I./lib -rdisable_skip.rb $(OUTDIR)/$(TSTFILE) $(ARGS)
|
31
|
-
@rm -rf $(OUTDIR)
|
32
|
-
|
33
|
-
# all tests
|
34
|
-
test:
|
35
|
-
@for assignment in $(ASSIGNMENTS); do \
|
36
|
-
ASSIGNMENT=$$assignment $(MAKE) -s test-assignment || exit 1;\
|
37
|
-
done
|