Repository: dubzzz/fast-check
Pull request #2701 (2022-02-01 19:34:56)

✨ Make ipV6 independent of size global settings
<!-- Context of the PR: short description and potentially linked issues -->

Related to #2648
<!-- ...a few words to describe the content of this PR...               -->
<!-- ... -->

<!-- Type of PR: [ ] unchecked / [ ] checked -->
**_Category:_**

- [x] ✨ Introduce new features
- [ ] 📝 Add or update documentation
- [ ] ✅ Add or update tests
- [ ] 🐛 Fix a bug
- [ ] 🏷️ Add or update types
- [ ] ⚡️ Improve performance
- [ ] _Other(s):_ ...
<!-- Don't forget to add the gitmoji icon in the name of the PR -->
<!-- See: https://gitmoji.dev/                                  -->

<!-- Fixing bugs, adding features... may impact existing ones           -->
<!-- in order to track potential issues that could be related to your PR -->
<!-- please check the impacts and describe more precisely what to expect -->

**_Potential impacts:_**

<!-- Generated values: Can your change impact any of the existing generators in terms of generated values, if so which ones? when? -->
<!-- Shrink values:    Can your change impact any of the existing generators in terms of shrink values, if so which ones? when? -->
<!-- Performance:      Can it require some typings changes on user side? Please give more details -->
<!-- Typings:          Is there a potential performance impact? In which cases? -->
- [ ] Generated values
- [ ] Shrink values
- [ ] Performance
- [ ] Typings
- [ ] _Other(s):_ ...


codesandbox[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/dubzzz/fast-check/pr/2701/builds/214268) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 6ba2162a93eedb33396f90035ba87132d03febbb:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-8bvh1)| Configuration |

codecov[bot]: # [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) Report
> Merging [#2701](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) (6ba2162) into [main](https://codecov.io/gh/dubzzz/fast-check/commit/cf07a7df9b023f2d2d02ab3898a56f90e75ffa14?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) (cf07a7d) will **decrease** coverage by `0.02%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dubzzz/fast-check/pull/2701/graphs/tree.svg?width=650&height=150&src=pr&token=fRi2fJN730&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN)](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN)

```diff
@@            Coverage Diff             @@
##             main    #2701      +/-   ##
==========================================
- Coverage   95.00%   94.98%   -0.03%     
==========================================
  Files         211      211              
  Lines        4905     4905              
  Branches      967      967              
==========================================
- Hits         4660     4659       -1     
- Misses        241      242       +1     
  Partials        4        4              
```

| Flag | Coverage Δ | |
|---|---|---|
| unit-tests | `94.98% <100.00%> (-0.03%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) | Coverage Δ | |
|---|---|---|
| [src/arbitrary/ipV6.ts](https://codecov.io/gh/dubzzz/fast-check/pull/2701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9pcFY2LnRz) | `100.00% <100.00%> (ø)` | |
| [src/arbitrary/\_internals/ArrayInt64Arbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/2701/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9faW50ZXJuYWxzL0FycmF5SW50NjRBcmJpdHJhcnkudHM=) | `93.18% <0.00%> (-1.14%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN). Last update [cf07a7d...6ba2162](https://codecov.io/gh/dubzzz/fast-check/pull/2701?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN).


Patch:
diff --git a/src/arbitrary/ipV6.ts b/src/arbitrary/ipV6.ts
index 35c620b4..04a3cd39 100644
--- a/src/arbitrary/ipV6.ts
+++ b/src/arbitrary/ipV6.ts
@@ -52,59 +52,78 @@ export function ipV6(): Arbitrary<string> {
   //               / [ *4( h16 ":" ) h16 ] "::"              ls32
   //               / [ *5( h16 ":" ) h16 ] "::"              h16
   //               / [ *6( h16 ":" ) h16 ] "::"
-  const h16Arb = hexaString({ minLength: 1, maxLength: 4 });
+
+  // Any size-based arbitrary called within the implementation of ipV6 has
+  // to be called with size:'max' in order to prevent any behaviour change
+  // related to global settings on size. ipV6 is fully independent of size
+  const h16Arb = hexaString({ minLength: 1, maxLength: 4, size: 'max' });
   const ls32Arb = oneof(
     convertFromNext(convertToNext(tuple(h16Arb, h16Arb)).map(h16sTol32Mapper, h16sTol32Unmapper)),
     ipV4()
   );
   return oneof(
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 6, maxLength: 6 }), ls32Arb)).map(
+      convertToNext(tuple(array(h16Arb, { minLength: 6, maxLength: 6, size: 'max' }), ls32Arb)).map(
         fullySpecifiedMapper,
         fullySpecifiedUnmapper
       )
     ),
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 5, maxLength: 5 }), ls32Arb)).map(
+      convertToNext(tuple(array(h16Arb, { minLength: 5, maxLength: 5, size: 'max' }), ls32Arb)).map(
         onlyTrailingMapper,
         onlyTrailingUnmapper
       )
     ),
     convertFromNext(
       convertToNext(
-        tuple(array(h16Arb, { minLength: 0, maxLength: 1 }), array(h16Arb, { minLength: 4, maxLength: 4 }), ls32Arb)
+        tuple(
+          array(h16Arb, { minLength: 0, maxLength: 1, size: 'max' }),
+          array(h16Arb, { minLength: 4, maxLength: 4, size: 'max' }),
+          ls32Arb
+        )
       ).map(multiTrailingMapper, multiTrailingUnmapper)
     ),
     convertFromNext(
       convertToNext(
-        tuple(array(h16Arb, { minLength: 0, maxLength: 2 }), array(h16Arb, { minLength: 3, maxLength: 3 }), ls32Arb)
+        tuple(
+          array(h16Arb, { minLength: 0, maxLength: 2, size: 'max' }),
+          array(h16Arb, { minLength: 3, maxLength: 3, size: 'max' }),
+          ls32Arb
+        )
       ).map(multiTrailingMapper, multiTrailingUnmapper)
     ),
     convertFromNext(
       convertToNext(
-        tuple(array(h16Arb, { minLength: 0, maxLength: 3 }), array(h16Arb, { minLength: 2, maxLength: 2 }), ls32Arb)
+        tuple(
+          array(h16Arb, { minLength: 0, maxLength: 3, size: 'max' }),
+          array(h16Arb, { minLength: 2, maxLength: 2, size: 'max' }),
+          ls32Arb
+        )
       ).map(multiTrailingMapper, multiTrailingUnmapper)
     ),
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 4 }), h16Arb, ls32Arb)).map(
+      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 4, size: 'max' }), h16Arb, ls32Arb)).map(
         multiTrailingMapperOne,
         multiTrailingUnmapperOne
       )
     ),
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 5 }), ls32Arb)).map(
+      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 5, size: 'max' }), ls32Arb)).map(
         singleTrailingMapper,
         singleTrailingUnmapper
       )
     ),
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 6 }), h16Arb)).map(
+      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 6, size: 'max' }), h16Arb)).map(
         singleTrailingMapper,
         singleTrailingUnmapper
       )
     ),
     convertFromNext(
-      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 7 }))).map(noTrailingMapper, noTrailingUnmapper)
+      convertToNext(tuple(array(h16Arb, { minLength: 0, maxLength: 7, size: 'max' }))).map(
+        noTrailingMapper,
+        noTrailingUnmapper
+      )
     )
   );
 }


