trackler 2.1.0.12 → 2.1.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/difference-of-squares/canonical-data.json +15 -21
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +9 -0
- data/tracks/c/exercises/scrabble-score/makefile +16 -0
- data/tracks/c/exercises/scrabble-score/src/example.c +43 -0
- data/tracks/c/exercises/scrabble-score/src/example.h +6 -0
- data/tracks/c/exercises/scrabble-score/test/test_scrabble_score.c +77 -0
- data/tracks/c/exercises/scrabble-score/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/scrabble-score/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/scrabble-score/test/vendor/unity_internals.h +701 -0
- data/tracks/csharp/exercises/grade-school/Example.cs +1 -1
- data/tracks/csharp/exercises/grade-school/GradeSchoolTest.cs +8 -8
- data/tracks/elixir/README.md +29 -12
- data/tracks/elixir/SETUP.md +0 -1
- data/tracks/elixir/docs/ABOUT.md +21 -7
- data/tracks/elixir/docs/LEARNING.md +4 -2
- data/tracks/elixir/docs/RESOURCES.md +2 -2
- data/tracks/elixir/docs/TESTS.md +0 -2
- data/tracks/go/exercises/atbash-cipher/.meta/gen.go +61 -0
- data/tracks/go/exercises/atbash-cipher/atbash_cipher_test.go +1 -16
- data/tracks/go/exercises/atbash-cipher/cases_test.go +61 -0
- data/tracks/go/exercises/atbash-cipher/example.go +1 -1
- data/tracks/java/exercises/hamming/src/main/java/Hamming.java +9 -0
- data/tracks/java/exercises/simple-linked-list/src/test/java/SimpleLinkedListTest.java +4 -4
- data/tracks/javascript/docs/TESTS.md +1 -1
- data/tracks/ocaml/config.json +5 -0
- data/tracks/ocaml/exercises/acronym/test.ml +2 -0
- data/tracks/ocaml/exercises/all-your-base/test.ml +2 -0
- data/tracks/ocaml/exercises/anagram/test.ml +2 -0
- data/tracks/ocaml/exercises/atbash-cipher/test.ml +3 -0
- data/tracks/ocaml/exercises/beer-song/test.ml +2 -0
- data/tracks/ocaml/exercises/binary-search/.merlin +5 -0
- data/tracks/ocaml/exercises/binary-search/Makefile +11 -0
- data/tracks/ocaml/exercises/binary-search/binary_search.mli +2 -0
- data/tracks/ocaml/exercises/binary-search/example.ml +19 -0
- data/tracks/ocaml/exercises/binary-search/test.ml +38 -0
- data/tracks/ocaml/exercises/bob/test.ml +2 -0
- data/tracks/ocaml/exercises/bowling/test.ml +2 -0
- data/tracks/ocaml/exercises/bracket-push/test.ml +2 -0
- data/tracks/ocaml/exercises/change/test.ml +2 -0
- data/tracks/ocaml/exercises/connect/test.ml +2 -0
- data/tracks/ocaml/exercises/difference-of-squares/test.ml +10 -8
- data/tracks/ocaml/exercises/dominoes/test.ml +2 -0
- data/tracks/ocaml/exercises/etl/test.ml +2 -0
- data/tracks/ocaml/exercises/hamming/test.ml +2 -0
- data/tracks/ocaml/exercises/hello-world/test.ml +2 -0
- data/tracks/ocaml/exercises/leap/test.ml +2 -0
- data/tracks/ocaml/exercises/luhn/test.ml +2 -0
- data/tracks/ocaml/exercises/minesweeper/test.ml +2 -0
- data/tracks/ocaml/exercises/pangram/test.ml +2 -0
- data/tracks/ocaml/exercises/phone-number/test.ml +2 -0
- data/tracks/ocaml/exercises/prime-factors/test.ml +2 -0
- data/tracks/ocaml/exercises/raindrops/test.ml +2 -0
- data/tracks/ocaml/exercises/roman-numerals/test.ml +2 -0
- data/tracks/ocaml/exercises/run-length-encoding/test.ml +2 -0
- data/tracks/ocaml/exercises/say/test.ml +2 -0
- data/tracks/ocaml/exercises/space-age/test.ml +2 -0
- data/tracks/ocaml/exercises/triangle/test.ml +2 -0
- data/tracks/ocaml/exercises/word-count/test.ml +2 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +15 -5
- data/tracks/ocaml/tools/test-generator/src/model.ml +5 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +5 -4
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +12 -0
- data/tracks/ocaml/tools/test-generator/templates/binary-search/template.ml +20 -0
- data/tracks/ocaml/tools/test-generator/templates/change/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/say/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +1 -1
- data/tracks/r/docs/TESTS.md +24 -4
- data/tracks/ruby/exercises/trinary/trinary_test.rb +1 -0
- data/tracks/scala/config.json +9 -0
- data/tracks/scala/exercises/accumulate/src/main/scala/Accumulate.scala +3 -0
- data/tracks/scala/exercises/bob/src/main/scala/Bob.scala +3 -0
- data/tracks/scala/exercises/difference-of-squares/src/main/scala/Squares.scala +8 -0
- data/tracks/scala/exercises/gigasecond/src/main/scala/Gigasecond.scala +8 -0
- data/tracks/scala/exercises/grade-school/src/main/scala/School.scala +11 -0
- data/tracks/scala/exercises/pangram/src/main/scala/Pangrams.scala +4 -0
- data/tracks/scala/exercises/protein-translation/build.sbt +3 -0
- data/tracks/scala/exercises/protein-translation/example.scala +41 -0
- data/tracks/scala/exercises/protein-translation/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/protein-translation/src/test/scala/ProteinTranslationTest.scala +59 -0
- data/tracks/scala/exercises/space-age/src/main/scala/SpaceAge.scala +10 -0
- metadata +28 -2
@@ -1,3 +1,5 @@
|
|
1
|
+
(* Test/exercise version: "1.0.0" *)
|
2
|
+
|
1
3
|
open Core.Std
|
2
4
|
open OUnit2
|
3
5
|
open Atbash_cipher
|
@@ -23,6 +25,7 @@ let encode_tests = [
|
|
23
25
|
ae "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" (encode "The quick brown fox jumps over the lazy dog.");
|
24
26
|
]
|
25
27
|
|
28
|
+
|
26
29
|
let decode_tests = [
|
27
30
|
"decode exercism" >::
|
28
31
|
ae "exercism" (decode "vcvix rhn");
|
@@ -0,0 +1,19 @@
|
|
1
|
+
open Core.Std
|
2
|
+
|
3
|
+
let find array value =
|
4
|
+
let rec go lo hi =
|
5
|
+
if lo > hi then None
|
6
|
+
else begin
|
7
|
+
let mid = lo + (hi - lo) / 2 in
|
8
|
+
let mid_val = array.(mid) in
|
9
|
+
if mid_val < value
|
10
|
+
then go (mid + 1) hi
|
11
|
+
else if mid_val > value
|
12
|
+
then go lo (mid - 1)
|
13
|
+
else Some mid
|
14
|
+
end
|
15
|
+
in
|
16
|
+
if Array.is_empty array
|
17
|
+
then None
|
18
|
+
else go 0 (Array.length array - 1)
|
19
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
(* Test/exercise version: "1.0.0" *)
|
2
|
+
|
3
|
+
open Core.Std
|
4
|
+
open OUnit2
|
5
|
+
open Binary_search
|
6
|
+
|
7
|
+
let option_to_string f = function
|
8
|
+
| None -> "None"
|
9
|
+
| Some x -> "Some " ^ f x
|
10
|
+
|
11
|
+
let ae exp got _test_ctxt =
|
12
|
+
assert_equal ~printer:(option_to_string Int.to_string) exp got
|
13
|
+
|
14
|
+
let tests = [
|
15
|
+
"finds a value in an array with one element" >::
|
16
|
+
ae (Some 0) (find [|6|] 6);
|
17
|
+
"finds a value in the middle of an array" >::
|
18
|
+
ae (Some 3) (find [|1; 3; 4; 6; 8; 9; 11|] 6);
|
19
|
+
"finds a value at the beginning of an array" >::
|
20
|
+
ae (Some 0) (find [|1; 3; 4; 6; 8; 9; 11|] 1);
|
21
|
+
"finds a value at the end of an array" >::
|
22
|
+
ae (Some 6) (find [|1; 3; 4; 6; 8; 9; 11|] 11);
|
23
|
+
"finds a value in an array of odd length" >::
|
24
|
+
ae (Some 9) (find [|1; 3; 5; 8; 13; 21; 34; 55; 89; 144; 233; 377; 634|] 144);
|
25
|
+
"finds a value in an array of even length" >::
|
26
|
+
ae (Some 5) (find [|1; 3; 5; 8; 13; 21; 34; 55; 89; 144; 233; 377|] 21);
|
27
|
+
"identifies that a value is not included in the array" >::
|
28
|
+
ae None (find [|1; 3; 4; 6; 8; 9; 11|] 7);
|
29
|
+
"a value smaller than the array's smallest value is not included" >::
|
30
|
+
ae None (find [|1; 3; 4; 6; 8; 9; 11|] 0);
|
31
|
+
"a value larger than the array's largest value is not included" >::
|
32
|
+
ae None (find [|1; 3; 4; 6; 8; 9; 11|] 13);
|
33
|
+
"nothing is included in an empty array" >::
|
34
|
+
ae None (find [||] 1);
|
35
|
+
]
|
36
|
+
|
37
|
+
let () =
|
38
|
+
run_test_tt_main ("binary-search tests" >::: tests)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
(* Test/exercise version: "1.1.0" *)
|
2
|
+
|
1
3
|
open Core.Std
|
2
4
|
open OUnit2
|
3
5
|
open Difference_of_squares
|
@@ -5,30 +7,30 @@ open Difference_of_squares
|
|
5
7
|
let ae exp got _test_ctxt = assert_equal exp got
|
6
8
|
|
7
9
|
let square_of_sum_tests = [
|
10
|
+
"square of sum 1" >::
|
11
|
+
ae 1 (square_of_sum 1);
|
8
12
|
"square of sum 5" >::
|
9
13
|
ae 225 (square_of_sum 5);
|
10
|
-
"square of sum 10" >::
|
11
|
-
ae 3025 (square_of_sum 10);
|
12
14
|
"square of sum 100" >::
|
13
15
|
ae 25502500 (square_of_sum 100);
|
14
16
|
]
|
15
17
|
|
18
|
+
|
16
19
|
let sum_of_squares_tests = [
|
20
|
+
"sum of squares 1" >::
|
21
|
+
ae 1 (sum_of_squares 1);
|
17
22
|
"sum of squares 5" >::
|
18
23
|
ae 55 (sum_of_squares 5);
|
19
|
-
"sum of squares 10" >::
|
20
|
-
ae 385 (sum_of_squares 10);
|
21
24
|
"sum of squares 100" >::
|
22
25
|
ae 338350 (sum_of_squares 100);
|
23
26
|
]
|
24
27
|
|
28
|
+
|
25
29
|
let difference_of_squares_tests = [
|
26
|
-
"difference of squares
|
27
|
-
ae 0 (difference_of_squares
|
30
|
+
"difference of squares 1" >::
|
31
|
+
ae 0 (difference_of_squares 1);
|
28
32
|
"difference of squares 5" >::
|
29
33
|
ae 170 (difference_of_squares 5);
|
30
|
-
"difference of squares 10" >::
|
31
|
-
ae 2640 (difference_of_squares 10);
|
32
34
|
"difference of squares 100" >::
|
33
35
|
ae 25164150 (difference_of_squares 100);
|
34
36
|
]
|
@@ -27,11 +27,16 @@ let combine_files (template_files: (string * content) list) (canonical_data_file
|
|
27
27
|
|
28
28
|
(* pangram in the canonical data is a suite but it does not really need to be as there's only one group. Convert a Suite to
|
29
29
|
a Single test in this case, to simplify the template. *)
|
30
|
-
let simplify_single_test_suite (
|
31
|
-
| Suite [{name = name; cases = cases}] -> Single cases
|
32
|
-
|
|
30
|
+
let simplify_single_test_suite (canonical_data: canonical_data): canonical_data = match canonical_data.tests with
|
31
|
+
| Suite [{name = name; cases = cases}] -> {version=canonical_data.version; tests=Single cases}
|
32
|
+
| _ -> canonical_data
|
33
33
|
|
34
|
-
|
34
|
+
|
35
|
+
let prepend_version (v: string option) (str: string): string = match v with
|
36
|
+
| None -> str
|
37
|
+
| Some v -> "(* Test/exercise version: \"" ^ v ^ "\" *)\n\n" ^ str
|
38
|
+
|
39
|
+
let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_file: content): (content, string) Result.t =
|
35
40
|
let open Result.Monad_infix in
|
36
41
|
Result.of_option ~error:("cannot recognize file for " ^ slug ^ " as a template") @@ find_template template_file >>= fun template ->
|
37
42
|
let edit_expected = edit_expected ~stringify:json_to_string ~slug in
|
@@ -40,11 +45,12 @@ let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_fil
|
|
40
45
|
let file_text = template.file_text in
|
41
46
|
let file_lines = String.split_lines file_text |> List.to_array in
|
42
47
|
parse_json_text canonical_data_file (expected_key_name slug) (cases_name slug)
|
43
|
-
|> Result.map_error ~f:show_error >>| simplify_single_test_suite >>= (
|
48
|
+
|> Result.map_error ~f:show_error >>| simplify_single_test_suite >>= fun cd -> (match cd.tests with
|
44
49
|
| Single cases ->
|
45
50
|
let template = to_single template.template in
|
46
51
|
fill_in_template template.template slug cases
|
47
52
|
|> fill_tests file_text template
|
53
|
+
|> prepend_version cd.version
|
48
54
|
|> Result.return
|
49
55
|
| Suite tests ->
|
50
56
|
let suites = to_multi template.template in
|
@@ -56,6 +62,7 @@ let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_fil
|
|
56
62
|
in
|
57
63
|
List.map tests ~f:fill_suite_tests |> sequence >>=
|
58
64
|
fill_suite template
|
65
|
+
|> Result.map ~f:(prepend_version cd.version)
|
59
66
|
)
|
60
67
|
|
61
68
|
let output_tests (files: (string * content * content) list) (output_folder: string) ~(generated_folder: string): unit =
|
@@ -69,6 +76,9 @@ let output_tests (files: (string * content * content) list) (output_folder: stri
|
|
69
76
|
| Error e -> print_endline ("Failed when generating " ^ slug ^ ", error: " ^ e) in
|
70
77
|
List.iter files ~f:output1
|
71
78
|
|
79
|
+
(*let add_header (canonical_data_folder: string) (generated: string): string =*)
|
80
|
+
|
81
|
+
|
72
82
|
let run ~(templates_folder: string) ~(canonical_data_folder: string) ~(output_folder: string) ~(generated_folder: string) (filter: string option) =
|
73
83
|
let template_files = find_template_files templates_folder filter in
|
74
84
|
let canonical_data_files = find_canonical_data_files canonical_data_folder in
|
@@ -15,6 +15,11 @@ type tests =
|
|
15
15
|
| Single of case list
|
16
16
|
| Suite of test list
|
17
17
|
|
18
|
+
type canonical_data = {
|
19
|
+
version: string option;
|
20
|
+
tests: tests
|
21
|
+
}
|
22
|
+
|
18
23
|
let rec json_to_string (j: json): string = match j with
|
19
24
|
| `Null -> "null"
|
20
25
|
| `String s -> "\"" ^ (String.escaped s) ^ "\""
|
@@ -69,13 +69,14 @@ let parse_cases_from_suite name suite expected_key cases_key =
|
|
69
69
|
to_list_note ExpectingListOfCases >>= fun tests ->
|
70
70
|
List.map tests ~f:(parse_case expected_key) |> sequence
|
71
71
|
|
72
|
-
let parse_json_text (text: string) (expected_key: string) (cases_key: string): (
|
72
|
+
let parse_json_text (text: string) (expected_key: string) (cases_key: string): (canonical_data, error) Result.t =
|
73
73
|
let open Result.Monad_infix in
|
74
74
|
let json = from_string text in
|
75
|
+
let version = member "version" json |> to_string_option in
|
75
76
|
match suite_cases json cases_key with
|
76
|
-
| Ok suite_cases -> Ok (Suite suite_cases)
|
77
|
-
| Error _ -> parse_single text expected_key cases_key
|
78
|
-
|
77
|
+
| Ok suite_cases -> Ok {version; tests=(Suite suite_cases)}
|
78
|
+
| Error _ -> parse_single text expected_key cases_key >>= fun tests -> Ok {version; tests}
|
79
|
+
|
79
80
|
let show_error = function
|
80
81
|
| TestMustHaveKeyCalledCases name -> "Test named '" ^ name ^ "' is expected to have an object with a key: 'cases'"
|
81
82
|
| ExpectingMapForCase -> "Expected a json map for a test case"
|
@@ -67,6 +67,7 @@ let edit_expected ~(stringify: json -> string) ~(slug: string) ~(value: json) =
|
|
67
67
|
| "connect" -> edit_connect_expected value
|
68
68
|
| "change" -> edit_change_expected value
|
69
69
|
| "bowling" -> edit_bowling_expected value
|
70
|
+
| "binary-search" -> optional_int ~none:(-1) value
|
70
71
|
| _ -> stringify value
|
71
72
|
|
72
73
|
let edit_say (ps: (string * json) list) =
|
@@ -106,6 +107,16 @@ let edit_bowling (ps: (string * json) list): (string * string) list =
|
|
106
107
|
| (k, v) -> (k, json_to_string v) in
|
107
108
|
List.map ps ~f:edit
|
108
109
|
|
110
|
+
let edit_binary_search (ps: (string * json) list): (string * string) list =
|
111
|
+
let open Yojson.Basic.Util in
|
112
|
+
let as_array_string xs =
|
113
|
+
let xs = to_list xs |> List.map ~f:to_int |> List.map ~f:Int.to_string in
|
114
|
+
"[|" ^ String.concat ~sep:"; " xs ^ "|]" in
|
115
|
+
let edit = function
|
116
|
+
| ("array", v) -> ("array", as_array_string v)
|
117
|
+
| (k, v) -> (k, json_to_string v) in
|
118
|
+
List.map ps ~f:edit
|
119
|
+
|
109
120
|
let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (slug, parameters) with
|
110
121
|
| ("hello-world", ps) -> default_value ~key:"name" ~value:"None" (optional_strings ~f:(fun _x -> true) parameters)
|
111
122
|
| ("say", ps) -> edit_say ps
|
@@ -113,6 +124,7 @@ let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (
|
|
113
124
|
| ("dominoes", ps) -> edit_dominoes ps
|
114
125
|
| ("space-age", ps) -> edit_space_age ps
|
115
126
|
| ("bowling", ps) -> edit_bowling ps
|
127
|
+
| ("binary-search", ps) -> edit_binary_search ps
|
116
128
|
| (_, ps) -> map_elements json_to_string ps
|
117
129
|
|
118
130
|
let expected_key_name slug = match slug with
|