trackler 2.0.6.30 → 2.0.6.31
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/common/exercises/beer-song/canonical-data.json +49 -0
- data/common/exercises/food-chain/description.md +1 -2
- data/common/exercises/list-ops/canonical-data.json +147 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/erlang/README.md +2 -3
- data/tracks/erlang/exercises/accumulate/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/accumulate/src/example.erl +4 -1
- data/tracks/erlang/exercises/accumulate/test/accumulate_tests.erl +2 -3
- data/tracks/erlang/exercises/allergies/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/allergies/src/example.erl +4 -1
- data/tracks/erlang/exercises/allergies/test/allergies_tests.erl +2 -3
- data/tracks/erlang/exercises/anagram/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/anagram/src/example.erl +4 -1
- data/tracks/erlang/exercises/anagram/test/anagram_tests.erl +2 -3
- data/tracks/erlang/exercises/atbash-cipher/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/atbash-cipher/src/example.erl +4 -1
- data/tracks/erlang/exercises/atbash-cipher/test/atbash_cipher_tests.erl +2 -3
- data/tracks/erlang/exercises/bank-account/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/bank-account/src/example.erl +5 -1
- data/tracks/erlang/exercises/bank-account/test/bank_account_tests.erl +2 -2
- data/tracks/erlang/exercises/beer-song/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/beer-song/src/example.erl +5 -1
- data/tracks/erlang/exercises/beer-song/test/beer_song_tests.erl +2 -2
- data/tracks/erlang/exercises/binary/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/binary/src/example.erl +4 -1
- data/tracks/erlang/exercises/binary/test/binary_string_tests.erl +2 -2
- data/tracks/erlang/exercises/bob/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/bob/src/example.erl +6 -1
- data/tracks/erlang/exercises/bob/test/bob_tests.erl +2 -3
- data/tracks/erlang/exercises/circular-buffer/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/circular-buffer/src/example.erl +4 -1
- data/tracks/erlang/exercises/circular-buffer/test/circular_buffer_tests.erl +2 -2
- data/tracks/erlang/exercises/clock/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/clock/src/example.erl +9 -3
- data/tracks/erlang/exercises/clock/test/clock_tests.erl +2 -2
- data/tracks/erlang/exercises/difference-of-squares/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/difference-of-squares/src/example.erl +4 -1
- data/tracks/erlang/exercises/difference-of-squares/test/difference_of_squares_tests.erl +2 -2
- data/tracks/erlang/exercises/etl/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/etl/src/example.erl +6 -1
- data/tracks/erlang/exercises/etl/test/etl_tests.erl +2 -2
- data/tracks/erlang/exercises/gigasecond/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/gigasecond/src/example.erl +4 -1
- data/tracks/erlang/exercises/gigasecond/test/gigasecond_tests.erl +2 -2
- data/tracks/erlang/exercises/grade-school/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/grade-school/src/example.erl +4 -1
- data/tracks/erlang/exercises/grade-school/test/grade_school_tests.erl +2 -2
- data/tracks/erlang/exercises/grains/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/grains/src/example.erl +4 -1
- data/tracks/erlang/exercises/grains/test/grains_tests.erl +2 -2
- data/tracks/erlang/exercises/hamming/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/hamming/src/example.erl +4 -1
- data/tracks/erlang/exercises/hamming/test/hamming_tests.erl +2 -2
- data/tracks/erlang/exercises/hello-world/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/hello-world/src/example.erl +4 -1
- data/tracks/erlang/exercises/hello-world/test/hello_world_tests.erl +2 -2
- data/tracks/erlang/exercises/largest-series-product/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/largest-series-product/src/example.erl +3 -1
- data/tracks/erlang/exercises/largest-series-product/test/largest_series_product_tests.erl +2 -2
- data/tracks/erlang/exercises/leap/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/leap/src/example.erl +6 -1
- data/tracks/erlang/exercises/leap/test/leap_tests.erl +2 -2
- data/tracks/erlang/exercises/luhn/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/luhn/src/example.erl +6 -1
- data/tracks/erlang/exercises/luhn/test/luhn_tests.erl +2 -2
- data/tracks/erlang/exercises/meetup/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/meetup/src/example.erl +6 -1
- data/tracks/erlang/exercises/meetup/test/meetup_tests.erl +2 -2
- data/tracks/erlang/exercises/nucleotide-count/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/nucleotide-count/src/example.erl +4 -1
- data/tracks/erlang/exercises/nucleotide-count/test/dna_tests.erl +2 -2
- data/tracks/erlang/exercises/parallel-letter-frequency/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/parallel-letter-frequency/src/example.erl +3 -1
- data/tracks/erlang/exercises/parallel-letter-frequency/test/parallel_letter_frequency_tests.erl +2 -2
- data/tracks/erlang/exercises/phone-number/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/phone-number/src/example.erl +4 -1
- data/tracks/erlang/exercises/phone-number/test/phone_tests.erl +2 -2
- data/tracks/erlang/exercises/rna-transcription/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/rna-transcription/src/example.erl +6 -1
- data/tracks/erlang/exercises/rna-transcription/test/rna_transcription_tests.erl +2 -2
- data/tracks/erlang/exercises/robot-simulator/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/robot-simulator/src/example.erl +12 -1
- data/tracks/erlang/exercises/robot-simulator/test/robot_simulator_tests.erl +2 -2
- data/tracks/erlang/exercises/roman-numerals/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/roman-numerals/src/example.erl +6 -1
- data/tracks/erlang/exercises/roman-numerals/test/roman_numerals_tests.erl +2 -2
- data/tracks/erlang/exercises/scrabble-score/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/scrabble-score/src/example.erl +4 -1
- data/tracks/erlang/exercises/scrabble-score/test/scrabble_score_tests.erl +2 -2
- data/tracks/erlang/exercises/series/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/series/src/example.erl +3 -1
- data/tracks/erlang/exercises/series/test/series_tests.erl +2 -2
- data/tracks/erlang/exercises/space-age/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/space-age/src/example.erl +6 -1
- data/tracks/erlang/exercises/space-age/test/space_age_tests.erl +2 -2
- data/tracks/erlang/exercises/strain/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/strain/src/example.erl +4 -1
- data/tracks/erlang/exercises/strain/test/strain_tests.erl +2 -2
- data/tracks/erlang/exercises/sum-of-multiples/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/sum-of-multiples/src/example.erl +6 -1
- data/tracks/erlang/exercises/sum-of-multiples/test/sum_of_multiples_tests.erl +2 -2
- data/tracks/erlang/exercises/triangle/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/triangle/src/example.erl +4 -1
- data/tracks/erlang/exercises/triangle/test/triangle_tests.erl +2 -2
- data/tracks/erlang/exercises/trinary/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/trinary/src/example.erl +4 -1
- data/tracks/erlang/exercises/trinary/test/trinary_tests.erl +2 -2
- data/tracks/erlang/exercises/word-count/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/word-count/src/example.erl +6 -1
- data/tracks/erlang/exercises/word-count/test/word_count_tests.erl +2 -2
- data/tracks/erlang/exercises/zipper/include/exercism.hrl +5 -0
- data/tracks/erlang/exercises/zipper/src/example.erl +4 -5
- data/tracks/erlang/exercises/zipper/test/zipper_tests.erl +2 -2
- data/tracks/go/exercises/pangram/pangram_test.go +9 -1
- data/tracks/java/.travis.yml +8 -0
- data/tracks/java/README.md +1 -1
- data/tracks/julia/config.json +11 -1
- data/tracks/julia/exercises/sieve/example.jl +15 -0
- data/tracks/julia/exercises/sieve/runtests.jl +37 -0
- data/tracks/julia/exercises/sieve/sieve.jl +3 -0
- data/tracks/objective-c/circle.yml +6 -0
- data/tracks/ocaml/SETUP.md +1 -13
- data/tracks/ocaml/exercises/atbash-cipher/test.ml +38 -29
- data/tracks/ocaml/tools/test-generator/src/codegen.ml +4 -3
- data/tracks/ocaml/tools/test-generator/src/controller.ml +1 -1
- data/tracks/ocaml/tools/test-generator/src/model.ml +16 -33
- data/tracks/ocaml/tools/test-generator/src/parser.ml +2 -35
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +36 -23
- data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/atbash-cipher/template.ml +24 -0
- data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/bracket-push/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/hello-world/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/luhn/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/pangram/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +1 -1
- data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +5 -3
- data/tracks/ocaml/tools/test-generator/test/model_test.ml +2 -20
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +10 -19
- data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +7 -6
- data/tracks/perl6/config.json +5 -0
- data/tracks/perl6/exercises/hello-world/Example.pm +5 -0
- data/tracks/perl6/exercises/hello-world/HelloWorld.pm6 +15 -0
- data/tracks/perl6/exercises/hello-world/hello-world.t +32 -0
- metadata +12 -2
data/tracks/ocaml/SETUP.md
CHANGED
@@ -9,19 +9,7 @@ To work on the exercises, you will need `Opam` and `Core`. Consult [opam](https:
|
|
9
9
|
opam install core
|
10
10
|
|
11
11
|
## Running Tests
|
12
|
-
|
13
|
-
|
14
|
-
```bash
|
15
|
-
$ corebuild -quiet test.native
|
16
|
-
```
|
17
|
-
|
18
|
-
and when successful run the tests by running the `test.native` executable:
|
19
|
-
|
20
|
-
```bash
|
21
|
-
./test.native
|
22
|
-
```
|
23
|
-
|
24
|
-
Alternatively just type
|
12
|
+
A Makefile is provided with a default target to compile your solution and run the tests. At the command line, type:
|
25
13
|
|
26
14
|
```bash
|
27
15
|
make
|
@@ -4,34 +4,43 @@ open Atbash_cipher
|
|
4
4
|
|
5
5
|
let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
|
6
6
|
|
7
|
-
let
|
8
|
-
|
9
|
-
|
10
|
-
"encode no">::
|
11
|
-
|
12
|
-
"encode OMG">::
|
13
|
-
|
14
|
-
"encode spaces">::
|
15
|
-
|
16
|
-
"encode mindblowingly">::
|
17
|
-
|
18
|
-
"encode numbers">::
|
19
|
-
|
20
|
-
"encode deep thought">::
|
21
|
-
|
22
|
-
"encode all the letters">::
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
7
|
+
let encode_tests = [
|
8
|
+
"encode yes" >::
|
9
|
+
ae "bvh" (encode "yes");
|
10
|
+
"encode no" >::
|
11
|
+
ae "ml" (encode "no");
|
12
|
+
"encode OMG" >::
|
13
|
+
ae "lnt" (encode "OMG");
|
14
|
+
"encode spaces" >::
|
15
|
+
ae "lnt" (encode "O M G");
|
16
|
+
"encode mindblowingly" >::
|
17
|
+
ae "nrmwy oldrm tob" (encode "mindblowingly");
|
18
|
+
"encode numbers" >::
|
19
|
+
ae "gvhgr mt123 gvhgr mt" (encode "Testing,1 2 3, testing.");
|
20
|
+
"encode deep thought" >::
|
21
|
+
ae "gifgs rhurx grlm" (encode "Truth is fiction.");
|
22
|
+
"encode all the letters" >::
|
23
|
+
ae "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" (encode "The quick brown fox jumps over the lazy dog.");
|
24
|
+
]
|
25
|
+
|
26
|
+
let decode_tests = [
|
27
|
+
"decode exercism" >::
|
28
|
+
ae "exercism" (decode "vcvix rhn");
|
29
|
+
"decode a sentence" >::
|
30
|
+
ae "anobstacleisoftenasteppingstone" (decode "zmlyh gzxov rhlug vmzhg vkkrm thglm v");
|
31
|
+
"decode numbers" >::
|
32
|
+
ae "testing123testing" (decode "gvhgr mt123 gvhgr mt");
|
33
|
+
"decode all the letters" >::
|
34
|
+
ae "thequickbrownfoxjumpsoverthelazydog" (decode "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt");
|
35
|
+
]
|
36
|
+
|
37
|
+
let different_block_size_test = [
|
38
|
+
"encode mindblowingly with a different block size">::
|
39
|
+
ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
|
40
|
+
]
|
35
41
|
|
36
42
|
let () =
|
37
|
-
run_test_tt_main (
|
43
|
+
run_test_tt_main (
|
44
|
+
"atbash-cipher tests" >:::
|
45
|
+
List.concat [encode_tests; decode_tests; different_block_size_test]
|
46
|
+
)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
open Core.Std
|
2
2
|
|
3
3
|
open Model
|
4
|
+
open Yojson.Basic
|
4
5
|
|
5
|
-
type edit_expected_function = value:
|
6
|
+
type edit_expected_function = value: json -> string
|
6
7
|
|
7
|
-
type edit_parameters_function = (string *
|
8
|
+
type edit_parameters_function = (string * json) list -> (string * string) list
|
8
9
|
|
9
10
|
type subst = Subst of string [@@deriving eq, show]
|
10
11
|
|
@@ -22,7 +23,7 @@ let rec replace_keys (f: edit_expected_function) (ed: edit_parameters_function)
|
|
22
23
|
let expected = f ~value:c.expected in
|
23
24
|
let s = replace_key "expected" expected s in
|
24
25
|
let s = replace_key "suite-name" suite_name s in
|
25
|
-
let parameter_strings = ed @@ List.map ~f:(fun (k,p) -> (k,
|
26
|
+
let parameter_strings = ed @@ List.map ~f:(fun (k,p) -> (k,p)) c.parameters in
|
26
27
|
List.fold parameter_strings ~init:(Subst s) ~f:(fun (Subst s) (k,v) -> Subst (replace_key k v s))
|
27
28
|
|
28
29
|
let fill_in_template (f: edit_expected_function) (ed: edit_parameters_function) test_template suite_name cases =
|
@@ -24,7 +24,7 @@ let combine_files (template_files: (string * content) list) (canonical_data_file
|
|
24
24
|
|
25
25
|
let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_file: content): (content, content) Result.t =
|
26
26
|
let template = find_template template_file in
|
27
|
-
let edit_expected = edit_expected ~stringify:
|
27
|
+
let edit_expected = edit_expected ~stringify:json_to_string ~slug in
|
28
28
|
let edit_parameters = edit_parameters ~slug in
|
29
29
|
let fill_in_template = fill_in_template edit_expected edit_parameters in
|
30
30
|
let open Result.Monad_infix in
|
@@ -1,43 +1,26 @@
|
|
1
1
|
open Core.Std
|
2
2
|
|
3
3
|
open Utils
|
4
|
-
|
5
|
-
type parameter =
|
6
|
-
| Null
|
7
|
-
| String of string
|
8
|
-
| Float of float
|
9
|
-
| Int of int
|
10
|
-
| Bool of bool
|
11
|
-
| StringList of (string list)
|
12
|
-
| IntList of (int list)
|
13
|
-
| IntTupleList of ((int * int) list)
|
14
|
-
| IntStringMap of ((string * int) list) [@@deriving eq, show]
|
15
|
-
|
16
|
-
type 'a elements = (string * 'a) list [@@deriving eq, show]
|
4
|
+
open Yojson.Basic
|
17
5
|
|
18
6
|
type case = {
|
19
7
|
description: string;
|
20
|
-
parameters:
|
21
|
-
expected:
|
22
|
-
}
|
8
|
+
parameters: (string * json) list;
|
9
|
+
expected: json;
|
10
|
+
}
|
23
11
|
|
24
|
-
type test = {name: string; cases: case list}
|
12
|
+
type test = {name: string; cases: case list}
|
25
13
|
|
26
14
|
type tests =
|
27
15
|
| Single of case list
|
28
|
-
| Suite of test list
|
29
|
-
|
30
|
-
let
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
39
|
-
| StringList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:(surround '\"' >> String.escaped) xs) ^ "]"
|
40
|
-
| IntList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:Int.to_string xs) ^ "]"
|
41
|
-
| IntTupleList xs -> "[" ^ String.concat ~sep:"; " (List.map xs ~f:(fun (x,y) -> sprintf "(%d,%d)" x y)) ^ "]"
|
42
|
-
| IntStringMap xs -> "[" ^ String.concat ~sep:"; "
|
43
|
-
(List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ Int.to_string v ^ ")")) ^ "]"
|
16
|
+
| Suite of test list
|
17
|
+
|
18
|
+
let rec json_to_string (j: json): string = match j with
|
19
|
+
| `Null -> "null"
|
20
|
+
| `String s -> "\"" ^ (String.escaped s) ^ "\""
|
21
|
+
| `Float f -> Float.to_string f
|
22
|
+
| `Int n -> Int.to_string n
|
23
|
+
| `Bool b -> Bool.to_string b
|
24
|
+
| `List xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:json_to_string xs) ^ "]"
|
25
|
+
| `Assoc xs -> "[" ^ String.concat ~sep:"; "
|
26
|
+
(List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ json_to_string v ^ ")")) ^ "]"
|
@@ -8,38 +8,6 @@ type error =
|
|
8
8
|
TestMustHaveKeyCalledCases of string | ExpectingListOfCases | ExpectingMapForCase |
|
9
9
|
NoDescription | BadDescription | NoExpected of string | BadExpected | UnrecognizedJson [@@deriving eq, show]
|
10
10
|
|
11
|
-
let to_int_safe = function
|
12
|
-
| `Int x -> Some x
|
13
|
-
| _ -> None
|
14
|
-
|
15
|
-
let to_tuple_safe xs = match xs with
|
16
|
-
| `List [`Int x; `Int y] -> Some (x,y)
|
17
|
-
| _ -> None
|
18
|
-
|
19
|
-
let rec to_list_safe xs: parameter option = let open Option.Monad_infix in match xs with
|
20
|
-
| [] -> Some (StringList [])
|
21
|
-
| `String x :: _ -> Some (StringList (List.map xs ~f:to_string))
|
22
|
-
| `Int x :: _ -> List.map xs ~f:to_int_safe |> sequence_option >>= (fun xs -> Some (IntList xs))
|
23
|
-
| `List x :: _ -> List.map xs ~f:to_tuple_safe |> sequence_option >>= (fun xs -> Some (IntTupleList xs))
|
24
|
-
| _ -> None
|
25
|
-
|
26
|
-
let q xs = let open Option.Monad_infix in
|
27
|
-
List.map xs ~f:(fun (k,v) -> (to_int_safe v |> Option.map ~f:(fun v -> (k,v))))
|
28
|
-
|
29
|
-
let to_parameter (s: json) = match s with
|
30
|
-
| `Null -> Some (Null)
|
31
|
-
| `String x -> Some (String x)
|
32
|
-
| `Float x -> Some (Float x)
|
33
|
-
| `Int x -> Some (Int x)
|
34
|
-
| `Bool x -> Some (Bool x)
|
35
|
-
| `List x -> to_list_safe x
|
36
|
-
| `Assoc xs -> let open Option.Monad_infix in
|
37
|
-
let xs = List.map xs ~f:(fun (k,v) -> (to_int_safe v |> Option.map ~f:(fun v -> (k,v)))) in
|
38
|
-
sequence_option xs >>= fun xs -> Some (IntStringMap xs)
|
39
|
-
|
40
|
-
let parse_parameters (parameters: (string * json) list): parameter elements =
|
41
|
-
List.filter_map parameters ~f:(fun (k, v) -> Option.map ~f:(fun v -> (k, v)) (to_parameter v))
|
42
|
-
|
43
11
|
let parse_case_assoc (parameters: (string * json) list) (expected_key: string): (case, error) Result.t =
|
44
12
|
let find name e = List.Assoc.find parameters name |> Result.of_option ~error:e in
|
45
13
|
let test_parameters = List.Assoc.remove parameters "description" in
|
@@ -47,9 +15,8 @@ let parse_case_assoc (parameters: (string * json) list) (expected_key: string):
|
|
47
15
|
let open Result.Monad_infix in
|
48
16
|
find "description" NoDescription >>=
|
49
17
|
to_string_note BadDescription >>= fun description ->
|
50
|
-
find expected_key (NoExpected description) >>= fun
|
51
|
-
|
52
|
-
Ok {description = description; parameters = parse_parameters test_parameters; expected = expected}
|
18
|
+
find expected_key (NoExpected description) >>= fun expected ->
|
19
|
+
Ok {description = description; parameters = test_parameters; expected = expected}
|
53
20
|
|
54
21
|
let parse_case (expected_key: string) (s: json): (case, error) Result.t = match s with
|
55
22
|
| `Assoc assoc -> parse_case_assoc assoc expected_key
|
@@ -1,60 +1,73 @@
|
|
1
1
|
open Core.Std
|
2
2
|
|
3
3
|
open Model
|
4
|
+
open Yojson.Basic
|
5
|
+
|
6
|
+
let map_elements (to_str: json -> string) (parameters: (string * json) list): (string * string) list =
|
7
|
+
List.map parameters ~f:(fun (k,j) -> (k,to_str j))
|
4
8
|
|
5
9
|
let optional_int ~(none: int) = function
|
6
|
-
| Int n when n = none -> "None"
|
7
|
-
| Int n -> "(Some " ^ Int.to_string n ^ ")"
|
8
|
-
| x ->
|
10
|
+
| `Int n when n = none -> "None"
|
11
|
+
| `Int n -> "(Some " ^ Int.to_string n ^ ")"
|
12
|
+
| x -> json_to_string x
|
9
13
|
|
10
14
|
let optional_int_list = function
|
11
|
-
|
|
15
|
+
| `List xs -> "(Some [" ^ String.concat ~sep:"; " (List.map ~f:json_to_string xs) ^ "])"
|
12
16
|
| _ -> "None"
|
13
17
|
|
14
18
|
let optional_int_or_string ~(none: int) = function
|
15
|
-
| String s -> "(Some \"" ^ s ^ "\")"
|
16
|
-
| Int n when n = none -> "None"
|
17
|
-
| x ->
|
19
|
+
| `String s -> "(Some \"" ^ s ^ "\")"
|
20
|
+
| `Int n when n = none -> "None"
|
21
|
+
| x -> json_to_string x
|
18
22
|
|
19
23
|
let default_value ~(key: string) ~(value: string) (parameters: (string * string) list): (string * string) list =
|
20
24
|
if List.exists ~f:(fun (k, _) -> k = key) parameters
|
21
25
|
then parameters
|
22
26
|
else (key, value) :: parameters
|
23
27
|
|
24
|
-
let optional_strings ~(f: string -> bool) (parameters: (string *
|
28
|
+
let optional_strings ~(f: string -> bool) (parameters: (string * json) list): (string * string) list =
|
25
29
|
let replace parameter =
|
26
30
|
let (k, v) = parameter in
|
27
31
|
if f k
|
28
|
-
then (k, "(Some
|
29
|
-
else
|
32
|
+
then (k, "(Some " ^ json_to_string v ^ ")")
|
33
|
+
else (k, json_to_string v) in
|
30
34
|
List.map ~f:replace parameters
|
31
35
|
|
32
|
-
let edit_expected ~(stringify:
|
36
|
+
let edit_expected ~(stringify: json -> string) ~(slug: string) ~(value: json) = match slug with
|
33
37
|
| "hamming" -> optional_int ~none:(-1) value
|
34
38
|
| "all-your-base" -> optional_int_list value
|
35
39
|
| "say" -> optional_int_or_string ~none:(-1) value
|
36
40
|
| _ -> stringify value
|
37
41
|
|
38
|
-
let edit_say (ps: (string *
|
42
|
+
let edit_say (ps: (string * json) list) =
|
39
43
|
let edit = function
|
40
|
-
| ("input", v) -> ("input", if Int.of_string v >= 0 then "(" ^ v ^ "L)" else v ^ "L")
|
41
|
-
|
|
44
|
+
| ("input", v) -> ("input", let v = json_to_string v in if Int.of_string v >= 0 then "(" ^ v ^ "L)" else v ^ "L")
|
45
|
+
| (k, ps) -> (k, json_to_string ps) in
|
42
46
|
List.map ps ~f:edit
|
43
47
|
|
44
|
-
let edit_all_your_base (ps: (string *
|
48
|
+
let edit_all_your_base (ps: (string * json) list): (string * string) list =
|
45
49
|
let edit = function
|
46
|
-
| ("output_base", v) -> ("output_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
|
47
|
-
| ("input_base", v) -> ("input_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
|
48
|
-
|
|
50
|
+
| ("output_base", v) -> let v = json_to_string v in ("output_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
|
51
|
+
| ("input_base", v) -> let v = json_to_string v in ("input_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
|
52
|
+
| (k, v) -> (k, json_to_string v) in
|
49
53
|
List.map ps ~f:edit
|
50
54
|
|
51
|
-
let
|
52
|
-
|
|
53
|
-
|
54
|
-
|
55
|
+
let two_elt_list_to_tuple (j: json): string = match j with
|
56
|
+
| `List [`Int x1; `Int x2] -> sprintf "(%d,%d)" x1 x2
|
57
|
+
| _ -> failwith "two element list expected, but got " ^ (json_to_string j)
|
58
|
+
|
59
|
+
let edit_dominoes (ps: (string * json) list): (string * string) list =
|
60
|
+
let edit (p: (string * json)) = match p with
|
61
|
+
| ("input", `List j) -> ("input", "[" ^ (List.map ~f:two_elt_list_to_tuple j |> String.concat ~sep:"; ") ^ "]")
|
62
|
+
| (k, v) -> (k, json_to_string v) in
|
63
|
+
List.map ps ~f:edit
|
64
|
+
|
65
|
+
let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (slug, parameters) with
|
66
|
+
| ("hello-world", ps) -> default_value ~key:"name" ~value:"None" (optional_strings ~f:(fun _x -> true) parameters)
|
55
67
|
| ("say", ps) -> edit_say ps
|
56
68
|
| ("all-your-base", ps) -> edit_all_your_base ps
|
57
|
-
| (
|
69
|
+
| ("dominoes", ps) -> edit_dominoes ps
|
70
|
+
| (_, ps) -> map_elements json_to_string ps
|
58
71
|
|
59
72
|
let expected_key_name slug = match slug with
|
60
73
|
| "dominoes" -> "can_chain"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Atbash_cipher
|
4
|
+
|
5
|
+
let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
|
6
|
+
|
7
|
+
let (* SUITE *)$(suite_name)_tests = [
|
8
|
+
(* TEST
|
9
|
+
"$description" >::
|
10
|
+
ae $expected ($suite-name $phrase);
|
11
|
+
END TEST *)
|
12
|
+
]
|
13
|
+
(* END SUITE *)
|
14
|
+
|
15
|
+
let different_block_size_test = [
|
16
|
+
"encode mindblowingly with a different block size" >::
|
17
|
+
ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
|
18
|
+
]
|
19
|
+
|
20
|
+
let () =
|
21
|
+
run_test_tt_main (
|
22
|
+
"atbash-cipher tests" >:::
|
23
|
+
List.concat [(* suite-all-names *); different_block_size_test]
|
24
|
+
)
|
@@ -2,11 +2,13 @@ open Core.Std
|
|
2
2
|
open OUnit2
|
3
3
|
open Codegen
|
4
4
|
open Model
|
5
|
+
open Yojson.Basic
|
5
6
|
|
6
7
|
let leap_template = "\"$description\" >:: ae $expected (leap_year $input);"
|
7
8
|
|
8
|
-
let edit_expected ~value =
|
9
|
-
let edit_parameters =
|
9
|
+
let edit_expected ~value = json_to_string value
|
10
|
+
let edit_parameters (j: (string * json) list): (string * string) list =
|
11
|
+
List.map ~f:(fun (k,v) -> (k,to_string v)) j
|
10
12
|
let assert_fill_in_template exp cases = assert_equal exp
|
11
13
|
~printer:(fun xs -> "[" ^ (String.concat ~sep:";" xs) ^ "]")
|
12
14
|
(fill_in_template edit_expected edit_parameters leap_template "suite-name" cases |> List.map ~f:subst_to_string)
|
@@ -17,7 +19,7 @@ let codegen_tests = [
|
|
17
19
|
ae [] [];
|
18
20
|
|
19
21
|
"generates one function based on leap year for one case" >::(fun ctxt ->
|
20
|
-
let c = {description = "leap_year"; parameters = [("input", Int 1996)]; expected = Bool true} in
|
22
|
+
let c = {description = "leap_year"; parameters = [("input", `Int 1996)]; expected = `Bool true} in
|
21
23
|
assert_fill_in_template ["\"leap_year\" >:: ae true (leap_year 1996);"] [c]
|
22
24
|
);
|
23
25
|
]
|
@@ -6,24 +6,6 @@ open Model
|
|
6
6
|
let ae exp got _ctxt = assert_equal ~printer:Fn.id exp got
|
7
7
|
|
8
8
|
let model_tests = [
|
9
|
-
"
|
10
|
-
ae "
|
11
|
-
"bool parameter to string" >::
|
12
|
-
ae "true" @@ parameter_to_string (Bool true);
|
13
|
-
"string parameter to string" >::
|
14
|
-
ae "xyz" @@ parameter_to_string (String "xyz");
|
15
|
-
"string parameter containing escaped characters to string" >::
|
16
|
-
ae "x\\t\\ny" @@ parameter_to_string (String "x\t\ny");
|
17
|
-
"float parameter to string" >::
|
18
|
-
ae "3.14" @@ parameter_to_string (Float 3.14);
|
19
|
-
"string list parameter to string" >::
|
20
|
-
ae "[\"a\"; \"bc\"; \"def\"]" @@ parameter_to_string (StringList ["a"; "bc"; "def"]);
|
21
|
-
"string list parameter with escaped characters to string" >::
|
22
|
-
ae "[\"a\\r\"; \"b\\nc\"; \"d\\tef\"]" @@ parameter_to_string (StringList ["a\r"; "b\nc"; "d\tef"]);
|
23
|
-
"int list parameter to string" >::
|
24
|
-
ae "[1; 2; 3; 4]" @@ parameter_to_string (IntList [1; 2; 3; 4]);
|
25
|
-
"int string map parameter to string" >::
|
26
|
-
ae "[(\"one\", 1); (\"two\", 1)]" @@ parameter_to_string (IntStringMap [("one", 1); ("two", 1)]);
|
27
|
-
"int string map parameter to string with escaped characters in the keys" >::
|
28
|
-
ae "[(\"\\t\\r\", 1); (\"two\\n\", 1)]" @@ parameter_to_string (IntStringMap [("\t\r", 1); ("two\n", 1)]);
|
9
|
+
"json_to_string on list of strings" >::
|
10
|
+
ae "[\"a\"; \"b\"; \"c\"]" @@ json_to_string (`List [`String "a"; `String "b"; `String "c"]);
|
29
11
|
]
|
@@ -3,12 +3,7 @@ open OUnit2
|
|
3
3
|
open Parser
|
4
4
|
open Model
|
5
5
|
|
6
|
-
let
|
7
|
-
| Ok (Single cs) -> List.map ~f:show_case cs |> String.concat
|
8
|
-
| Ok (Suite cs) -> failwith "no printer"
|
9
|
-
| Error e -> show_error e
|
10
|
-
|
11
|
-
let ae exp got _test_ctxt = assert_equal exp got ~printer:show_cases
|
6
|
+
let ae exp got _test_ctxt = assert_equal exp got
|
12
7
|
|
13
8
|
let single x = Ok (Single x)
|
14
9
|
|
@@ -31,41 +26,37 @@ let parser_tests = [
|
|
31
26
|
(call_parser "{\"cases\" : [\"key\"]}");
|
32
27
|
|
33
28
|
"parses a single element with a description and expected string output" >::
|
34
|
-
ae (single [{description = "d1"; parameters = []; expected = String "value"}])
|
29
|
+
ae (single [{description = "d1"; parameters = []; expected = `String "value"}])
|
35
30
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : \"value\"}]}");
|
36
31
|
|
37
32
|
"parses a single element with a description and expected float output" >::
|
38
|
-
ae (single [{description = "d1"; parameters = []; expected = Float 100.}])
|
33
|
+
ae (single [{description = "d1"; parameters = []; expected = `Float 100.}])
|
39
34
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : 100.0}]}");
|
40
35
|
|
41
36
|
"parses a single element with a description and expected bool output" >::
|
42
|
-
ae (single [{description = "d1"; parameters = []; expected = Bool true}])
|
37
|
+
ae (single [{description = "d1"; parameters = []; expected = `Bool true}])
|
43
38
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : true}]}");
|
44
39
|
|
45
40
|
"parses a single element with a description and expected int list output" >::
|
46
|
-
ae (single [{description = "d1"; parameters = []; expected =
|
41
|
+
ae (single [{description = "d1"; parameters = []; expected = `List [`Int 1;`Int 2;`Int 3]}])
|
47
42
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : [1, 2, 3]}]}");
|
48
43
|
|
49
44
|
"parses a single element with a description and expected null output" >::
|
50
|
-
ae (single [{description = "d1"; parameters = []; expected = Null}])
|
45
|
+
ae (single [{description = "d1"; parameters = []; expected = `Null}])
|
51
46
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : null}]}");
|
52
47
|
|
53
48
|
"parses a single element with an int key value pair" >::
|
54
|
-
ae (single [{description = "d1"; parameters = [("input", Int 1996)]; expected = Bool true}])
|
49
|
+
ae (single [{description = "d1"; parameters = [("input", `Int 1996)]; expected = `Bool true}])
|
55
50
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : 1996, \"expected\" : true}]}");
|
56
51
|
|
57
52
|
"parses a single element with a string key value pair" >::
|
58
|
-
ae (single [{description = "d1"; parameters = [("input", String "some-string")]; expected = Int 85}])
|
53
|
+
ae (single [{description = "d1"; parameters = [("input", `String "some-string")]; expected = `Int 85}])
|
59
54
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : \"some-string\", \"expected\" : 85}]}");
|
60
55
|
|
61
56
|
"parses a single element with a string list key value pair" >::
|
62
|
-
ae (single [{description = "d1"; parameters = [("input",
|
57
|
+
ae (single [{description = "d1"; parameters = [("input", `List [`String "s1"; `String "s2"])]; expected = `Int 85}])
|
63
58
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [\"s1\", \"s2\"], \"expected\" : 85}]}");
|
64
59
|
|
65
|
-
"parses a single element with a int tuple list (modelled as an int list) key value pair" >::
|
66
|
-
ae (single [{description = "d1"; parameters = [("input", IntTupleList [(1,2);(3,4)])]; expected = Int 85}])
|
67
|
-
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [[1,2],[3,4]], \"expected\" : 85}]}");
|
68
|
-
|
69
60
|
"an element without a description is an Error" >::
|
70
61
|
ae (Error NoDescription)
|
71
62
|
(call_parser "{\"cases\" : [{\"input\" : 11, \"expected\" : 85}]}");
|
@@ -79,7 +70,7 @@ let parser_tests = [
|
|
79
70
|
(call_parser "{\"cases\" : [{\"input\" : 11}]}");
|
80
71
|
|
81
72
|
"parses a map in the expected parameter" >::(fun _ctx ->
|
82
|
-
assert_equal (single [{description = "d1"; parameters = []; expected =
|
73
|
+
assert_equal (single [{description = "d1"; parameters = []; expected = `Assoc [("one", `Int 1); ("two", `Int 2)]}])
|
83
74
|
(call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : {\"one\": 1, \"two\": 2}}]}");
|
84
75
|
);
|
85
76
|
|
@@ -3,6 +3,7 @@ open OUnit2
|
|
3
3
|
open Model
|
4
4
|
open Codegen
|
5
5
|
open Special_cases
|
6
|
+
open Yojson.Basic
|
6
7
|
|
7
8
|
let ae exp got _ctxt = assert_equal ~printer:Fn.id exp got
|
8
9
|
|
@@ -10,20 +11,20 @@ let tuples_printer kvs =
|
|
10
11
|
String.concat ~sep:";" @@ List.map ~f:(fun (k,v) -> "(" ^ k ^ "," ^ v ^ ")") kvs
|
11
12
|
|
12
13
|
let stringify = function
|
13
|
-
| Bool true -> "stringified"
|
14
|
+
| `Bool true -> "stringified"
|
14
15
|
| _ -> failwith "Bad type for stringify"
|
15
16
|
|
16
17
|
let special_cases_tests = [
|
17
18
|
"for a non special cased slug convert the parameter to a string" >:: (fun _ctx ->
|
18
|
-
assert_equal ~printer:Fn.id "stringified" @@ edit_expected ~stringify ~slug:"some-slug" ~value:(Bool true)
|
19
|
+
assert_equal ~printer:Fn.id "stringified" @@ edit_expected ~stringify ~slug:"some-slug" ~value:(`Bool true)
|
19
20
|
);
|
20
21
|
|
21
22
|
"an optional int parameter is converted to none if it matches the special value" >:: (fun _ctx ->
|
22
|
-
assert_equal "None" @@ optional_int ~none:88 (Int 88)
|
23
|
+
assert_equal "None" @@ optional_int ~none:88 (`Int 88)
|
23
24
|
);
|
24
25
|
|
25
26
|
"an optional int parameter is converted to (Some value) if it does not match the special value" >:: (fun _ctx ->
|
26
|
-
assert_equal "(Some 0)" @@ optional_int ~none:88 (Int 0)
|
27
|
+
assert_equal "(Some 0)" @@ optional_int ~none:88 (`Int 0)
|
27
28
|
);
|
28
29
|
|
29
30
|
"default_value does not provide a default for a list that has the given key already" >:: (fun _ctx ->
|
@@ -36,7 +37,7 @@ let special_cases_tests = [
|
|
36
37
|
);
|
37
38
|
|
38
39
|
"optional_strings replace value with Some(value)" >:: (fun _ctx ->
|
39
|
-
assert_equal ~printer:tuples_printer [("key", "(Some \"value\")"); ("key2", "value2")]
|
40
|
-
@@ optional_strings ~f:(fun x -> x = "key") [("key", "value"); ("key2", "value2")]
|
40
|
+
assert_equal ~printer:tuples_printer [("key", "(Some \"value\")"); ("key2", "\"value2\"")]
|
41
|
+
@@ optional_strings ~f:(fun x -> x = "key") [("key", `String "value"); ("key2", `String "value2")]
|
41
42
|
);
|
42
43
|
]
|