From 5e9c3f9a01c1e34cda9f7b3dc7fb4b0235fbaad6 Mon Sep 17 00:00:00 2001
From: Nipunn Koorapati <nipunn1313@gmail.com>
Date: Fri, 30 Jun 2023 14:16:14 -0700
Subject: [PATCH] Add ability to customize max default SizeRange via env var.

The implementation directly accesses Config::default() from
SizeRange::default().

I don't love the implementation for two reasons
- It clones the full config on every call to SizeRange::default()
- It is hard to test.

However, it does achieve the goal. I am open to better ideas!
---
 proptest/CHANGELOG.md              |  5 +++++
 proptest/src/collection.rs         |  8 +++++---
 proptest/src/test_runner/config.rs | 19 +++++++++++++++++++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/proptest/CHANGELOG.md b/proptest/CHANGELOG.md
index 5ee6cc26..2526c5ec 100644
--- a/proptest/CHANGELOG.md
+++ b/proptest/CHANGELOG.md
@@ -1,5 +1,10 @@
 ## Unreleased
 
+### New Features
+
+- Setting `PROPTEST_MAX_DEFAULT_SIZE_RANGE` now customizes the default `SizeRange`
+  used by the default strategies for collections (like `Vec`). The default remains 100.
+
 ## 1.2.0
 
 ### Breaking Changes
diff --git a/proptest/src/collection.rs b/proptest/src/collection.rs
index ce27991d..91f7b286 100644
--- a/proptest/src/collection.rs
+++ b/proptest/src/collection.rs
@@ -37,7 +37,8 @@ use crate::tuple::TupleValueTree;
 /// A value like `0..=std::usize::MAX` will still be accepted but will silently
 /// truncate the maximum to `std::usize::MAX - 1`.
 ///
-/// The `Default` is `0..100`.
+/// The `Default` is `0..PROPTEST_MAX_DEFAULT_SIZE_RANGE`. The max can be set with
+/// the `PROPTEST_MAX_DEFAULT_SIZE_RANGE` env var, which defaults to `100`.
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct SizeRange(Range<usize>);
 
@@ -47,9 +48,10 @@ pub fn size_range(from: impl Into<SizeRange>) -> SizeRange {
 }
 
 impl Default for SizeRange {
-    /// Constructs a `SizeRange` equivalent to `size_range(0..100)`.
+    /// Constructs a `SizeRange` equivalent to `size_range(0..PROPTEST_MAX_DEFAULT_SIZE_RANGE)`.
+    /// The max can be set with the `PROPTEST_MAX_DEFAULT_SIZE_RANGE` env var, which defaults to `100`.
     fn default() -> Self {
-        size_range(0..100)
+        size_range(0..Config::default().max_default_size_range)
     }
 }
 
diff --git a/proptest/src/test_runner/config.rs b/proptest/src/test_runner/config.rs
index 232de951..90c1f4e3 100644
--- a/proptest/src/test_runner/config.rs
+++ b/proptest/src/test_runner/config.rs
@@ -37,6 +37,8 @@ const MAX_FLAT_MAP_REGENS: &str = "PROPTEST_MAX_FLAT_MAP_REGENS";
 const MAX_SHRINK_TIME: &str = "PROPTEST_MAX_SHRINK_TIME";
 #[cfg(feature = "std")]
 const MAX_SHRINK_ITERS: &str = "PROPTEST_MAX_SHRINK_ITERS";
+#[cfg(feature = "std")]
+const MAX_DEFAULT_SIZE_RANGE: &str = "PROPTEST_MAX_DEFAULT_SIZE_RANGE";
 #[cfg(feature = "fork")]
 const FORK: &str = "PROPTEST_FORK";
 #[cfg(feature = "timeout")]
@@ -121,6 +123,12 @@ pub fn contextualize_config(mut result: Config) -> Config {
                 "u32",
                 MAX_SHRINK_ITERS,
             ),
+            MAX_DEFAULT_SIZE_RANGE => parse_or_warn(
+                &value,
+                &mut result.max_default_size_range,
+                "usize",
+                MAX_DEFAULT_SIZE_RANGE,
+            ),
             VERBOSE => {
                 parse_or_warn(&value, &mut result.verbose, "u32", VERBOSE)
             }
@@ -165,6 +173,7 @@ fn default_default_config() -> Config {
         #[cfg(feature = "std")]
         max_shrink_time: 0,
         max_shrink_iters: u32::MAX,
+        max_default_size_range: 100,
         result_cache: noop_result_cache,
         #[cfg(feature = "std")]
         verbose: 0,
@@ -331,6 +340,16 @@ pub struct Config {
     /// considered when the `std` feature is enabled, which it is by default.)
     pub max_shrink_iters: u32,
 
+    /// The default maximum size to `proptest::collection::SizeRange`. The default
+    /// strategy for collections (like `Vec`) use collections in the range of
+    /// `0..max_default_size_range`.
+    ///
+    /// The default is `100` which can be overridden by setting the
+    /// `PROPTEST_MAX_DEFAULT_SIZE_RANGE` environment variable. (The variable
+    /// is only considered when the `std` feature is enabled, which it is by
+    /// default.)
+    pub max_default_size_range: usize,
+
     /// A function to create new result caches.
     ///
     /// The default is to do no caching. The easiest way to enable caching is