trackler 2.0.6.9 → 2.0.6.10
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/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
|