Repository: dubzzz/fast-check
Pull request #904 (2020-08-19 07:09:15)

🐛 Asynchrorous properties should be able to use `asyncReporter`
A typo introduced into the codebase made users unable to to use the `asyncReporter` with asynchronous properties... but not with synchronous ones.

<!-- 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

If users set an `asyncReporter` onto a synchronous properties the code will fails now (but actually, not failing was a mistake).


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

Latest deployment of this branch, based on commit 5416d9700bc2e4f21740639665acb8db6f02d5cb:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-b1y9x)| Configuration |
|[dubzzz/fast-check: example](https://codesandbox.io/s/dubzzzfast-check-example-vfnhy)| Configuration |

coveralls: 
[![Coverage Status](https://coveralls.io/builds/32851368/badge)](https://coveralls.io/builds/32851368)

Coverage increased (+0.2%) to 96.136% when pulling **5416d9700bc2e4f21740639665acb8db6f02d5cb on fix-reporter-bug** into **cdc60cd14d1e47d009d29699e979178634f9e552 on master**.


Patch:
diff --git a/src/check/runner/Runner.ts b/src/check/runner/Runner.ts
index 44bf3422..d94b0fa1 100644
--- a/src/check/runner/Runner.ts
+++ b/src/check/runner/Runner.ts
@@ -121,7 +121,7 @@ function check<Ts>(rawProperty: IRawProperty<Ts>, params?: Parameters<Ts>) {
   });
   if (qParams.reporter !== null && qParams.asyncReporter !== null)
     throw new Error('Invalid parameters encountered, reporter and asyncReporter cannot be specified together');
-  if (qParams.asyncReporter !== null && rawProperty.isAsync())
+  if (qParams.asyncReporter !== null && !rawProperty.isAsync())
     throw new Error('Invalid parameters encountered, only asyncProperty can be used when asyncReporter specified');
   const property = decorateProperty(rawProperty, qParams);
   const generator = toss(property, qParams.seed, qParams.randomType, qParams.examples);


Test patch:
diff --git a/test/unit/check/runner/Runner.spec.ts b/test/unit/check/runner/Runner.spec.ts
index 311467cd..7a1b355c 100644
--- a/test/unit/check/runner/Runner.spec.ts
+++ b/test/unit/check/runner/Runner.spec.ts
@@ -22,6 +22,50 @@ describe('Runner', () => {
     it('Should throw if property is an Arbitrary', () => {
       expect(() => check((char() as any) as IRawProperty<unknown>)).toThrowError();
     });
+    it.each`
+      isAsync
+      ${false}
+      ${true}
+    `('Should throw if both reporter and asyncReporter are defined (isAsync: $isAsync)', ({ isAsync }) => {
+      const p: IRawProperty<[number]> = {
+        isAsync: () => isAsync,
+        generate: () => new Shrinkable([0]),
+        run: () => null,
+      };
+      expect(() => check(p, { reporter: () => {}, asyncReporter: async () => {} })).toThrowError();
+    });
+    it('Should not throw if reporter is specified on synchronous properties', () => {
+      const p: IRawProperty<[number]> = {
+        isAsync: () => false,
+        generate: () => new Shrinkable([0]),
+        run: () => null,
+      };
+      expect(() => check(p, { reporter: () => {} })).not.toThrowError();
+    });
+    it('Should not throw if reporter is specified on asynchronous properties', () => {
+      const p: IRawProperty<[number]> = {
+        isAsync: () => true,
+        generate: () => new Shrinkable([0]),
+        run: () => null,
+      };
+      expect(() => check(p, { reporter: () => {} })).not.toThrowError();
+    });
+    it('Should throw if asyncReporter is specified on synchronous properties', () => {
+      const p: IRawProperty<[number]> = {
+        isAsync: () => false,
+        generate: () => new Shrinkable([0]),
+        run: () => null,
+      };
+      expect(() => check(p, { asyncReporter: async () => {} })).toThrowError();
+    });
+    it('Should not throw if asyncReporter is specified on asynchronous properties', () => {
+      const p: IRawProperty<[number]> = {
+        isAsync: () => true,
+        generate: () => new Shrinkable([0]),
+        run: () => null,
+      };
+      expect(() => check(p, { asyncReporter: async () => {} })).not.toThrowError();
+    });
     it('Should call the property 100 times by default (on success)', () => {
       let numCallsGenerate = 0;
       let numCallsRun = 0;