An extension of Expect_test_helpers_kernel
with Async-aware functions.
include Expect_test_helpers_kernel.S
val hide_positions_in_string : string ‑> string
hide_positions_in_string
does line-based regexp matching to replace line numbers
and column numbers that appear in source-code positions with constant text LINE
and COL
. This can be useful in making displayed test output less fragile.
val sexp_to_string : ?hide_positions:bool ‑> Core_kernel.Sexp.t ‑> string
Renders an s-expression as a string. With ~hide_positions:true
, patterns in the
string that match OCaml-style file positions are modified to hide the line number,
column number, and character positions, to make output less fragile.
val print_s : ?hide_positions:bool ‑> Core_kernel.Sexp.t ‑> unit
For printing an s-expression to stdout. hide_positions
works as in
sexp_to_string
.
val print_and_check_stable_type : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> ?max_binable_length:int ‑> Core_kernel.Source_code_position.t ‑> (module Core_kernel.Stable_without_comparator with type t = 'a) ‑> 'a list ‑> unit
print_and_check_stable_type
prints the bin-io digest for the given type, and the
bin-io and sexp serializations of the given values. Prints an error message for any
serializations that fail to round-trip, and for any bin-io serializations that
exceed max_binable_length
.
val print_and_check_stable_int63able_type : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> ?max_binable_length:int ‑> Core_kernel.Source_code_position.t ‑> (module Core_kernel.Stable_int63able with type t = 'a) ‑> 'a list ‑> unit
print_and_check_stable_int63able_type
works like print_and_check_stable_type
,
and includes Int63.t
serializations.
val print_bin_ios : (module Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.Print_bin_ios_arg with type t = 'a) ‑> 'a list ‑> unit
print_bin_ios
prints the shape digest of a Binable
type, and the bin-io
serialization of example values. print_bin_ios
is used to write expect tests that
can detect if the serialization format of a stable type changes.
val print_bin_ios_with_max : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> Core_kernel.Source_code_position.t ‑> (module Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.Print_bin_ios_with_max_arg with type t = 'a) ‑> 'a list ‑> unit
print_bin_ios_with_max
is like print_bin_ios
, except it causes a CR to be
printed (using require
) if any serializations are longer than the supplied
max_binable_length
. This is useful for ensuring that serializations fit in some
required size, e.g. an ethernet MTU.
val require : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> ?if_false_then_print_s:Core_kernel.Sexp.t Core_kernel.Lazy.t ‑> Core_kernel.Source_code_position.t ‑> bool ‑> unit
require here bool
is a no-op if bool = true
, but if not, prints a CR
require-failed:
, which will appear in the expect-test output. The CR will appear
in the feature owner's fe todo
, thus preventing release of the feature. require
is an expect-test-friendly version of assert
. It works with the normal
expect-test workflow because it does not raise, and it prevents mistakenly releasing
features that violate a required property. There is no need to 'X' a CR
require-failed
; simply fix the property tested by the require
and re-run the test
to restore the empty output.
require
prints if_false_then_print_s
only if bool = false
. It is useful for
including information that may help debug the problem, but that would otherwise be
too voluminous. if_false_then_print_s
is lazy to avoid construction of the sexp
except when needed.
val show_raise : ?hide_positions:bool ‑> ?show_backtrace:bool ‑> (unit ‑> _) ‑> unit
show_raise
calls f ()
and prints the exception that it raises, or, if it doesn't
raise, prints did not raise
. show_raise
ignores the result of f
so that one
doesn't have to put an ignore
inside the body of an f
that is expected to raise.
~hide_positions:true
operates as in print_s
, to make output less fragile.
val require_does_not_raise : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> ?show_backtrace:bool ‑> Core_kernel.Source_code_position.t ‑> (unit ‑> unit) ‑> unit
require_does_not_raise
is like show_raise
, but does not print anything if the
function does not raise, and prints a CR along with the exception if it does raise.
Unlike for show_raise
, the supplied function is required to return unit
to avoid
mistakes like incomplete partial application that silently would not raise, but for
the wrong reason.
val show_allocation : (unit ‑> 'a) ‑> 'a
show_allocation
calls f ()
and prints out the allocations, major and minor, of
f
. If f
returns a value that should be ignored, use this idiom:
ignore (show_allocation f : t)
rather than this idiom:
show_allocation (fun () -> ignore (f () : t))
With the latter idiom, the compiler may optimize the computation of f ()
taking
advantage of the fact that the result is ignored, and eliminate allocation that is
intended to be measured. With the former idiom, the compiler cannot do such
optimization and must compute the result of f ()
.
val require_no_allocation : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> Core_kernel.Source_code_position.t ‑> (unit ‑> 'a) ‑> 'a
require_no_allocation f
combines show_allocation
with require
. If f
does
not allocate, nothing is printed. If f
allocates, a summary of the allocation is
printed along with a CR comment. If f
returns a value that should be ignored, you
should use the idiom as described above for show_allocation
.
val print_and_check_container_sexps : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> Core_kernel.Source_code_position.t ‑> (module Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.With_containers with type t = 'a) ‑> 'a list ‑> unit
print_and_check_container_sexps
prints the sexp representation of maps, sets, hash
tables, and hash sets based on the given values. For sets and hash sets, prints a
CR if the sexp does not correspond to a list of elements. For maps and hash tables,
prints a CR if the sexp does not correspond to an association list keyed on
elements.
val print_and_check_comparable_sexps : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> Core_kernel.Source_code_position.t ‑> (module Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.With_comparable with type t = 'a) ‑> 'a list ‑> unit
print_and_check_comparable_sexps
is like print_and_check_container_sexps
for
maps and sets only.
val print_and_check_hashable_sexps : ?cr:Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.CR.t ‑> ?hide_positions:bool ‑> Core_kernel.Source_code_position.t ‑> (module Expect_test_helpers_kernel__.Expect_test_helpers_kernel_intf.With_hashable with type t = 'a) ‑> 'a list ‑> unit
print_and_check_hashable_sexps
is like print_and_check_container_sexps
for hash
tables and hash sets only.
val with_temp_dir : (string ‑> 'a Async.Deferred.t) ‑> 'a Async.Deferred.t
with_temp_dir f
creates a temporary directory which is fed to f
. The directory
is removed after f
exits.
val within_temp_dir : ?links:(string * [ `In_path_as | `In_temp_as ] * string) list ‑> (unit ‑> 'a Async.Deferred.t) ‑> 'a Async.Deferred.t
within_temp_dir ?links f
creates a temporary directory, $T, and:
1. Adds $T/bin to the PATH environment variable.
2. For each file, `In_path_as, name
in links
, links file
as $T/bin/name
.
3. For each file, `In_temp_as, name
in links
, links file
as $T/name
.
It then cd
s to $T and calls f
. After f
exits, it cd
s back, removes the
temporary directory, and restores the original PATH.
val run : ?enable_ocaml_backtraces:bool ‑> ?hide_positions:bool ‑> ?print_cmdline:bool ‑> ?stdin:string ‑> string ‑> string list ‑> unit Async.Deferred.t
run ?stdin prog args
creates a child process that runs prog
, with arguments args
and its stdin coming from stdin
. No expansion or escaping is done to args
or
stdin
. The child process's stdout and stderr are captured separately for
comparison.
val system : ?enable_ocaml_backtraces:bool ‑> ?hide_positions:bool ‑> ?print_cmdline:bool ‑> ?stdin:string ‑> string ‑> unit Async.Deferred.t
system ?stdin cmd
creates a child process that runs /bin/sh
, with arguments
"-c"; cmd
and its stdin coming from stdin
. The child process's stdout and stderr
are captured separately for comparison. Unlike with Unix.system
, the child shell's
stdin is never a tty, even if the stdin of this process is a tty, and the child
shell's stderr is never copied to this process's stderr.
val show_raise' : ?hide_positions:bool ‑> (unit ‑> _ Async.Deferred.t) ‑> unit Async.Deferred.t
show_raise' ?hide_positions ?rest f
calls f ()
and prints either the exception
raised by f
or "did not raise". show_raise'
ignores the result of f
so that one
doesn't have to put an ignore
inside f
. ~hide_positions
operates as in
print_s
, to make output less fragile. Once a result is returned, the rest of the
errors are printed to stdout.
module Expect_test_config : Expect_test_helpers__.Import.Expect_test_config_lib.S with type 'a IO.t = 'a Async.Deferred.t
We export Expect_test_config
so that the %expect
syntax uses Async, to prevent a
confusing situation in which one is using Expect_test_helpers
functions, which
expect Async to be running, but Async isn't running. Also, we override
Expect_test_config.run f
so that, if f ()
raises, run
prints the exception
rather than raising. Printing works better with the expect-test workflow than an
unhandled exception, because there is a .corrected
file that one can accept and
inspect.