diff --git a/CHANGES.md b/CHANGES.md index eabe19628..04573fe88 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## Next +- #379: Extend the set of `Util.Pp` pretty-printers and teach them to + add break hints similar to `ppx_deriving.show`; teach `to_show` to + generate truncated strings when `$MCTUTILS_TRUNCATE` environment + variable is set - #368: Switch `STM_domain.agree_prop_par_asym` from using `Semaphore.Binary` to using an `int Atomic.t` which improves the error rate across platforms and backends diff --git a/dune b/dune index 37f6e8b6c..dc8ad24b1 100644 --- a/dune +++ b/dune @@ -1,5 +1,11 @@ (env - (debug-runtime (link_flags :standard -runtime-variant=d)) + (debug-runtime + (link_flags :standard -runtime-variant=d) + (env-vars + (MCTUTILS_TRUNCATE 50))) + (_ + (env-vars + (MCTUTILS_TRUNCATE 50))) ) ;; make `dune build` target a recursive default target diff --git a/lib/util.ml b/lib/util.ml index 71fc4d3e6..098d5432e 100644 --- a/lib/util.ml +++ b/lib/util.ml @@ -80,28 +80,77 @@ module Pp = struct type 'a t = bool -> Format.formatter -> 'a -> unit - let to_show f x = asprintf "%a" (f false) x + type pp_thunk = Format.formatter -> unit + + let truncate_message = "... (truncated)" + + let truncate_length = + let truncate_env = "MCTUTILS_TRUNCATE" in + let ( let* ) = Option.bind in + let* l = Sys.getenv_opt truncate_env in + let* l = int_of_string_opt l in + (* it does not make sense to truncate at less than the length of + [truncate_message] *) + if l > 0 then Some (max l (String.length truncate_message - 1)) else None + + let to_show f x = + match truncate_length with + | None -> + let buf = Buffer.create 512 in + let fmt = formatter_of_buffer buf in + pp_set_margin fmt max_int; + fprintf fmt "@[%a@]@?" (f false) x; + let s = Buffer.contents buf in + Buffer.reset buf; + s + | Some trlen -> + (* if we overflow, we'll have the [truncate_message] at the end of the + buffer, filling it until [trlen + 1]: we'll use the fact that the + buffer contains more than [trlen] to indicate that it has already + overflown *) + let buf = Buffer.create (trlen + 1) in + let msglen = String.length truncate_message in + let out str ofs len = + let blen = Buffer.length buf in + (* if we didn't overflow yet... *) + if blen <= trlen then + if blen + len > trlen then ( + let fits = trlen - blen - msglen + 1 in + if fits > 0 then Buffer.add_substring buf str ofs fits + else Buffer.truncate buf (trlen + 1 - msglen); + Buffer.add_string buf truncate_message) + else Buffer.add_substring buf str ofs len + in + let ppf = make_formatter out ignore in + pp_set_margin ppf max_int; + fprintf ppf "@[%a@]@?" (f false) x; + let s = Buffer.contents buf in + Buffer.reset buf; + s let of_show f par fmt x = - fprintf fmt (if par then "(%s)" else "%s") (f x) + fprintf fmt (if par then "@[(%s)@]" else "@[%s@]") (f x) let cst0 name fmt = pp_print_string fmt name let cst1 (pp : 'a t) name par fmt x = - fprintf fmt (if par then "(%s %a)" else "%s %a") name (pp true) x + let o, c = if par then ("(", ")") else ("", "") in + fprintf fmt "%s@[<2>%s@ %a@]%s" o name (pp true) x c let cst2 (pp1 : 'a t) (pp2 : 'b t) name par fmt x y = - fprintf fmt (if par then "(%s (%a, %a))" else "%s (%a, %a)") name (pp1 false) x (pp2 false) y + let o, c = if par then ("(", ")") else ("", "") in + fprintf fmt "%s@[<2>%s (@,%a,@ %a)@]%s" o name (pp1 false) x (pp2 false) y c let cst3 (pp1 : 'a t) (pp2 : 'b t) (pp3 : 'c t) name par fmt x y z = - fprintf fmt - (if par then "(%s (%a, %a, %a))" else "%s (%a, %a, %a)") - name (pp1 false) x (pp2 false) y (pp3 false) z + let o, c = if par then ("(", ")") else ("", "") in + fprintf fmt "%s@[<2>%s (@,%a,@ %a,@ %a)@]%s" o name (pp1 false) x + (pp2 false) y (pp3 false) z c let pp_exn = of_show Printexc.to_string let pp_unit _ fmt () = pp_print_string fmt "()" let pp_bool _ fmt b = fprintf fmt "%B" b let pp_int par fmt i = fprintf fmt (if par && i < 0 then "(%d)" else "%d") i + let pp_int32 par fmt i = fprintf fmt (if par && i < 0l then "(%ldl)" else "%ldl") i let pp_int64 par fmt i = fprintf fmt (if par && i < 0L then "(%LdL)" else "%LdL") i let pp_float par fmt f = fprintf fmt (if par && f < 0.0 then "(%F)" else "%F") f let pp_char _ fmt c = fprintf fmt "%C" c @@ -110,42 +159,144 @@ module Pp = struct let pp_option (pp_s : 'a t) par fmt o = match o with - | None -> pp_print_string fmt "None" - | Some s -> fprintf fmt (if par then "(Some %a)" else "Some %a") (pp_s true) s + | None -> cst0 "None" fmt + | Some s -> cst1 pp_s "Some" par fmt s let pp_result (pp_o : 'o t) (pp_e : 'e t) par fmt r = let open Result in match r with - | Ok o -> fprintf fmt (if par then "(Ok %a)" else "Ok %a") (pp_o true) o - | Error e -> fprintf fmt (if par then "(Error %a)" else "Error %a") (pp_e true) e + | Ok o -> cst1 pp_o "Ok" par fmt o + | Error e -> cst1 pp_e "Error" par fmt e + + type pp_tuple_item = pp_thunk + + let pp_tuple_item pp x fmt = pp false fmt x + + let pp_tuple _ fmt items = + fprintf fmt "(@["; + pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt ",@ ") (fun fmt ppf -> ppf fmt) fmt items; + fprintf fmt "@])" + + let pp_tuple2 pp1 pp2 p fmt (x1, x2) = + pp_tuple p fmt [ pp_tuple_item pp1 x1; pp_tuple_item pp2 x2 ] + + let pp_tuple3 pp1 pp2 pp3 p fmt (x1, x2, x3) = + pp_tuple p fmt + [ pp_tuple_item pp1 x1; pp_tuple_item pp2 x2; pp_tuple_item pp3 x3 ] + + let pp_tuple4 pp1 pp2 pp3 pp4 p fmt (x1, x2, x3, x4) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + ] + + let pp_tuple5 pp1 pp2 pp3 pp4 pp5 p fmt (x1, x2, x3, x4, x5) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + ] + + let pp_tuple6 pp1 pp2 pp3 pp4 pp5 pp6 p fmt (x1, x2, x3, x4, x5, x6) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + pp_tuple_item pp6 x6; + ] + + let pp_tuple7 pp1 pp2 pp3 pp4 pp5 pp6 pp7 p fmt (x1, x2, x3, x4, x5, x6, x7) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + pp_tuple_item pp6 x6; + pp_tuple_item pp7 x7; + ] + + let pp_tuple8 pp1 pp2 pp3 pp4 pp5 pp6 pp7 pp8 p fmt + (x1, x2, x3, x4, x5, x6, x7, x8) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + pp_tuple_item pp6 x6; + pp_tuple_item pp7 x7; + pp_tuple_item pp8 x8; + ] + + let pp_tuple9 pp1 pp2 pp3 pp4 pp5 pp6 pp7 pp8 pp9 p fmt + (x1, x2, x3, x4, x5, x6, x7, x8, x9) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + pp_tuple_item pp6 x6; + pp_tuple_item pp7 x7; + pp_tuple_item pp8 x8; + pp_tuple_item pp9 x9; + ] + + let pp_tuple10 pp1 pp2 pp3 pp4 pp5 pp6 pp7 pp8 pp9 pp10 p fmt + (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) = + pp_tuple p fmt + [ + pp_tuple_item pp1 x1; + pp_tuple_item pp2 x2; + pp_tuple_item pp3 x3; + pp_tuple_item pp4 x4; + pp_tuple_item pp5 x5; + pp_tuple_item pp6 x6; + pp_tuple_item pp7 x7; + pp_tuple_item pp8 x8; + pp_tuple_item pp9 x9; + pp_tuple_item pp10 x10; + ] - let pp_pair (pp_f : 'a t) (pp_s : 'b t) _ fmt (x,y) = - fprintf fmt "(%a, %a)" (pp_f false) x (pp_s false) y + let pp_pair = pp_tuple2 let pp_list (pp_e : 'a t) _ fmt l = - pp_print_string fmt "["; + fprintf fmt "@[<2>["; pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt ";@ ") (pp_e false) fmt l; - pp_print_string fmt "]" + fprintf fmt "@,]@]" let pp_seq (pp_e : 'a t) _ fmt s = - pp_print_string fmt "<"; + fprintf fmt "@[<2><"; pp_print_seq ~pp_sep:(fun fmt () -> fprintf fmt ";@ ") (pp_e false) fmt s; - pp_print_string fmt ">" + fprintf fmt "@,>@]" let pp_array (pp_e : 'a t) _ fmt a = - pp_print_string fmt "[|"; + fprintf fmt "@[<2>[|"; pp_print_seq ~pp_sep:(fun fmt () -> fprintf fmt ";@ ") (pp_e false) fmt (Array.to_seq a); - pp_print_string fmt "|]" + fprintf fmt "@,|]@]" - type pp_field = Format.formatter -> unit + type pp_field = pp_thunk let pp_field name (pp_c : 'a t) c fmt = - fprintf fmt "%s =@ %a" name (pp_c false) c + fprintf fmt "@[%s =@ %a@]" name (pp_c false) c let pp_record _ fmt fields = - pp_print_string fmt "{ "; + fprintf fmt "@[<2>{ "; pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt ";@ ") (fun fmt ppf -> ppf fmt) fmt fields; - fprintf fmt "@ }" + fprintf fmt "@ }@]" end module Equal = struct diff --git a/lib/util.mli b/lib/util.mli index 128ef66a5..5dee04219 100644 --- a/lib/util.mli +++ b/lib/util.mli @@ -51,7 +51,10 @@ module Pp : sig if it produces a non-atomic expression. *) val to_show : 'a t -> 'a -> string - (** [to_show pp] converts a pretty-printer to a simple ['a -> string] function. *) + (** [to_show pp] converts a pretty-printer to a simple ['a -> string] function + that generate everything on one line. If the environment variable + [MCTUTILS_TRUNCATE] is set to a length, it will truncate the resulting + string if it exceeds that length. *) val of_show : ('a -> string) -> 'a t (** [of_show show] uses a simple ['a -> string] function as a pretty-printer. @@ -90,6 +93,9 @@ module Pp : sig val pp_int : int t (** Pretty-printer for type [int] *) + val pp_int32 : int32 t + (** Pretty-printer for type [int32] *) + val pp_int64 : int64 t (** Pretty-printer for type [int64] *) @@ -114,10 +120,93 @@ module Pp : sig using [pp_ok] to pretty-print values of type ['o] and [pp_error] for values of type ['e]. *) + type pp_tuple_item + (** The abstract type for the pretty-printer of a tuple item *) + + val pp_tuple_item : 'a t -> 'a -> pp_tuple_item + (** [pp_tuple_item pp v] builds a pretty-printer for a tuple item using [pp] + to pretty-print its value [v]. *) + + val pp_tuple : pp_tuple_item list t + (** [pp_tuple] pretty-prints a tuple taken as a list of [pp_tuple_item]s. *) + val pp_pair : 'a t -> 'b t -> ('a * 'b) t (** [pp_pair pp_a pp_b] pretty-prints a value of type ['a * 'b] using [pp_a] to pretty-print values of type ['a] and [pp_b] for values of type ['b]. *) + val pp_tuple2 : 'a t -> 'b t -> ('a * 'b) t + (** [pp_tuple2] pretty-prints pairs, synonym for [pp_pair]. *) + + val pp_tuple3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t + (** [pp_tuple3] pretty-prints triples. *) + + val pp_tuple4 : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t + (** [pp_tuple4] pretty-prints tuples of 4 elements. *) + + val pp_tuple5 : + 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> ('a * 'b * 'c * 'd * 'e) t + (** [pp_tuple5] pretty-prints tuples of 5 elements. *) + + val pp_tuple6 : + 'a t -> + 'b t -> + 'c t -> + 'd t -> + 'e t -> + 'f t -> + ('a * 'b * 'c * 'd * 'e * 'f) t + (** [pp_tuple6] pretty-prints tuples of 6 elements. *) + + val pp_tuple7 : + 'a t -> + 'b t -> + 'c t -> + 'd t -> + 'e t -> + 'f t -> + 'g t -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g) t + (** [pp_tuple7] pretty-prints tuples of 7 elements. *) + + val pp_tuple8 : + 'a t -> + 'b t -> + 'c t -> + 'd t -> + 'e t -> + 'f t -> + 'g t -> + 'h t -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h) t + (** [pp_tuple8] pretty-prints tuples of 8 elements. *) + + val pp_tuple9 : + 'a t -> + 'b t -> + 'c t -> + 'd t -> + 'e t -> + 'f t -> + 'g t -> + 'h t -> + 'i t -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i) t + (** [pp_tuple9] pretty-prints tuples of 9 elements. *) + + val pp_tuple10 : + 'a t -> + 'b t -> + 'c t -> + 'd t -> + 'e t -> + 'f t -> + 'g t -> + 'h t -> + 'i t -> + 'j t -> + ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j) t + (** [pp_tuple10] pretty-prints tuples of 10 elements. *) + val pp_list : 'a t -> 'a list t (** [pp_list pp] pretty-prints a list using [pp] to pretty-print its elements. *) @@ -128,10 +217,10 @@ module Pp : sig (** [pp_array pp] pretty-prints an array using [pp] to pretty-print its elements. *) type pp_field - (** The abtract type for the pretty-printer of a record field *) + (** The abstract type for the pretty-printer of a record field *) val pp_field : string -> 'a t -> 'a -> pp_field - (** [pp_field name pp v] build a pretty-printer for a record field of given + (** [pp_field name pp v] builds a pretty-printer for a record field of given [name] using [pp] to pretty-print its content value [v]. *) val pp_record : pp_field list t diff --git a/test/dune b/test/dune index 3e0e6d205..51fdd68b2 100644 --- a/test/dune +++ b/test/dune @@ -6,6 +6,44 @@ (package qcheck-multicoretests-util) (libraries qcheck-multicoretests-util)) +(test + (name util_pp) + (modules util_pp) + (package qcheck-multicoretests-util) + (libraries qcheck-multicoretests-util) + (action + (setenv MCTUTILS_TRUNCATE "" + (run %{dep:util_pp.exe})))) + +(rule + (alias runtest) + (package qcheck-multicoretests-util) + (action + (progn + (with-outputs-to util_pp_trunc150.output + (setenv MCTUTILS_TRUNCATE 150 + (run %{dep:util_pp.exe}))) + (diff? util_pp_trunc150.expected util_pp_trunc150.output)))) + +(rule + (alias runtest) + (package qcheck-multicoretests-util) + (action + (progn + (with-outputs-to util_pp_trunc79.output + (setenv MCTUTILS_TRUNCATE 79 + (run %{dep:util_pp.exe}))) + (diff? util_pp_trunc79.expected util_pp_trunc79.output)))) + +(rule + (alias runtest) + (package qcheck-multicoretests-util) + (action + (progn + (with-outputs-to util_pp_trunc5.output + (setenv MCTUTILS_TRUNCATE 5 + (run %{dep:util_pp.exe}))) + (diff? util_pp_trunc5.expected util_pp_trunc5.output)))) (executable (name cleanup_lin) diff --git a/test/util_pp.expected b/test/util_pp.expected new file mode 100644 index 000000000..ba5c00a37 --- /dev/null +++ b/test/util_pp.expected @@ -0,0 +1,75 @@ +Test of pp_bool: +true + +Test of pp_int (positive): +12345 + +Test of pp_int (negative): +-12345 + +Test of pp_int32 (positive): +12345l + +Test of pp_int64 (negative): +-12345L + +Test of pp_float (infinity): +infinity + +Test of pp_float (pi): +3.14159265359 + +Test of pp_char (printable): +'a' + +Test of pp_char (unprintable): +'\000' + +Test of pp_string: +"Hello world" + +Test of pp_string (long): +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +Test of pp_bytes (empty): +"" + +Test of pp_bytes (long): +"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +Test of pp_option pp_int (positive): +Some 12345 + +Test of pp_option pp_int (negative): +Some (-12345) + +Test of pp_result pp_int pp_string: +Ok (-12345) + +Test of pp_result pp_int pp_string: +Error "Failure" + +Test of pp_pair pp_char pp_int: +('a', -12345) + +Test of pp_list pp_int: +[1; 2; 3; -1; -2; -3] + +Test of pp_list pp_int (long): +[1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3] + +Test of pp_seq pp_int: +<-5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5> + +Test of pp_seq pp_int (long): +<-50; -49; -48; -47; -46; -45; -44; -43; -42; -41; -40; -39; -38; -37; -36; -35; -34; -33; -32; -31; -30; -29; -28; -27; -26; -25; -24; -23; -22; -21; -20; -19; -18; -17; -16; -15; -14; -13; -12; -11; -10; -9; -8; -7; -6; -5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50> + +Test of pp_array pp_int: +[|1; 2; 3; -1; -2; -3|] + +Test of pp_array pp_int (long): +[|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0|] + +Test of pp_record: +{ key = 123; value = "content" } + diff --git a/test/util_pp.ml b/test/util_pp.ml new file mode 100644 index 000000000..c52e4154b --- /dev/null +++ b/test/util_pp.ml @@ -0,0 +1,44 @@ +(* Tests of Util.Pp *) + +open Util.Pp + +let pr name pp x = Printf.printf "Test of %s:\n%s\n\n" name (to_show pp x) + +let seq_interval x y () = + let rec aux i = + let open Seq in + if i <= y then Cons (i, fun () -> aux (i + 1)) else Nil + in + aux x + +let _ = + pr "pp_bool" pp_bool true; + pr "pp_int (positive)" pp_int 12345; + pr "pp_int (negative)" pp_int (-12345); + pr "pp_int32 (positive)" pp_int32 12345l; + pr "pp_int64 (negative)" pp_int64 (-12345L); + pr "pp_float (infinity)" pp_float Float.infinity; + pr "pp_float (pi)" pp_float Float.pi; + pr "pp_char (printable)" pp_char 'a'; + pr "pp_char (unprintable)" pp_char '\000'; + pr "pp_string" pp_string "Hello world"; + pr "pp_string (long)" pp_string (String.make 1234 'a'); + pr "pp_bytes (empty)" pp_bytes Bytes.empty; + pr "pp_bytes (long)" pp_bytes (Bytes.make 1234 'b'); + pr "pp_option pp_int (positive)" (pp_option pp_int) (Some 12345); + pr "pp_option pp_int (negative)" (pp_option pp_int) (Some (-12345)); + pr "pp_result pp_int pp_string" (pp_result pp_int pp_string) (Ok (-12345)); + pr "pp_result pp_int pp_string" (pp_result pp_int pp_string) (Error "Failure"); + pr "pp_pair pp_char pp_int" (pp_pair pp_char pp_int) ('a', -12345); + let l = [ 1; 2; 3; -1; -2; -3 ] in + pr "pp_list pp_int" (pp_list pp_int) l; + let l = l @ l @ l @ l in + let l = l @ l @ l @ l in + let l = l @ l @ l @ l in + pr "pp_list pp_int (long)" (pp_list pp_int) l; + pr "pp_seq pp_int" (pp_seq pp_int) (seq_interval (-5) 5); + pr "pp_seq pp_int (long)" (pp_seq pp_int) (seq_interval (-50) 50); + pr "pp_array pp_int" (pp_array pp_int) [| 1; 2; 3; -1; -2; -3 |]; + pr "pp_array pp_int (long)" (pp_array pp_int) (Array.make 100 0); + pr "pp_record" pp_record + [ pp_field "key" pp_int 123; pp_field "value" pp_string "content" ] diff --git a/test/util_pp_trunc150.expected b/test/util_pp_trunc150.expected new file mode 100644 index 000000000..502fe6757 --- /dev/null +++ b/test/util_pp_trunc150.expected @@ -0,0 +1,75 @@ +Test of pp_bool: +true + +Test of pp_int (positive): +12345 + +Test of pp_int (negative): +-12345 + +Test of pp_int32 (positive): +12345l + +Test of pp_int64 (negative): +-12345L + +Test of pp_float (infinity): +infinity + +Test of pp_float (pi): +3.14159265359 + +Test of pp_char (printable): +'a' + +Test of pp_char (unprintable): +'\000' + +Test of pp_string: +"Hello world" + +Test of pp_string (long): +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... (truncated) + +Test of pp_bytes (empty): +"" + +Test of pp_bytes (long): +"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb... (truncated) + +Test of pp_option pp_int (positive): +Some 12345 + +Test of pp_option pp_int (negative): +Some (-12345) + +Test of pp_result pp_int pp_string: +Ok (-12345) + +Test of pp_result pp_int pp_string: +Error "Failure" + +Test of pp_pair pp_char pp_int: +('a', -12345) + +Test of pp_list pp_int: +[1; 2; 3; -1; -2; -3] + +Test of pp_list pp_int (long): +[1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; ... (truncated) + +Test of pp_seq pp_int: +<-5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5> + +Test of pp_seq pp_int (long): +<-50; -49; -48; -47; -46; -45; -44; -43; -42; -41; -40; -39; -38; -37; -36; -35; -34; -33; -32; -31; -30; -29; -28; -27; -26; -25; -24; ... (truncated) + +Test of pp_array pp_int: +[|1; 2; 3; -1; -2; -3|] + +Test of pp_array pp_int (long): +[|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;... (truncated) + +Test of pp_record: +{ key = 123; value = "content" } + diff --git a/test/util_pp_trunc5.expected b/test/util_pp_trunc5.expected new file mode 100644 index 000000000..361406566 --- /dev/null +++ b/test/util_pp_trunc5.expected @@ -0,0 +1,75 @@ +Test of pp_bool: +true + +Test of pp_int (positive): +12345 + +Test of pp_int (negative): +-12345 + +Test of pp_int32 (positive): +12345l + +Test of pp_int64 (negative): +-12345L + +Test of pp_float (infinity): +infinity + +Test of pp_float (pi): +3.14159265359 + +Test of pp_char (printable): +'a' + +Test of pp_char (unprintable): +'\000' + +Test of pp_string: +"Hello world" + +Test of pp_string (long): +... (truncated) + +Test of pp_bytes (empty): +"" + +Test of pp_bytes (long): +... (truncated) + +Test of pp_option pp_int (positive): +Some 12345 + +Test of pp_option pp_int (negative): +Some (-12345) + +Test of pp_result pp_int pp_string: +Ok (-12345) + +Test of pp_result pp_int pp_string: +... (truncated) + +Test of pp_pair pp_char pp_int: +('a', -12345) + +Test of pp_list pp_int: +... (truncated) + +Test of pp_list pp_int (long): +... (truncated) + +Test of pp_seq pp_int: +... (truncated) + +Test of pp_seq pp_int (long): +... (truncated) + +Test of pp_array pp_int: +... (truncated) + +Test of pp_array pp_int (long): +... (truncated) + +Test of pp_record: +... (truncated) + diff --git a/test/util_pp_trunc79.expected b/test/util_pp_trunc79.expected new file mode 100644 index 000000000..2b10a364f --- /dev/null +++ b/test/util_pp_trunc79.expected @@ -0,0 +1,75 @@ +Test of pp_bool: +true + +Test of pp_int (positive): +12345 + +Test of pp_int (negative): +-12345 + +Test of pp_int32 (positive): +12345l + +Test of pp_int64 (negative): +-12345L + +Test of pp_float (infinity): +infinity + +Test of pp_float (pi): +3.14159265359 + +Test of pp_char (printable): +'a' + +Test of pp_char (unprintable): +'\000' + +Test of pp_string: +"Hello world" + +Test of pp_string (long): +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... (truncated) + +Test of pp_bytes (empty): +"" + +Test of pp_bytes (long): +"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb... (truncated) + +Test of pp_option pp_int (positive): +Some 12345 + +Test of pp_option pp_int (negative): +Some (-12345) + +Test of pp_result pp_int pp_string: +Ok (-12345) + +Test of pp_result pp_int pp_string: +Error "Failure" + +Test of pp_pair pp_char pp_int: +('a', -12345) + +Test of pp_list pp_int: +[1; 2; 3; -1; -2; -3] + +Test of pp_list pp_int (long): +[1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1; 2; 3; -1; -2; -3; 1... (truncated) + +Test of pp_seq pp_int: +<-5; -4; -3; -2; -1; 0; 1; 2; 3; 4; 5> + +Test of pp_seq pp_int (long): +<-50; -49; -48; -47; -46; -45; -44; -43; -42; -41; -40; -39; -38;... (truncated) + +Test of pp_array pp_int: +[|1; 2; 3; -1; -2; -3|] + +Test of pp_array pp_int (long): +[|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; ... (truncated) + +Test of pp_record: +{ key = 123; value = "content" } +