trackler 2.0.6.30 → 2.0.6.31
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
]
|