Test patch:
diff --git a/test/unit/arbitrary/__test-helpers__/NextArbitraryAssertions.ts b/test/unit/arbitrary/__test-helpers__/NextArbitraryAssertions.ts
index c2588c0e..166991fd 100644
--- a/test/unit/arbitrary/__test-helpers__/NextArbitraryAssertions.ts
+++ b/test/unit/arbitrary/__test-helpers__/NextArbitraryAssertions.ts
@@ -3,7 +3,9 @@ import * as fc from '../../../../lib/fast-check';
 
 import { NextArbitrary } from '../../../../src/check/arbitrary/definition/NextArbitrary';
 import { NextValue } from '../../../../src/check/arbitrary/definition/NextValue';
+import { configureGlobal, readConfigureGlobal } from '../../../../src/check/runner/configuration/GlobalParameters';
 import { Random } from '../../../../src/random/generator/Random';
+import { sizeArb } from './SizeHelpers';
 
 // Minimal requirements
 // > The following assertions are supposed to be fulfilled by any of the arbitraries
@@ -220,6 +222,44 @@ export function assertProduceSomeSpecificValues<T, U = never>(
   expect(foundOne).toBe(true);
 }
 
+export function assertGenerateIndependentOfSize<T, U = never>(
+  arbitraryBuilder: (extraParameters: U) => NextArbitrary<T>,
+  options: {
+    isEqual?: (v1: T, v2: T, extraParameters: U) => void | boolean;
+    isEqualContext?: (c1: unknown, c2: unknown, extraParameters: U) => void | boolean;
+    extraParameters?: fc.Arbitrary<U>;
+    assertParameters?: fc.Parameters<unknown>;
+  } = {}
+): void {
+  const {
+    extraParameters = fc.constant(undefined as unknown as U) as fc.Arbitrary<U>,
+    isEqual,
+    isEqualContext,
+    assertParameters,
+  } = options;
+  assertGenerateEquivalentTo(
+    (extra) => arbitraryBuilder(extra.requested),
+    (extra) => {
+      const previousGlobal = readConfigureGlobal();
+      try {
+        configureGlobal(extra.global);
+        return arbitraryBuilder(extra.requested);
+      } finally {
+        configureGlobal(previousGlobal || {});
+      }
+    },
+    {
+      extraParameters: fc.record({
+        requested: extraParameters,
+        global: fc.record({ defaultSizeToMaxWhenMaxSpecified: fc.boolean(), baseSize: sizeArb }, { requiredKeys: [] }),
+      }),
+      isEqual: isEqual !== undefined ? (a, b, extra) => isEqual(a, b, extra.requested) : undefined,
+      isEqualContext: isEqualContext !== undefined ? (a, b, extra) => isEqualContext(a, b, extra.requested) : undefined,
+      assertParameters,
+    }
+  );
+}
+
 // Various helpers
 
 function randomFromSeed(seed: number): Random {
diff --git a/test/unit/arbitrary/ipV6.spec.ts b/test/unit/arbitrary/ipV6.spec.ts
index cf84cddc..90253904 100644
--- a/test/unit/arbitrary/ipV6.spec.ts
+++ b/test/unit/arbitrary/ipV6.spec.ts
@@ -7,6 +7,7 @@ import {
   assertShrinkProducesSameValueWithoutInitialContext,
   assertProduceCorrectValues,
   assertProduceSameValueGivenSameSeed,
+  assertGenerateIndependentOfSize,
 } from './__test-helpers__/NextArbitraryAssertions';
 import { buildNextShrinkTree, renderTree } from './__test-helpers__/ShrinkTree';
 
@@ -70,6 +71,10 @@ describe('ipV6 (integration)', () => {
     assertShrinkProducesSameValueWithoutInitialContext(ipV6Builder);
   });
 
+  it('should be independent of global settings overriding defaults on size', () => {
+    assertGenerateIndependentOfSize(ipV6Builder);
+  });
+
   it.each`
     source
     ${'::1'}