Source file expect_test_helpers_base_intf.ml
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
open! Base
module CR = struct
type t =
| CR
| CR_soon
| CR_someday
| Comment
| Suppress
[@@deriving sexp_of]
end
module Sexp_style = struct
type t =
| To_string_mach
| To_string_hum
| Pretty of Sexp_pretty.Config.t
[@@deriving sexp_of]
end
module type With_comparator = sig
type t [@@deriving sexp_of]
include Comparator.S with type t := t
end
module type With_compare = sig
type t [@@deriving compare, sexp_of]
end
module type With_equal = sig
type t [@@deriving sexp_of]
include Equal.S with type t := t
end
module Quickcheck = Base_quickcheck
module type Expect_test_helpers_base = sig
(** Helpers for producing output inside [let%expect_test]. Designed for code using
[Base]. See also [Expect_test_helpers_core] and [Expect_test_helpers_async]. *)
module type With_comparator = With_comparator
module type With_compare = With_compare
module type With_equal = With_equal
module CR : sig
include module type of struct
include CR
end
(** [hide_unstable_output t] returns [false] if [t = CR] and [true] otherwise. Useful
to provide a default for arguments such as [?hide_positions] in functions that
also have a [?cr] argument. *)
val hide_unstable_output : t -> bool
end
module Phys_equal (M : sig
type t [@@deriving sexp_of]
end) : With_equal with type t = M.t
module Sexp_style : sig
include module type of struct
include Sexp_style
end
(** Pretty-printing via [Sexp_pretty] with default config, except no colors. *)
val default_pretty : t
(** Pretty-printing via [Sexp_pretty] with most heuristics disabled. *)
val simple_pretty : t
end
(** [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 hide_positions_in_string : string -> string
(** [hide_temp_files_in_string] replaces [.tmp.______], where each [_] represents some
alphanumeric character, with ".tmp.RANDOM". This can make output deterministic when
describing temporary files generated by, e.g., [Core_unix.mkstemp]. *)
val hide_temp_files_in_string : string -> 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 sexp_to_string : ?hide_positions:bool (** default is [false] *) -> Sexp.t -> string
(** Substitutes [with_] for every occurrence of [pattern] in a string. *)
val replace : string -> pattern:string -> with_:string -> string
(** Like [replace], for every atom in a sexp. *)
val replace_s : Sexp.t -> pattern:string -> with_:string -> Sexp.t
(** Applies [f] at every node in the given sexp, top-down, recurring on the contents of
the output. The word "smash" is used as in the sexp command-line tool's query
language. See: https://github.com/janestreet/sexp *)
val smash_sexp : Sexp.t -> f:(Sexp.t -> Sexp.t) -> Sexp.t
(** Removes OCaml backtraces from sexps. *)
val remove_backtraces : Sexp.t -> Sexp.t
(** For printing an s-expression to stdout. [hide_positions] works as in
[sexp_to_string]. *)
val print_s : ?hide_positions:bool (** default is [false] *) -> Sexp.t -> unit
val print_string : ?hide_positions:bool (** default is [false] *) -> string -> unit
val print_endline : ?hide_positions:bool (** default is [false] *) -> string -> unit
(** Behaves like [[%expect.output]]. *)
val expect_test_output : Source_code_position.t -> string
(** [print_cr here message] prints a [CR require-failed], which will appear in
expect-test output. The CR will appear in the feature owner's [fe todo], thus
preventing release of the feature. [print_cr] is an expect-test-friendly version of
[assert false]. 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
that triggered the [print_cr] and re-run the test to restore the empty output. *)
val print_cr
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> Source_code_position.t
-> Sexp.t
-> unit
(** [require here bool] is a no-op if [bool = true], but if not, prints a [CR
require-failed] similarly to [print_cr], with a message determined by the
[if_false_then_print_s] argument, if any.
[if_false_then_print_s] 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 require
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?if_false_then_print_s:Sexp.t Lazy.t
-> Source_code_position.t
-> bool
-> unit
(** [require_equal] compares its two arguments using the equality predicate of the
provided module. If the comparison fails, prints a message that renders the
arguments as sexps. *)
val require_equal
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?if_false_then_print_s:Sexp.t Lazy.t
-> ?message:string
-> Source_code_position.t
-> (module With_equal with type t = 'a)
-> 'a
-> 'a
-> unit
(** Like [require_equal], but derives an equality predicate from a comparison
function. *)
val require_compare_equal
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?message:string
-> Source_code_position.t
-> (module With_compare with type t = 'a)
-> 'a
-> 'a
-> unit
(** Like [require_equal], but when equality fails produces a message including sexps of
both [Set.diff first second] and [Set.diff second first] to aid in debugging. *)
val require_sets_are_equal
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?names:string * string (** default is ["first", "second"] *)
-> Source_code_position.t
-> (module With_comparator with type t = 'elt and type comparator_witness = 'cmp)
-> ('elt, 'cmp) Set.t
-> ('elt, 'cmp) Set.t
-> 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. Using
[~show_backtrace:true] will result in a CR in the expectation, but it's still
available here as it is still valuable when initially writing tests and
debugging. *)
val show_raise
: ?hide_positions:bool (** default is [false] *)
-> ?show_backtrace:bool (** default is [false] *)
-> (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 require_does_not_raise
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?show_backtrace:bool (** default is [false] *)
-> Source_code_position.t
-> (unit -> unit)
-> unit
(** [require_does_raise] is like [show_raise], but additionally prints a CR if the
function does not raise. *)
val require_does_raise
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?show_backtrace:bool (** default is [false] *)
-> Source_code_position.t
-> (unit -> _)
-> unit
(** [require_some here option] is like [require here (is_some option)], with improved
output. If [option = None], it prints a CR. If [option = Some some] and
[~print_some] is provided, it prints [print_some some]. *)
val require_some
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?print_some:('some -> Sexp.t)
-> Source_code_position.t
-> 'some option
-> unit
(** [require_none here sexp_of_some option] is like [require here (is_none option)],
with improved output. If [option = Some some], it prints a CR including
[sexp_of_some some]. If [option = None], it does not print. *)
val require_none
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> Source_code_position.t
-> ('some -> Sexp.t)
-> 'some option
-> unit
(** [require_ok here or_error] is like [require here (is_ok or_error)], with improved
output. If [or_error = Error error], it prints a CR including [error]. If
[or_error = Ok ok] and [~print_ok] is provided, it prints [print_ok ok]. *)
val require_ok
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?print_ok:('ok -> Sexp.t)
-> Source_code_position.t
-> 'ok Or_error.t
-> unit
(** [require_error here sexp_of_ok or_error] is like [require here (is_error or_error)],
with improved output. If [or_error = Ok ok], it prints a CR including [sexp_of_ok
ok]. If [or_error = Error error] and [print_error = true], it prints [error]. *)
val require_error
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?print_error:bool (** default is [false] *)
-> Source_code_position.t
-> ('ok -> Sexp.t)
-> 'ok Or_error.t
-> unit
(** [require_ok_result here sexp_of_error result] is like [require here (is_ok
or_error)], with improved output. If [result = Error error], it prints a CR
including [sexp_of_error error]. If [result = Ok ok] and [~print_ok] is provided,
it prints [print_ok ok]. *)
val require_ok_result
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?print_ok:('ok -> Sexp.t)
-> Source_code_position.t
-> ('error -> Sexp.t)
-> ('ok, 'error) Result.t
-> unit
(** [require_error_result here sexp_of_ok result] is like [require here (is_error
result)], with improved output. If [result = Ok ok], it prints a CR including
[sexp_of_ok ok]. If [result = Error error] and [~print_error] is supplied, it
prints [print_error error]. *)
val require_error_result
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?print_error:('error -> Sexp.t)
-> Source_code_position.t
-> ('ok -> Sexp.t)
-> ('ok, 'error) Result.t
-> unit
(** [require_first here print_second either] is like [require here (is_first either)],
with improved output. If [either = Second second], it prints a CR including
[sexp_of_second second]. If [either = First first] and [~print_first] is provided,
it prints [print_first first]. *)
val require_first
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true otherwise] *)
-> ?print_first:('first -> Sexp.t)
-> Source_code_position.t
-> ('second -> Sexp.t)
-> ('first, 'second) Either.t
-> unit
(** [require_second here sexp_of_first either] is like [require here (is_second
either)], with improved output. If [either = First first], it prints a CR including
[sexp_of_first first]. If [either = Second second] and [~print_second] is provided,
it prints [print_second second]. *)
val require_second
: ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true otherwise] *)
-> ?print_second:('second -> Sexp.t)
-> Source_code_position.t
-> ('first -> Sexp.t)
-> ('first, 'second) Either.t
-> unit
(** [quickcheck] is similar to [Base_quickcheck.Test.run], but
1. [quickcheck] takes separate arguments for the values which
[Base_quickcheck.Test.run] takes in a first-class module.
2. [quickcheck] stops after the first iteration that raises or prints a CR, as
detected by [on_print_cr]. *)
val quickcheck
: Source_code_position.t
-> ?cr:CR.t (** default is [CR] *)
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> ?seed:Quickcheck.Test.Config.Seed.t
-> ?sizes:int Sequence.t
-> ?trials:int
-> ?shrinker:'a Quickcheck.Shrinker.t
-> ?shrink_attempts:int
-> ?examples:'a list
-> sexp_of:('a -> Sexp.t)
-> f:('a -> unit)
-> 'a Quickcheck.Generator.t
-> unit
(** [quickcheck_m] is similar to [Base_quickcheck.Test.run]. It stops after the first
iteration that raises or prints a CR, as detected by [on_print_cr]. *)
val quickcheck_m
: Source_code_position.t
-> ?config:Base_quickcheck.Test.Config.t
(** default is [Base_quickcheck.Test.default_config] *)
-> ?cr:CR.t (** default is [CR] *)
-> ?examples:'a list
-> ?hide_positions:bool (** default is [false] when [cr=CR], [true] otherwise *)
-> (module Base_quickcheck.Test.S with type t = 'a)
-> f:('a -> unit)
-> unit
(** [sexp_style] determines the sexp format used by [sexp_to_string], [print_s], and
other functions in this module. Defaults to [Sexp_style.default_pretty]. *)
val sexp_style : Sexp_style.t ref
(** [on_print_cr] determines the behavior of all functions above that print CRs, such as
[print_cr] and [require]. The rendered string form of the CR is passed to
[!on_print_cr]. The default value is [print_endline]; this can be overridden to
replace or extend the default behavior. For example, some testing harnesses may
choose to abort a series of tests after the first CR is printed. *)
val on_print_cr : (string -> unit) ref
end