trackler 2.0.6.0 → 2.0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/csharp/.gitignore +3 -1
- data/tracks/csharp/README.md +1 -1
- data/tracks/csharp/build.fsx +6 -0
- data/tracks/csharp/circle.yml +16 -0
- data/tracks/csharp/paket.dependencies +2 -1
- data/tracks/csharp/paket.lock +3 -0
- data/tracks/ecmascript/exercises/phone-number/example.js +15 -28
- data/tracks/ecmascript/exercises/phone-number/phone-number.spec.js +28 -13
- data/tracks/fsharp/.gitignore +3 -1
- data/tracks/fsharp/README.md +1 -1
- data/tracks/fsharp/build.fsx +7 -1
- data/tracks/fsharp/circle.yml +16 -0
- data/tracks/fsharp/paket.dependencies +2 -1
- data/tracks/fsharp/paket.lock +3 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +5 -5
- data/tracks/ocaml/tools/test-generator/src/model.ml +2 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +35 -31
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +27 -23
- data/tracks/ocaml/tools/test-generator/src/utils.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/dominoes/template.ml +40 -0
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +27 -21
- data/tracks/pony/config.json +5 -0
- data/tracks/pony/docs/ABOUT.md +12 -0
- data/tracks/pony/docs/INSTALLATION.md +4 -6
- data/tracks/pony/docs/LEARNING.md +7 -0
- data/tracks/pony/docs/RESOURCES.md +7 -0
- data/tracks/pony/docs/TESTS.md +11 -0
- data/tracks/pony/exercises/hamming/test.pony +2 -2
- data/tracks/pony/exercises/rna-transcription/example.pony +13 -0
- data/tracks/pony/exercises/rna-transcription/test.pony +32 -0
- data/tracks/r/exercises/anagram/example.R +18 -2
- data/tracks/r/exercises/bob/example.R +16 -1
- data/tracks/r/exercises/luhn/example.R +23 -7
- data/tracks/r/exercises/luhn/luhn.R +6 -0
- data/tracks/r/exercises/word-count/example.R +5 -0
- data/tracks/ruby/exercises/series/example.rb +12 -22
- data/tracks/ruby/exercises/series/series_test.rb +19 -12
- data/tracks/ruby/test/test_helper.rb +3 -3
- data/tracks/scala/config.json +7 -0
- data/tracks/scala/exercises/sieve/build.sbt +2 -2
- data/tracks/scala/exercises/simple-cipher/build.sbt +2 -2
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0a5ee73b9501fd6101f3faf9913c4634acd6cf8
|
4
|
+
data.tar.gz: 4c49bfef6fa06b4a9b9fed119dd455a7a2dd6859
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 240744071c995385c5f96242c76a12c41ae1d60f4bc82194771c9feb90d9b0d2ee2efe97925a11a57ebb0969927572f6ecec12e721a7eb303111e5bde0d021ee
|
7
|
+
data.tar.gz: 76be73161db9c3d6114e2b2f2f7409c59ad09de0b79d56515b52e2df3d4a03b7909e9b0229ad84d4e0e88976ba37dae44f394a09a17d5512851cb83d7149fa7f
|
data/lib/trackler/version.rb
CHANGED
data/tracks/csharp/.gitignore
CHANGED
data/tracks/csharp/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# xCSharp
|
2
2
|
|
3
|
-
[](https://travis-ci.org/exercism/xcsharp) [](https://ci.appveyor.com/project/ErikSchierboom/xcsharp-c03a2/branch/master)
|
3
|
+
[](https://travis-ci.org/exercism/xcsharp) [](https://ci.appveyor.com/project/ErikSchierboom/xcsharp-c03a2/branch/master) [](https://circleci.com/gh/exercism/xcsharp)
|
4
4
|
|
5
5
|
Exercism exercises in C#
|
6
6
|
|
data/tracks/csharp/build.fsx
CHANGED
@@ -11,6 +11,7 @@ let sourceDir = "./exercises/"
|
|
11
11
|
// Files
|
12
12
|
let solutionFile = buildDir @@ "/exercises.csproj"
|
13
13
|
let compiledOutput = buildDir @@ "xcsharp.dll"
|
14
|
+
let nunitToJunitTransformFile = "./paket-files" @@ "nunit" @@ "nunit-transforms" @@ "nunit3-junit" @@ "nunit3-junit.xslt"
|
14
15
|
|
15
16
|
// Targets
|
16
17
|
Target "PrepareUnchanged" (fun _ ->
|
@@ -44,6 +45,11 @@ Target "Test" (fun _ ->
|
|
44
45
|
|> NUnit3 (fun p -> { p with
|
45
46
|
ShadowCopy = false
|
46
47
|
ToolPath = "nunit3-console.exe" })
|
48
|
+
else if getEnvironmentVarAsBool "CIRCLECI" then
|
49
|
+
[compiledOutput]
|
50
|
+
|> NUnit3 (fun p -> { p with
|
51
|
+
ShadowCopy = false
|
52
|
+
ResultSpecs = [sprintf "junit-results.xml;transform=%s" nunitToJunitTransformFile] })
|
47
53
|
else
|
48
54
|
[compiledOutput]
|
49
55
|
|> NUnit3 (fun p -> { p with ShadowCopy = false })
|
@@ -0,0 +1,16 @@
|
|
1
|
+
machine:
|
2
|
+
environment:
|
3
|
+
TERM: xterm-256color
|
4
|
+
dependencies:
|
5
|
+
pre:
|
6
|
+
- sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
7
|
+
- echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
|
8
|
+
- sudo apt-get update
|
9
|
+
- sudo apt-get install mono-complete
|
10
|
+
test:
|
11
|
+
override:
|
12
|
+
- ./build.sh
|
13
|
+
post:
|
14
|
+
- mkdir -p $CIRCLE_TEST_REPORTS/junit/
|
15
|
+
- sed -i '1 s/^\xef\xbb\xbf//' .*/junit-results.xml
|
16
|
+
- find . -type f -regex ".*/junit-results.xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
|
data/tracks/csharp/paket.lock
CHANGED
@@ -75,3 +75,6 @@ NUGET
|
|
75
75
|
Microsoft.NETCore.Platforms (>= 1.0.1) - framework: dnxcore50, netstandard10, >= netstandard13
|
76
76
|
Microsoft.NETCore.Targets (>= 1.0.1) - framework: dnxcore50, netstandard10, >= netstandard13
|
77
77
|
System.Runtime (>= 4.1) - framework: dnxcore50, netstandard10, >= netstandard13
|
78
|
+
GITHUB
|
79
|
+
remote: nunit/nunit-transforms
|
80
|
+
nunit3-junit/nunit3-junit.xslt (2a7c74198375b4b280ff3e79033c3d44e3083850)
|
@@ -2,40 +2,27 @@ export default class PhoneNumber {
|
|
2
2
|
|
3
3
|
constructor(number) {
|
4
4
|
this.rawNumber = number;
|
5
|
-
this.cleanedNumber = cleanNumber(number);
|
6
5
|
}
|
7
6
|
|
8
|
-
number() {
|
7
|
+
number() {
|
8
|
+
if(/[a-zA-Z]/.test(this.rawNumber)) {
|
9
|
+
return null;
|
10
|
+
}
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
toString() {
|
13
|
-
return '(' + this.areaCode() + ')' +
|
14
|
-
' ' +
|
15
|
-
exchangeCode(this.cleanedNumber) + '-' +
|
16
|
-
subscriberNumber(this.cleanedNumber);
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
function cleanNumber(number) {
|
21
|
-
const num = number.replace(/\D/g,'');
|
22
|
-
|
23
|
-
if (num.length === 10) {
|
24
|
-
return num;
|
12
|
+
return this._cleanedNumber();
|
25
13
|
}
|
26
14
|
|
27
|
-
|
28
|
-
|
29
|
-
}
|
15
|
+
_cleanedNumber() {
|
16
|
+
let num = this.rawNumber.replace(/\D/g,'');
|
30
17
|
|
31
|
-
|
32
|
-
|
18
|
+
if (num.length === 10) {
|
19
|
+
return num;
|
20
|
+
}
|
33
21
|
|
34
|
-
|
35
|
-
|
36
|
-
}
|
22
|
+
if (num.length === 11 && num[0] === '1') {
|
23
|
+
return num.substr(1);
|
24
|
+
}
|
37
25
|
|
38
|
-
|
39
|
-
|
26
|
+
return null;
|
27
|
+
}
|
40
28
|
}
|
41
|
-
|
@@ -2,7 +2,7 @@ import PhoneNumber from './phone-number';
|
|
2
2
|
|
3
3
|
describe('PhoneNumber()', () => {
|
4
4
|
|
5
|
-
it('cleans the number
|
5
|
+
it('cleans the number', () => {
|
6
6
|
const phone = new PhoneNumber('(123) 456-7890');
|
7
7
|
expect(phone.number()).toEqual('1234567890');
|
8
8
|
});
|
@@ -12,29 +12,44 @@ describe('PhoneNumber()', () => {
|
|
12
12
|
expect(phone.number()).toEqual('1234567890');
|
13
13
|
});
|
14
14
|
|
15
|
-
xit('
|
16
|
-
const phone = new PhoneNumber('
|
15
|
+
xit('cleans numbers with multiple spaces', () => {
|
16
|
+
const phone = new PhoneNumber('123 456 7890 ');
|
17
17
|
expect(phone.number()).toEqual('1234567890');
|
18
18
|
});
|
19
19
|
|
20
|
+
xit('invalid when 9 digits', () => {
|
21
|
+
const phone = new PhoneNumber('123456789');
|
22
|
+
expect(phone.number()).toEqual(null);
|
23
|
+
});
|
24
|
+
|
20
25
|
xit('invalid when 11 digits', () => {
|
21
26
|
const phone = new PhoneNumber('21234567890');
|
22
|
-
expect(phone.number()).toEqual(
|
27
|
+
expect(phone.number()).toEqual(null);
|
23
28
|
});
|
24
29
|
|
25
|
-
xit('
|
26
|
-
const phone = new PhoneNumber('
|
27
|
-
expect(phone.number()).toEqual('
|
30
|
+
xit('valid when 11 digits and starting with 1', () => {
|
31
|
+
const phone = new PhoneNumber('11234567890');
|
32
|
+
expect(phone.number()).toEqual('1234567890');
|
33
|
+
});
|
34
|
+
|
35
|
+
xit('invalid when 12 digits', () => {
|
36
|
+
const phone = new PhoneNumber('321234567890');
|
37
|
+
expect(phone.number()).toEqual(null);
|
38
|
+
});
|
39
|
+
|
40
|
+
xit('invalid with letters', () => {
|
41
|
+
const phone = new PhoneNumber('123-abc-7890');
|
42
|
+
expect(phone.number()).toEqual(null);
|
28
43
|
});
|
29
44
|
|
30
|
-
xit('
|
31
|
-
const phone = new PhoneNumber('
|
32
|
-
expect(phone.
|
45
|
+
xit('invalid with punctuations', () => {
|
46
|
+
const phone = new PhoneNumber('123-@:!-7890');
|
47
|
+
expect(phone.number()).toEqual(null);
|
33
48
|
});
|
34
49
|
|
35
|
-
xit('
|
36
|
-
const phone = new PhoneNumber('
|
37
|
-
expect(phone.
|
50
|
+
xit('invalid with right number of digits but letters mixed in', () => {
|
51
|
+
const phone = new PhoneNumber('1a2b3c4d5e6f7g8h9i0j');
|
52
|
+
expect(phone.number()).toEqual(null);
|
38
53
|
});
|
39
54
|
|
40
55
|
});
|
data/tracks/fsharp/.gitignore
CHANGED
data/tracks/fsharp/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# xFSharp
|
2
2
|
|
3
|
-
[](https://travis-ci.org/exercism/xfsharp) [](https://ci.appveyor.com/project/ErikSchierboom/xfsharp-8gbdd/branch/master)
|
3
|
+
[](https://travis-ci.org/exercism/xfsharp) [](https://ci.appveyor.com/project/ErikSchierboom/xfsharp-8gbdd/branch/master) [](https://circleci.com/gh/exercism/xfsharp)
|
4
4
|
|
5
5
|
Exercism exercises in F#
|
6
6
|
|
data/tracks/fsharp/build.fsx
CHANGED
@@ -6,11 +6,12 @@ open Fake.Testing.NUnit3
|
|
6
6
|
|
7
7
|
// Directories
|
8
8
|
let buildDir = "./build/"
|
9
|
-
let sourceDir
|
9
|
+
let sourceDir = "./exercises/"
|
10
10
|
|
11
11
|
// Files
|
12
12
|
let solutionFile = buildDir @@ "/exercises.fsproj"
|
13
13
|
let compiledOutput = buildDir @@ "xfsharp.dll"
|
14
|
+
let nunitToJunitTransformFile = "./paket-files" @@ "nunit" @@ "nunit-transforms" @@ "nunit3-junit" @@ "nunit3-junit.xslt"
|
14
15
|
|
15
16
|
// Targets
|
16
17
|
Target "Clean" (fun _ ->
|
@@ -42,6 +43,11 @@ Target "Test" (fun _ ->
|
|
42
43
|
|> NUnit3 (fun p -> { p with
|
43
44
|
ShadowCopy = false
|
44
45
|
ToolPath = "nunit3-console.exe" })
|
46
|
+
else if getEnvironmentVarAsBool "CIRCLECI" then
|
47
|
+
[compiledOutput]
|
48
|
+
|> NUnit3 (fun p -> { p with
|
49
|
+
ShadowCopy = false
|
50
|
+
ResultSpecs = [sprintf "junit-results.xml;transform=%s" nunitToJunitTransformFile] })
|
45
51
|
else
|
46
52
|
[compiledOutput]
|
47
53
|
|> NUnit3 (fun p -> { p with ShadowCopy = false })
|
@@ -0,0 +1,16 @@
|
|
1
|
+
machine:
|
2
|
+
environment:
|
3
|
+
TERM: xterm-256color
|
4
|
+
dependencies:
|
5
|
+
pre:
|
6
|
+
- sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
7
|
+
- echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
|
8
|
+
- sudo apt-get update
|
9
|
+
- sudo apt-get install mono-complete fsharp
|
10
|
+
test:
|
11
|
+
override:
|
12
|
+
- ./build.sh
|
13
|
+
post:
|
14
|
+
- mkdir -p $CIRCLE_TEST_REPORTS/junit/
|
15
|
+
- sed -i '1 s/^\xef\xbb\xbf//' .*/junit-results.xml
|
16
|
+
- find . -type f -regex ".*/junit-results.xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
|
data/tracks/fsharp/paket.lock
CHANGED
@@ -10,9 +10,9 @@ type content = string
|
|
10
10
|
|
11
11
|
let find_nested_files (name: string) (base: string): (string * content) list =
|
12
12
|
Sys.ls_dir base
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
|> List.filter ~f:(fun slug -> Sys.is_directory_exn (base ^ "/" ^ slug))
|
14
|
+
|> List.filter ~f:(fun slug -> Sys.file_exists_exn (base ^ "/" ^ slug ^ "/" ^ name))
|
15
|
+
|> List.map ~f:(fun slug -> (slug, In_channel.read_all (base ^ "/" ^ slug ^ "/" ^ name)))
|
16
16
|
|
17
17
|
let find_template_files = find_nested_files "template.ml"
|
18
18
|
|
@@ -28,7 +28,7 @@ let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_fil
|
|
28
28
|
let fill_in_template = fill_in_template edit_expected edit_parameters in
|
29
29
|
let open Result.Monad_infix in
|
30
30
|
Result.of_option template ("cannot recognize file for " ^ slug ^ " as a template") >>= fun template ->
|
31
|
-
parse_json_text canonical_data_file
|
31
|
+
parse_json_text canonical_data_file (expected_key_name slug)
|
32
32
|
|> Result.map_error ~f:show_error >>= (function
|
33
33
|
| Single cases ->
|
34
34
|
fill_in_template template.template slug cases
|
@@ -60,7 +60,7 @@ let check_canonical_data canonical_data_folder =
|
|
60
60
|
let canonical_data_files = List.sort canonical_data_files ~cmp:(fun (s1, _) (s2, _) -> String.compare s1 s2) in
|
61
61
|
let total_count = List.length canonical_data_files in
|
62
62
|
List.iter canonical_data_files ~f:(fun (slug, text) ->
|
63
|
-
match parse_json_text text with
|
63
|
+
match parse_json_text text (expected_key_name slug) with
|
64
64
|
| Error e -> print_endline @@ slug ^ ": " ^ (show_error e)
|
65
65
|
| _ -> ok_count := !ok_count + 1
|
66
66
|
);
|
@@ -10,6 +10,7 @@ type parameter =
|
|
10
10
|
| Bool of bool
|
11
11
|
| StringList of (string list)
|
12
12
|
| IntList of (int list)
|
13
|
+
| IntTupleList of ((int * int) list)
|
13
14
|
| IntStringMap of ((string * int) list) [@@deriving eq, show]
|
14
15
|
|
15
16
|
type 'a elements = (string * 'a) list [@@deriving eq, show]
|
@@ -37,5 +38,6 @@ let parameter_to_string = function
|
|
37
38
|
| Bool b -> Bool.to_string b
|
38
39
|
| StringList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:(surround '\"' >> String.escaped) xs) ^ "]"
|
39
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)) ^ "]"
|
40
42
|
| IntStringMap xs -> "[" ^ String.concat ~sep:"; "
|
41
43
|
(List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ Int.to_string v ^ ")")) ^ "]"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
open Core.Std
|
2
2
|
open Utils
|
3
|
-
open Yojson.
|
4
|
-
open Yojson.
|
3
|
+
open Yojson.Basic
|
4
|
+
open Yojson.Basic.Util
|
5
5
|
open Model
|
6
6
|
|
7
7
|
type error =
|
@@ -9,46 +9,50 @@ type error =
|
|
9
9
|
NoDescription | BadDescription | NoExpected of string | BadExpected | UnrecognizedJson [@@deriving eq, show]
|
10
10
|
|
11
11
|
let to_int_safe = function
|
12
|
-
|
13
|
-
|
12
|
+
| `Int x -> Some x
|
13
|
+
| _ -> None
|
14
14
|
|
15
|
-
let
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
20
25
|
|
21
26
|
let q xs = let open Option.Monad_infix in
|
22
27
|
List.map xs ~f:(fun (k,v) -> (to_int_safe v |> Option.map ~f:(fun v -> (k,v))))
|
23
28
|
|
24
29
|
let to_parameter (s: json) = match s with
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
| _ -> None
|
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)
|
35
39
|
|
36
40
|
let parse_parameters (parameters: (string * json) list): parameter elements =
|
37
41
|
List.filter_map parameters ~f:(fun (k, v) -> Option.map ~f:(fun v -> (k, v)) (to_parameter v))
|
38
42
|
|
39
|
-
let parse_case_assoc (parameters: (string * json) list): (case, error) Result.t =
|
43
|
+
let parse_case_assoc (parameters: (string * json) list) (expected_key: string): (case, error) Result.t =
|
40
44
|
let find name e = List.Assoc.find parameters name |> Result.of_option ~error:e in
|
41
45
|
let test_parameters = List.Assoc.remove parameters "description" in
|
42
|
-
let test_parameters = List.Assoc.remove test_parameters
|
46
|
+
let test_parameters = List.Assoc.remove test_parameters expected_key in
|
43
47
|
let open Result.Monad_infix in
|
44
48
|
find "description" NoDescription >>=
|
45
49
|
to_string_note BadDescription >>= fun description ->
|
46
|
-
find
|
50
|
+
find expected_key (NoExpected description) >>= fun expectedJson ->
|
47
51
|
to_parameter expectedJson |> Result.of_option ~error:BadExpected >>= fun expected ->
|
48
52
|
Ok {description = description; parameters = parse_parameters test_parameters; expected = expected}
|
49
53
|
|
50
|
-
let parse_case (s: json): (case, error) Result.t = match s with
|
51
|
-
| `Assoc assoc -> parse_case_assoc assoc
|
54
|
+
let parse_case (expected_key: string) (s: json): (case, error) Result.t = match s with
|
55
|
+
| `Assoc assoc -> parse_case_assoc assoc expected_key
|
52
56
|
| _ -> Error ExpectingMapForCase
|
53
57
|
|
54
58
|
let parse_cases (text: string): (json, error) Result.t =
|
@@ -56,11 +60,11 @@ let parse_cases (text: string): (json, error) Result.t =
|
|
56
60
|
| `Null -> Error (TestMustHaveKeyCalledCases "xx")
|
57
61
|
| json -> Ok json
|
58
62
|
|
59
|
-
let parse_single (text: string): (tests, error) Result.t =
|
63
|
+
let parse_single (text: string) (expected_key: string): (tests, error) Result.t =
|
60
64
|
let open Result.Monad_infix in
|
61
65
|
parse_cases text >>=
|
62
66
|
to_list_note ExpectingListOfCases >>=
|
63
|
-
(sequence >> (List.map ~f:parse_case)) >>= fun ts ->
|
67
|
+
(sequence >> (List.map ~f:(parse_case expected_key))) >>= fun ts ->
|
64
68
|
Result.return (Single ts)
|
65
69
|
|
66
70
|
let is_suite (json: json) =
|
@@ -72,24 +76,24 @@ let merge_result = function
|
|
72
76
|
| (_, Error x) -> Error x
|
73
77
|
| (n, Ok c) -> Ok {name = n; cases = c}
|
74
78
|
|
75
|
-
let parse_cases_from_suite name suite =
|
79
|
+
let parse_cases_from_suite name suite expected_key =
|
76
80
|
let open Result.Monad_infix in
|
77
81
|
member_note (TestMustHaveKeyCalledCases name) "cases" suite >>=
|
78
82
|
to_list_note ExpectingListOfCases >>= fun tests ->
|
79
|
-
List.map tests ~f:parse_case |> sequence
|
83
|
+
List.map tests ~f:(parse_case expected_key) |> sequence
|
80
84
|
|
81
|
-
let parse_json_text (text: string): (tests, error) Result.t =
|
85
|
+
let parse_json_text (text: string) (expected_key: string): (tests, error) Result.t =
|
82
86
|
let open Result.Monad_infix in
|
83
87
|
let json = from_string text in
|
84
88
|
if is_suite json
|
85
89
|
then
|
86
90
|
to_assoc_note UnrecognizedJson json >>= fun tests ->
|
87
91
|
let tests = List.filter tests ~f:(fun (n, _) -> n <> "#") in
|
88
|
-
let tests = List.map tests ~f:(fun (name, suite) -> merge_result (name, parse_cases_from_suite name suite)) in
|
92
|
+
let tests = List.map tests ~f:(fun (name, suite) -> merge_result (name, parse_cases_from_suite name suite expected_key)) in
|
89
93
|
sequence tests >>= fun tests ->
|
90
94
|
Ok (Suite tests)
|
91
95
|
else
|
92
|
-
parse_single text
|
96
|
+
parse_single text expected_key
|
93
97
|
|
94
98
|
let show_error = function
|
95
99
|
| TestMustHaveKeyCalledCases name -> "Test named '" ^ name ^ "' is expected to have an object with a key: 'cases'"
|