Repository: c-cube/qcheck (ocaml)

Issue:
count cannot be zero
In `0.19` (since #220), the `~count` argument to `Test.make` can no longer be zero.

Why?

Is this documented?

Using a zero count can be used to disable a test. Real-life use:
https://github.com/andrenth/ocaml-stdint/blob/0.7.0/tests/stdint_test.ml#L6

Pull request:
Fix: allow 0 count and 0 long_factor
Closes #254

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fdd7e0..20e2c5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changes
 
+## 0.19.1
+
+- fix: allow `~count` in `Test.make` to be 0
+
+- fix: allow `~long_factor` in `Test.make` to be 0
+
 ## 0.19
 
 - use `Float.equal` for comparing `float`s in the `Observable` module underlying function generators.
diff --git a/src/core/QCheck2.ml b/src/core/QCheck2.ml
index 3f0e90e..0a4f1b3 100644
--- a/src/core/QCheck2.ml
+++ b/src/core/QCheck2.ml
@@ -1424,17 +1424,17 @@ module Test = struct
 
   let default_long_factor = 1
 
-  let global_positive_var default env_var var =
+  let global_nonnegative_var default env_var var =
     let var = match (var, Sys.getenv_opt env_var) with
     | (Some x, _) -> x
     | (_, Some x) -> int_of_string x
     | (None, None) -> default
   in
-  if var <= 0 then invalid_arg (env_var ^ " must be > 0 but value is " ^ string_of_int var) else var
+  if var < 0 then invalid_arg (env_var ^ " must be >= 0 but value is " ^ string_of_int var) else var
 
-  let global_count count = global_positive_var default_count "QCHECK_COUNT" count
+  let global_count count = global_nonnegative_var default_count "QCHECK_COUNT" count
 
-  let global_long_factor long_factor = global_positive_var default_long_factor "QCHECK_LONG_FACTOR" long_factor
+  let global_long_factor long_factor = global_nonnegative_var default_long_factor "QCHECK_LONG_FACTOR" long_factor
 
   let fresh_name =
     let r = ref 0 in


Test patch:
diff --git a/test/core/QCheck2_unit_tests.ml b/test/core/QCheck2_unit_tests.ml
index 36b8d8f..773e130 100644
--- a/test/core/QCheck2_unit_tests.ml
+++ b/test/core/QCheck2_unit_tests.ml
@@ -179,11 +179,23 @@ module TestCount = struct
     let actual = QCheck2.Test.test_get_count t in
     Alcotest.(check int) "default count is from QCHECK_COUNT" 5 actual
 
+  let test_count_0 () = test_count_n ~count:0 0
+
+  let test_count_negative_fail () =
+    try
+      let _ = test_count_n ~count:(-1) (-1) in
+      Alcotest.fail "A negative count in a test should fail"
+    with
+    | _ -> ()
+
   let tests =
     ("Test.make ~count", Alcotest.[
          test_case "make with custom count" `Quick test_count_10;
          test_case "make with default count" `Quick test_count_default;
          test_case "make with env count" `Quick test_count_env;
+         test_case "make with 0 count" `Quick test_count_0;
+         test_case "make with negative count should fail"
+           `Quick test_count_negative_fail;
        ])
 end
 
@@ -205,11 +217,23 @@ module TestLongFactor = struct
     let actual = QCheck2.Test.test_get_long_factor t in
     Alcotest.(check int) "default long factor is from QCHECK_LONG_FACTOR" 5 actual
 
+  let test_long_factor_0 () = test_long_factor_n ~long_factor:0 0
+
+  let test_long_factor_negative_fail () =
+    try
+      let _ = test_long_factor_n ~long_factor:(-1) (-1) in
+      Alcotest.fail "A negative long factor in a test should fail"
+    with
+    | _ -> ()
+
   let tests =
     ("Test.make ~long_factor", Alcotest.[
          test_case "make with custom long_factor" `Quick test_long_factor_10;
          test_case "make with default long_factor" `Quick test_long_factor_default;
          test_case "make with env long_factor" `Quick test_long_factor_env;
+         test_case "make with 0 long_factor" `Quick test_long_factor_0;
+         test_case "make with negative long_factor fail should"
+           `Quick test_long_factor_negative_fail;
        ])
 end
 
diff --git a/test/core/QCheck_unit_tests.ml b/test/core/QCheck_unit_tests.ml
index c0d6401..b904202 100644
--- a/test/core/QCheck_unit_tests.ml
+++ b/test/core/QCheck_unit_tests.ml
@@ -179,11 +179,23 @@ module TestCount = struct
     let actual = QCheck.Test.get_count cell in
     Alcotest.(check int) "default count is from QCHECK_COUNT" 5 actual
 
+  let test_count_0 () = test_count_n ~count:0 0
+
+  let test_count_negative_fail () =
+    try
+      let _ = test_count_n ~count:(-1) (-1) in
+      Alcotest.fail "A negative count in a test should fail"
+    with
+    | _ -> ()
+
   let tests =
     ("Test.make ~count", Alcotest.[
          test_case "make with custom count" `Quick test_count_10;
          test_case "make with default count" `Quick test_count_default;
          test_case "make with env count" `Quick test_count_env;
+         test_case "make with 0 count" `Quick test_count_0;
+         test_case "make with negative count should fail"
+           `Quick test_count_negative_fail;
        ])
 end
 
@@ -205,12 +217,24 @@ module TestLongFactor = struct
     let actual = QCheck.Test.get_long_factor cell in
     Alcotest.(check int) "default long factor is from QCHECK_LONG_FACTOR" 5 actual
 
-  let tests =
-    ("Test.make ~long_factor", Alcotest.[
-         test_case "make with custom long_factor" `Quick test_long_factor_10;
-         test_case "make with default long_factor" `Quick test_long_factor_default;
-         test_case "make with env long_factor" `Quick test_long_factor_env;
-       ])
+   let test_long_factor_0 () = test_long_factor_n ~long_factor:0 0
+  
+   let test_long_factor_negative_fail () =
+     try
+       let _ = test_long_factor_n ~long_factor:(-1) (-1) in
+       Alcotest.fail "A negative long factor in a test should fail"
+     with
+     | _ -> ()
+  
+   let tests =
+     ("Test.make ~long_factor", Alcotest.[
+          test_case "make with custom long_factor" `Quick test_long_factor_10;
+          test_case "make with default long_factor" `Quick test_long_factor_default;
+          test_case "make with env long_factor" `Quick test_long_factor_env;
+          test_case "make with 0 long_factor" `Quick test_long_factor_0;
+          test_case "make with negative long_factor should fail"
+            `Quick test_long_factor_negative_fail;
+     ])
 end
 
 let () =