Repository: dubzzz/fast-check
Pull request #1834 (2021-05-06 07:06:50)

🚚 Move `mapToConstant` arbitrary into /arbitrary
<!-- Why is this PR for? -->
<!-- Describe the reason why you opened this PR or give a link towards the associated issue. -->

## In a nutshell

❌ New feature
❌ Fix an issue
❌ Documentation improvement
✔️ Other: *please explain*

(✔️: yes, ❌: no)

## Potential impacts

No

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/1834/builds/127262) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 07ff1695d311436f4e8dcbdd2d0580d96bea95f9:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-6qo5x)| Configuration |
|[fast-check-examples](https://codesandbox.io/s/fast-check-examples-94zxg)| Configuration |

codecov[bot]: # [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1834?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) Report
> Merging [#1834](https://codecov.io/gh/dubzzz/fast-check/pull/1834?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) (07ff169) into [main](https://codecov.io/gh/dubzzz/fast-check/commit/07e0451ae0435a1da9bcddd6109cf3d0b61f09e2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) (07e0451) will **increase** coverage by `0.26%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dubzzz/fast-check/pull/1834/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/1834?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    #1834      +/-   ##
==========================================
+ Coverage   97.27%   97.53%   +0.26%     
==========================================
  Files         139      143       +4     
  Lines        3774     3851      +77     
  Branches      741      700      -41     
==========================================
+ Hits         3671     3756      +85     
+ Misses         99       91       -8     
  Partials        4        4              
```

| Flag | Coverage Δ | |
|---|---|---|
| unit-tests | `97.53% <100.00%> (+0.26%)` | :arrow_up: |
| unit-tests-10.x-Linux | `?` | |
| unit-tests-12.x-Linux | `?` | |
| unit-tests-14.x-Linux | `97.53% <100.00%> (+0.26%)` | :arrow_up: |

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/1834?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) | Coverage Δ | |
|---|---|---|
| [...itrary/\_internals/mappers/IndexToMappedConstant.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9faW50ZXJuYWxzL21hcHBlcnMvSW5kZXhUb01hcHBlZENvbnN0YW50LnRz) | `100.00% <100.00%> (ø)` | |
| [src/arbitrary/mapToConstant.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9tYXBUb0NvbnN0YW50LnRz) | `92.85% <100.00%> (ø)` | |
| [.../check/arbitrary/helpers/SpecificCharacterRange.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9oZWxwZXJzL1NwZWNpZmljQ2hhcmFjdGVyUmFuZ2UudHM=) | `100.00% <100.00%> (ø)` | |
| [src/fast-check-default.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2Zhc3QtY2hlY2stZGVmYXVsdC50cw==) | `100.00% <100.00%> (ø)` | |
| [src/arbitrary/string.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9zdHJpbmcudHM=) | `100.00% <0.00%> (ø)` | |
| [src/arbitrary/stringOf.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9zdHJpbmdPZi50cw==) | `100.00% <0.00%> (ø)` | |
| [src/arbitrary/hexaString.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9oZXhhU3RyaW5nLnRz) | `100.00% <0.00%> (ø)` | |
| [src/arbitrary/asciiString.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9hc2NpaVN0cmluZy50cw==) | `100.00% <0.00%> (ø)` | |
| [src/arbitrary/base64String.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9iYXNlNjRTdHJpbmcudHM=) | `100.00% <0.00%> (ø)` | |
| [src/arbitrary/string16bits.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN#diff-c3JjL2FyYml0cmFyeS9zdHJpbmcxNmJpdHMudHM=) | `100.00% <0.00%> (ø)` | |
| ... and [17 more](https://codecov.io/gh/dubzzz/fast-check/pull/1834/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1834?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/1834?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Nicolas+DUBIEN). Last update [07e0451...07ff169](https://codecov.io/gh/dubzzz/fast-check/pull/1834?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/_internals/mappers/IndexToMappedConstant.ts b/src/arbitrary/_internals/mappers/IndexToMappedConstant.ts
new file mode 100644
index 00000000..9450273f
--- /dev/null
+++ b/src/arbitrary/_internals/mappers/IndexToMappedConstant.ts
@@ -0,0 +1,13 @@
+/** @internal */
+export function indexToMappedConstantMapperFor<T>(
+  entries: { num: number; build: (idInGroup: number) => T }[]
+): (index: number) => T {
+  return function indexToMappedConstantMapper(choiceIndex: number): T {
+    let idx = -1;
+    let numSkips = 0;
+    while (choiceIndex >= numSkips) {
+      numSkips += entries[++idx].num;
+    }
+    return entries[idx].build(choiceIndex - numSkips + entries[idx].num);
+  };
+}
diff --git a/src/check/arbitrary/MapToConstantArbitrary.ts b/src/arbitrary/mapToConstant.ts
similarity index 77%
rename from src/check/arbitrary/MapToConstantArbitrary.ts
rename to src/arbitrary/mapToConstant.ts
index d4ecbb00..d61b715d 100644
--- a/src/check/arbitrary/MapToConstantArbitrary.ts
+++ b/src/arbitrary/mapToConstant.ts
@@ -1,5 +1,6 @@
-import { Arbitrary } from './definition/Arbitrary';
-import { nat } from '../../arbitrary/nat';
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { nat } from './nat';
+import { indexToMappedConstantMapperFor } from './_internals/mappers/IndexToMappedConstant';
 
 /** @internal */
 function computeNumChoices<T>(options: { num: number; build: (idInGroup: number) => T }[]): number {
@@ -34,12 +35,5 @@ function computeNumChoices<T>(options: { num: number; build: (idInGroup: number)
  */
 export function mapToConstant<T>(...entries: { num: number; build: (idInGroup: number) => T }[]): Arbitrary<T> {
   const numChoices = computeNumChoices(entries);
-  return nat(numChoices - 1).map((choice) => {
-    let idx = -1;
-    let numSkips = 0;
-    while (choice >= numSkips) {
-      numSkips += entries[++idx].num;
-    }
-    return entries[idx].build(choice - numSkips + entries[idx].num);
-  });
+  return nat({ max: numChoices - 1 }).map(indexToMappedConstantMapperFor(entries));
 }
diff --git a/src/check/arbitrary/helpers/SpecificCharacterRange.ts b/src/check/arbitrary/helpers/SpecificCharacterRange.ts
index 3a23a03b..41c65c14 100644
--- a/src/check/arbitrary/helpers/SpecificCharacterRange.ts
+++ b/src/check/arbitrary/helpers/SpecificCharacterRange.ts
@@ -1,7 +1,7 @@
 import { fullUnicode } from '../../../arbitrary/fullUnicode';
 import { Arbitrary } from '../definition/Arbitrary';
 import { frequency } from '../../../arbitrary/frequency';
-import { mapToConstant } from '../MapToConstantArbitrary';
+import { mapToConstant } from '../../../arbitrary/mapToConstant';
 
 /** @internal */
 const lowerCaseMapper = { num: 26, build: (v: number) => String.fromCharCode(v + 0x61) };
diff --git a/src/fast-check-default.ts b/src/fast-check-default.ts
index 6c165991..276b02cb 100644
--- a/src/fast-check-default.ts
+++ b/src/fast-check-default.ts
@@ -55,7 +55,7 @@ import { nat, NatConstraints } from './arbitrary/nat';
 import { ipV4, ipV4Extended, ipV6 } from './check/arbitrary/IpArbitrary';
 import { letrec } from './arbitrary/letrec';
 import { lorem, LoremConstraints } from './check/arbitrary/LoremArbitrary';
-import { mapToConstant } from './check/arbitrary/MapToConstantArbitrary';
+import { mapToConstant } from './arbitrary/mapToConstant';
 import { memo, Memo } from './arbitrary/memo';
 import { mixedCase, MixedCaseConstraints } from './arbitrary/mixedCase';
 import {


Test patch:
diff --git a/test/unit/check/arbitrary/MapToConstantArbitrary.spec.ts b/test/unit/arbitrary/MapToConstantArbitrary.spec.ts
similarity index 86%
rename from test/unit/check/arbitrary/MapToConstantArbitrary.spec.ts
rename to test/unit/arbitrary/MapToConstantArbitrary.spec.ts
index 183f0573..5a17afe6 100644
--- a/test/unit/check/arbitrary/MapToConstantArbitrary.spec.ts
+++ b/test/unit/arbitrary/MapToConstantArbitrary.spec.ts
@@ -1,10 +1,10 @@
 import * as prand from 'pure-rand';
-import * as fc from '../../../../lib/fast-check';
+import * as fc from '../../../lib/fast-check';
 
-import { mapToConstant } from '../../../../src/check/arbitrary/MapToConstantArbitrary';
-import { Random } from '../../../../src/random/generator/Random';
-import { minMax } from './generic/GenericArbitraryHelper';
-import { nat } from '../../../../src/arbitrary/nat';
+import { mapToConstant } from '../../../src/arbitrary/mapToConstant';
+import { Random } from '../../../src/random/generator/Random';
+import { minMax } from '../check/arbitrary/generic/GenericArbitraryHelper';
+import { nat } from '../../../src/arbitrary/nat';
 
 describe('MapToConstantArbitrary', () => {
   describe('mapToConstant', () => {