diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml index f98c64b7..c0d76697 100644 --- a/src/core/QCheck2.ml +++ b/src/core/QCheck2.ml @@ -266,12 +266,14 @@ module Gen = struct else if origin > high then invalid_arg Format.(asprintf "%s: origin value %a is greater than high value %a" loc pp origin pp high) else origin - let small_nat : int t = fun st -> + let nat_small : int t = fun st -> let p = RS.float st 1. in let x = if p < 0.75 then RS.int st 10 else RS.int st 100 in let shrink a = fun () -> Shrink.int_towards 0 a () in Tree.make_primitive shrink x + let small_nat = nat_small + (** Natural number generator *) let nat : int t = fun st -> let p = RS.float st 1. in @@ -284,7 +286,7 @@ module Gen = struct let shrink a = fun () -> Shrink.int_towards 0 a () in Tree.make_primitive shrink x - let big_nat : int t = fun st -> + let nat_big : int t = fun st -> let p = RS.float st 1. in if p < 0.75 then nat st @@ -292,6 +294,8 @@ module Gen = struct let shrink a = fun () -> Shrink.int_towards 0 a () in Tree.make_primitive shrink (RS.int st 1_000_000) + let big_nat = nat_big + let unit : unit t = fun _st -> Tree.pure () let bool : bool t = fun st -> @@ -307,9 +311,13 @@ module Gen = struct let shrink a = fun () -> Shrink.float_towards 0. a () in Tree.make_primitive shrink x - let pfloat : float t = float >|= abs_float + let float_pos : float t = float >|= abs_float + + let pfloat = float_pos + + let float_neg : float t = float_pos >|= Float.neg - let nfloat : float t = pfloat >|= Float.neg + let nfloat = float_neg let float_bound_inclusive ?(origin : float = 0.) (bound : float) : float t = fun st -> let (low, high) = Float.min_max_num 0. bound in @@ -353,15 +361,20 @@ module Gen = struct let (--.) low high = float_range ?origin:None low high - let neg_int : int t = nat >|= Int.neg + let int_neg : int t = nat >|= Int.neg - (** [opt gen] shrinks towards [None] then towards shrinks of [gen]. *) - let opt ?(ratio : float = 0.85) (gen : 'a t) : 'a option t = fun st -> + let neg_int = int_neg + + let option_ratio ~ratio (gen : 'a t) : 'a option t = fun st -> let p = RS.float st 1. in if p < (1. -. ratio) then Tree.pure None else Tree.opt (gen st) + let option gen = option_ratio ~ratio:0.85 gen + + let opt ?(ratio = 0.85) = option_ratio ~ratio + (* Uniform positive random int generator. We can't use {!RS.int} because the upper bound must be positive and is excluded, @@ -399,14 +412,16 @@ module Gen = struct let right = RS.bits st in left lor middle lor right - let pint ?(origin : int = 0) : int t = fun st -> + let nat_origin origin : int t = fun st -> let x = pint_raw st in let shrink a = fun () -> - let origin = parse_origin "Gen.pint" Format.pp_print_int ~origin ~low:0 ~high:max_int in + let origin = parse_origin "Gen.nat_origin" Format.pp_print_int ~origin ~low:0 ~high:max_int in Shrink.int_towards origin a () in Tree.make_primitive shrink x + let pint ?(origin = 0) = nat_origin origin + let number_towards = Shrink.number_towards let int_towards = Shrink.int_towards @@ -420,15 +435,15 @@ module Gen = struct let int : int t = bool >>= fun b -> if b - then pint ~origin:0 >|= (fun n -> - n - 1) - else pint ~origin:0 + then nat_origin 0 >|= (fun n -> - n - 1) + else nat_origin 0 let int_bound (n : int) : int t = if n < 0 then invalid_arg "Gen.int_bound"; fun st -> if n <= (1 lsl 30) - 2 then Tree.make_primitive (fun a () -> Shrink.int_towards 0 a ()) (RS.int st (n + 1)) - else Tree.map (fun r -> r mod (n + 1)) (pint st) + else Tree.map (fun r -> r mod (n + 1)) (nat st) (** To support ranges wider than [Int.max_int], the general idea is to find the center, and generate a random half-difference number as well as whether we add or @@ -467,20 +482,20 @@ module Gen = struct let oneof (l : 'a t list) : 'a t = int_range 0 (List.length l - 1) >>= List.nth l - let oneofl (l : 'a list) : 'a t = + let oneof_l (l : 'a list) : 'a t = int_range 0 (List.length l - 1) >|= List.nth l + let oneofl = oneof_l - let oneofa (a : 'a array) : 'a t = + let oneof_a (a : 'a array) : 'a t = int_range 0 (Array.length a - 1) >|= Array.get a + let oneofa = oneof_a - (* NOTE: we keep this alias to not break code that uses [small_int] - for sizes of strings, arrays, etc. *) - let small_int = small_nat - - let small_signed_int : int t = fun st -> + let int_small : int t = fun st -> if RS.bool st - then small_nat st - else (small_nat >|= Int.neg) st + then nat_small st + else (nat_small >|= Int.neg) st + + let small_signed_int = int_small (** Shrink towards the first element of the list *) let frequency (l : (int * 'a t) list) : 'a t = @@ -495,11 +510,13 @@ module Gen = struct in aux 0 l - let frequencyl (l : (int * 'a) list) : 'a t = + let frequency_l (l : (int * 'a) list) : 'a t = List.map (fun (weight, value) -> (weight, pure value)) l |> frequency + let frequencyl = frequency_l - let frequencya a = frequencyl (Array.to_list a) + let frequency_a a = frequencyl (Array.to_list a) + let frequencya = frequency_a let char_range ?(origin : char option) (a : char) (b : char) : char t = (int_range ~origin:(Char.code (Option.value ~default:a origin)) (Char.code a) (Char.code b)) >|= Char.chr @@ -519,15 +536,11 @@ module Gen = struct let shrink a = fun () -> Shrink.int32_towards 0l a () in Tree.make_primitive shrink x - let ui32 : int32 t = map Int32.abs int32 - let int64 : int64 t = fun st -> let x = random_binary_string 64 st |> Int64.of_string in let shrink a = fun () -> Shrink.int64_towards 0L a () in Tree.make_primitive shrink x - let ui64 : int64 t = map Int64.abs int64 - (* A tail-recursive implementation over Tree.t *) let list_size (size : int t) (gen : 'a t) : 'a list t = fun st -> @@ -561,7 +574,7 @@ module Gen = struct let flatten_opt (o : 'a t option) : 'a option t = match o with | None -> pure None - | Some gen -> opt gen + | Some gen -> option gen let flatten_res (res : ('a t, 'e) result) : ('a, 'e) result t = match res with @@ -644,15 +657,19 @@ module Gen = struct (* Put alphabet first for shrinking *) List.flatten [lower_alphabet; before_lower_alphabet; after_lower_alphabet; newline] - let printable : char t = + let char_printable : char t = int_range ~origin:0 0 (List.length printable_chars - 1) >|= List.nth printable_chars - let numeral : char t = + let printable = char_printable + + let char_numeral : char t = let zero = 48 in let nine = 57 in int_range ~origin:zero zero nine >|= char_of_int + let numeral = char_numeral + let bytes_size ?(gen = char) (size : int t) : bytes t = fun st -> let open Tree in size st >>= fun size -> @@ -683,13 +700,16 @@ module Gen = struct let string_of gen = string_size ~gen nat - let string_printable = string_size ~gen:printable nat + let string_printable = string_size ~gen:char_printable nat - let small_string ?gen st = string_size ?gen small_nat st + let string_small ?gen st = string_size ?gen nat_small st + let small_string = string_small - let small_list gen = list_size small_nat gen + let list_small gen = list_size nat_small gen + let small_list = list_small - let small_array gen = array_size small_nat gen + let array_small gen = array_size nat_small gen + let small_array = array_small let join (gen : 'a t t) : 'a t = gen >>= Fun.id @@ -704,7 +724,8 @@ module Gen = struct let int_corners = int_pos_corners @ [min_int] - let small_int_corners () : int t = graft_corners nat int_pos_corners () + let int_small_corners () : int t = graft_corners nat int_pos_corners () + let small_int_corners = int_small_corners (* sized, fix *) diff --git a/src/core/QCheck2.mli b/src/core/QCheck2.mli index b7b35925..fe5d6337 100644 --- a/src/core/QCheck2.mli +++ b/src/core/QCheck2.mli @@ -59,7 +59,7 @@ content will appear. *) ~name:"All lists are sorted" ~count:10_000 ~print:Print.(list int) - Gen.(list small_nat) + Gen.(list nat_small) (fun l -> l = List.sort compare l));; QCheck2.Test.check_exn test;; @@ -161,10 +161,28 @@ module Gen : sig Shrinks towards [0]. *) + val nat_origin : int -> int t + (** Generates non-strictly positive integers uniformly ([0] included). + + Shrinks towards [origin] if specified, otherwise towards [0]. + + @since NEXT_RELEASE *) + val pint : ?origin : int -> int t (** Generates non-strictly positive integers uniformly ([0] included). - Shrinks towards [origin] if specified, otherwise towards [0]. *) + Shrinks towards [origin] if specified, otherwise towards [0]. + + @deprecated use {!int_origin} *) + + val nat_small : int t + (** Small positive integers (< [100], [0] included). + + Non-uniform: smaller numbers are more likely than bigger numbers. + + Shrinks towards [0]. + + @since NEXT_RELEASE *) val small_nat : int t (** Small positive integers (< [100], [0] included). @@ -173,7 +191,9 @@ module Gen : sig Shrinks towards [0]. - @since 0.5.1 *) + @since 0.5.1 + + @deprecated use {!nat_small}. *) val nat : int t (** Generates natural numbers (< [10_000]). @@ -183,6 +203,15 @@ module Gen : sig Shrinks towards [0]. *) + val nat_big : int t + (** Generates natural numbers, possibly large (< [1_000_000]). + + Non-uniform: smaller numbers are more likely than bigger numbers. + + Shrinks towards [0]. + + @since NEXT_RELEASE *) + val big_nat : int t (** Generates natural numbers, possibly large (< [1_000_000]). @@ -190,36 +219,65 @@ module Gen : sig Shrinks towards [0]. - @since 0.10 *) + @since 0.10 - val neg_int : int t + @deprecated use {!nat_big}. *) + + val int_neg : int t (** Generates non-strictly negative integers ([0] included). - Non-uniform: smaller numbers (in absolute value) are more likely than bigger numbers. + Non-uniform: smaller numbers (in absolute value) are more likely than + bigger numbers. Shrinks towards [0]. + + @since NEXT_RELEASE *) - val small_int : int t - (** Small UNSIGNED integers, for retrocompatibility. + val neg_int : int t + (** Generates non-strictly negative integers ([0] included). + + Non-uniform: smaller numbers (in absolute value) are more likely than + bigger numbers. Shrinks towards [0]. - @deprecated use {!small_nat}. *) + @deprecated use {!int_neg}. *) + + val int_small : int t + (** Small SIGNED integers, based on {!nat_small}. + + Non-uniform: smaller numbers (in absolute value) are more likely than + bigger numbers. + + Shrinks towards [0]. + + @since NEXT_RELEASE *) val small_signed_int : int t - (** Small SIGNED integers, based on {!small_nat}. + (** Small SIGNED integers, based on {!nat_small}. - Non-uniform: smaller numbers (in absolute value) are more likely than bigger numbers. + Non-uniform: smaller numbers (in absolute value) are more likely than + bigger numbers. Shrinks towards [0]. - @since 0.5.2 *) + @since 0.5.2 + + @deprecated use {!int_small} *) + + val int_small_corners : unit -> int t + (** As {!int_small}, but each newly created generator starts with + a list of corner cases before falling back on random generation. + + @since NEXT_RELEASE + *) val small_int_corners : unit -> int t - (** As {!small_int}, but each newly created generator starts with - a list of corner cases before falling back on random generation. *) + (** As {!int_small}, but each newly created generator starts with + a list of corner cases before falling back on random generation. + @deprecated use {!int_small_corners}. *) val int32 : int32 t (** Generates uniform {!int32} values. @@ -227,45 +285,47 @@ module Gen : sig Shrinks towards [0l]. *) - val ui32 : int32 t - (** Generates {!int32} values. - - Shrinks towards [0l]. - - @deprecated use {!val:int32} instead, the name is wrong, values {i are} signed. - *) - val int64 : int64 t (** Generates uniform {!int64} values. Shrinks towards [0L]. *) - val ui64 : int64 t - (** Generates {!int64} values. - - Shrinks towards [0L]. - - @deprecated use {!val:int64} instead, the name is wrong, values {i are} signed. - *) - val float : float t (** Generates floating point numbers. Shrinks towards [0.]. *) - val pfloat : float t + val float_pos : float t (** Generates positive floating point numbers ([0.] included). Shrinks towards [0.]. + + @since NEXT_RELEASE *) + val pfloat : float t + (** Generates positive floating point numbers ([0.] included). + + Shrinks towards [0.]. + + @deprecated use {!float_pos} *) + + val float_neg : float t + (** Generates negative floating point numbers. ([-0.] included). + + Shrinks towards [-0.]. + + @since NEXT_RELEASE + *) + val nfloat : float t (** Generates negative floating point numbers. ([-0.] included). Shrinks towards [-0.]. - *) + + @deprecated use {!float_neg}. *) val char : char t (** Generates characters in the [0..255] range. @@ -273,6 +333,18 @@ module Gen : sig Shrinks towards ['a']. *) + val char_printable : char t + (** Generates printable characters. + + The exhaustive list of character codes is: + - [32] to [126], inclusive + - ['\n'] + + Shrinks towards ['a']. + + @since NEXT_RELEASE + *) + val printable : char t (** Generates printable characters. @@ -281,12 +353,24 @@ module Gen : sig - ['\n'] Shrinks towards ['a']. + + @deprecated use {!char_printable} + *) + + val char_numeral : char t + (** Generates numeral characters ['0'..'9']. + + Shrinks towards ['0']. + + @since NEXT_RELEASE *) val numeral : char t (** Generates numeral characters ['0'..'9']. Shrinks towards ['0']. + + @deprecated use {!char_numeral} *) val string_size : ?gen:char t -> int t -> string t @@ -313,17 +397,28 @@ module Gen : sig @since 0.11 *) val string_printable : string t - (** Builds a string generator using the {!printable} character generator. + (** Builds a string generator using the {!char_printable} character generator. Shrinks on the number of characters first, then on the characters. @since 0.11 *) + val string_small : ?gen:char t -> string t + (** Builds a string generator, length is {!nat_small}. + 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 - (** Builds a string generator, length is {!small_nat}. + (** Builds a string generator, length is {!nat_small}. Accepts an optional character generator (the default is {!char}). Shrinks on the number of characters first, then on the characters. + + @deprecated use {!string_small} *) val pure : 'a -> 'a t @@ -465,18 +560,40 @@ module Gen : sig @raise Invalid_argument or Failure if [l] is empty *) - val oneofl : 'a list -> 'a t + val oneof_l : 'a list -> 'a t + (** [oneof_l l] constructs a generator that selects among the given list of values [l]. + + Shrinks towards the first element of the list. + @raise Invalid_argument or Failure if [l] is empty + + @since NEXT_RELEASE + *) + + val oneofl : 'a list -> 'a t (** [oneofl l] constructs a generator that selects among the given list of values [l]. Shrinks towards the first element of the list. @raise Invalid_argument or Failure if [l] is empty + + @deprecated use {!oneof_l} *) + val oneof_a : 'a array -> 'a t + (** [oneof_a a] constructs a generator that selects among the given array of values [a]. + + Shrinks towards the first element of the array. + @raise Invalid_argument or Failure if [l] is empty + + @since NEXT_RELEASE + *) + val oneofa : 'a array -> 'a t (** [oneofa a] constructs a generator that selects among the given array of values [a]. Shrinks towards the first element of the array. @raise Invalid_argument or Failure if [l] is empty + + @deprecated use {!oneof_a} *) val frequency : (int * 'a t) list -> 'a t @@ -486,18 +603,40 @@ module Gen : sig Shrinks towards the first element of the list. *) + val frequency_l : (int * 'a) list -> 'a t + (** Constructs a generator that selects among a given list of values. + Each of the given values are chosen based on a positive integer weight. + + Shrinks towards the first element of the list. + + @since NEXT_RELEASE + *) + val frequencyl : (int * 'a) list -> 'a t (** Constructs a generator that selects among a given list of values. Each of the given values are chosen based on a positive integer weight. Shrinks towards the first element of the list. + + @deprecated use {!frequency_l} *) + val frequency_a : (int * 'a) array -> 'a t + (** Constructs a generator that selects among a given array of values. + Each of the array entries are chosen based on a positive integer weight. + + Shrinks towards the first element of the array. + + @since NEXT_RELEASE + *) + val frequencya : (int * 'a) array -> 'a t (** Constructs a generator that selects among a given array of values. Each of the array entries are chosen based on a positive integer weight. Shrinks towards the first element of the array. + + @deprecated use {!frequency_a} *) (** {3 Shuffling elements} *) @@ -551,12 +690,21 @@ module Gen : sig Shrinks on the number of elements first, then on elements. *) + val list_small : 'a t -> 'a list t + (** Generates lists of small size (see {!nat_small}). + + Shrinks on the number of elements first, then on elements. + + @since NEXT_RELEASE *) + val small_list : 'a t -> 'a list t - (** Generates lists of small size (see {!small_nat}). + (** Generates lists of small size (see {!nat_small}). Shrinks on the number of elements first, then on elements. - @since 0.5.3 *) + @since 0.5.3 + + @deprecated use {!list_small} *) val list_size : int t -> 'a t -> 'a list t (** Builds a list generator from a (non-negative) size generator and an element generator. @@ -582,12 +730,21 @@ module Gen : sig Shrinks on the number of elements first, then on elements. *) + val array_small : 'a t -> 'a array t + (** Generates arrays of small size (see {!nat_small}). + + Shrinks on the number of elements first, then on elements. + + @since NEXT_RELEASE *) + val small_array : 'a t -> 'a array t - (** Generates arrays of small size (see {!small_nat}). + (** Generates arrays of small size (see {!nat_small}). Shrinks on the number of elements first, then on elements. - @since 0.10 *) + @since 0.10 + + @deprecated use {!array_small} *) val array_repeat : int -> 'a t -> 'a array t (** [array_repeat i g] builds an array generator from exactly [i] elements generated by [g]. @@ -595,6 +752,21 @@ module Gen : sig Shrinks on elements only. *) + val option : 'a t -> 'a option t + (** [option gen] is an [option] generator that uses [gen] when generating [Some] values. + + Shrinks towards {!None} then towards shrinks of [gen]. + *) + + val option_ratio : ratio:float -> 'a t -> 'a option t + (** [option_ratio ratio gen] is an [option] generator that uses [gen] when generating [Some] values. + + Shrinks towards {!None} then towards shrinks of [gen]. + + @param ratio a float between [0.] and [1.] indicating the probability of a sample to be [Some _] + rather than [None] (value is [0.85]). + *) + val opt : ?ratio:float -> 'a t -> 'a option t (** [opt gen] is an [option] generator that uses [gen] when generating [Some] values. @@ -602,6 +774,8 @@ module Gen : sig @param ratio a float between [0.] and [1.] indicating the probability of a sample to be [Some _] rather than [None] (value is [0.85]). + + @deprecated use {!option} *) (** {3 Combining generators} *) @@ -784,7 +958,7 @@ module Gen : sig let string_prefixed_with_keyword_gen : string Gen.t = Gen.map2 (fun prefix s -> prefix ^ s) - (Gen.oneofl ["foo"; "bar"; "baz"]) + (Gen.oneof_l ["foo"; "bar"; "baz"]) Gen.string_printable ]} @@ -1316,7 +1490,7 @@ type 'f fun_repr For example (note the [Fun (_, f)] part): {[ QCheck2.(Test.make - Gen.(pair (fun1 Observable.int bool) (small_list int)) + Gen.(pair (fun1 Observable.int bool) (list_small int)) (fun (Fun (_, f), l) -> l = (List.rev_map f l |> List.rev l)) ]} diff --git a/test/core/QCheck2_expect_test.ml b/test/core/QCheck2_expect_test.ml index 91e82e3c..83899672 100644 --- a/test/core/QCheck2_expect_test.ml +++ b/test/core/QCheck2_expect_test.ml @@ -40,11 +40,11 @@ module Overall = struct let passing = Test.make ~name:"list_rev_is_involutive" ~count:100 ~long_factor:100 ~print:Print.(list int) - Gen.(list small_int) (fun l -> List.rev (List.rev l) = l) + Gen.(list nat_small) (fun l -> List.rev (List.rev l) = l) let failing = Test.make ~name:"should_fail_sort_id" ~count:10 ~print:Print.(list int) - Gen.(small_list small_int) (fun l -> l = List.sort compare l) + Gen.(list_small nat_small) (fun l -> l = List.sort compare l) exception Error @@ -67,7 +67,7 @@ module Overall = struct let retries = Test.make ~name:"with shrinking retries" ~retries:10 ~print:Print.int - Gen.small_nat (fun i -> Printf.printf "%i %!" i; i mod 3 <> 1) + Gen.nat_small (fun i -> Printf.printf "%i %!" i; i mod 3 <> 1) let bad_assume_warn = Test.make ~name:"WARN_unlikely_precond" ~count:2_000 ~print:Print.int @@ -132,13 +132,13 @@ module Generator = struct let list_repeat_test = Test.make ~name:"list_repeat has constant length" ~count:1000 ~print:Print.(pair int (list unit)) - Gen.(small_nat >>= fun i -> list_repeat i unit >>= fun l -> return (i,l)) + Gen.(nat_small >>= fun i -> list_repeat i unit >>= fun l -> return (i,l)) (fun (i,l) -> List.length l = i) let array_repeat_test = Test.make ~name:"array_repeat has constant length" ~count:1000 ~print:Print.(pair int (array unit)) - Gen.(small_nat >>= fun i -> array_repeat i unit >>= fun l -> return (i,l)) + Gen.(nat_small >>= fun i -> array_repeat i unit >>= fun l -> return (i,l)) (fun (i,l) -> Array.length l = i) let passing_tree_rev = @@ -232,7 +232,7 @@ module Shrink = struct (* example from issue #59 *) let test_fac_issue59 = Test.make ~name:"test fac issue59" - (Gen.make_primitive ~gen:(fun st -> Gen.generate1 ~rand:st (Gen.small_int_corners ())) ~shrink:(fun _ -> Seq.empty)) + (Gen.make_primitive ~gen:(fun st -> Gen.generate1 ~rand:st (Gen.int_small_corners ())) ~shrink:(fun _ -> Seq.empty)) (fun n -> try (fac n) mod n = 0 with (*| Stack_overflow -> false*) @@ -240,7 +240,7 @@ module Shrink = struct let big_bound_issue59 = Test.make ~name:"big bound issue59" ~print:Print.int - (Gen.small_int_corners()) (fun i -> i < 209609) + (Gen.int_small_corners()) (fun i -> i < 209609) let long_shrink = let listgen = Gen.(list_size (int_range 1000 10000) int) in @@ -259,7 +259,7 @@ module Shrink = struct (* test from issue #59 *) let ints_smaller_209609 = Test.make ~name:"ints < 209609" ~print:Print.int - (Gen.small_int_corners()) (fun i -> i < 209609) + (Gen.int_small_corners()) (fun i -> i < 209609) let nats_smaller_5001 = Test.make ~name:"nat < 5001" ~count:1000 ~print:Print.int @@ -288,36 +288,36 @@ module Shrink = struct let lists_are_empty_issue_64 = Test.make ~name:"lists are empty" ~print:Print.(list int) - Gen.(list small_int) (fun xs -> print_list xs; xs = []) + Gen.(list nat_small) (fun xs -> print_list xs; xs = []) let list_shorter_10 = Test.make ~name:"lists shorter than 10" ~print:Print.(list int) - Gen.(list small_int) (fun xs -> List.length xs < 10) + Gen.(list nat_small) (fun xs -> List.length xs < 10) let length_printer xs = Printf.sprintf "[...] list length: %i" (List.length xs) - let size_gen = Gen.(oneof [small_nat; int_bound 750_000]) + let size_gen = Gen.(oneof [nat_small; int_bound 750_000]) let list_shorter_432 = Test.make ~name:"lists shorter than 432" ~print:length_printer - Gen.(list_size size_gen small_int) + Gen.(list_size size_gen nat_small) (fun xs -> List.length xs < 432) let list_shorter_4332 = Test.make ~name:"lists shorter than 4332" ~print:length_printer - Gen.(list_size size_gen small_int) + Gen.(list_size size_gen nat_small) (fun xs -> List.length xs < 4332) let list_equal_dupl = Test.make ~name:"lists equal to duplication" ~print:Print.(list int) - Gen.(list_size size_gen small_int) + Gen.(list_size size_gen nat_small) (fun xs -> try xs = xs @ xs with Stack_overflow -> false) let list_unique_elems = Test.make ~name:"lists have unique elems" ~print:Print.(list int) - Gen.(list small_int) + Gen.(list nat_small) (fun xs -> let ys = List.sort_uniq Int.compare xs in print_list xs; List.length xs = List.length ys) @@ -330,56 +330,56 @@ module Shrink = struct Test.make ~print:Print.(tup2 int int) ~name:"forall (a, b) in nat: a < b" - Gen.(tup2 small_int small_int) + Gen.(tup2 nat_small nat_small) (fun (a, b) -> a < b) let test_tup3 = Test.make ~print:Print.(tup3 int int int) ~name:"forall (a, b, c) in nat: a < b < c" - Gen.(tup3 small_int small_int small_int) + Gen.(tup3 nat_small nat_small nat_small) (fun (a, b, c) -> a < b && b < c) let test_tup4 = Test.make ~print:Print.(tup4 int int int int) ~name:"forall (a, b, c, d) in nat: a < b < c < d" - Gen.(tup4 small_int small_int small_int small_int) + Gen.(tup4 nat_small nat_small nat_small nat_small) (fun (a, b, c, d) -> a < b && b < c && c < d) let test_tup5 = Test.make ~print:Print.(tup5 int int int int int) ~name:"forall (a, b, c, d, e) in nat: a < b < c < d < e" - Gen.(tup5 small_int small_int small_int small_int small_int) + Gen.(tup5 nat_small nat_small nat_small nat_small nat_small) (fun (a, b, c, d, e) -> a < b && b < c && c < d && d < e) let test_tup6 = Test.make ~print:Print.(tup6 int int int int int int) ~name:"forall (a, b, c, d, e, f) in nat: a < b < c < d < e < f" - Gen.(tup6 small_int small_int small_int small_int small_int small_int) + Gen.(tup6 nat_small nat_small nat_small nat_small nat_small nat_small) (fun (a, b, c, d, e, f) -> a < b && b < c && c < d && d < e && e < f) let test_tup7 = Test.make ~print:Print.(tup7 int int int int int int int) ~name:"forall (a, b, c, d, e, f, g) in nat: a < b < c < d < e < f < g" - Gen.(tup7 small_int small_int small_int small_int small_int small_int small_int) + Gen.(tup7 nat_small nat_small nat_small nat_small nat_small nat_small nat_small) (fun (a, b, c, d, e, f, g) -> a < b && b < c && c < d && d < e && e < f && f < g) let test_tup8 = Test.make ~print:Print.(tup8 int int int int int int int int) ~name:"forall (a, b, c, d, e, f, g, h) in nat: a < b < c < d < e < f < g < h" - Gen.(tup8 small_int small_int small_int small_int small_int small_int small_int small_int) + Gen.(tup8 nat_small nat_small nat_small nat_small nat_small nat_small nat_small nat_small) (fun (a, b, c, d, e, f, g, h) -> a < b && b < c && c < d && d < e && e < f && f < g && g < h) let test_tup9 = Test.make ~print:Print.(tup9 int int int int int int int int int) ~name:"forall (a, b, c, d, e, f, g, h, i) in nat: a < b < c < d < e < f < g < h < i" - Gen.(tup9 small_int small_int small_int small_int small_int small_int small_int small_int small_int) + Gen.(tup9 nat_small nat_small nat_small nat_small nat_small nat_small nat_small nat_small nat_small) (fun (a, b, c, d, e, f, g, h, i) -> a < b && b < c && c < d && d < e && e < f && f < g && g < h && h < i) let tests = [ @@ -420,7 +420,7 @@ module Function = struct Test.make ~name:"fail_pred_map_commute" ~count:100 ~long_factor:100 ~print:Print.(triple (list int) Fn.print Fn.print) Gen.(triple - (small_list small_int) + (list_small nat_small) (fun1 ~print:Print.int Observable.int int) (fun1 ~print:Print.bool Observable.int bool)) (fun (l,Fun (_,f),Fun (_,p)) -> @@ -431,7 +431,7 @@ module Function = struct (fun1 Observable.string ~print:Print.bool Gen.bool) (fun (Fun (_,p)) -> not (p "some random string") || p "some other string") - let int_gen = Gen.small_nat (* int *) + let int_gen = Gen.nat_small (* int *) (* Another example (false) property *) let prop_foldleft_foldright = @@ -479,10 +479,10 @@ 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) - (list small_int) - (list small_int)) + (fun2 ~print:Print.string Observable.string Observable.int (string_small ~gen:char)) + (string_small ~gen:char) + (list nat_small) + (list nat_small)) (fun (f,acc,is,js) -> let f = Fn.apply f in List.fold_left f acc (is @ js) @@ -545,14 +545,14 @@ module Stats = struct 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_small len dist" ~count:5_000 ~stats:[len] Gen.(string_small ~gen:char)(*ugh*)(fun _ -> true); ] let list_len_tests = let len = ("len",List.length) in [ (* test from issue #30 *) Test.make ~name:"list len dist" ~count:5_000 ~stats:[len] Gen.(list int) (fun _ -> true); - Test.make ~name:"small_list len dist" ~count:5_000 ~stats:[len] Gen.(small_list int) (fun _ -> true); + Test.make ~name:"list_small len dist" ~count:5_000 ~stats:[len] Gen.(list_small int) (fun _ -> true); Test.make ~name:"list_size len dist" ~count:5_000 ~stats:[len] Gen.(list_size (int_range 5 10) int) (fun _ -> true); Test.make ~name:"list_repeat len dist" ~count:5_000 ~stats:[len] Gen.(list_repeat 42 int) (fun _ -> true); ] @@ -561,7 +561,7 @@ module Stats = struct let len = ("len",Array.length) in [ Test.make ~name:"array len dist" ~count:5_000 ~stats:[len] Gen.(array int) (fun _ -> true); - Test.make ~name:"small_array len dist" ~count:5_000 ~stats:[len] Gen.(small_array int) (fun _ -> true); + Test.make ~name:"array_small len dist" ~count:5_000 ~stats:[len] Gen.(array_small int) (fun _ -> true); Test.make ~name:"array_size len dist" ~count:5_000 ~stats:[len] Gen.(array_size (int_range 5 10) int) (fun _ -> true); Test.make ~name:"array_repeat len dist" ~count:5_000 ~stats:[len] Gen.(array_repeat 42 int) (fun _ -> true); ] @@ -570,22 +570,22 @@ module Stats = struct let dist = ("dist",fun x -> x) in [ (* test from issue #40 *) - Test.make ~name:"int_stats_neg" ~count:5000 ~stats:[dist] Gen.small_signed_int (fun _ -> true); + Test.make ~name:"int_stats_neg" ~count:5000 ~stats:[dist] Gen.int_small (fun _ -> true); (* distribution tests from PR #45 *) - Test.make ~name:"small_signed_int dist" ~count:1000 ~stats:[dist] Gen.small_signed_int (fun _ -> true); - Test.make ~name:"small_nat dist" ~count:1000 ~stats:[dist] Gen.small_nat (fun _ -> true); + Test.make ~name:"int_small dist" ~count:1000 ~stats:[dist] Gen.int_small (fun _ -> true); + Test.make ~name:"nat_small dist" ~count:1000 ~stats:[dist] Gen.nat_small (fun _ -> true); Test.make ~name:"nat dist" ~count:1000 ~stats:[dist] Gen.nat (fun _ -> true); Test.make ~name:"int_range (-43643) 435434 dist" ~count:1000 ~stats:[dist] (Gen.int_range (-43643) 435434) (fun _ -> true); Test.make ~name:"int_range (-40000) 40000 dist" ~count:1000 ~stats:[dist] (Gen.int_range (-40000) 40000) (fun _ -> true); Test.make ~name:"int_range (-4) 4 dist" ~count:1000 ~stats:[dist] (Gen.int_range (-4) 4) (fun _ -> true); Test.make ~name:"int_range (-4) 17 dist" ~count:1000 ~stats:[dist] (Gen.int_range (-4) 17) (fun _ -> true); Test.make ~name:"int dist" ~count:100000 ~stats:[dist] Gen.int (fun _ -> true); - Test.make ~name:"oneof int dist" ~count:1000 ~stats:[dist] (Gen.oneofl[min_int;-1;0;1;max_int]) (fun _ -> true); + Test.make ~name:"oneof int dist" ~count:1000 ~stats:[dist] (Gen.oneof_l [min_int;-1;0;1;max_int]) (fun _ -> true); ] let int_dist_empty_bucket = Test.make ~name:"int_dist_empty_bucket" ~count:1_000 ~stats:[("dist",fun x -> x)] - Gen.(oneof [small_int_corners ();int]) (fun _ -> true) + Gen.(oneof [int_small_corners ();int]) (fun _ -> true) let tree_depth_test = let depth = ("depth", IntTree.depth) in diff --git a/test/core/qcheck2_output.txt.expected b/test/core/qcheck2_output.txt.expected index efe05edb..1e91b461 100644 --- a/test/core/qcheck2_output.txt.expected +++ b/test/core/qcheck2_output.txt.expected @@ -589,7 +589,7 @@ stats len: 8982..9480: 16 9481..9979: 12 -+++ Stats for small_string len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for string_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: num: 5000, avg: 15.57, stddev: 24.36, median 6, min 0, max 99 @@ -639,7 +639,7 @@ stats len: 9000.. 9499: 15 9500.. 9999: 20 -+++ Stats for small_list len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for list_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: num: 5000, avg: 16.14, stddev: 24.86, median 6, min 0, max 99 @@ -706,7 +706,7 @@ stats len: 9000.. 9499: 15 9500.. 9999: 20 -+++ Stats for small_array len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for array_small len dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats len: num: 5000, avg: 16.14, stddev: 24.86, median 6, min 0, max 99 @@ -773,7 +773,7 @@ stats dist: 81.. 90: # 60 91..100: # 66 -+++ Stats for small_signed_int dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for int_small dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats dist: num: 1000, avg: 0.90, stddev: 28.23, median 0, min -99, max 99 @@ -798,7 +798,7 @@ stats dist: 81.. 90: # 16 91..100: # 10 -+++ Stats for small_nat dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++ Stats for nat_small dist ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stats dist: num: 1000, avg: 15.11, stddev: 23.27, median 6, min 0, max 99 diff --git a/test/core/test.ml b/test/core/test.ml index aae8b636..254c4e48 100644 --- a/test/core/test.ml +++ b/test/core/test.ml @@ -66,8 +66,12 @@ module Shrink = struct end module Gen = struct - let test_gen_opt ~ratio = - let opt_int = Gen.opt ?ratio Gen.int in + let test_gen_opt ?ratio () = + let opt_int = + match ratio with + | None -> Gen.option Gen.int + | Some ratio -> Gen.option_ratio ~ratio Gen.int + in let nb = ref 0 in for _i = 0 to 1000 do Gen.generate1 opt_int |> function None -> () | Some _ -> nb := !nb + 1 @@ -75,14 +79,14 @@ module Gen = struct !nb let test_gen_opt_default () = - let nb = test_gen_opt ~ratio:None in + let nb = test_gen_opt () in let b = nb > 800 && nb < 900 in - Alcotest.(check bool) "Gen.opt produces around 85% of Some" b true + Alcotest.(check bool) "[Gen.option] produces around 85% of Some" b true let test_gen_opt_custom () = - let nb = test_gen_opt ~ratio:(Some 0.5) in + let nb = test_gen_opt ~ratio:0.5 () in let b = nb > 450 && nb < 550 in - Alcotest.(check bool) "Gen.opt produces around 50% of Some" b true + Alcotest.(check bool) "[Gen.option_ratio ~ratio:0.5] produces around 50% of Some" b true let tests = ("Gen", Alcotest.[