From d3beee9c9f4bc469107a9fd51466a27aa3aa4067 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Wed, 8 Jun 2022 16:39:22 +0200 Subject: [PATCH 01/26] add bytes gen and Co --- src/core/QCheck.ml | 58 +++++++++++++++++++++++++++++++++++++++---- src/core/QCheck.mli | 60 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 5 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index ca267b69..3c5d2bc0 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -86,15 +86,20 @@ let _opt_sum a b = match a, b with let sum_int = List.fold_left (+) 0 -(* Included for backwards compatibility, pre 4.13 *) -let string_fold_right f s acc = - let len = String.length s in +let _fold_righ length get f x acc = + let len = length x in let rec loop i acc = if i<0 then acc - else loop (i-1) (f s.[i] acc) in + else loop (i-1) (f (get x i) acc) in loop (len-1) acc +(* Included for backwards compatibility, pre 4.13 *) +let bytes_fold_right = _fold_righ Bytes.length Bytes.get + +(* Included for backwards compatibility, pre 4.13 *) +let string_fold_right = _fold_righ String.length String.get + exception No_example_found of string (* raised if an example failed to be found *) @@ -365,16 +370,26 @@ module Gen = struct let printable st = printable_chars.[RS.int st (String.length printable_chars)] let numeral st = char_of_int (48 + RS.int st 10) - let string_size ?(gen = char) size st = + let bytes_size ?(gen = char) size st = let s = Bytes.create (size st) in for i = 0 to Bytes.length s - 1 do Bytes.set s i (gen st) done; + s + + let string_size ?(gen = char) size st = + let s = bytes_size ~gen size st in Bytes.unsafe_to_string s + + let bytes ?gen st = bytes_size ?gen nat st let string ?gen st = string_size ?gen nat st + let bytes_of gen = bytes_size ~gen nat let string_of gen = string_size ~gen nat + let bytes_printable = bytes_size ~gen:printable nat let string_printable = string_size ~gen:printable nat + let bytes_readable = bytes_printable let string_readable = string_printable + let small_bytes ?gen st = bytes_size ?gen small_nat st let small_string ?gen st = string_size ?gen small_nat st let small_list gen = list_size small_nat gen let small_array gen = array_size small_nat gen @@ -462,6 +477,7 @@ module Print = struct let int = string_of_int let bool = string_of_bool let float = string_of_float + let bytes = Bytes.to_string let string s = s let char c = String.make 1 c @@ -771,6 +787,16 @@ module Shrink = struct | Some shrink -> list_elems shrink l yield let string ?(shrink = char) s yield = + let buf = Buffer.create 42 in + list ~shrink + (bytes_fold_right (fun c acc -> c::acc) b []) + (fun cs -> + List.iter (fun c -> Buffer.add_char buf c) cs; + let b = Buffer.contents buf |> Bytes.of_string in + Buffer.clear buf; + yield b) + + let bytes (b : bytes) (yield : bytes -> unit) = let buf = Buffer.create 42 in list ~shrink (string_fold_right (fun c acc -> c::acc) s []) @@ -940,6 +966,7 @@ module Observable = struct let int i = i land max_int let bool b = if b then 1 else 2 let char x = Char.code x + let bytes (x:bytes) = Hashtbl.hash x let string (x:string) = Hashtbl.hash x let opt f = function | None -> 42 @@ -953,6 +980,7 @@ module Observable = struct type 'a t = 'a -> 'a -> bool let int : int t = (=) + let bytes : bytes t = (=) let string : string t = (=) let bool : bool t = (=) let float = Float.equal @@ -986,6 +1014,7 @@ module Observable = struct let bool : bool t = make ~hash:H.bool ~eq:Eq.bool Print.bool let int : int t = make ~hash:H.int ~eq:Eq.int Print.int let float : float t = make ~eq:Eq.float Print.float + let bytes = make ~hash:H.bytes ~eq:Eq.bytes Print.bytes let string = make ~hash:H.string ~eq:Eq.string Print.string let char = make ~hash:H.char ~eq:Eq.char Print.char @@ -1109,6 +1138,25 @@ let printable_char = let numeral_char = make ~print:(sprintf "%C") ~small:(small_char '0') ~shrink:Shrink.char_numeral Gen.numeral + +let bytes_gen_of_size size gen = + make ~shrink:Shrink.bytes ~small:Bytes.length + ~print:(Print.bytes) (Gen.bytes_size ~gen size) +let bytes_gen gen = + make ~shrink:Shrink.bytes ~small:Bytes.length + ~print:(Print.bytes) (Gen.bytes ~gen) + +let bytes = bytes_gen Gen.char +let bytes_of_size size = bytes_gen_of_size size Gen.char +let small_bytes = bytes_gen_of_size Gen.small_nat Gen.char + +let printable_bytes = bytes_gen Gen.printable +let printable_bytes_of_size size = bytes_gen_of_size size Gen.printable +let small_printable_bytes = bytes_gen_of_size Gen.small_nat Gen.printable + +let numeral_bytes = bytes_gen Gen.numeral +let numeral_bytes_of_size size = bytes_gen_of_size size Gen.numeral + let string_gen_of_size size gen = make ~shrink:Shrink.string ~small:String.length ~print:(sprintf "%S") (Gen.string_size ~gen size) diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 6e342c9f..89cf1580 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -397,6 +397,26 @@ module Gen : sig Example: [char_range 'a' 'z'] for all lower case ascii letters. @since 0.13 *) + val bytes_size : ?gen:char t -> int t -> bytes t + (** Builds a bytes generator from a (non-negative) size generator. + Accepts an optional character generator (the default is {!char}). *) + + val bytes : ?gen:char t -> bytes t + (** Builds a bytes generator. Bytes size is generated by {!nat}. + Accepts an optional character generator (the default is {!char}). + See also {!bytes_of} and {!bytes_readable} for versions without + optional parameters. *) + + val bytes_of : char t -> bytes t + (** Builds a bytes generator using the given character generator. *) + + val bytes_printable : bytes t + (** Builds a bytes generator using the {!printable} character generator. *) + + val small_bytes : ?gen:char t -> bytes t + (** Builds a bytes generator, length is {!small_nat} + Accepts an optional character generator (the default is {!char}). *) + val string_size : ?gen:char t -> int t -> string t (** Builds a string generator from a (non-negative) size generator. Accepts an optional character generator (the default is {!char}). *) @@ -577,6 +597,8 @@ module Print : sig val char : char t (** Character printer. *) + val bytes : bytes t (** Bytes printer. *) + val string : string t (** String printer. *) val option : 'a t -> 'a option t (** Option printer. *) @@ -709,6 +731,9 @@ module Shrink : sig val option : 'a t -> 'a option t + val bytes : bytes t + (** @since NEXT_RELEASE *) + val string : ?shrink:(char t) -> string t val filter : ('a -> bool) -> 'a t -> 'a t @@ -811,6 +836,7 @@ module Observable : sig val int : int t val float : float t val string : string t + val bytes : bytes t val char : char t val make : @@ -1241,6 +1267,19 @@ val printable_char : char arbitrary val numeral_char : char arbitrary (** Uniformly distributed over ['0'..'9']. *) +val bytes_gen_of_size : int Gen.t -> char Gen.t -> bytes arbitrary +(** Builds a bytes generator from a (non-negative) size generator and a character generator. *) + +val bytes_gen : char Gen.t -> bytes arbitrary +(** Generates bytess with a distribution of length of {!Gen.nat}. *) + +val bytes : bytes arbitrary +(** Generates bytess with a distribution of length of {!Gen.nat} + and distribution of characters of [char]. *) + +val small_bytes : bytes arbitrary +(** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). *) + val string_gen_of_size : int Gen.t -> char Gen.t -> string arbitrary (** Builds a string generator from a (non-negative) size generator and a character generator. *) @@ -1258,6 +1297,27 @@ val small_list : 'a arbitrary -> 'a list arbitrary (** Generates lists of small size (see {!Gen.small_nat}). @since 0.5.3 *) +val bytes_of_size : int Gen.t -> bytes arbitrary +(** Generates bytess with distribution of characters of [char]. *) + +val printable_bytes : bytes arbitrary +(** Generates bytess with a distribution of length of {!Gen.nat} + and distribution of characters of [printable_char]. *) + +val printable_bytes_of_size : int Gen.t -> bytes arbitrary +(** Generates bytess with distribution of characters of [printable_char]. *) + +val small_printable_bytes : bytes arbitrary +(** Generates bytess with a length of [small_nat] + and distribution of characters of [printable_char]. *) + +val numeral_bytes : bytes arbitrary +(** Generates bytess with a distribution of length of {!Gen.nat} + and distribution of characters of [numeral_char]. *) + +val numeral_bytes_of_size : int Gen.t -> bytes arbitrary +(** Generates bytess with a distribution of characters of [numeral_char]. *) + val string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [char]. *) From f2fa08305bfdc15ebebb31d230573cc627eb363b Mon Sep 17 00:00:00 2001 From: Nicolas Osborne Date: Thu, 9 Jun 2022 09:12:23 +0200 Subject: [PATCH 02/26] Update src/core/QCheck.mli Co-authored-by: Valentin Chaboche --- src/core/QCheck.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 89cf1580..e8246a53 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -411,7 +411,7 @@ module Gen : sig (** Builds a bytes generator using the given character generator. *) val bytes_printable : bytes t - (** Builds a bytes generator using the {!printable} character generator. *) + (** Generator using the {!printable} character generator. *) val small_bytes : ?gen:char t -> bytes t (** Builds a bytes generator, length is {!small_nat} From dec48c83584528317b8559879d2007bd7487bd15 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Thu, 9 Jun 2022 10:09:13 +0200 Subject: [PATCH 03/26] add tests for bytes --- src/core/QCheck.ml | 24 ++-- test/core/QCheck_expect_test.expected.64 | 139 ++++++++++++++++++++++- test/core/QCheck_tests.ml | 45 ++++++++ 3 files changed, 194 insertions(+), 14 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 3c5d2bc0..134e515a 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -86,7 +86,7 @@ let _opt_sum a b = match a, b with let sum_int = List.fold_left (+) 0 -let _fold_righ length get f x acc = +let _fold_right length get f x acc = let len = length x in let rec loop i acc = if i<0 @@ -95,10 +95,10 @@ let _fold_righ length get f x acc = loop (len-1) acc (* Included for backwards compatibility, pre 4.13 *) -let bytes_fold_right = _fold_righ Bytes.length Bytes.get +let bytes_fold_right = _fold_right Bytes.length Bytes.get (* Included for backwards compatibility, pre 4.13 *) -let string_fold_right = _fold_righ String.length String.get +let string_fold_right = _fold_right String.length String.get exception No_example_found of string (* raised if an example failed to be found *) @@ -789,22 +789,22 @@ module Shrink = struct let string ?(shrink = char) s yield = let buf = Buffer.create 42 in list ~shrink - (bytes_fold_right (fun c acc -> c::acc) b []) + (string_fold_right (fun c acc -> c::acc) s []) (fun cs -> - List.iter (fun c -> Buffer.add_char buf c) cs; - let b = Buffer.contents buf |> Bytes.of_string in - Buffer.clear buf; - yield b) + List.iter (fun c -> Buffer.add_char buf c) cs; + let s = Buffer.contents buf in + Buffer.clear buf; + yield s) let bytes (b : bytes) (yield : bytes -> unit) = let buf = Buffer.create 42 in - list ~shrink - (string_fold_right (fun c acc -> c::acc) s []) + list ~shrink:char + (bytes_fold_right (fun c acc -> c::acc) b []) (fun cs -> List.iter (fun c -> Buffer.add_char buf c) cs; - let s = Buffer.contents buf in + let b = Buffer.contents buf |> Bytes.of_string in Buffer.clear buf; - yield s) + yield b) let pair a b (x,y) yield = a x (fun x' -> yield (x',y)); diff --git a/test/core/QCheck_expect_test.expected.64 b/test/core/QCheck_expect_test.expected.64 index e6a4e83b..ae65c3c7 100644 --- a/test/core/QCheck_expect_test.expected.64 +++ b/test/core/QCheck_expect_test.expected.64 @@ -196,7 +196,7 @@ Test FAIL_bad_gen failed: ERROR: uncaught exception in generator for test FAIL_bad_gen after 100 steps: Exception: Invalid_argument("Gen.int_bound") -Backtrace: +Backtrace: --- Failure -------------------------------------------------------------------- @@ -284,6 +284,30 @@ Test printable never produces less than '5 failed (3 shrink steps): --- Failure -------------------------------------------------------------------- +Test bytes are empty failed (15 shrink steps): + +a + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \000 char failed (8 shrink steps): + + + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \255 char failed (14 shrink steps): + +˙ + +--- Failure -------------------------------------------------------------------- + +Test bytes have unique chars failed (13 shrink steps): + + + +--- Failure -------------------------------------------------------------------- + Test strings are empty failed (15 shrink steps): "a" @@ -553,7 +577,7 @@ Test FAIL_#99_1 failed: ERROR: uncaught exception in generator for test FAIL_#99_1 after 100 steps: Exception: QCheck.No_example_found("") -Backtrace: +Backtrace: +++ Collect ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -673,6 +697,117 @@ stats dist: 19: ################################################## 253 20: ############################################## 230 ++++ Stats for bytes_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 7.49, stddev: 1.70, median 7, min 5, max 10 + 5: ##################################################### 837 + 6: ##################################################### 826 + 7: ###################################################### 843 + 8: ####################################################### 855 + 9: #################################################### 813 + 10: ##################################################### 826 + ++++ Stats for bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for bytes_of len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 363.14, stddev: 1245.80, median 9, min 0, max 9986 + 0.. 499: ####################################################### 4270 + 500.. 999: ###### 493 + 1000.. 1499: 16 + 1500.. 1999: 11 + 2000.. 2499: 15 + 2500.. 2999: 17 + 3000.. 3499: 11 + 3500.. 3999: 19 + 4000.. 4499: 14 + 4500.. 4999: 10 + 5000.. 5499: 16 + 5500.. 5999: 11 + 6000.. 6499: 15 + 6500.. 6999: 13 + 7000.. 7499: 12 + 7500.. 7999: 16 + 8000.. 8499: 11 + 8500.. 8999: 4 + 9000.. 9499: 13 + 9500.. 9999: 13 + ++++ Stats for printable_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for small_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 + 0.. 4: #################################################### 1925 + 5.. 9: ####################################################### 2005 + 10.. 14: # 52 + 15.. 19: # 50 + 20.. 24: # 55 + 25.. 29: # 56 + 30.. 34: # 55 + 35.. 39: # 49 + 40.. 44: # 65 + 45.. 49: # 65 + 50.. 54: # 55 + 55.. 59: # 68 + 60.. 64: # 61 + 65.. 69: # 65 + 70.. 74: # 57 + 75.. 79: # 66 + 80.. 84: # 65 + 85.. 89: # 64 + 90.. 94: # 60 + 95.. 99: # 62 + +++ Stats for string_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: diff --git a/test/core/QCheck_tests.ml b/test/core/QCheck_tests.ml index 0b26559c..929c9824 100644 --- a/test/core/QCheck_tests.ml +++ b/test/core/QCheck_tests.ml @@ -201,6 +201,15 @@ module Generator = struct Test.make ~name:"nat has right range" ~count:1000 (make ~print:Print.int Gen.nat) (fun n -> 0 <= n && n < 10000) + let bytes_test = + Test.make ~name:"bytes has right length and content" ~count:1000 + bytes + (fun b -> + let len = Bytes.length b in + 0 <= len && len < 10000 + && Bytes.to_seq b |> + Seq.fold_left (fun acc c -> acc && '\000' <= c && c <= '\255') true) + let string_test = Test.make ~name:"string has right length and content" ~count:1000 string @@ -389,6 +398,7 @@ module Generator = struct printable_test; numeral_test; nat_test; + bytes_test; string_test; pair_test; triple_test; @@ -471,6 +481,26 @@ module Shrink = struct let numeral_is_never_less_5 = Test.make ~name:"printable never produces less than '5" ~count:1000 numeral_char (fun c -> c >= '5') + let bytes_are_empty = + Test.make ~name:"bytes are empty" ~count:1000 + bytes (fun b -> b = Bytes.empty) + + let bytes_never_has_000_char = + Test.make ~name:"bytes never has a \\000 char" ~count:1000 + bytes + (fun b -> Bytes.to_seq b |> Seq.fold_left (fun acc c -> acc && c <> '\000') true) + + let bytes_never_has_255_char = + Test.make ~name:"bytes never has a \\255 char" ~count:1000 + bytes + (fun s -> Bytes.to_seq s |> Seq.fold_left (fun acc c -> acc && c <> '\255') true) + + let bytes_unique_chars = + Test.make ~name:"bytes have unique chars" ~count:1000 + bytes + (fun s -> + let ch_list = Bytes.to_seq s |> List.of_seq in + List.length ch_list = List.length (List.sort_uniq Char.compare ch_list)) let strings_are_empty = Test.make ~name:"strings are empty" ~count:1000 @@ -676,6 +706,10 @@ module Shrink = struct char_is_never_abcdef; printable_is_never_sign; numeral_is_never_less_5; + bytes_are_empty; + bytes_never_has_000_char; + bytes_never_has_255_char; + bytes_unique_chars; strings_are_empty; string_never_has_000_char; string_never_has_255_char; @@ -842,6 +876,16 @@ module Stats = struct Test.make ~name:"numeral char code dist" ~count:500_000 (add_stat ("char code", Char.code) numeral_char) (fun _ -> true); ] + let bytes_len_tests = + let len = ("len",Bytes.length) in + [ + Test.make ~name:"bytes_size len dist" ~count:5_000 (add_stat len (bytes_of_size (Gen.int_range 5 10))) (fun _ -> true); + Test.make ~name:"bytes len dist" ~count:5_000 (add_stat len bytes) (fun _ -> true); + Test.make ~name:"bytes_of len dist" ~count:5_000 (add_stat len (bytes_gen (Gen.return 'a'))) (fun _ -> true); + Test.make ~name:"printable_bytes len dist" ~count:5_000 (add_stat len printable_bytes) (fun _ -> true); + Test.make ~name:"small_bytes len dist" ~count:5_000 (add_stat len small_bytes) (fun _ -> true); + ] + let string_len_tests = let len = ("len",String.length) in [ @@ -924,6 +968,7 @@ module Stats = struct @ char_dist_tests @ [tree_depth_test; range_subset_test;] + @ bytes_len_tests @ string_len_tests @ [pair_dist; triple_dist; From 1584cf319efc3be95ae09762ed1c4cc562ddab37 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Thu, 9 Jun 2022 14:04:31 +0200 Subject: [PATCH 04/26] add bytes to QCheck2 --- CHANGELOG.md | 4 + src/core/QCheck.mli | 57 +++++---- src/core/QCheck2.ml | 16 +++ src/core/QCheck2.mli | 49 ++++++++ test/core/QCheck2_expect_test.expected.64 | 137 +++++++++++++++++++++- test/core/QCheck2_tests.ml | 46 ++++++++ test/core/QCheck_expect_test.expected.64 | 6 +- 7 files changed, 290 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 463f1d05..8752b5e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.20 +- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,small_bytes}` +- add `QCheck.{Print,Shrink,Observable}.bytes` +- add `QCheck2.{Print,Shrink}.bytes` +- add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,small_bytes,bytes_of_size,printable_bytes,printable_bytes_of_size,numeral_bytes,numeral_bytes_of_size}` - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) - add `QCheck2.Gen.set_shrink` to modify the generator's shrinker diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index e8246a53..82f6a35f 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -399,23 +399,28 @@ module Gen : sig val bytes_size : ?gen:char t -> int t -> bytes t (** Builds a bytes generator from a (non-negative) size generator. - Accepts an optional character generator (the default is {!char}). *) + Accepts an optional character generator (the default is {!char}). + @since NEXT_RELEASE *) val bytes : ?gen:char t -> bytes t (** Builds a bytes generator. Bytes size is generated by {!nat}. Accepts an optional character generator (the default is {!char}). See also {!bytes_of} and {!bytes_readable} for versions without - optional parameters. *) + optional parameters. + @since NEXT_RELEASE *) val bytes_of : char t -> bytes t - (** Builds a bytes generator using the given character generator. *) + (** Builds a bytes generator using the given character generator. + @since NEXT_RELEASE *) val bytes_printable : bytes t - (** Generator using the {!printable} character generator. *) + (** Generator using the {!printable} character generator. + @since NEXT_RELEASE *) val small_bytes : ?gen:char t -> bytes t (** Builds a bytes generator, length is {!small_nat} - Accepts an optional character generator (the default is {!char}). *) + Accepts an optional character generator (the default is {!char}). + @since NEXT_RELEASE *) val string_size : ?gen:char t -> int t -> string t (** Builds a string generator from a (non-negative) size generator. @@ -597,7 +602,7 @@ module Print : sig val char : char t (** Character printer. *) - val bytes : bytes t (** Bytes printer. *) + val bytes : bytes t (** Bytes printer. @since NEXT_RELEASE *) val string : string t (** String printer. *) @@ -836,7 +841,7 @@ module Observable : sig val int : int t val float : float t val string : string t - val bytes : bytes t + val bytes : bytes t (** @since NEXT_RELEASE *) val char : char t val make : @@ -1268,17 +1273,21 @@ val numeral_char : char arbitrary (** Uniformly distributed over ['0'..'9']. *) val bytes_gen_of_size : int Gen.t -> char Gen.t -> bytes arbitrary -(** Builds a bytes generator from a (non-negative) size generator and a character generator. *) +(** Builds a bytes generator from a (non-negative) size generator and a character generator. + @since NEXT_RELEASE *) val bytes_gen : char Gen.t -> bytes arbitrary -(** Generates bytess with a distribution of length of {!Gen.nat}. *) +(** Generates bytes with a distribution of length of {!Gen.nat}. + @since NEXT_RELEASE *) val bytes : bytes arbitrary -(** Generates bytess with a distribution of length of {!Gen.nat} - and distribution of characters of [char]. *) +(** Generates bytes with a distribution of length of {!Gen.nat} + and distribution of characters of [char]. + @since NEXT_RELEASE *) val small_bytes : bytes arbitrary -(** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). *) +(** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). + @since NEXT_RELEASE *) val string_gen_of_size : int Gen.t -> char Gen.t -> string arbitrary (** Builds a string generator from a (non-negative) size generator and a character generator. *) @@ -1298,25 +1307,31 @@ val small_list : 'a arbitrary -> 'a list arbitrary @since 0.5.3 *) val bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytess with distribution of characters of [char]. *) +(** Generates bytes with distribution of characters of [char]. + @since NEXT_RELEASE *) val printable_bytes : bytes arbitrary -(** Generates bytess with a distribution of length of {!Gen.nat} - and distribution of characters of [printable_char]. *) +(** Generates bytes with a distribution of length of {!Gen.nat} + and distribution of characters of [printable_char]. + @since NEXT_RELEASE *) val printable_bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytess with distribution of characters of [printable_char]. *) +(** Generates bytes with distribution of characters of [printable_char]. + @since NEXT_RELEASE *) val small_printable_bytes : bytes arbitrary -(** Generates bytess with a length of [small_nat] - and distribution of characters of [printable_char]. *) +(** Generates bytes with a length of [small_nat] + and distribution of characters of [printable_char]. + @since NEXT_RELEASE *) val numeral_bytes : bytes arbitrary -(** Generates bytess with a distribution of length of {!Gen.nat} - and distribution of characters of [numeral_char]. *) +(** Generates bytes with a distribution of length of {!Gen.nat} + and distribution of characters of [numeral_char]. + @since NEXT_RELEASE *) val numeral_bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytess with a distribution of characters of [numeral_char]. *) +(** Generates bytes with a distribution of characters of [numeral_char]. + @since NEXT_RELEASE *) val string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [char]. *) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index ec346577..a3593e53 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -698,6 +698,14 @@ module Gen = struct let string_size ?(gen = char) (size : int t) : string t = bytes_size ~gen size >|= Bytes.unsafe_to_string + let bytes : bytes t = bytes_size nat + + let bytes_of gen = bytes_size ~gen nat + + let bytes_printable = bytes_size ~gen:printable nat + + let small_bytes ?gen st = bytes_size ?gen small_nat st + let string : string t = string_size nat let string_of gen = string_size ~gen nat @@ -777,6 +785,8 @@ module Print = struct let float = string_of_float + let bytes = Bytes.to_string + let string s = Printf.sprintf "%S" s let char c = Printf.sprintf "%C" c @@ -962,6 +972,8 @@ module Observable = struct let char x = Char.code x + let bytes (x:bytes) = Hashtbl.hash x + let string (x:string) = Hashtbl.hash x let option f = function @@ -979,6 +991,8 @@ module Observable = struct let int : int t = (=) + let bytes : bytes t = (=) + let string : string t = (=) let bool : bool t = (=) @@ -1020,6 +1034,8 @@ module Observable = struct let float : float t = make ~eq:Eq.float Print.float + let bytes = make ~hash:H.bytes ~eq:Eq.bytes Print.bytes + let string = make ~hash:H.string ~eq:Eq.string Print.string let char = make ~hash:H.char ~eq:Eq.char Print.char diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index f5810ea0..f78ddc9c 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -289,6 +289,47 @@ module Gen : sig Shrinks towards ['0']. *) + val bytes_size : ?gen:char t -> int t -> bytes t + (** Builds a bytes generator from a (non-negative) size generator. + Accepts an optional character generator (the default is {!char}). + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + + val bytes : bytes t + (** Builds a bytes generator. Bytes size is generated by {!nat}. + The default character generator is {!char}. + See also {!bytes_of} and {!bytes_printable} for versions with + custom char generator. + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + + val bytes_of : char t -> bytes t + (** Builds a bytes generator using the given character generator. + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + + val bytes_printable : bytes t + (** Builds a bytes generator using the {!printable} character generator. + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + + val small_bytes : ?gen:char t -> bytes t + (** Builds a bytes generator, length is {!small_nat}. + Accepts an optional character generator (the default is {!char}). + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + + val string_size : ?gen:char t -> int t -> string t (** Builds a string generator from a (non-negative) size generator. Accepts an optional character generator (the default is {!char}). @@ -1036,6 +1077,10 @@ module Print : sig val char : char t (** [char] is a printer of character. *) + val bytes : bytes t + (** [bytes] is a printer of bytes. + @since NEXT_RELEASE *) + val string : string t (** [string] is a printer of string. *) @@ -1234,6 +1279,10 @@ module Observable : sig val float : float t (** [float] is an observable of [float]. *) + val bytes : bytes t + (** [bytes] is an observable of [bytes]. + @since NEXT_RELEASE *) + val string : string t (** [string] is an observable of [string]. *) diff --git a/test/core/QCheck2_expect_test.expected.64 b/test/core/QCheck2_expect_test.expected.64 index 803bc65b..30df1c04 100644 --- a/test/core/QCheck2_expect_test.expected.64 +++ b/test/core/QCheck2_expect_test.expected.64 @@ -346,6 +346,30 @@ Test printable never produces less than '5 failed (1 shrink steps): --- Failure -------------------------------------------------------------------- +Test bytes are empty failed (8 shrink steps): + +a + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \000 char failed (22 shrink steps): + +aaaaaaaaaaaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \255 char failed (59 shrink steps): + +aaaaaaaaaaaaaaaaaaaaaaaaaa˙aaaaaaaaaaaaaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + +Test bytes have unique chars failed (18 shrink steps): + +aaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + Test strings are empty failed (8 shrink steps): "a" @@ -715,6 +739,117 @@ stats depth: 14: # 7 15: 4 ++++ Stats for bytes_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 7.49, stddev: 1.70, median 7, min 5, max 10 + 5: ##################################################### 837 + 6: ##################################################### 826 + 7: ###################################################### 843 + 8: ####################################################### 855 + 9: #################################################### 813 + 10: ##################################################### 826 + ++++ Stats for bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for bytes_of len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 363.14, stddev: 1245.80, median 9, min 0, max 9986 + 0.. 499: ####################################################### 4270 + 500.. 999: ###### 493 + 1000.. 1499: 16 + 1500.. 1999: 11 + 2000.. 2499: 15 + 2500.. 2999: 17 + 3000.. 3499: 11 + 3500.. 3999: 19 + 4000.. 4499: 14 + 4500.. 4999: 10 + 5000.. 5499: 16 + 5500.. 5999: 11 + 6000.. 6499: 15 + 6500.. 6999: 13 + 7000.. 7499: 12 + 7500.. 7999: 16 + 8000.. 8499: 11 + 8500.. 8999: 4 + 9000.. 9499: 13 + 9500.. 9999: 13 + ++++ Stats for bytes_printable len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for small_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 + 0.. 4: #################################################### 1925 + 5.. 9: ####################################################### 2005 + 10.. 14: # 52 + 15.. 19: # 50 + 20.. 24: # 55 + 25.. 29: # 56 + 30.. 34: # 55 + 35.. 39: # 49 + 40.. 44: # 65 + 45.. 49: # 65 + 50.. 54: # 55 + 55.. 59: # 68 + 60.. 64: # 61 + 65.. 69: # 65 + 70.. 74: # 57 + 75.. 79: # 66 + 80.. 84: # 65 + 85.. 89: # 64 + 90.. 94: # 60 + 95.. 99: # 62 + +++ Stats for string_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: @@ -1326,7 +1461,7 @@ stats dist: 4150517416584649600.. 4611686018427387903: ################# 189 ================================================================================ 1 warning(s) -failure (60 tests failed, 3 tests errored, ran 131 tests) +failure (64 tests failed, 3 tests errored, ran 141 tests) random seed: 153870556 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml index ab6c78fe..fb0fce3a 100644 --- a/test/core/QCheck2_tests.ml +++ b/test/core/QCheck2_tests.ml @@ -193,6 +193,15 @@ module Generator = struct Test.make ~name:"nat has right range" ~count:1000 ~print:Print.int Gen.nat (fun n -> 0 <= n && n < 10000) + let bytes_test = + Test.make ~name:"bytes has right length and content" ~count:1000 ~print:Print.bytes + Gen.bytes + (fun s -> + let len = Bytes.length s in + 0 <= len && len < 10000 + && Bytes.to_seq s |> + Seq.fold_left (fun acc c -> acc && '\000' <= c && c <= '\255') true) + let string_test = Test.make ~name:"string has right length and content" ~count:1000 ~print:Print.string Gen.string @@ -308,6 +317,7 @@ module Generator = struct char_dist_issue_23; char_test; nat_test; + bytes_test; string_test; pair_test; triple_test; @@ -386,6 +396,27 @@ module Shrink = struct Test.make ~name:"printable never produces less than '5" ~count:1000 ~print:Print.char Gen.numeral (fun c -> c >= '5') + let bytes_are_empty = + Test.make ~name:"bytes are empty" ~count:1000 ~print:Print.bytes + Gen.bytes (fun s -> s = Bytes.empty) + + let bytes_never_has_000_char = + Test.make ~name:"bytes never has a \\000 char" ~count:1000 ~print:Print.bytes + Gen.bytes + (fun s -> Bytes.to_seq s |> Seq.fold_left (fun acc c -> acc && c <> '\000') true) + + let bytes_never_has_255_char = + Test.make ~name:"bytes never has a \\255 char" ~count:1000 ~print:Print.bytes + Gen.bytes + (fun s -> Bytes.to_seq s |> Seq.fold_left (fun acc c -> acc && c <> '\255') true) + + let bytes_unique_chars = + Test.make ~name:"bytes have unique chars" ~count:1000 ~print:Print.bytes + Gen.bytes + (fun s -> + let ch_list = Bytes.to_seq s |> List.of_seq in + List.length ch_list = List.length (List.sort_uniq Char.compare ch_list)) + let strings_are_empty = Test.make ~name:"strings are empty" ~count:1000 ~print:Print.string Gen.string (fun s -> s = "") @@ -604,6 +635,10 @@ module Shrink = struct char_is_never_abcdef; printable_is_never_sign; numeral_is_never_less_5; + bytes_are_empty; + bytes_never_has_000_char; + bytes_never_has_255_char; + bytes_unique_chars; strings_are_empty; string_never_has_000_char; string_never_has_255_char; @@ -776,6 +811,16 @@ module Stats = struct Test.make ~name:"numeral char code dist" ~count:500_000 ~stats:[("char code", Char.code)] Gen.numeral (fun _ -> true); ] + let bytes_len_tests = + let len = ("len",Bytes.length) in + [ + Test.make ~name:"bytes_size len dist" ~count:5_000 ~stats:[len] Gen.(bytes_size (int_range 5 10)) (fun _ -> true); + Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); + Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); + Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); + Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes ~gen:char)(*ugh*)(fun _ -> true); + ] + let string_len_tests = let len = ("len",String.length) in [ @@ -850,6 +895,7 @@ module Stats = struct [ bool_dist; ] @ char_dist_tests @ [ tree_depth_test;] + @ bytes_len_tests @ string_len_tests @ [pair_dist; triple_dist; diff --git a/test/core/QCheck_expect_test.expected.64 b/test/core/QCheck_expect_test.expected.64 index ae65c3c7..15cc10c8 100644 --- a/test/core/QCheck_expect_test.expected.64 +++ b/test/core/QCheck_expect_test.expected.64 @@ -196,7 +196,7 @@ Test FAIL_bad_gen failed: ERROR: uncaught exception in generator for test FAIL_bad_gen after 100 steps: Exception: Invalid_argument("Gen.int_bound") -Backtrace: +Backtrace: --- Failure -------------------------------------------------------------------- @@ -577,7 +577,7 @@ Test FAIL_#99_1 failed: ERROR: uncaught exception in generator for test FAIL_#99_1 after 100 steps: Exception: QCheck.No_example_found("") -Backtrace: +Backtrace: +++ Collect ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1419,7 +1419,7 @@ stats dist: 4150517416584649600.. 4611686018427387903: ################# 189 ================================================================================ 1 warning(s) -failure (59 tests failed, 3 tests errored, ran 139 tests) +failure (63 tests failed, 3 tests errored, ran 149 tests) random seed: 153870556 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From b3ee03e2e0a4a53f685e4cf9e9b535031934943d Mon Sep 17 00:00:00 2001 From: Nicolas Osborne Date: Fri, 10 Jun 2022 09:47:51 +0200 Subject: [PATCH 05/26] Update src/core/QCheck2.mli Co-authored-by: Valentin Chaboche --- src/core/QCheck2.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index f78ddc9c..1d953fb6 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -315,7 +315,7 @@ module Gen : sig @since NEXT_RELEASE *) val bytes_printable : bytes t - (** Builds a bytes generator using the {!printable} character generator. + (** Generator using the {!printable} character generator. Shrinks on the number of characters first, then on the characters. From ea3ce087353235827f8ebc81cf1d8bb95a2605d4 Mon Sep 17 00:00:00 2001 From: Nicolas Osborne Date: Fri, 10 Jun 2022 09:48:02 +0200 Subject: [PATCH 06/26] Update src/core/QCheck2.mli Co-authored-by: Valentin Chaboche --- src/core/QCheck2.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index 1d953fb6..01da8d83 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -298,7 +298,7 @@ module Gen : sig @since NEXT_RELEASE *) val bytes : bytes t - (** Builds a bytes generator. Bytes size is generated by {!nat}. + (** Bytes generator. Bytes size is generated by {!nat}. The default character generator is {!char}. See also {!bytes_of} and {!bytes_printable} for versions with custom char generator. From 4d61e56bac235cae5db0922a92ac72a0b821e8cc Mon Sep 17 00:00:00 2001 From: n-osborne Date: Fri, 10 Jun 2022 13:31:13 +0200 Subject: [PATCH 07/26] no optional gen in QCheck2 --- src/core/QCheck2.ml | 24 ++++++++++++------------ src/core/QCheck2.mli | 19 ++++++++----------- test/core/QCheck2_tests.ml | 24 ++++++++++++------------ 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index a3593e53..670d897f 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -672,7 +672,7 @@ module Gen = struct let nine = 57 in int_range ~origin:zero zero nine >|= char_of_int - let bytes_size ?(gen = char) (size : int t) : bytes t = fun st -> + let bytes_size gen (size : int t) : bytes t = fun st -> let open Tree in size st >>= fun size -> (* Adding char shrinks to a mutable list is expensive: ~20-30% cost increase *) @@ -695,24 +695,24 @@ module Gen = struct in Tree (bytes, shrink) - let string_size ?(gen = char) (size : int t) : string t = - bytes_size ~gen size >|= Bytes.unsafe_to_string + let string_size gen (size : int t) : string t = + bytes_size gen size >|= Bytes.unsafe_to_string - let bytes : bytes t = bytes_size nat + let bytes : bytes t = bytes_size char nat - let bytes_of gen = bytes_size ~gen nat + let bytes_of gen = bytes_size gen nat - let bytes_printable = bytes_size ~gen:printable nat + let bytes_printable = bytes_size printable nat - let small_bytes ?gen st = bytes_size ?gen small_nat st + let small_bytes gen st = bytes_size gen small_nat st - let string : string t = string_size nat + let string : string t = string_size char nat - let string_of gen = string_size ~gen nat + let string_of gen = string_size gen nat - let string_printable = string_size ~gen:printable nat + let string_printable = string_size printable nat - let small_string ?gen st = string_size ?gen small_nat st + let small_string gen st = string_size gen small_nat st let small_list gen = list_size small_nat gen @@ -786,7 +786,7 @@ module Print = struct let float = string_of_float let bytes = Bytes.to_string - + let string s = Printf.sprintf "%S" s let char c = Printf.sprintf "%C" c diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index 01da8d83..3cae909e 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -289,9 +289,8 @@ module Gen : sig Shrinks towards ['0']. *) - val bytes_size : ?gen:char t -> int t -> bytes t + val bytes_size : char t -> int t -> bytes t (** Builds a bytes generator from a (non-negative) size generator. - Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. @@ -321,18 +320,17 @@ module Gen : sig @since NEXT_RELEASE *) - val small_bytes : ?gen:char t -> bytes t + val small_bytes : char t -> bytes t (** Builds a bytes generator, length is {!small_nat}. - Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. @since NEXT_RELEASE *) - val string_size : ?gen:char t -> int t -> string t - (** Builds a string generator from a (non-negative) size generator. - Accepts an optional character generator (the default is {!char}). + val string_size : char t -> int t -> string t + (** Builds a string generator from a character generator and a + (non-negative) size generator. Shrinks on the number of characters first, then on the characters. *) @@ -360,9 +358,8 @@ module Gen : sig @since 0.11 *) - val small_string : ?gen:char t -> string t + val small_string : char t -> string t (** Builds a string generator, length is {!small_nat}. - Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. *) @@ -1078,7 +1075,7 @@ module Print : sig (** [char] is a printer of character. *) val bytes : bytes t - (** [bytes] is a printer of bytes. + (** [bytes] is a printer of bytes. @since NEXT_RELEASE *) val string : string t @@ -1323,7 +1320,7 @@ module Observable : sig (** [quad o1 o2 o3 o4] is an observable of quadruples of [('a * 'b * 'c * 'd)]. *) end - + (** Utils on combining function arguments. *) module Tuple : sig (** Heterogeneous tuple, used to pass any number of arguments to diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml index fb0fce3a..c816408c 100644 --- a/test/core/QCheck2_tests.ml +++ b/test/core/QCheck2_tests.ml @@ -748,8 +748,8 @@ module Function = struct let fold_left_test = Test.make ~name:"fold_left test, fun first" ~print:Print.(quad Fn.print string (list int) (list int)) Gen.(quad (* string -> int -> string *) - (fun2 ~print:Print.string Observable.string Observable.int (small_string ~gen:char)) - (small_string ~gen:char) + (fun2 ~print:Print.string Observable.string Observable.int (small_string char)) + (small_string char) (list small_int) (list small_int)) (fun (f,acc,is,js) -> @@ -814,21 +814,21 @@ module Stats = struct let bytes_len_tests = let len = ("len",Bytes.length) in [ - Test.make ~name:"bytes_size len dist" ~count:5_000 ~stats:[len] Gen.(bytes_size (int_range 5 10)) (fun _ -> true); - Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); - Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); - Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); - Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes ~gen:char)(*ugh*)(fun _ -> true); + Test.make ~name:"bytes_size len dist" ~count:5_000 ~stats:[len] Gen.(bytes_size char (int_range 5 10)) (fun _ -> true); + Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); + Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); + Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); + Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes char) (fun _ -> true); ] let string_len_tests = let len = ("len",String.length) in [ - Test.make ~name:"string_size len dist" ~count:5_000 ~stats:[len] Gen.(string_size (int_range 5 10)) (fun _ -> true); - Test.make ~name:"string len dist" ~count:5_000 ~stats:[len] Gen.string (fun _ -> true); - Test.make ~name:"string_of len dist" ~count:5_000 ~stats:[len] Gen.(string_of (return 'a')) (fun _ -> true); - Test.make ~name:"string_printable len dist" ~count:5_000 ~stats:[len] Gen.string_printable (fun _ -> true); - Test.make ~name:"small_string len dist" ~count:5_000 ~stats:[len] Gen.(small_string ~gen:char)(*ugh*)(fun _ -> true); + Test.make ~name:"string_size len dist" ~count:5_000 ~stats:[len] Gen.(string_size char (int_range 5 10)) (fun _ -> true); + Test.make ~name:"string len dist" ~count:5_000 ~stats:[len] Gen.string (fun _ -> true); + Test.make ~name:"string_of len dist" ~count:5_000 ~stats:[len] Gen.(string_of (return 'a')) (fun _ -> true); + Test.make ~name:"string_printable len dist" ~count:5_000 ~stats:[len] Gen.string_printable (fun _ -> true); + Test.make ~name:"small_string len dist" ~count:5_000 ~stats:[len] Gen.(small_string char) (fun _ -> true); ] let pair_dist = From 712830ccc73a69368b674337a2fbd2d8fff58368 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Tue, 14 Jun 2022 14:50:19 +0200 Subject: [PATCH 08/26] Revert "no optional gen in QCheck2" This reverts commit dad4bb81693d4999fb349923821057276f17a6ab. --- src/core/QCheck2.ml | 26 +++++++++++++------------- src/core/QCheck2.mli | 23 +++++++++++++---------- test/core/QCheck2_tests.ml | 24 ++++++++++++------------ 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 670d897f..d26d7d91 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -672,7 +672,7 @@ module Gen = struct let nine = 57 in int_range ~origin:zero zero nine >|= char_of_int - let bytes_size gen (size : int t) : bytes t = fun st -> + let bytes_size ?(gen = char) (size : int t) : bytes t = fun st -> let open Tree in size st >>= fun size -> (* Adding char shrinks to a mutable list is expensive: ~20-30% cost increase *) @@ -695,24 +695,24 @@ module Gen = struct in Tree (bytes, shrink) - let string_size gen (size : int t) : string t = - bytes_size gen size >|= Bytes.unsafe_to_string + let string_size ?(gen = char) (size : int t) : string t = + bytes_size ~gen size >|= Bytes.unsafe_to_string - let bytes : bytes t = bytes_size char nat + let bytes : bytes t = bytes_size nat - let bytes_of gen = bytes_size gen nat + let bytes_of gen = bytes_size ~gen nat - let bytes_printable = bytes_size printable nat + let bytes_printable = bytes_size ~gen:printable nat - let small_bytes gen st = bytes_size gen small_nat st + let small_bytes ?gen st = bytes_size ?gen small_nat st - let string : string t = string_size char nat + let string : string t = string_size nat - let string_of gen = string_size gen nat + let string_of gen = string_size ~gen nat - let string_printable = string_size printable nat + let string_printable = string_size ~gen:printable nat - let small_string gen st = string_size gen small_nat st + let small_string ?gen st = string_size ?gen small_nat st let small_list gen = list_size small_nat gen @@ -786,7 +786,7 @@ module Print = struct let float = string_of_float let bytes = Bytes.to_string - + let string s = Printf.sprintf "%S" s let char c = Printf.sprintf "%C" c @@ -1524,7 +1524,7 @@ module Test = struct let make_neg = make' ~negative:true let test_get_count (Test cell) = get_count cell - + let test_get_long_factor (Test cell) = get_long_factor cell (** {6 Running the test} *) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index 3cae909e..114bed38 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -289,8 +289,9 @@ module Gen : sig Shrinks towards ['0']. *) - val bytes_size : char t -> int t -> bytes t + val bytes_size : ?gen:char t -> int t -> bytes t (** Builds a bytes generator from a (non-negative) size generator. + Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. @@ -320,17 +321,18 @@ module Gen : sig @since NEXT_RELEASE *) - val small_bytes : char t -> bytes t + val small_bytes : ?gen:char t -> bytes t (** Builds a bytes generator, length is {!small_nat}. + Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. @since NEXT_RELEASE *) - val string_size : char t -> int t -> string t - (** Builds a string generator from a character generator and a - (non-negative) size generator. + val string_size : ?gen:char t -> int t -> string t + (** Builds a string generator from a (non-negative) size generator. + Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. *) @@ -358,8 +360,9 @@ module Gen : sig @since 0.11 *) - val small_string : char t -> string t + val small_string : ?gen:char t -> string t (** Builds a string generator, length is {!small_nat}. + Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. *) @@ -1075,7 +1078,7 @@ module Print : sig (** [char] is a printer of character. *) val bytes : bytes t - (** [bytes] is a printer of bytes. + (** [bytes] is a printer of bytes. @since NEXT_RELEASE *) val string : string t @@ -1320,7 +1323,7 @@ module Observable : sig (** [quad o1 o2 o3 o4] is an observable of quadruples of [('a * 'b * 'c * 'd)]. *) end - + (** Utils on combining function arguments. *) module Tuple : sig (** Heterogeneous tuple, used to pass any number of arguments to @@ -1645,7 +1648,7 @@ module Test : sig type 'a cell (** A single property test on a value of type ['a]. A {!Test.t} wraps a [cell] and hides its type parameter. *) - + val make_cell : ?if_assumptions_fail:([`Fatal | `Warning] * float) -> ?count:int -> ?long_factor:int -> ?negative:bool -> ?max_gen:int -> ?max_fail:int -> ?retries:int -> @@ -1684,7 +1687,7 @@ module Test : sig ?retries:int -> ?name:string -> gen:(Random.State.t -> 'a) -> ?shrink:('a -> ('a -> unit) -> unit) -> ?print:('a -> string) -> ?collect:('a -> string) -> stats:'a stat list -> ('a -> bool) -> 'a cell - (** ⚠️ Do not use, this is exposed for internal reasons only. ⚠️ + (** ⚠️ Do not use, this is exposed for internal reasons only. ⚠️ @deprecated Migrate to QCheck2 and use {!make_cell} instead. *) diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml index c816408c..c6a6d070 100644 --- a/test/core/QCheck2_tests.ml +++ b/test/core/QCheck2_tests.ml @@ -748,8 +748,8 @@ module Function = struct let fold_left_test = Test.make ~name:"fold_left test, fun first" ~print:Print.(quad Fn.print string (list int) (list int)) Gen.(quad (* string -> int -> string *) - (fun2 ~print:Print.string Observable.string Observable.int (small_string char)) - (small_string char) + (fun2 ~print:Print.string Observable.string Observable.int (small_string ~gen:char)) + (small_string ~gen:char) (list small_int) (list small_int)) (fun (f,acc,is,js) -> @@ -814,21 +814,21 @@ module Stats = struct let bytes_len_tests = let len = ("len",Bytes.length) in [ - Test.make ~name:"bytes_size len dist" ~count:5_000 ~stats:[len] Gen.(bytes_size char (int_range 5 10)) (fun _ -> true); - Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); - Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); - Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); - Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes char) (fun _ -> true); + Test.make ~name:"bytes_size len dist" ~count:5_000 ~stats:[len] Gen.(bytes_size (int_range 5 10)) (fun _ -> true); + Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); + Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); + Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); + Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes ~gen:char) (fun _ -> true); ] let string_len_tests = let len = ("len",String.length) in [ - Test.make ~name:"string_size len dist" ~count:5_000 ~stats:[len] Gen.(string_size char (int_range 5 10)) (fun _ -> true); - Test.make ~name:"string len dist" ~count:5_000 ~stats:[len] Gen.string (fun _ -> true); - Test.make ~name:"string_of len dist" ~count:5_000 ~stats:[len] Gen.(string_of (return 'a')) (fun _ -> true); - Test.make ~name:"string_printable len dist" ~count:5_000 ~stats:[len] Gen.string_printable (fun _ -> true); - Test.make ~name:"small_string len dist" ~count:5_000 ~stats:[len] Gen.(small_string char) (fun _ -> true); + Test.make ~name:"string_size len dist" ~count:5_000 ~stats:[len] Gen.(string_size (int_range 5 10)) (fun _ -> true); + Test.make ~name:"string len dist" ~count:5_000 ~stats:[len] Gen.string (fun _ -> true); + Test.make ~name:"string_of len dist" ~count:5_000 ~stats:[len] Gen.(string_of (return 'a')) (fun _ -> true); + Test.make ~name:"string_printable len dist" ~count:5_000 ~stats:[len] Gen.string_printable (fun _ -> true); + Test.make ~name:"small_string len dist" ~count:5_000 ~stats:[len] Gen.(small_string ~gen:char)(*ugh*)(fun _ -> true); ] let pair_dist = From 96abba4735f3de5e18496a88bc62ee8f57942aa0 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Mon, 20 Jun 2022 13:16:53 +0200 Subject: [PATCH 09/26] reverse fix on Eq.float (other PR) --- src/core/QCheck2.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index d26d7d91..4e2a39e1 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -997,7 +997,7 @@ module Observable = struct let bool : bool t = (=) - let float = Float.equal + let float = (=) let unit () () = true From 49c133569206e8694fbbbc5330828e7d32c8c648 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Mon, 20 Jun 2022 15:17:08 +0200 Subject: [PATCH 10/26] naming consistency --- CHANGELOG.md | 4 ++++ src/core/QCheck.ml | 20 ++++++++++---------- src/core/QCheck.mli | 22 ++-------------------- src/core/QCheck2.ml | 9 +++++---- src/core/QCheck2.mli | 20 ++++++++++++-------- test/core/QCheck2_tests.ml | 2 +- test/core/QCheck_tests.ml | 3 +-- 7 files changed, 35 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8752b5e6..ef4bf1d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - add `QCheck.{Print,Shrink,Observable}.bytes` - add `QCheck2.{Print,Shrink}.bytes` - add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,small_bytes,bytes_of_size,printable_bytes,printable_bytes_of_size,numeral_bytes,numeral_bytes_of_size}` +- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small,string_small}` +- add `QCheck.{Print,Shrink,Observable}.bytes` +- add `QCheck2.{Print,Shrink}.bytes` +- add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,bytes_small,bytes_of_size,bytes_printable}` - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) - add `QCheck2.Gen.set_shrink` to modify the generator's shrinker diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 134e515a..bc440e55 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -1138,7 +1138,6 @@ let printable_char = let numeral_char = make ~print:(sprintf "%C") ~small:(small_char '0') ~shrink:Shrink.char_numeral Gen.numeral - let bytes_gen_of_size size gen = make ~shrink:Shrink.bytes ~small:Bytes.length ~print:(Print.bytes) (Gen.bytes_size ~gen size) @@ -1148,14 +1147,8 @@ let bytes_gen gen = let bytes = bytes_gen Gen.char let bytes_of_size size = bytes_gen_of_size size Gen.char -let small_bytes = bytes_gen_of_size Gen.small_nat Gen.char - -let printable_bytes = bytes_gen Gen.printable -let printable_bytes_of_size size = bytes_gen_of_size size Gen.printable -let small_printable_bytes = bytes_gen_of_size Gen.small_nat Gen.printable - -let numeral_bytes = bytes_gen Gen.numeral -let numeral_bytes_of_size size = bytes_gen_of_size size Gen.numeral +let bytes_small = bytes_gen_of_size Gen.small_nat Gen.char +let bytes_printable = bytes_gen Gen.printable let string_gen_of_size size gen = make ~shrink:Shrink.string ~small:String.length @@ -1166,7 +1159,8 @@ let string_gen gen = let string = string_gen Gen.char let string_of_size size = string_gen_of_size size Gen.char -let small_string = string_gen_of_size Gen.small_nat Gen.char +let string_small = string_gen_of_size Gen.small_nat Gen.char +let small_string = string_small let printable_string = make ~shrink:(Shrink.string ~shrink:Shrink.char_printable) ~small:String.length @@ -1188,6 +1182,12 @@ let numeral_string_of_size size = make ~shrink:(Shrink.string ~shrink:Shrink.char_numeral) ~small:String.length ~print:(sprintf "%S") (Gen.string_size ~gen:Gen.numeral size) +let string_printable = printable_string +let string_printable_of_size = printable_string_of_size +let string_small_printable = small_printable_string +let string_numeral = numeral_string +let string_numeral_of_size = numeral_string_of_size + let list_sum_ f l = List.fold_left (fun acc x-> f x+acc) 0 l let mk_list a gen = diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 82f6a35f..0e78761b 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1285,7 +1285,7 @@ val bytes : bytes arbitrary and distribution of characters of [char]. @since NEXT_RELEASE *) -val small_bytes : bytes arbitrary +val bytes_small : bytes arbitrary (** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). @since NEXT_RELEASE *) @@ -1310,29 +1310,11 @@ val bytes_of_size : int Gen.t -> bytes arbitrary (** Generates bytes with distribution of characters of [char]. @since NEXT_RELEASE *) -val printable_bytes : bytes arbitrary +val bytes_printable : bytes arbitrary (** Generates bytes with a distribution of length of {!Gen.nat} and distribution of characters of [printable_char]. @since NEXT_RELEASE *) -val printable_bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytes with distribution of characters of [printable_char]. - @since NEXT_RELEASE *) - -val small_printable_bytes : bytes arbitrary -(** Generates bytes with a length of [small_nat] - and distribution of characters of [printable_char]. - @since NEXT_RELEASE *) - -val numeral_bytes : bytes arbitrary -(** Generates bytes with a distribution of length of {!Gen.nat} - and distribution of characters of [numeral_char]. - @since NEXT_RELEASE *) - -val numeral_bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytes with a distribution of characters of [numeral_char]. - @since NEXT_RELEASE *) - val string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [char]. *) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 4e2a39e1..3e6cbd10 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -704,7 +704,7 @@ module Gen = struct let bytes_printable = bytes_size ~gen:printable nat - let small_bytes ?gen st = bytes_size ?gen small_nat st + let bytes_small ~gen st = bytes_size ~gen small_nat st let string : string t = string_size nat @@ -712,7 +712,8 @@ module Gen = struct let string_printable = string_size ~gen:printable nat - let small_string ?gen st = string_size ?gen small_nat st + let string_small ?gen st = string_size ?gen small_nat st + let small_string ?gen = string_small ?gen let small_list gen = list_size small_nat gen @@ -786,7 +787,7 @@ module Print = struct let float = string_of_float let bytes = Bytes.to_string - + let string s = Printf.sprintf "%S" s let char c = Printf.sprintf "%C" c @@ -1524,7 +1525,7 @@ module Test = struct let make_neg = make' ~negative:true let test_get_count (Test cell) = get_count cell - + let test_get_long_factor (Test cell) = get_long_factor cell (** {6 Running the test} *) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index 114bed38..6a8a609e 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -321,9 +321,8 @@ module Gen : sig @since NEXT_RELEASE *) - val small_bytes : ?gen:char t -> bytes t - (** Builds a bytes generator, length is {!small_nat}. - Accepts an optional character generator (the default is {!char}). + val bytes_small : gen:char t -> bytes t + (** Builds a bytes generator using the given character generator, length is {!small_nat}. Shrinks on the number of characters first, then on the characters. @@ -360,13 +359,18 @@ module Gen : sig @since 0.11 *) - val small_string : ?gen:char t -> string t + val string_small : ?gen:char t -> string t (** Builds a string generator, length is {!small_nat}. Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) + val small_string : ?gen:char t -> string t + (** alias for [string_small] for backward compatibility *) + val pure : 'a -> 'a t (** [pure a] creates a generator that always returns [a]. @@ -1078,7 +1082,7 @@ module Print : sig (** [char] is a printer of character. *) val bytes : bytes t - (** [bytes] is a printer of bytes. + (** [bytes] is a printer of bytes. @since NEXT_RELEASE *) val string : string t @@ -1323,7 +1327,7 @@ module Observable : sig (** [quad o1 o2 o3 o4] is an observable of quadruples of [('a * 'b * 'c * 'd)]. *) end - + (** Utils on combining function arguments. *) module Tuple : sig (** Heterogeneous tuple, used to pass any number of arguments to @@ -1648,7 +1652,7 @@ module Test : sig type 'a cell (** A single property test on a value of type ['a]. A {!Test.t} wraps a [cell] and hides its type parameter. *) - + val make_cell : ?if_assumptions_fail:([`Fatal | `Warning] * float) -> ?count:int -> ?long_factor:int -> ?negative:bool -> ?max_gen:int -> ?max_fail:int -> ?retries:int -> @@ -1687,7 +1691,7 @@ module Test : sig ?retries:int -> ?name:string -> gen:(Random.State.t -> 'a) -> ?shrink:('a -> ('a -> unit) -> unit) -> ?print:('a -> string) -> ?collect:('a -> string) -> stats:'a stat list -> ('a -> bool) -> 'a cell - (** ⚠️ Do not use, this is exposed for internal reasons only. ⚠️ + (** ⚠️ Do not use, this is exposed for internal reasons only. ⚠️ @deprecated Migrate to QCheck2 and use {!make_cell} instead. *) diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml index c6a6d070..4b51b63b 100644 --- a/test/core/QCheck2_tests.ml +++ b/test/core/QCheck2_tests.ml @@ -818,7 +818,7 @@ module Stats = struct Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); - Test.make ~name:"small_bytes len dist" ~count:5_000 ~stats:[len] Gen.(small_bytes ~gen:char) (fun _ -> true); + Test.make ~name:"bytes_small len dist" ~count:5_000 ~stats:[len] Gen.(bytes_small ~gen:char) (fun _ -> true); ] let string_len_tests = diff --git a/test/core/QCheck_tests.ml b/test/core/QCheck_tests.ml index 929c9824..7bd596d1 100644 --- a/test/core/QCheck_tests.ml +++ b/test/core/QCheck_tests.ml @@ -882,8 +882,7 @@ module Stats = struct Test.make ~name:"bytes_size len dist" ~count:5_000 (add_stat len (bytes_of_size (Gen.int_range 5 10))) (fun _ -> true); Test.make ~name:"bytes len dist" ~count:5_000 (add_stat len bytes) (fun _ -> true); Test.make ~name:"bytes_of len dist" ~count:5_000 (add_stat len (bytes_gen (Gen.return 'a'))) (fun _ -> true); - Test.make ~name:"printable_bytes len dist" ~count:5_000 (add_stat len printable_bytes) (fun _ -> true); - Test.make ~name:"small_bytes len dist" ~count:5_000 (add_stat len small_bytes) (fun _ -> true); + Test.make ~name:"small_bytes len dist" ~count:5_000 (add_stat len bytes_small) (fun _ -> true); ] let string_len_tests = From 659a2b650dcec5db6748bc885d8643a4b1b67f18 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Mon, 20 Jun 2022 15:32:43 +0200 Subject: [PATCH 11/26] small_string no longer takes optional argument --- CHANGELOG.md | 1 + src/core/QCheck2.ml | 4 ++-- src/core/QCheck2.mli | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef4bf1d1..cdb92da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - add `QCheck.{Print,Shrink,Observable}.bytes` - add `QCheck2.{Print,Shrink}.bytes` - add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,bytes_small,bytes_of_size,bytes_printable}` +- `QCheck2.{small_string}` character generator argument is no more optional - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) - add `QCheck2.Gen.set_shrink` to modify the generator's shrinker diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 3e6cbd10..1c9032dc 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -712,8 +712,8 @@ module Gen = struct let string_printable = string_size ~gen:printable nat - let string_small ?gen st = string_size ?gen small_nat st - let small_string ?gen = string_small ?gen + let string_small ~gen st = string_size ~gen small_nat st + let small_string ~gen = string_small ~gen let small_list gen = list_size small_nat gen diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index 6a8a609e..ea21a496 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -359,16 +359,15 @@ module Gen : sig @since 0.11 *) - val string_small : ?gen:char t -> string t - (** Builds a string generator, length is {!small_nat}. - Accepts an optional character generator (the default is {!char}). + val string_small : gen:char t -> string t + (** Builds a string generator using the given characher generator, length is {!small_nat}. Shrinks on the number of characters first, then on the characters. @since NEXT_RELEASE *) - val small_string : ?gen:char t -> string t + val small_string : gen:char t -> string t (** alias for [string_small] for backward compatibility *) val pure : 'a -> 'a t From d9555228aec5921af5a55e133e65441116aaae78 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Mon, 20 Jun 2022 16:25:49 +0200 Subject: [PATCH 12/26] Iter.map version of bytes shrinker --- src/core/QCheck.ml | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index bc440e55..5c0d0e69 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -86,20 +86,15 @@ let _opt_sum a b = match a, b with let sum_int = List.fold_left (+) 0 -let _fold_right length get f x acc = - let len = length x in +(* Included for backwards compatibility, pre 4.13 *) +let string_fold_right f s acc = + let len = String.length s in let rec loop i acc = if i<0 then acc - else loop (i-1) (f (get x i) acc) in + else loop (i-1) (f (String.get s i) acc) in loop (len-1) acc -(* Included for backwards compatibility, pre 4.13 *) -let bytes_fold_right = _fold_right Bytes.length Bytes.get - -(* Included for backwards compatibility, pre 4.13 *) -let string_fold_right = _fold_right String.length String.get - exception No_example_found of string (* raised if an example failed to be found *) @@ -796,15 +791,7 @@ module Shrink = struct Buffer.clear buf; yield s) - let bytes (b : bytes) (yield : bytes -> unit) = - let buf = Buffer.create 42 in - list ~shrink:char - (bytes_fold_right (fun c acc -> c::acc) b []) - (fun cs -> - List.iter (fun c -> Buffer.add_char buf c) cs; - let b = Buffer.contents buf |> Bytes.of_string in - Buffer.clear buf; - yield b) + let bytes b = Iter.map Bytes.of_string (string (Bytes.to_string b)) let pair a b (x,y) yield = a x (fun x' -> yield (x',y)); From b4b7a8906a7a54956c96b2436ec867bde24988af Mon Sep 17 00:00:00 2001 From: n-osborne Date: Wed, 22 Jun 2022 11:10:05 +0200 Subject: [PATCH 13/26] smaller diff --- src/core/QCheck.ml | 5 ++-- src/core/QCheck.mli | 2 +- src/core/QCheck2.ml | 3 +-- test/core/QCheck2_expect_test.expected.64 | 2 +- test/core/QCheck_expect_test.expected.64 | 29 ++--------------------- test/core/QCheck_tests.ml | 2 +- 6 files changed, 8 insertions(+), 35 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 5c0d0e69..5fb20694 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -92,7 +92,7 @@ let string_fold_right f s acc = let rec loop i acc = if i<0 then acc - else loop (i-1) (f (String.get s i) acc) in + else loop (i-1) (f s.[i] acc) in loop (len-1) acc exception No_example_found of string @@ -382,9 +382,8 @@ module Gen = struct let string_of gen = string_size ~gen nat let bytes_printable = bytes_size ~gen:printable nat let string_printable = string_size ~gen:printable nat - let bytes_readable = bytes_printable let string_readable = string_printable - let small_bytes ?gen st = bytes_size ?gen small_nat st + let bytes_small ?gen st = bytes_size ?gen small_nat st let small_string ?gen st = string_size ?gen small_nat st let small_list gen = list_size small_nat gen let small_array gen = array_size small_nat gen diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 0e78761b..29ca5db4 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -417,7 +417,7 @@ module Gen : sig (** Generator using the {!printable} character generator. @since NEXT_RELEASE *) - val small_bytes : ?gen:char t -> bytes t + val bytes_small : ?gen:char t -> bytes t (** Builds a bytes generator, length is {!small_nat} Accepts an optional character generator (the default is {!char}). @since NEXT_RELEASE *) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 1c9032dc..3e81ba4a 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -998,7 +998,7 @@ module Observable = struct let bool : bool t = (=) - let float = (=) + let float : float t = (=) let unit () () = true @@ -1525,7 +1525,6 @@ module Test = struct let make_neg = make' ~negative:true let test_get_count (Test cell) = get_count cell - let test_get_long_factor (Test cell) = get_long_factor cell (** {6 Running the test} *) diff --git a/test/core/QCheck2_expect_test.expected.64 b/test/core/QCheck2_expect_test.expected.64 index 30df1c04..9854be8a 100644 --- a/test/core/QCheck2_expect_test.expected.64 +++ b/test/core/QCheck2_expect_test.expected.64 @@ -825,7 +825,7 @@ stats len: 8982..9480: 16 9481..9979: 12 -+++ Stats for small_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for bytes_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 diff --git a/test/core/QCheck_expect_test.expected.64 b/test/core/QCheck_expect_test.expected.64 index 15cc10c8..26cb5722 100644 --- a/test/core/QCheck_expect_test.expected.64 +++ b/test/core/QCheck_expect_test.expected.64 @@ -758,32 +758,7 @@ stats len: 9000.. 9499: 13 9500.. 9999: 13 -+++ Stats for printable_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -stats len: - num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 - 0.. 498: ####################################################### 4246 - 499.. 997: ###### 518 - 998..1496: 21 - 1497..1995: 10 - 1996..2494: 11 - 2495..2993: 10 - 2994..3492: 13 - 3493..3991: 13 - 3992..4490: 5 - 4491..4989: 10 - 4990..5488: 19 - 5489..5987: 9 - 5988..6486: 10 - 6487..6985: 12 - 6986..7484: 17 - 7485..7983: 16 - 7984..8482: 16 - 8483..8981: 16 - 8982..9480: 16 - 9481..9979: 12 - -+++ Stats for small_bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for bytes_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 @@ -1419,7 +1394,7 @@ stats dist: 4150517416584649600.. 4611686018427387903: ################# 189 ================================================================================ 1 warning(s) -failure (63 tests failed, 3 tests errored, ran 149 tests) +failure (63 tests failed, 3 tests errored, ran 148 tests) random seed: 153870556 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/test/core/QCheck_tests.ml b/test/core/QCheck_tests.ml index 7bd596d1..c27fadee 100644 --- a/test/core/QCheck_tests.ml +++ b/test/core/QCheck_tests.ml @@ -882,7 +882,7 @@ module Stats = struct Test.make ~name:"bytes_size len dist" ~count:5_000 (add_stat len (bytes_of_size (Gen.int_range 5 10))) (fun _ -> true); Test.make ~name:"bytes len dist" ~count:5_000 (add_stat len bytes) (fun _ -> true); Test.make ~name:"bytes_of len dist" ~count:5_000 (add_stat len (bytes_gen (Gen.return 'a'))) (fun _ -> true); - Test.make ~name:"small_bytes len dist" ~count:5_000 (add_stat len bytes_small) (fun _ -> true); + Test.make ~name:"bytes_small len dist" ~count:5_000 (add_stat len bytes_small) (fun _ -> true); ] let string_len_tests = From b7ca0dab0da2f608ff104ba56e8d5de5a5a0c67a Mon Sep 17 00:00:00 2001 From: n-osborne Date: Tue, 13 Sep 2022 11:38:44 +0200 Subject: [PATCH 14/26] expose missing string arbitrary --- CHANGELOG.md | 1 + src/core/QCheck.mli | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdb92da1..e39dd0e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - add `QCheck.{Print,Shrink,Observable}.bytes` - add `QCheck2.{Print,Shrink}.bytes` - add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,bytes_small,bytes_of_size,bytes_printable}` +- add `QCheck.{string_small,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` - `QCheck2.{small_string}` character generator argument is no more optional - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 29ca5db4..693e9f6c 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1302,6 +1302,10 @@ val string : string arbitrary val small_string : string arbitrary (** Same as {!string} but with a small length (ie {!Gen.small_nat} ). *) +val string_small : string arbitrary +(** Same as {!string} but with a small length (ie {!Gen.small_nat} ). + @since NEXT_RELEASE *) + val small_list : 'a arbitrary -> 'a list arbitrary (** Generates lists of small size (see {!Gen.small_nat}). @since 0.5.3 *) @@ -1322,20 +1326,43 @@ val printable_string : string arbitrary (** Generates strings with a distribution of length of {!Gen.nat} and distribution of characters of [printable_char]. *) +val string_printable : string arbitrary +(** Generates strings with a distribution of length of {!Gen.nat} + and distribution of characters of [printable_char]. + @since NEXT_RELEASE *) + val printable_string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [printable_char]. *) +val string_printable_of_size : int Gen.t -> string arbitrary +(** Generates strings with distribution of characters of [printable_char]. + @since NEXT_RELEASE *) + val small_printable_string : string arbitrary (** Generates strings with a length of [small_nat] and distribution of characters of [printable_char]. *) +val string_small_printable : string arbitrary +(** Generates strings with a length of [small_nat] + and distribution of characters of [printable_char]. + @since NEXT_RELEASE *) + val numeral_string : string arbitrary (** Generates strings with a distribution of length of {!Gen.nat} and distribution of characters of [numeral_char]. *) +val string_numeral : string arbitrary +(** Generates strings with a distribution of length of {!Gen.nat} + and distribution of characters of [numeral_char]. + @since NEXT_RELEASE *) + val numeral_string_of_size : int Gen.t -> string arbitrary (** Generates strings with a distribution of characters of [numeral_char]. *) +val string_numeral_of_size : int Gen.t -> string arbitrary +(** Generates strings with a distribution of characters of [numeral_char]. + @since NEXT_RELEASE *) + val list : 'a arbitrary -> 'a list arbitrary (** Generates lists with length generated by {!Gen.nat}. *) From c15418cc0791353d9ddfbdbeff43463991f88041 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Wed, 26 Oct 2022 10:07:52 +0200 Subject: [PATCH 15/26] Update documentation for string arbitraries synomyms. Indicate what the new name is a synonym of, so that newcommers can easily make their choice. --- src/core/QCheck.mli | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 693e9f6c..335a8c0b 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1303,7 +1303,7 @@ val small_string : string arbitrary (** Same as {!string} but with a small length (ie {!Gen.small_nat} ). *) val string_small : string arbitrary -(** Same as {!string} but with a small length (ie {!Gen.small_nat} ). +(** Synonym to [small_string] added for convenience. @since NEXT_RELEASE *) val small_list : 'a arbitrary -> 'a list arbitrary @@ -1327,15 +1327,14 @@ val printable_string : string arbitrary and distribution of characters of [printable_char]. *) val string_printable : string arbitrary -(** Generates strings with a distribution of length of {!Gen.nat} - and distribution of characters of [printable_char]. +(** Synonym to [printable_string] added for convenience. @since NEXT_RELEASE *) val printable_string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [printable_char]. *) val string_printable_of_size : int Gen.t -> string arbitrary -(** Generates strings with distribution of characters of [printable_char]. +(** Synonym to [printable_string_of_size] added for convenience. @since NEXT_RELEASE *) val small_printable_string : string arbitrary @@ -1343,8 +1342,7 @@ val small_printable_string : string arbitrary and distribution of characters of [printable_char]. *) val string_small_printable : string arbitrary -(** Generates strings with a length of [small_nat] - and distribution of characters of [printable_char]. +(** Synonym to [small_printable_string] added for convenience. @since NEXT_RELEASE *) val numeral_string : string arbitrary @@ -1352,15 +1350,14 @@ val numeral_string : string arbitrary and distribution of characters of [numeral_char]. *) val string_numeral : string arbitrary -(** Generates strings with a distribution of length of {!Gen.nat} - and distribution of characters of [numeral_char]. +(** Synonym to [numeral_string] added for convenience. @since NEXT_RELEASE *) val numeral_string_of_size : int Gen.t -> string arbitrary (** Generates strings with a distribution of characters of [numeral_char]. *) val string_numeral_of_size : int Gen.t -> string arbitrary -(** Generates strings with a distribution of characters of [numeral_char]. +(** Synonym to [numeral_string_of_size] added for convenience. @since NEXT_RELEASE *) val list : 'a arbitrary -> 'a list arbitrary From 0d6b8f84a8d5d78fdefd480cd9f846fb9d71a47b Mon Sep 17 00:00:00 2001 From: n-osborne Date: Wed, 26 Oct 2022 10:26:56 +0200 Subject: [PATCH 16/26] Fix shrinker for QCheck.bytes_printable. This is the same fix that has been made in #258 for strings. `Shrink.bytes` now takes an optional char shrinker (default value being `Shrink.char`). So `bytes_printable` can shrink only on printable chars. --- src/core/QCheck.ml | 6 ++++-- src/core/QCheck.mli | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 5fb20694..9787e3b8 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -790,7 +790,7 @@ module Shrink = struct Buffer.clear buf; yield s) - let bytes b = Iter.map Bytes.of_string (string (Bytes.to_string b)) + let bytes ?(shrink = char) b = Iter.map Bytes.of_string (string ~shrink (Bytes.to_string b)) let pair a b (x,y) yield = a x (fun x' -> yield (x',y)); @@ -1134,7 +1134,9 @@ let bytes_gen gen = let bytes = bytes_gen Gen.char let bytes_of_size size = bytes_gen_of_size size Gen.char let bytes_small = bytes_gen_of_size Gen.small_nat Gen.char -let bytes_printable = bytes_gen Gen.printable +let bytes_printable = + make ~shrink:(Shrink.bytes ~shrink:Shrink.char_printable) ~small:Bytes.length + ~print:(Print.bytes) (Gen.bytes ~gen:Gen.printable) let string_gen_of_size size gen = make ~shrink:Shrink.string ~small:String.length diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 335a8c0b..e3e18e55 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -736,7 +736,7 @@ module Shrink : sig val option : 'a t -> 'a option t - val bytes : bytes t + val bytes : ?shrink:(char t) -> bytes t (** @since NEXT_RELEASE *) val string : ?shrink:(char t) -> string t From 2b4110678ffedb960d145f87b1d40dbe1ee604f9 Mon Sep 17 00:00:00 2001 From: n-osborne Date: Fri, 28 Oct 2022 14:15:13 +0200 Subject: [PATCH 17/26] fix CHANGELOG and restore Float.equal --- CHANGELOG.md | 9 +++------ src/core/QCheck.mli | 18 +++++++++--------- src/core/QCheck2.ml | 2 +- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e39dd0e8..35c66a71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,13 @@ ## 0.20 -- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,small_bytes}` -- add `QCheck.{Print,Shrink,Observable}.bytes` -- add `QCheck2.{Print,Shrink}.bytes` -- add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,small_bytes,bytes_of_size,printable_bytes,printable_bytes_of_size,numeral_bytes,numeral_bytes_of_size}` -- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small,string_small}` +- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small}` +- add `QCheck2.Gen.string_small` - add `QCheck.{Print,Shrink,Observable}.bytes` - add `QCheck2.{Print,Shrink}.bytes` - add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,bytes_small,bytes_of_size,bytes_printable}` - add `QCheck.{string_small,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` -- `QCheck2.{small_string}` character generator argument is no more optional +- `QCheck2.small_string` character generator argument is no more optional - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) - add `QCheck2.Gen.set_shrink` to modify the generator's shrinker diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index e3e18e55..9b61b9e9 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1289,6 +1289,15 @@ val bytes_small : bytes arbitrary (** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). @since NEXT_RELEASE *) +val bytes_of_size : int Gen.t -> bytes arbitrary +(** Generates bytes with distribution of characters of [char]. + @since NEXT_RELEASE *) + +val bytes_printable : bytes arbitrary +(** Generates bytes with a distribution of length of {!Gen.nat} + and distribution of characters of [printable_char]. + @since NEXT_RELEASE *) + val string_gen_of_size : int Gen.t -> char Gen.t -> string arbitrary (** Builds a string generator from a (non-negative) size generator and a character generator. *) @@ -1310,15 +1319,6 @@ val small_list : 'a arbitrary -> 'a list arbitrary (** Generates lists of small size (see {!Gen.small_nat}). @since 0.5.3 *) -val bytes_of_size : int Gen.t -> bytes arbitrary -(** Generates bytes with distribution of characters of [char]. - @since NEXT_RELEASE *) - -val bytes_printable : bytes arbitrary -(** Generates bytes with a distribution of length of {!Gen.nat} - and distribution of characters of [printable_char]. - @since NEXT_RELEASE *) - val string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [char]. *) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 3e81ba4a..58929c0a 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -998,7 +998,7 @@ module Observable = struct let bool : bool t = (=) - let float : float t = (=) + let float = Float.equal let unit () () = true From abf86cd21d99b7ea150bb883a41498ad785ccd81 Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 16:42:59 +0100 Subject: [PATCH 18/26] consistent QCheck.Gen.{bytes,string}_small{,_of} combinators --- src/core/QCheck.ml | 5 ++++- src/core/QCheck.mli | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 9787e3b8..7b7d93e7 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -383,10 +383,13 @@ module Gen = struct let bytes_printable = bytes_size ~gen:printable nat let string_printable = string_size ~gen:printable nat let string_readable = string_printable - let bytes_small ?gen st = bytes_size ?gen small_nat st + let bytes_small st = bytes_size small_nat st + let bytes_small_of gen st = bytes_size ~gen small_nat st let small_string ?gen st = string_size ?gen small_nat st let small_list gen = list_size small_nat gen let small_array gen = array_size small_nat gen + let string_small st = string_size small_nat st + let string_small_of gen st = string_size ~gen small_nat st let join g st = (g st) st diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 9b61b9e9..41b83d9a 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -417,9 +417,12 @@ module Gen : sig (** Generator using the {!printable} character generator. @since NEXT_RELEASE *) - val bytes_small : ?gen:char t -> bytes t - (** Builds a bytes generator, length is {!small_nat} - Accepts an optional character generator (the default is {!char}). + val bytes_small : bytes t + (** Builds a bytes generator using the {!char} character generator, length is {!small_nat} + @since NEXT_RELEASE *) + + val bytes_small_of : char t -> bytes t + (** Builds a bytes generator using the given character generator, length is {!small_nat}. @since NEXT_RELEASE *) val string_size : ?gen:char t -> int t -> string t @@ -450,6 +453,14 @@ module Gen : sig (** Builds a string generator, length is {!small_nat} Accepts an optional character generator (the default is {!char}). *) + val string_small : string t + (** Builds a string generator using the {!char} character generator, length is {!small_nat} + @since NEXT_RELEASE *) + + val string_small_of : char t -> string t + (** Builds a string generator using the given character generator, length is {!small_nat}. + @since NEXT_RELEASE *) + val small_list : 'a t -> 'a list t (** Generates lists of small size (see {!small_nat}). @since 0.5.3 *) From fb1ea0ef0818b5ba3d53461f0dd6513af6d58aa1 Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 17:04:57 +0100 Subject: [PATCH 19/26] consistent QCheck.{bytes,string}_of combinators --- src/core/QCheck.ml | 9 +++++---- src/core/QCheck.mli | 6 +++++- test/core/QCheck_tests.ml | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 7b7d93e7..13e41a14 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -1130,11 +1130,11 @@ let numeral_char = let bytes_gen_of_size size gen = make ~shrink:Shrink.bytes ~small:Bytes.length ~print:(Print.bytes) (Gen.bytes_size ~gen size) -let bytes_gen gen = +let bytes_of gen = make ~shrink:Shrink.bytes ~small:Bytes.length ~print:(Print.bytes) (Gen.bytes ~gen) -let bytes = bytes_gen Gen.char +let bytes = bytes_of Gen.char let bytes_of_size size = bytes_gen_of_size size Gen.char let bytes_small = bytes_gen_of_size Gen.small_nat Gen.char let bytes_printable = @@ -1144,14 +1144,15 @@ let bytes_printable = let string_gen_of_size size gen = make ~shrink:Shrink.string ~small:String.length ~print:(sprintf "%S") (Gen.string_size ~gen size) -let string_gen gen = +let string_of gen = make ~shrink:Shrink.string ~small:String.length ~print:(sprintf "%S") (Gen.string ~gen) -let string = string_gen Gen.char +let string = string_of Gen.char let string_of_size size = string_gen_of_size size Gen.char let string_small = string_gen_of_size Gen.small_nat Gen.char let small_string = string_small +let string_gen = string_of let printable_string = make ~shrink:(Shrink.string ~shrink:Shrink.char_printable) ~small:String.length diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 41b83d9a..5d824479 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1287,7 +1287,7 @@ val bytes_gen_of_size : int Gen.t -> char Gen.t -> bytes arbitrary (** Builds a bytes generator from a (non-negative) size generator and a character generator. @since NEXT_RELEASE *) -val bytes_gen : char Gen.t -> bytes arbitrary +val bytes_of : char Gen.t -> bytes arbitrary (** Generates bytes with a distribution of length of {!Gen.nat}. @since NEXT_RELEASE *) @@ -1315,6 +1315,10 @@ val string_gen_of_size : int Gen.t -> char Gen.t -> string arbitrary val string_gen : char Gen.t -> string arbitrary (** Generates strings with a distribution of length of {!Gen.nat}. *) +val string_of : char Gen.t -> string arbitrary +(** Synonym to {!string_gen} added for convenience. + @since NEXT_RELEASE *) + val string : string arbitrary (** Generates strings with a distribution of length of {!Gen.nat} and distribution of characters of [char]. *) diff --git a/test/core/QCheck_tests.ml b/test/core/QCheck_tests.ml index c27fadee..7d22045b 100644 --- a/test/core/QCheck_tests.ml +++ b/test/core/QCheck_tests.ml @@ -881,7 +881,7 @@ module Stats = struct [ Test.make ~name:"bytes_size len dist" ~count:5_000 (add_stat len (bytes_of_size (Gen.int_range 5 10))) (fun _ -> true); Test.make ~name:"bytes len dist" ~count:5_000 (add_stat len bytes) (fun _ -> true); - Test.make ~name:"bytes_of len dist" ~count:5_000 (add_stat len (bytes_gen (Gen.return 'a'))) (fun _ -> true); + Test.make ~name:"bytes_of len dist" ~count:5_000 (add_stat len (bytes_of (Gen.return 'a'))) (fun _ -> true); Test.make ~name:"bytes_small len dist" ~count:5_000 (add_stat len bytes_small) (fun _ -> true); ] @@ -890,7 +890,7 @@ module Stats = struct [ Test.make ~name:"string_size len dist" ~count:5_000 (add_stat len (string_of_size (Gen.int_range 5 10))) (fun _ -> true); Test.make ~name:"string len dist" ~count:5_000 (add_stat len string) (fun _ -> true); - Test.make ~name:"string_of len dist" ~count:5_000 (add_stat len (string_gen (Gen.return 'a'))) (fun _ -> true); + Test.make ~name:"string_of len dist" ~count:5_000 (add_stat len (string_of (Gen.return 'a'))) (fun _ -> true); Test.make ~name:"printable_string len dist" ~count:5_000 (add_stat len printable_string) (fun _ -> true); Test.make ~name:"small_string len dist" ~count:5_000 (add_stat len small_string) (fun _ -> true); ] From d1cb85e8fecd7fc2bed42631a06fdf7bbdde5feb Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 17:26:12 +0100 Subject: [PATCH 20/26] add consistent QCheck2.Gen.small_{bytes,string}{,_of} combinators --- src/core/QCheck2.ml | 11 ++++++++--- src/core/QCheck2.mli | 20 +++++++++++++++++--- test/core/QCheck2_tests.ml | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index 58929c0a..2ab713db 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -704,7 +704,9 @@ module Gen = struct let bytes_printable = bytes_size ~gen:printable nat - let bytes_small ~gen st = bytes_size ~gen small_nat st + let bytes_small st = bytes_size small_nat st + + let bytes_small_of gen st = bytes_size ~gen small_nat st let string : string t = string_size nat @@ -712,8 +714,11 @@ module Gen = struct let string_printable = string_size ~gen:printable nat - let string_small ~gen st = string_size ~gen small_nat st - let small_string ~gen = string_small ~gen + let string_small st = string_size small_nat st + + let string_small_of gen st = string_size ~gen small_nat st + + let small_string ~gen = string_small_of gen let small_list gen = list_size small_nat gen diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index ea21a496..d73c68c8 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -321,13 +321,19 @@ module Gen : sig @since NEXT_RELEASE *) - val bytes_small : gen:char t -> bytes t - (** Builds a bytes generator using the given character generator, length is {!small_nat}. + val bytes_small : bytes t + (** Builds a bytes generator using the {!char} character generator, length is {!small_nat}. Shrinks on the number of characters first, then on the characters. @since NEXT_RELEASE *) + val bytes_small_of : char t -> bytes t + (** Builds a bytes generator using the given character generator, length is {!small_nat}. + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE *) val string_size : ?gen:char t -> int t -> string t (** Builds a string generator from a (non-negative) size generator. @@ -359,7 +365,15 @@ module Gen : sig @since 0.11 *) - val string_small : gen:char t -> string t + val string_small : string t + (** Builds a string generator using the {!char} characher generator, length is {!small_nat}. + + Shrinks on the number of characters first, then on the characters. + + @since NEXT_RELEASE + *) + + val string_small_of : char t -> string t (** Builds a string generator using the given characher generator, length is {!small_nat}. Shrinks on the number of characters first, then on the characters. diff --git a/test/core/QCheck2_tests.ml b/test/core/QCheck2_tests.ml index 4b51b63b..87b843ce 100644 --- a/test/core/QCheck2_tests.ml +++ b/test/core/QCheck2_tests.ml @@ -818,7 +818,7 @@ module Stats = struct Test.make ~name:"bytes len dist" ~count:5_000 ~stats:[len] Gen.bytes (fun _ -> true); Test.make ~name:"bytes_of len dist" ~count:5_000 ~stats:[len] Gen.(bytes_of (return 'a')) (fun _ -> true); Test.make ~name:"bytes_printable len dist" ~count:5_000 ~stats:[len] Gen.bytes_printable (fun _ -> true); - Test.make ~name:"bytes_small len dist" ~count:5_000 ~stats:[len] Gen.(bytes_small ~gen:char) (fun _ -> true); + Test.make ~name:"bytes_small len dist" ~count:5_000 ~stats:[len] Gen.(bytes_small_of char) (fun _ -> true); ] let string_len_tests = From c587c889763f6ed345c55fc23f8a5d5f58b7deae Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 17:29:32 +0100 Subject: [PATCH 21/26] fix comment for QCheck2.Gen.bytes --- src/core/QCheck2.mli | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index d73c68c8..03d743d3 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -298,8 +298,7 @@ module Gen : sig @since NEXT_RELEASE *) val bytes : bytes t - (** Bytes generator. Bytes size is generated by {!nat}. - The default character generator is {!char}. + (** Bytes generator using the {!char} character generator. Bytes size is generated by {!nat}. See also {!bytes_of} and {!bytes_printable} for versions with custom char generator. From 41ceeae7aab4daed7e0132a2b1fbcdad97d9408b Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 17:40:30 +0100 Subject: [PATCH 22/26] update CHANGELOG --- CHANGELOG.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5efd849..31e70ae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,14 @@ ## 0.20 -- add `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small}` -- add `QCheck2.Gen.string_small` -- add `QCheck.{Print,Shrink,Observable}.bytes` -- add `QCheck2.{Print,Shrink}.bytes` -- add `QCheck.{bytes_gen_of_size,bytes_gen,bytes,bytes_small,bytes_of_size,bytes_printable}` -- add `QCheck.{string_small,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` +- add several new `bytes` combinators: + - `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small,bytes_small_of}` + - `QCheck.{Print,Shrink,Observable}.bytes` + - `QCheck2.{Print,Shrink}.bytes` + - `QCheck.{bytes_gen_of_size,bytes_of,bytes,bytes_small,bytes_of_size,bytes_printable}` +- add new `string` combinators and aliases: + - `{QCheck,QCheck2}.Gen.{string_small,string_small_of}` + - `QCheck.{string_small,string_of,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` - `QCheck2.small_string` character generator argument is no more optional - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) From 37d8d8a10fd4b84e24dab55b822b882185349cf0 Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 18:03:03 +0100 Subject: [PATCH 23/26] add QCheck.{bytes,string}_small_of for consistency --- src/core/QCheck.ml | 2 ++ src/core/QCheck.mli | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/core/QCheck.ml b/src/core/QCheck.ml index 13e41a14..aca834e8 100644 --- a/src/core/QCheck.ml +++ b/src/core/QCheck.ml @@ -1137,6 +1137,7 @@ let bytes_of gen = let bytes = bytes_of Gen.char let bytes_of_size size = bytes_gen_of_size size Gen.char let bytes_small = bytes_gen_of_size Gen.small_nat Gen.char +let bytes_small_of gen = bytes_gen_of_size Gen.small_nat gen let bytes_printable = make ~shrink:(Shrink.bytes ~shrink:Shrink.char_printable) ~small:Bytes.length ~print:(Print.bytes) (Gen.bytes ~gen:Gen.printable) @@ -1151,6 +1152,7 @@ let string_of gen = let string = string_of Gen.char let string_of_size size = string_gen_of_size size Gen.char let string_small = string_gen_of_size Gen.small_nat Gen.char +let string_small_of gen = string_gen_of_size Gen.small_nat gen let small_string = string_small let string_gen = string_of diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 5d824479..910d39b7 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -1300,6 +1300,10 @@ val bytes_small : bytes arbitrary (** Same as {!bytes} but with a small length (ie {!Gen.small_nat} ). @since NEXT_RELEASE *) +val bytes_small_of : char Gen.t -> bytes arbitrary +(** Same as {!bytes_of} but with a small length (ie {!Gen.small_nat} ). + @since NEXT_RELEASE *) + val bytes_of_size : int Gen.t -> bytes arbitrary (** Generates bytes with distribution of characters of [char]. @since NEXT_RELEASE *) @@ -1330,6 +1334,10 @@ val string_small : string arbitrary (** Synonym to [small_string] added for convenience. @since NEXT_RELEASE *) +val string_small_of : char Gen.t -> string arbitrary +(** Same as {!string_of} but with a small length (ie {!Gen.small_nat} ). + @since NEXT_RELEASE *) + val small_list : 'a arbitrary -> 'a list arbitrary (** Generates lists of small size (see {!Gen.small_nat}). @since 0.5.3 *) From a14a7678dcbe87745167cbbcb594e48e02b2ec8d Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 18:03:25 +0100 Subject: [PATCH 24/26] update CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31e70ae5..c798cf16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,10 @@ - `{QCheck,QCheck2}.Gen.{bytes_size,bytes,bytes_of,bytes_printable,bytes_small,bytes_small_of}` - `QCheck.{Print,Shrink,Observable}.bytes` - `QCheck2.{Print,Shrink}.bytes` - - `QCheck.{bytes_gen_of_size,bytes_of,bytes,bytes_small,bytes_of_size,bytes_printable}` + - `QCheck.{bytes_gen_of_size,bytes_of,bytes,bytes_small,bytes_small_of,bytes_of_size,bytes_printable}` - add new `string` combinators and aliases: - `{QCheck,QCheck2}.Gen.{string_small,string_small_of}` - - `QCheck.{string_small,string_of,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` + - `QCheck.{string_small,string_small_of,string_of,string_printable,string_printable_of_size,string_small_printable,string_numeral,string_numeral_of_size}` - `QCheck2.small_string` character generator argument is no more optional - add an optional argument with conservative default to `Shrink.string` - fix shrinkers in `QCheck.{printable_string,printable_string_of_size,small_printable_string,numeral_string,numeral_string_of_size}` [#257](https://github.com/c-cube/qcheck/issues/257) From b32cce6fe07072512eb5e3fe30c594f116c84004 Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 17:23:36 +0000 Subject: [PATCH 25/26] update expected 32-bit output --- test/core/QCheck2_expect_test.expected.32 | 143 +++++++++++++++++++++- test/core/QCheck_expect_test.expected.32 | 112 ++++++++++++++++- 2 files changed, 253 insertions(+), 2 deletions(-) diff --git a/test/core/QCheck2_expect_test.expected.32 b/test/core/QCheck2_expect_test.expected.32 index 4762e562..597728f6 100644 --- a/test/core/QCheck2_expect_test.expected.32 +++ b/test/core/QCheck2_expect_test.expected.32 @@ -282,6 +282,30 @@ Test printable never produces less than '5 failed (1 shrink steps): --- Failure -------------------------------------------------------------------- +Test bytes are empty failed (8 shrink steps): + +a + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \000 char failed (22 shrink steps): + +aaaaaaaaaaaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \255 char failed (59 shrink steps): + +aaaaaaaaaaaaaaaaaaaaaaaaaa˙aaaaaaaaaaaaaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + +Test bytes have unique chars failed (18 shrink steps): + +aaaaaaaaaaaaa + +--- Failure -------------------------------------------------------------------- + Test strings are empty failed (8 shrink steps): "a" @@ -504,6 +528,12 @@ Leaf 0 --- Failure -------------------------------------------------------------------- +Test sum list = 0 failed (0 shrink steps): + +[7; 1; 42; 1; 8; 5; 3; 9; 5; 38; 3; 3; 0; 1; 98; 1; 4; 13; 9; 2; 6; 9; 47; 6; 5; 8; 8; 6; 0; 9; 7; 2; 8; 6; 62; 6; 4; 31; 19; 1; 41; 60; 6; 5; 8; 1; 1; 4; 7; 7; 0; 5; 5; 71; 14; 26; 47; 5; 1; 6; 34; 9; 4; 2; 37; 3; 8; 4; 31; 6; 2; 1; 0; 7; 5; 1; 0; 15; 6; 1; 8; 13; 0; 6; 2; 4; 2; 6; 6; 1; 4; 1; 9; 79; 0; 87; 6; 8; 8; 62; 1; 4; 62; 6; 31; 1; 5; 6; 5; 9; 3; 3; 1; 79; 4; 3; 2; 67; 5; 7; 12; 70; 8; 8; 6; 1; 3; 14; 15; 1; 61; 4; 1; 4; 1; 7; 4; 4; 4; 2; 8; 8; 7; 5; 4; 27; 0; 9; 80; 25; 1; 8; 1; 3; 7; 4; 3; 5; 5; 6; 5; 5; 31; 7; 0; 3; 3; 6; 71; 76; 28; 60; 6; 2; 6; 3; 0; 4; 1; 0; 5; 7; 0; 28; 86; 4; 7; 51; 36; 0; 5; 0; 1; 4; 3; 6; 0; 1; 1; 8; 18; 4; 2; 8; 8; 1; 4; 7; 1; 0; 93; 5; 3; 0; 80; 1; 7; 7; 8; 8; 5; 7; 8; 9; 24; 4; 25; 8; 8; 5; 4; 90; 4; 6; 8; 4; 4; 0; 60; 8; 9; 7; 44; 5; 1; 2; 9; 74; 7; 7] + +--- Failure -------------------------------------------------------------------- + Test fail_pred_map_commute failed (37 shrink steps): ([1], {_ -> 0}, {0 -> false; 1 -> true; -489114431 -> false; -334037599 -> false; -1002044798 -> false; 3 -> false; 607479396 -> false; 4 -> false; 5 -> false; 442140485 -> false; 50542662 -> false; 38 -> false; 281414086 -> false; 757535206 -> false; 6 -> false; 7 -> false; 8 -> false; 629085609 -> false; 10 -> false; -765856245 -> false; 44 -> false; 12 -> false; -386873971 -> false; 15 -> false; 47 -> false; -842421617 -> false; 588710735 -> false; 49 -> false; 18 -> false; 51 -> false; 449695123 -> false; 20 -> false; 21 -> false; -386709771 -> false; -92591850 -> false; 136918038 -> false; 54 -> false; -484444937 -> false; -1042148456 -> false; 24 -> false; 1062551480 -> false; 747852089 -> false; 25 -> false; -737785766 -> false; 58 -> false; -530708612 -> false; -60654788 -> false; 28 -> false; 60 -> false; 29 -> false; 947455871 -> false; _ -> false}) @@ -645,6 +675,117 @@ stats depth: 14: # 7 15: 4 ++++ Stats for bytes_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 7.49, stddev: 1.70, median 7, min 5, max 10 + 5: ##################################################### 837 + 6: ##################################################### 826 + 7: ###################################################### 843 + 8: ####################################################### 855 + 9: #################################################### 813 + 10: ##################################################### 826 + ++++ Stats for bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for bytes_of len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 363.14, stddev: 1245.80, median 9, min 0, max 9986 + 0.. 499: ####################################################### 4270 + 500.. 999: ###### 493 + 1000.. 1499: 16 + 1500.. 1999: 11 + 2000.. 2499: 15 + 2500.. 2999: 17 + 3000.. 3499: 11 + 3500.. 3999: 19 + 4000.. 4499: 14 + 4500.. 4999: 10 + 5000.. 5499: 16 + 5500.. 5999: 11 + 6000.. 6499: 15 + 6500.. 6999: 13 + 7000.. 7499: 12 + 7500.. 7999: 16 + 8000.. 8499: 11 + 8500.. 8999: 4 + 9000.. 9499: 13 + 9500.. 9999: 13 + ++++ Stats for bytes_printable len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for bytes_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 + 0.. 4: #################################################### 1925 + 5.. 9: ####################################################### 2005 + 10.. 14: # 52 + 15.. 19: # 50 + 20.. 24: # 55 + 25.. 29: # 56 + 30.. 34: # 55 + 35.. 39: # 49 + 40.. 44: # 65 + 45.. 49: # 65 + 50.. 54: # 55 + 55.. 59: # 68 + 60.. 64: # 61 + 65.. 69: # 65 + 70.. 74: # 57 + 75.. 79: # 66 + 80.. 84: # 65 + 85.. 89: # 64 + 90.. 94: # 60 + 95.. 99: # 62 + +++ Stats for string_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: @@ -1256,7 +1397,7 @@ stats dist: 966367653.. 1073741823: ################# 189 ================================================================================ 1 warning(s) -failure (59 tests failed, 3 tests errored, ran 130 tests) +failure (64 tests failed, 3 tests errored, ran 141 tests) random seed: 153870556 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/test/core/QCheck_expect_test.expected.32 b/test/core/QCheck_expect_test.expected.32 index de696d1f..50d79b29 100644 --- a/test/core/QCheck_expect_test.expected.32 +++ b/test/core/QCheck_expect_test.expected.32 @@ -252,6 +252,30 @@ Test printable never produces less than '5 failed (3 shrink steps): --- Failure -------------------------------------------------------------------- +Test bytes are empty failed (15 shrink steps): + +a + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \000 char failed (8 shrink steps): + + + +--- Failure -------------------------------------------------------------------- + +Test bytes never has a \255 char failed (14 shrink steps): + +˙ + +--- Failure -------------------------------------------------------------------- + +Test bytes have unique chars failed (13 shrink steps): + + + +--- Failure -------------------------------------------------------------------- + Test strings are empty failed (15 shrink steps): "a" @@ -641,6 +665,92 @@ stats dist: 19: ################################################## 253 20: ############################################## 230 ++++ Stats for bytes_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 7.49, stddev: 1.70, median 7, min 5, max 10 + 5: ##################################################### 837 + 6: ##################################################### 826 + 7: ###################################################### 843 + 8: ####################################################### 855 + 9: #################################################### 813 + 10: ##################################################### 826 + ++++ Stats for bytes len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 384.53, stddev: 1330.61, median 9, min 0, max 9969 + 0.. 498: ####################################################### 4246 + 499.. 997: ###### 518 + 998..1496: 21 + 1497..1995: 10 + 1996..2494: 11 + 2495..2993: 10 + 2994..3492: 13 + 3493..3991: 13 + 3992..4490: 5 + 4491..4989: 10 + 4990..5488: 19 + 5489..5987: 9 + 5988..6486: 10 + 6487..6985: 12 + 6986..7484: 17 + 7485..7983: 16 + 7984..8482: 16 + 8483..8981: 16 + 8982..9480: 16 + 9481..9979: 12 + ++++ Stats for bytes_of len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 363.14, stddev: 1245.80, median 9, min 0, max 9986 + 0.. 499: ####################################################### 4270 + 500.. 999: ###### 493 + 1000.. 1499: 16 + 1500.. 1999: 11 + 2000.. 2499: 15 + 2500.. 2999: 17 + 3000.. 3499: 11 + 3500.. 3999: 19 + 4000.. 4499: 14 + 4500.. 4999: 10 + 5000.. 5499: 16 + 5500.. 5999: 11 + 6000.. 6499: 15 + 6500.. 6999: 13 + 7000.. 7499: 12 + 7500.. 7999: 16 + 8000.. 8499: 11 + 8500.. 8999: 4 + 9000.. 9499: 13 + 9500.. 9999: 13 + ++++ Stats for bytes_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +stats len: + num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 + 0.. 4: #################################################### 1925 + 5.. 9: ####################################################### 2005 + 10.. 14: # 52 + 15.. 19: # 50 + 20.. 24: # 55 + 25.. 29: # 56 + 30.. 34: # 55 + 35.. 39: # 49 + 40.. 44: # 65 + 45.. 49: # 65 + 50.. 54: # 55 + 55.. 59: # 68 + 60.. 64: # 61 + 65.. 69: # 65 + 70.. 74: # 57 + 75.. 79: # 66 + 80.. 84: # 65 + 85.. 89: # 64 + 90.. 94: # 60 + 95.. 99: # 62 + +++ Stats for string_size len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: @@ -1252,7 +1362,7 @@ stats dist: 966367653.. 1073741823: ################# 189 ================================================================================ 1 warning(s) -failure (59 tests failed, 3 tests errored, ran 139 tests) +failure (63 tests failed, 3 tests errored, ran 148 tests) random seed: 153870556 +++ Stats for int_dist_empty_bucket ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From d4eba3726784323dd461068372ebd4aeac82d30a Mon Sep 17 00:00:00 2001 From: Jan Midtgaard Date: Wed, 2 Nov 2022 18:34:50 +0100 Subject: [PATCH 26/26] use 'synonym for' consistently --- src/core/QCheck.mli | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/QCheck.mli b/src/core/QCheck.mli index 910d39b7..d448999d 100644 --- a/src/core/QCheck.mli +++ b/src/core/QCheck.mli @@ -315,7 +315,7 @@ module Gen : sig (** All corner cases for int. @since 0.6 *) - val (--) : int -> int -> int t (** Synonym to {!int_range}. *) + val (--) : int -> int -> int t (** Synonym for {!int_range}. *) val ui32 : int32 t (** Generates (unsigned) [int32] values. *) @@ -683,7 +683,7 @@ module Iter : sig val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val (>|=) : 'a t -> ('a -> 'b) -> 'b t val append : 'a t -> 'a t -> 'a t - val (<+>) : 'a t -> 'a t -> 'a t (** Synonym to {!append}. *) + val (<+>) : 'a t -> 'a t -> 'a t (** Synonym for {!append}. *) val of_list : 'a list -> 'a t val of_array : 'a array -> 'a t @@ -1249,7 +1249,7 @@ val small_signed_int : int arbitrary @since 0.5.2 *) val (--) : int -> int -> int arbitrary -(** Synonym to {!int_range}. *) +(** Synonym for {!int_range}. *) val int32 : int32 arbitrary (** Int32 generator. Uniformly distributed. *) @@ -1320,7 +1320,7 @@ val string_gen : char Gen.t -> string arbitrary (** Generates strings with a distribution of length of {!Gen.nat}. *) val string_of : char Gen.t -> string arbitrary -(** Synonym to {!string_gen} added for convenience. +(** Synonym for {!string_gen} added for convenience. @since NEXT_RELEASE *) val string : string arbitrary @@ -1331,7 +1331,7 @@ val small_string : string arbitrary (** Same as {!string} but with a small length (ie {!Gen.small_nat} ). *) val string_small : string arbitrary -(** Synonym to [small_string] added for convenience. +(** Synonym for [small_string] added for convenience. @since NEXT_RELEASE *) val string_small_of : char Gen.t -> string arbitrary @@ -1350,14 +1350,14 @@ val printable_string : string arbitrary and distribution of characters of [printable_char]. *) val string_printable : string arbitrary -(** Synonym to [printable_string] added for convenience. +(** Synonym for [printable_string] added for convenience. @since NEXT_RELEASE *) val printable_string_of_size : int Gen.t -> string arbitrary (** Generates strings with distribution of characters of [printable_char]. *) val string_printable_of_size : int Gen.t -> string arbitrary -(** Synonym to [printable_string_of_size] added for convenience. +(** Synonym for [printable_string_of_size] added for convenience. @since NEXT_RELEASE *) val small_printable_string : string arbitrary @@ -1365,7 +1365,7 @@ val small_printable_string : string arbitrary and distribution of characters of [printable_char]. *) val string_small_printable : string arbitrary -(** Synonym to [small_printable_string] added for convenience. +(** Synonym for [small_printable_string] added for convenience. @since NEXT_RELEASE *) val numeral_string : string arbitrary @@ -1373,14 +1373,14 @@ val numeral_string : string arbitrary and distribution of characters of [numeral_char]. *) val string_numeral : string arbitrary -(** Synonym to [numeral_string] added for convenience. +(** Synonym for [numeral_string] added for convenience. @since NEXT_RELEASE *) val numeral_string_of_size : int Gen.t -> string arbitrary (** Generates strings with a distribution of characters of [numeral_char]. *) val string_numeral_of_size : int Gen.t -> string arbitrary -(** Synonym to [numeral_string_of_size] added for convenience. +(** Synonym for [numeral_string_of_size] added for convenience. @since NEXT_RELEASE *) val list : 'a arbitrary -> 'a list arbitrary