@@ -78,3 +78,86 @@ t @@ fun () ->
7878 print_endline @@ Printexc. to_string e ^ " \n " ^ st;
7979 assert false );
8080 true ;;
81+
82+ module CS = CCCanonical_sexp
83+
84+
85+ module Csexp_arg = struct
86+ open Csexp
87+ type t = Csexp .t
88+ let atom s = Atom s
89+ let list l = List l
90+ let match_ s ~atom ~list = match s with
91+ | Atom s -> atom s
92+ | List l -> list l
93+ type loc = unit
94+ let make_loc = None
95+ let atom_with_loc ~loc :() = atom
96+ let list_with_loc ~loc :() = list
97+ end
98+
99+ module CS0 = CS. Make (Csexp_arg )
100+ module Sexp0 = CCSexp. Make (Csexp_arg )
101+
102+ let gen_csexp (str :string Q.Gen.t ) : CS0.t Q.Gen.t =
103+ let open Q.Gen in
104+ let open Csexp in
105+ begin fix @@ fun self depth ->
106+ let mklist n =
107+ list_size (0 -- n) (self (depth+ 1 )) > |= fun l -> List l
108+ in
109+ frequency @@ List. flatten [
110+ [(3 , str
111+ > |= fun s -> Atom s)];
112+ (match depth with
113+ | 0 -> [4 ,mklist 25 ]
114+ | 1 -> [2 ,mklist 7 ]
115+ | 2 -> [1 ,mklist 2 ]
116+ | _ -> [] );
117+ ]
118+ end 0
119+
120+ let rec shrink_csexp (s :Csexp.t ) : Csexp.t Q.Iter.t =
121+ let open Csexp in
122+ let open Q.Iter in
123+ match s with
124+ | Atom s -> Q.Shrink. string s > |= fun s -> Atom s
125+ | List l -> Q.Shrink. list ~shrink: shrink_csexp l > |= fun l -> List l
126+
127+ let arb_csexp_pp =
128+ let genstr = Q.Gen. (string_size ~gen: Q.Gen. printable (0 -- 15 )) in
129+ Q. make ~print: Sexp0. to_string
130+ ~shrink: shrink_csexp (gen_csexp genstr)
131+
132+ let arb_csexp_arb =
133+ (* binary-ready *)
134+ let genchar = Q.Gen. (0 -- 255 > |= Char. chr) in
135+ let genstr = Q.Gen. (string_size ~gen: genchar (0 -- 15 )) in
136+ Q. make
137+ ~print: Sexp0. to_string
138+ ~shrink: shrink_csexp (gen_csexp genstr)
139+
140+ module Make (X : sig val arb : Csexp.t Q.arbitrary end )() = struct
141+ open X ;;
142+
143+ q ~count: 2_000 arb @@ fun sexp ->
144+ let s = CS0. to_string sexp in
145+ match Csexp. parse_string s with
146+ | Ok sexp' -> sexp = sexp'
147+ | Error (_ ,msg ) -> Q.Test. fail_report msg;;
148+
149+ q ~count: 2_000 arb @@ fun sexp ->
150+ let s = Csexp. to_string sexp in
151+ match CS0. parse_string s with
152+ | Ok sexp' -> sexp = sexp'
153+ | Error msg -> Q.Test. fail_report msg;;
154+
155+ let init () = ()
156+ end
157+
158+ let () =
159+ let module M1 = Make (struct let arb= arb_csexp_pp end )() in
160+ let module M2 = Make (struct let arb= arb_csexp_arb end )() in
161+ M1. init() ;
162+ M2. init() ;
163+ ()
0 commit comments