Repository: dubzzz/fast-check
Pull request #1602 (2021-03-11 22:16:16)

✨ Stricter checks on args of `fc.frequency`
<!-- 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

Can eventually break some invalid calls to `fc.frequency`. Actually those calls should result in runtime failures on generate or infinite loops.


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

Latest deployment of this branch, based on commit 2d5b537b4d3f89b4f31cd9dc7160178054578281:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-lwoxj)| Configuration |
|[fast-check-examples](https://codesandbox.io/s/fast-check-examples-ik7mm)| Configuration |

codecov[bot]: # [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=h1) Report
> Merging [#1602](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=desc) (2d5b537) into [main](https://codecov.io/gh/dubzzz/fast-check/commit/29b51e8740a617784f76c4155415f4714b62d704?el=desc) (29b51e8) will **decrease** coverage by `0.02%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dubzzz/fast-check/pull/1602/graphs/tree.svg?width=650&height=150&src=pr&token=fRi2fJN730)](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##             main    #1602      +/-   ##
==========================================
- Coverage   97.46%   97.44%   -0.03%     
==========================================
  Files          93       93              
  Lines        3195     3209      +14     
  Branches      619      622       +3     
==========================================
+ Hits         3114     3127      +13     
- Misses         77       78       +1     
  Partials        4        4              
```

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

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/check/arbitrary/FrequencyArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1602/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9GcmVxdWVuY3lBcmJpdHJhcnkudHM=) | `98.46% <100.00%> (+0.42%)` | :arrow_up: |
| [src/check/arbitrary/ArrayArbitrary.ts](https://codecov.io/gh/dubzzz/fast-check/pull/1602/diff?src=pr&el=tree#diff-c3JjL2NoZWNrL2FyYml0cmFyeS9BcnJheUFyYml0cmFyeS50cw==) | `93.54% <0.00%> (-1.08%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=footer). Last update [29b51e8...2d5b537](https://codecov.io/gh/dubzzz/fast-check/pull/1602?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/check/arbitrary/FrequencyArbitrary.ts b/src/check/arbitrary/FrequencyArbitrary.ts
index b7d4a647..a2214772 100644
--- a/src/check/arbitrary/FrequencyArbitrary.ts
+++ b/src/check/arbitrary/FrequencyArbitrary.ts
@@ -40,8 +40,15 @@ class FrequencyArbitrary<T> extends Arbitrary<T> {
     }
     let totalWeight = 0;
     for (let idx = 0; idx !== warbs.length; ++idx) {
+      const currentArbitrary = warbs[idx].arbitrary;
+      if (currentArbitrary === undefined) {
+        throw new Error('fc.frequency expects arbitraries to be specified');
+      }
       const currentWeight = warbs[idx].weight;
       totalWeight += currentWeight;
+      if (!Number.isInteger(currentWeight)) {
+        throw new Error('fc.frequency expects weights to be integer values');
+      }
       if (currentWeight < 0) {
         throw new Error('fc.frequency expects weights to be superior or equal to 0');
       }


Test patch:
diff --git a/test/unit/check/arbitrary/FrequencyArbitrary.utest.spec.ts b/test/unit/check/arbitrary/FrequencyArbitrary.utest.spec.ts
index 13570e1d..a1f06dc9 100644
--- a/test/unit/check/arbitrary/FrequencyArbitrary.utest.spec.ts
+++ b/test/unit/check/arbitrary/FrequencyArbitrary.utest.spec.ts
@@ -148,6 +148,14 @@ describe('FrequencyArbitrary', () => {
     it('Should reject calls without any weighted arbitraries', () => {
       expect(() => frequency()).toThrowError();
     });
+    it('Should reject calls without weight', () => {
+      expect(() => frequency({ arbitrary: stubArb.single(0), weight: undefined! })).toThrowError(
+        /expects weights to be integer values/
+      );
+    });
+    it('Should reject calls without arbitrary', () => {
+      expect(() => frequency({ arbitrary: undefined!, weight: 1 })).toThrowError(/expects arbitraries to be specified/);
+    });
     it('Should reject calls including at least one strictly negative weight', () =>
       fc.assert(
         fc.property(