package hegel

  1. Overview
  2. Docs

Source file hegel.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
(** The current version of Hegel for OCaml. *)
let version = "0.25.0"

(** Generators for composable test data generation. *)
module Generators = Generators

(** Stateful property-based testing on top of {!Generators}. *)
module Stateful = Stateful

(** Concurrency capabilities for concurrent stateful tests. *)
module Concurrency = Concurrency

module Settings = Settings

(** Auxiliary submodule for [@@deriving hegel_generator]. Included
    below so [open Hegel] alone makes derived code resolve. *)
module Derive = Derive

include Derive

(** Test runner and run-loop internals; re-exported (doc-hidden) for white-box
    tests, not for direct use. *)
module Internal = Internal

module type Io = Io.S

module Make = Io.Make

type ('a, 'p) generator = ('a, 'p) Generators.generator
type printable = Generators.printable
type unprintable = Generators.unprintable

include Generators.Public

(* Test-case and test-location types re-exported so the whole
   public API lives directly under Hegel. The module re-exports above are
   doc-hidden in the mli: white-box surfaces for the test suite. *)

type test_case = Internal.test_case

type test_location = Internal.test_location =
  { function_name : string
  ; file : string
  ; begin_line : int
  }

exception Assume_rejected = Internal.Assume_rejected
exception Usage_error = Internal.Usage_error

(** {2 Convenience re-exports} *)

(** [run_hegel_test ?settings ?test_location ?database_key ?failure_blobs test_fn]
    runs a property test against the native engine, defaulting to
    [Settings.default ()]. The [let%hegel_test] PPX runs tests through the
    equivalent {!run_hegel_test_ppx}. *)
let run_hegel_test ?settings ?test_location ?database_key ?failure_blobs test_fn =
  Internal.run_hegel_test ?settings ?test_location ?database_key ?failure_blobs test_fn
;;

(** [run_hegel_test_ppx] is {!run_hegel_test} with the PPX replay hint enabled;
    the [let%hegel_test] PPX targets it. Not for direct use. *)
let run_hegel_test_ppx ?settings ?test_location ?database_key ?failure_blobs test_fn =
  Internal.run_hegel_test
    ?settings
    ?test_location
    ~from_ppx:true
    ?database_key
    ?failure_blobs
    test_fn
;;

(** [assume tc condition] rejects the current test case if [condition] is
    [false]. *)
let assume = Internal.assume

(** [note tc message] prints [message] to stderr subject to the run's verbosity:
    never under [Quiet], only on the final (failing) replay under [Normal], and
    on every test case under [Verbose] or [Debug]. *)
let note = Internal.note

(** [require tc ?msg condition] fails the current test case when [condition] is
    [false]. See {!Internal.require}. *)
let require = Internal.require

(** [require_equal tc ?msg sexp_of lhs rhs] fails the current test case when the
    two values render to different sexps, printing a sexp diff in the failure
    report. See {!Internal.require_equal}. *)
let require_equal = Internal.require_equal

(** [target tc ~label ~value] sends a target command to guide the search engine
    toward higher values. *)
let target = Internal.target

(** [event tc ~label] records [label] as observed on this test case for the
    end-of-run statistics report. *)
let event = Internal.event

(** [event_value tc ~label ~value] records the finite observation [value] under
    [label] for the end-of-run statistics report. *)
let event_value = Internal.event_value

(** [draw ?label tc gen] produces a typed value from the printable generator
    [gen]. On the final replay of a failing test, an outermost draw prints its
    value. See {!Generators.draw}. *)
let draw = Generators.draw

(** [draw_named ~label ~repeatable tc gen] is the naming-aware draw the
    [let%hegel_test] PPX rewrites bindings to; not intended for direct use
    (prefer {!draw}). See {!Generators.draw_named}. *)
let draw_named = Generators.draw_named

(** [draw_silent tc gen] is {!draw} without printing the value on the final
    replay, and accepts a generator with no printer. *)
let draw_silent = Generators.draw_silent

(** [draw_silent_named ~name tc gen] is the naming-aware {!draw_silent} the
    [let%hegel_test] PPX rewrites bindings to; not intended for direct use
    (prefer {!draw_silent}). See {!Generators.draw_silent_named}. *)
let draw_silent_named = Generators.draw_silent_named

(** [clone tc] forks an independent clone of [tc] for driving generation
    concurrently. Its native resources are owned by the test case and freed
    once the case completes. See {!Internal.clone}. *)
let clone = Internal.clone

(** [with_printer sexp_of gen] attaches [sexp_of] so [gen] can be drawn with
    {!draw}. See {!Generators.with_printer}. *)
let%template with_printer = Generators.with_printer [@mode m]
[@@mode m = (nonportable, portable)]
;;