package base_quickcheck

  1. Overview
  2. Docs

Source file ppx_generator_expander.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
open! Import

let arrow
      ~generator_of_core_type
      ~observer_of_core_type
      ~loc
      ~arg_label
      ~input_type
      ~output_type
  =
  let input_observer =
    match arg_label with
    | Nolabel | Labelled _ ->
      observer_of_core_type input_type
    | Optional _ ->
      [%expr
        Base_quickcheck.Observer.option
          [%e observer_of_core_type input_type]]
  in
  let output_generator =
    generator_of_core_type output_type
  in
  let unlabelled =
    [%expr
      Base_quickcheck.Generator.fn
        [%e input_observer]
        [%e output_generator]]
  in
  match arg_label with
  | Nolabel -> unlabelled
  | Labelled _
  | Optional _ ->
    [%expr
      Base_quickcheck.Generator.map
        ~f:[%e fn_map_label ~loc ~from:Nolabel ~to_:arg_label]
        [%e unlabelled]]

let compound_generator ~loc ~make_compound_expr generator_list =
  let size_pat, size_expr = gensym "size" loc in
  let random_pat, random_expr = gensym "random" loc in
  [%expr
    Base_quickcheck.Generator.create
      (fun ~size:[%p size_pat] ~random:[%p random_pat] ->
         [%e
           make_compound_expr ~loc
             (List.map generator_list ~f:(fun generator ->
                let loc = generator.pexp_loc in
                [%expr
                  Base_quickcheck.Generator.generate
                    [%e generator]
                    ~size:[%e size_expr]
                    ~random:[%e random_expr]]))])]

let compound
      (type field)
      ~generator_of_core_type
      ~loc
      ~fields
      (module Field : Field_syntax.S with type ast = field)
  =
  let fields = List.map fields ~f:Field.create in
  compound_generator
    ~loc
    ~make_compound_expr:(Field.expression fields)
    (List.map fields ~f:(fun field ->
       generator_of_core_type (Field.core_type field)))

let variant
      (type clause)
      ~generator_of_core_type
      ~loc
      ~variant_type
      ~clauses
      (module Clause : Clause_syntax.S with type ast = clause)
  =
  let clauses = Clause.create_list clauses in
  let generators =
    List.map clauses ~f:(fun clause ->
      let loc = Clause.location clause in
      compound_generator
        ~loc
        ~make_compound_expr:(Clause.expression clause variant_type)
        (List.map (Clause.core_type_list clause) ~f:generator_of_core_type))
  in
  [%expr Base_quickcheck.Generator.union [%e elist ~loc generators]]
OCaml

Innovation. Community. Security.