This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
87
unikernel/duniverse/astring/test/examples.ml
Normal file
87
unikernel/duniverse/astring/test/examples.ml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
(* This code is in the public domain *)
|
||||
|
||||
open Astring
|
||||
|
||||
(* Version number (v|V).major.minor[.patch][(+|-)info] *)
|
||||
|
||||
let parse_version : string -> (int * int * int * string option) option =
|
||||
fun s -> try
|
||||
let parse_opt_v s = match String.Sub.head s with
|
||||
| Some ('v'|'V') -> String.Sub.tail s
|
||||
| Some _ -> s
|
||||
| None -> raise Exit
|
||||
in
|
||||
let parse_dot s = match String.Sub.head s with
|
||||
| Some '.' -> String.Sub.tail s
|
||||
| Some _ | None -> raise Exit
|
||||
in
|
||||
let parse_int s =
|
||||
match String.Sub.span ~min:1 ~sat:Char.Ascii.is_digit s with
|
||||
| (i, _) when String.Sub.is_empty i -> raise Exit
|
||||
| (i, s) ->
|
||||
match String.Sub.to_int i with
|
||||
| None -> raise Exit | Some i -> i, s
|
||||
in
|
||||
let maj, s = parse_int (parse_opt_v (String.sub s)) in
|
||||
let min, s = parse_int (parse_dot s) in
|
||||
let patch, s = match String.Sub.head s with
|
||||
| Some '.' -> parse_int (parse_dot s)
|
||||
| _ -> 0, s
|
||||
in
|
||||
let info = match String.Sub.head s with
|
||||
| Some ('+' | '-') -> Some (String.Sub.(to_string (tail s)))
|
||||
| Some _ -> raise Exit
|
||||
| None -> None
|
||||
in
|
||||
Some (maj, min, patch, info)
|
||||
with Exit -> None
|
||||
|
||||
(* Key value bindings *)
|
||||
|
||||
let parse_env : string -> string String.map option =
|
||||
fun s -> try
|
||||
let skip_white s = String.Sub.drop ~sat:Char.Ascii.is_white s in
|
||||
let parse_key s =
|
||||
let id_char c = Char.Ascii.is_letter c || c = '_' in
|
||||
match String.Sub.span ~min:1 ~sat:id_char s with
|
||||
| (key, _) when String.Sub.is_empty key -> raise Exit
|
||||
| (key, rem) -> (String.Sub.to_string key), rem
|
||||
in
|
||||
let parse_eq s = match String.Sub.head s with
|
||||
| Some '=' -> String.Sub.tail s
|
||||
| Some _ | None -> raise Exit
|
||||
in
|
||||
let parse_value s = match String.Sub.head s with
|
||||
| Some '"' -> (* quoted *)
|
||||
let is_data = function '\\' | '"' -> false | _ -> true in
|
||||
let rec loop acc s =
|
||||
let data, rem = String.Sub.span ~sat:is_data s in
|
||||
match String.Sub.head rem with
|
||||
| Some '"' ->
|
||||
let acc = List.rev (data :: acc) in
|
||||
String.Sub.(to_string @@ concat acc), (String.Sub.tail rem)
|
||||
| Some '\\' ->
|
||||
let rem = String.Sub.tail rem in
|
||||
begin match String.Sub.head rem with
|
||||
| Some ('"' | '\\' as c) ->
|
||||
let acc = String.(sub (of_char c)) :: data :: acc in
|
||||
loop acc (String.Sub.tail rem)
|
||||
| Some _ | None -> raise Exit
|
||||
end
|
||||
| None | Some _ -> raise Exit
|
||||
in
|
||||
loop [] (String.Sub.tail s)
|
||||
| Some _ ->
|
||||
let is_data c = not (Char.Ascii.is_white c) in
|
||||
let data, rem = String.Sub.span ~sat:is_data s in
|
||||
String.Sub.to_string data, rem
|
||||
| None -> "", s
|
||||
in
|
||||
let rec parse_bindings acc s =
|
||||
if String.Sub.is_empty s then acc else
|
||||
let key, s = parse_key s in
|
||||
let value, s = s |> skip_white |> parse_eq |> skip_white |> parse_value in
|
||||
parse_bindings (String.Map.add key value acc) (skip_white s)
|
||||
in
|
||||
Some (String.sub s |> skip_white |> parse_bindings String.Map.empty)
|
||||
with Exit -> None
|
||||
29
unikernel/duniverse/astring/test/test.ml
Normal file
29
unikernel/duniverse/astring/test/test.ml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers. All rights reserved.
|
||||
Distributed under the ISC license, see terms at the end of the file.
|
||||
---------------------------------------------------------------------------*)
|
||||
|
||||
let tests () = Testing.run
|
||||
[ Test_char.suite;
|
||||
Test_string.suite;
|
||||
Test_sub.suite; ]
|
||||
|
||||
let run () = tests (); Testing.log_results ()
|
||||
|
||||
let () = if run () then exit 0 else exit 1
|
||||
|
||||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
---------------------------------------------------------------------------*)
|
||||
130
unikernel/duniverse/astring/test/test_char.ml
Normal file
130
unikernel/duniverse/astring/test/test_char.ml
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers. All rights reserved.
|
||||
Distributed under the ISC license, see terms at the end of the file.
|
||||
---------------------------------------------------------------------------*)
|
||||
|
||||
open Testing
|
||||
open Astring
|
||||
|
||||
let eq = eq ~pp:Char.dump
|
||||
let eq_opt = eq_option ~pp:Char.dump ~eq:Char.equal
|
||||
let invalid = app_invalid ~pp:Char.dump
|
||||
|
||||
let misc = test "Char.{of_byte,of_int,to_int}" @@ fun () ->
|
||||
invalid Char.of_byte (-1);
|
||||
invalid Char.of_byte (256);
|
||||
eq_opt (Char.of_int (-1)) None;
|
||||
eq_opt (Char.of_int 256) None;
|
||||
for i = 0 to 0xFF do
|
||||
let of_int = Char.of_int $ pp_int @-> ret_get_option Char.dump in
|
||||
eq_int (Char.to_int (of_int i)) i
|
||||
done;
|
||||
()
|
||||
|
||||
let predicates = test "Char.{equal,compare}" @@ fun () ->
|
||||
eq_bool (Char.equal ' ' ' ') true;
|
||||
eq_bool (Char.equal ' ' 'a') false;
|
||||
eq_int (Char.compare ' ' 'a') (-1);
|
||||
eq_int (Char.compare ' ' ' ') (0);
|
||||
eq_int (Char.compare 'a' ' ') (1);
|
||||
eq_int (Char.compare '\x00' ' ') (-1);
|
||||
()
|
||||
|
||||
let ascii_predicates = test "Char.Ascii.is_*" @@ fun () ->
|
||||
let pp_int ppf i = Format.fprintf ppf "%X" i in
|
||||
let test_pred p pi i =
|
||||
let pred p i = p (Char.of_byte i) in
|
||||
(pred p $ pp_int @-> ret_eq ~eq:(=) pp_bool (pi i)) i
|
||||
in
|
||||
let test p pi = for i = 0 to 255 do ignore (test_pred p pi i) done in
|
||||
test Char.Ascii.is_valid (fun i -> i <= 0x7F);
|
||||
test Char.Ascii.is_digit (fun i -> 0x30 <= i && i <= 0x39);
|
||||
test Char.Ascii.is_hex_digit (fun i -> (0x30 <= i && i <= 0x39) ||
|
||||
(0x41 <= i && i <= 0x46) ||
|
||||
(0x61 <= i && i <= 0x66));
|
||||
test Char.Ascii.is_upper (fun i -> 0x41 <= i && i <= 0x5A);
|
||||
test Char.Ascii.is_lower (fun i -> 0x61 <= i && i <= 0x7A);
|
||||
test Char.Ascii.is_letter (fun i -> (0x41 <= i && i <= 0x5A) ||
|
||||
(0x61 <= i && i <= 0x7A));
|
||||
test Char.Ascii.is_alphanum (fun i -> (0x30 <= i && i <= 0x39) ||
|
||||
(0x41 <= i && i <= 0x5A) ||
|
||||
(0x61 <= i && i <= 0x7A));
|
||||
test Char.Ascii.is_white (fun i -> (0x09 <= i && i <= 0x0D) || i = 0x20);
|
||||
test Char.Ascii.is_blank (fun i -> (i = 0x20 || i = 0x09));
|
||||
test Char.Ascii.is_graphic (fun i -> (0x21 <= i && i <= 0x7E));
|
||||
test Char.Ascii.is_print (fun i -> (0x21 <= i && i <= 0x7E) || i = 0x20);
|
||||
test Char.Ascii.is_control (fun i -> (0x00 <= i && i <= 0x1F) || i = 0x7F);
|
||||
()
|
||||
|
||||
let ascii_transforms = test "Char.Ascii.{uppercase,lowercase}" @@ fun () ->
|
||||
for i = 0 to 255 do
|
||||
if (0x61 <= i && i <= 0x7A)
|
||||
then eq_char Char.(Ascii.uppercase @@ of_byte i) (Char.of_byte (i - 32))
|
||||
else eq_char Char.(Ascii.uppercase @@ of_byte i) (Char.of_byte i)
|
||||
done;
|
||||
for i = 0 to 255 do
|
||||
if (0x41 <= i && i <= 0x5A)
|
||||
then eq_char Char.(Ascii.lowercase @@ of_byte i) (Char.of_byte (i + 32))
|
||||
else eq_char Char.(Ascii.lowercase @@ of_byte i) (Char.of_byte i)
|
||||
done;
|
||||
()
|
||||
|
||||
let ascii_escape = test "Char.Ascii.{escape,escape_char}" @@ fun () ->
|
||||
for i = 0 to 255 do
|
||||
let c = Char.of_byte i in
|
||||
let esc = Char.Ascii.escape c in
|
||||
begin match String.Ascii.unescape esc with
|
||||
| None -> fail "could not unescape";
|
||||
| Some unesc ->
|
||||
eq_int (String.length unesc) 1;
|
||||
eq_char unesc.[0] (Char.of_byte i);
|
||||
end;
|
||||
if (0x00 <= i && i <= 0x1F) || (0x7F <= i && i <= 0xFF)
|
||||
then eq_str esc (Printf.sprintf "\\x%02X" i)
|
||||
else if (i = 0x5C)
|
||||
then eq_str esc "\\\\"
|
||||
else eq_str esc (Printf.sprintf "%c" c)
|
||||
done;
|
||||
for i = 0 to 255 do
|
||||
let c = Char.of_byte i in
|
||||
let esc = Char.Ascii.escape_char c in
|
||||
begin match String.Ascii.unescape_string esc with
|
||||
| None -> fail "could not unescape";
|
||||
| Some unesc ->
|
||||
eq_int (String.length unesc) 1;
|
||||
eq_char unesc.[0] (Char.of_byte i);
|
||||
end;
|
||||
if (i = 0x08) then eq_str esc "\\b" else
|
||||
if (i = 0x09) then eq_str esc "\\t" else
|
||||
if (i = 0x0A) then eq_str esc "\\n" else
|
||||
if (i = 0x0D) then eq_str esc "\\r" else
|
||||
if (i = 0x27) then eq_str esc "\\'" else
|
||||
if (i = 0x5C) then eq_str esc "\\\\" else
|
||||
if (0x00 <= i && i <= 0x1F) || (0x7F <= i && i <= 0xFF)
|
||||
then eq_str esc (Printf.sprintf "\\x%02X" i)
|
||||
else eq_str esc (Printf.sprintf "%c" c)
|
||||
done;
|
||||
()
|
||||
|
||||
let suite = suite "Char functions"
|
||||
[ misc;
|
||||
predicates;
|
||||
ascii_predicates;
|
||||
ascii_transforms;
|
||||
ascii_escape; ]
|
||||
|
||||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
---------------------------------------------------------------------------*)
|
||||
1226
unikernel/duniverse/astring/test/test_string.ml
Normal file
1226
unikernel/duniverse/astring/test/test_string.ml
Normal file
File diff suppressed because it is too large
Load diff
1184
unikernel/duniverse/astring/test/test_sub.ml
Normal file
1184
unikernel/duniverse/astring/test/test_sub.ml
Normal file
File diff suppressed because it is too large
Load diff
257
unikernel/duniverse/astring/test/testing.ml
Normal file
257
unikernel/duniverse/astring/test/testing.ml
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers. All rights reserved.
|
||||
Distributed under the ISC license, see terms at the end of the file.
|
||||
---------------------------------------------------------------------------*)
|
||||
|
||||
(* Value equality and pretty printing *)
|
||||
|
||||
type 'a eq = 'a -> 'a -> bool
|
||||
type 'a pp = Format.formatter -> 'a -> unit
|
||||
|
||||
(* Pretty printers *)
|
||||
|
||||
let pp = Format.fprintf
|
||||
let pp_exn ppf v = pp ppf "%s" (Printexc.to_string v)
|
||||
let pp_bool ppf v = pp ppf "%b" v
|
||||
let pp_char ppf v = pp ppf "%C" v
|
||||
let pp_str ppf v = pp ppf "%S" v
|
||||
let pp_int = Format.pp_print_int
|
||||
let pp_float ppf v = pp ppf "%.10f" (* bof... *) v
|
||||
let pp_int32 ppf v = pp ppf "%ld" v
|
||||
let pp_int64 ppf v = pp ppf "%Ld" v
|
||||
let pp_text = Format.pp_print_text
|
||||
let pp_list pp_v ppf l =
|
||||
let pp_sep ppf () = pp ppf ";@," in
|
||||
pp ppf "@[<1>[%a]@]" (Format.pp_print_list ~pp_sep pp_v) l
|
||||
|
||||
let pp_option pp_v ppf = function
|
||||
| None -> Format.fprintf ppf "None"
|
||||
| Some v -> Format.fprintf ppf "Some %a" pp_v v
|
||||
|
||||
let pp_slot_loc ppf l =
|
||||
pp ppf "%s:%d.%d-%d:"
|
||||
l.Printexc.filename l.Printexc.line_number
|
||||
l.Printexc.start_char l.Printexc.end_char
|
||||
|
||||
let pp_bt ppf bt = match Printexc.backtrace_slots bt with
|
||||
| None -> pp ppf "@,@[%a@]" pp_text "No backtrace. Did you compile with -g ?"
|
||||
| Some slots ->
|
||||
let rec loop = function
|
||||
| [] -> assert false
|
||||
| s :: ss ->
|
||||
begin match Printexc.Slot.location s with
|
||||
| None -> ()
|
||||
| Some l when l.Printexc.filename = "test/testing.ml" ||
|
||||
l.Printexc.filename = "test/test.ml" -> ()
|
||||
| Some l -> pp ppf "@,%a" pp_slot_loc l
|
||||
end;
|
||||
if ss <> [] then (loop ss) else ()
|
||||
in
|
||||
loop (Array.to_list slots)
|
||||
|
||||
(* Assertion counters *)
|
||||
|
||||
let fail_count = ref 0
|
||||
let pass_count = ref 0
|
||||
|
||||
(* Logging *)
|
||||
|
||||
let log_part fmt = Format.printf fmt
|
||||
let log ?header fmt = match header with
|
||||
| Some h -> Format.printf ("[%s] " ^^ fmt ^^ "@.") h
|
||||
| None -> Format.printf (fmt ^^ "@.")
|
||||
|
||||
let log_results () =
|
||||
let total = !pass_count + !fail_count in
|
||||
match !fail_count with
|
||||
| 0 -> log ~header:"OK" "All %d assertions succeeded !@." total; true
|
||||
| 1 -> log ~header:"FAIL" "1 failure out of %d assertions" total; false
|
||||
| n -> log ~header:"FAIL" "%d failures out of %d assertions"
|
||||
!fail_count total; false
|
||||
|
||||
let log_fail msg bt =
|
||||
log ~header:"FAIL" "@[<v>@[%a@]%a@]" pp_text msg pp_bt bt
|
||||
|
||||
let log_unexpected_exn ~header exn bt =
|
||||
log ~header:"SUITE" "@[<v>@[ABORTED: unexpected exception:@]@,%a%a@]"
|
||||
pp_exn exn pp_bt bt
|
||||
|
||||
(* Testing scopes *)
|
||||
|
||||
exception Fail
|
||||
exception Fail_handled
|
||||
|
||||
let block f = try f () with
|
||||
| Fail | Fail_handled -> ()
|
||||
| exn ->
|
||||
let bt = Printexc.get_raw_backtrace () in
|
||||
incr fail_count;
|
||||
log_unexpected_exn ~header:"BLOCK" exn bt
|
||||
|
||||
type test = string * (unit -> unit)
|
||||
|
||||
let test n f = n, f
|
||||
let run_test (n, f) =
|
||||
log "* %s" n;
|
||||
try f () with
|
||||
| Fail | Fail_handled ->
|
||||
log ~header:"TEST" "ABORTED: a test failure blew the test scope"
|
||||
| exn ->
|
||||
let bt = Printexc.get_raw_backtrace () in
|
||||
incr fail_count;
|
||||
log_unexpected_exn ~header:"TEST" exn bt
|
||||
|
||||
type suite = string * test list
|
||||
let suite n ts = n, ts
|
||||
let run_suite (n, ts) = try log "%s" n; List.iter run_test ts with
|
||||
| exn ->
|
||||
let bt = Printexc.get_raw_backtrace () in
|
||||
incr fail_count;
|
||||
log_unexpected_exn ~header:"SUITE" exn bt
|
||||
|
||||
let run suites = List.iter run_suite suites
|
||||
|
||||
(* Passing and failing tests *)
|
||||
|
||||
let pass () = incr pass_count
|
||||
let fail fmt =
|
||||
let bt = Printexc.get_callstack 10 in
|
||||
let fail _ = log_fail (Format.flush_str_formatter ()) bt in
|
||||
(incr fail_count; Format.kfprintf fail Format.str_formatter fmt)
|
||||
|
||||
(* Checking values *)
|
||||
|
||||
let pp_neq pp_v ppf (v, v') = pp ppf "@[%a@]@ <>@ @[%a@]@]" pp_v v pp_v v'
|
||||
|
||||
let fail_eq pp v v' = fail "%a" (pp_neq pp) (v, v')
|
||||
|
||||
let eq ~eq ~pp v v' = if eq v v' then pass () else fail_eq pp v v'
|
||||
let eq_char = eq ~eq:(=) ~pp:pp_char
|
||||
let eq_str = eq ~eq:(=) ~pp:pp_str
|
||||
let eq_bool = eq ~eq:(=) ~pp:Format.pp_print_bool
|
||||
let eq_int = eq ~eq:(=) ~pp:Format.pp_print_int
|
||||
let eq_int32 = eq ~eq:(=) ~pp:pp_int32
|
||||
let eq_int64 = eq ~eq:(=) ~pp:pp_int64
|
||||
let eq_float = eq ~eq:(=) ~pp:pp_float
|
||||
let eq_nan f =
|
||||
if f <> f then pass () else fail "@[%a@]@ is@ not a NaN" pp_float f
|
||||
|
||||
let eq_option ~eq:eq_v ~pp =
|
||||
let eq_opt v v' = match v, v' with
|
||||
| Some v, Some v' -> eq_v v v'
|
||||
| None, None -> true
|
||||
| _ -> false
|
||||
in
|
||||
let pp = pp_option pp in
|
||||
fun v v' -> eq ~eq:eq_opt ~pp v v'
|
||||
|
||||
let eq_some = function
|
||||
| Some _ -> pass ()
|
||||
| None -> fail "None <> Some _"
|
||||
|
||||
let eq_none ~pp = function
|
||||
| None -> pass ()
|
||||
| Some v -> fail "@[%a <>@ None@]" pp v
|
||||
|
||||
let eq_list ~eq:eq_v ~pp:pp_v =
|
||||
let eql l l' = try List.for_all2 eq_v l l' with Invalid_argument _ -> false in
|
||||
fun l l' -> eq ~eq:eql ~pp:(pp_list pp_v) l l'
|
||||
|
||||
(* Tracing and checking function applications. *)
|
||||
|
||||
type app = (* Gathers information about the application *)
|
||||
{ fail_count : int; (* fail_count checkpoint when the app starts *)
|
||||
pp_args : Format.formatter -> unit -> unit; }
|
||||
|
||||
let ctx () = { fail_count = -1; pp_args = fun ppf () -> (); }
|
||||
|
||||
let log_app_raised app exn =
|
||||
log "@[<2>@[%a@]==> raised %a" app.pp_args () pp_exn exn
|
||||
|
||||
let pp_app app pp_v ppf v =
|
||||
pp ppf "@[<2>@[%a@]==>@ @[%a@]@]" app.pp_args () pp_v v
|
||||
|
||||
let log_app app pp_v v = log "%a" (pp_app app pp_v) v
|
||||
|
||||
let ( $ ) f k = k (ctx ()) f
|
||||
|
||||
let ( @-> ) (pp_v : 'a pp) k app f v =
|
||||
let pp_args ppf () = app.pp_args ppf (); pp ppf "%a@ " pp_v v in
|
||||
let fc = if app.fail_count = -1 then !fail_count else app.fail_count in
|
||||
let app = { fail_count = fc; pp_args } in
|
||||
try k app (f v) with
|
||||
| Fail ->
|
||||
log_app app pp_v v;
|
||||
raise Fail_handled
|
||||
| Fail_handled as e -> raise e
|
||||
| exn ->
|
||||
log_app_raised app exn;
|
||||
fail "unexpected exception %a raised" pp_exn exn;
|
||||
raise Fail_handled
|
||||
|
||||
let ret pp app v =
|
||||
if !fail_count <> app.fail_count then log_app app pp v;
|
||||
v
|
||||
|
||||
let ret_eq ~eq pp r app v =
|
||||
if eq r v then (pass (); ret pp app v) else
|
||||
(fail "@[<v>%a@,%a@]" (pp_neq pp) (r, v) (pp_app app pp) v;
|
||||
raise Fail_handled)
|
||||
|
||||
let ret_none pp app v = match v with
|
||||
| None -> pass (); ret (pp_option pp) app v
|
||||
| Some _ -> ret_eq ~eq:(=) (pp_option pp) None app v
|
||||
|
||||
let ret_some pp app v = match v with
|
||||
| Some _ as v -> pass (); ret (pp_option pp) app v
|
||||
| None as v ->
|
||||
fail "@[<v>Some _ <> None@,%a@]" (pp_app app (pp_option pp)) v;
|
||||
raise Fail_handled
|
||||
|
||||
let ret_get_option pp app v = match ret_some pp app v with
|
||||
| Some v -> v
|
||||
| None -> assert false
|
||||
|
||||
(* I think we could handle the following functions on app traced ones
|
||||
by enriching the app type and have alternate functions to $ for
|
||||
handling these cases. Note that the only place were we can check
|
||||
for these things are in the @-> combinator *)
|
||||
|
||||
let app_invalid ~pp f v =
|
||||
try
|
||||
let r = f v in
|
||||
fail "%a <> exception Invalid_arg _" pp r
|
||||
with
|
||||
| Invalid_argument _ -> pass ()
|
||||
| exn -> fail "exception %a <> exception Invalid_arg _" pp_exn exn
|
||||
|
||||
let app_exn ~pp e f v =
|
||||
try
|
||||
let r = f v in
|
||||
fail "%a <> exception %a" pp r pp_exn e
|
||||
with
|
||||
| exn when exn = e -> pass ()
|
||||
| exn -> fail "exception %a <> exception %a_" pp_exn exn pp_exn e
|
||||
|
||||
let app_raises ~pp f v =
|
||||
try
|
||||
let r = f v in
|
||||
fail "%a <> exception _ " pp r
|
||||
with
|
||||
| exn -> pass ()
|
||||
|
||||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
---------------------------------------------------------------------------*)
|
||||
92
unikernel/duniverse/astring/test/testing.mli
Normal file
92
unikernel/duniverse/astring/test/testing.mli
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers. All rights reserved.
|
||||
Distributed under the ISC license, see terms at the end of the file.
|
||||
---------------------------------------------------------------------------*)
|
||||
|
||||
(* {1 Value equality and pretty printing} *)
|
||||
|
||||
type 'a eq = 'a -> 'a -> bool
|
||||
type 'a pp = Format.formatter -> 'a -> unit
|
||||
|
||||
(* {1 Pretty printers} *)
|
||||
|
||||
val pp_int : int pp
|
||||
val pp_bool : bool pp
|
||||
val pp_float : float pp
|
||||
val pp_char : char pp
|
||||
val pp_str : string pp
|
||||
val pp_list : 'a pp -> 'a list pp
|
||||
val pp_option : 'a pp -> 'a option pp
|
||||
|
||||
(* {1 Logging} *)
|
||||
|
||||
val log_part : ('a, Format.formatter, unit) format -> 'a
|
||||
val log : ?header:string -> ('a, Format.formatter, unit) format -> 'a
|
||||
val log_results : unit -> bool
|
||||
|
||||
(* {1 Testing scopes} *)
|
||||
|
||||
type test
|
||||
type suite
|
||||
|
||||
val block : (unit -> unit) -> unit
|
||||
val test : string -> (unit -> unit) -> test
|
||||
val suite : string -> test list -> suite
|
||||
|
||||
val run : suite list -> unit
|
||||
|
||||
(* {1 Passing and failing tests} *)
|
||||
|
||||
val pass : unit -> unit
|
||||
val fail : ('a, Format.formatter, unit, unit) format4 -> 'a
|
||||
|
||||
(* {1 Checking values} *)
|
||||
|
||||
val eq : eq:'a eq -> pp:'a pp -> 'a -> 'a -> unit
|
||||
val eq_char : char -> char -> unit
|
||||
val eq_str : string -> string -> unit
|
||||
val eq_bool : bool -> bool -> unit
|
||||
val eq_int : int -> int -> unit
|
||||
val eq_int32 : int32 -> int32 -> unit
|
||||
val eq_int64 : int64 -> int64 -> unit
|
||||
val eq_float : float -> float -> unit
|
||||
val eq_nan : float -> unit
|
||||
|
||||
val eq_option : eq:'a eq -> pp:'a pp -> 'a option -> 'a option -> unit
|
||||
val eq_some : 'a option -> unit
|
||||
val eq_none : pp:'a pp -> 'a option -> unit
|
||||
|
||||
val eq_list : eq:'a eq -> pp:'a pp -> 'a list -> 'a list -> unit
|
||||
|
||||
(* {1 Tracing and checking function applications} *)
|
||||
|
||||
type app (* holds information about the application *)
|
||||
|
||||
val ( $ ) : 'a -> (app -> 'a -> 'b) -> 'b
|
||||
val ( @-> ) : 'a pp -> (app -> 'b -> 'c) -> app -> ('a -> 'b) -> 'a -> 'c
|
||||
|
||||
val ret : 'a pp -> app -> 'a -> 'a
|
||||
val ret_eq : eq:'a eq -> 'a pp -> 'a -> app -> 'a -> 'a
|
||||
val ret_some : 'a pp -> app -> 'a option -> 'a option
|
||||
val ret_none : 'a pp -> app -> 'a option -> 'a option
|
||||
val ret_get_option : 'a pp -> app -> 'a option -> 'a
|
||||
|
||||
val app_invalid : pp:'b pp -> ('a -> 'b) -> 'a -> unit
|
||||
val app_exn : pp:'b pp -> exn -> ('a -> 'b) -> 'a -> unit
|
||||
val app_raises : pp:'b pp -> ('a -> 'b) -> 'a -> unit
|
||||
|
||||
(*---------------------------------------------------------------------------
|
||||
Copyright (c) 2015 The astring programmers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
---------------------------------------------------------------------------*)
|
||||
20
unikernel/duniverse/astring/test/total.ml
Normal file
20
unikernel/duniverse/astring/test/total.ml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
open Astring
|
||||
|
||||
(* Total *)
|
||||
let find_all p s =
|
||||
let rec loop acc i = match String.find ~start:i p s with
|
||||
| None -> List.rev acc
|
||||
| Some i -> loop (i :: acc) (i + 1)
|
||||
in
|
||||
loop [] 0
|
||||
|
||||
(* Not total *)
|
||||
let find_all p s =
|
||||
let rec loop acc i =
|
||||
if i > String.length s then List.rev acc else
|
||||
match String.find ~start:i p s with
|
||||
| None -> List.rev acc
|
||||
| Some i -> loop (i :: acc) (i + 1)
|
||||
in
|
||||
loop [] 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue