leebyron / testcheck-js

Generative testing for JavaScript

Home Page:http://leebyron.com/testcheck-js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

property function issue with throws assertion

RiftLurker opened this issue · comments

According to the TypeScript declarations the property function of property allows to return void. The documentation and the JSDoc right above it say it should return true or false, so this is a bit of an inconsistency.

export function property<A>(
genA: ValueGenerator<A>,
f: (a: A) => boolean | void
): Property<[A]>;

Unfortunate this results in some unexpected behaviour when using the throws assertion from chai. In this example I'm explicitly not using mocha-testcheck, despite working in a mocha workspace, partially to properly show the issue, but also because no TypeScript declarations exist for that package yet.

describe('testcheck issue reproduction', () => {
  it('should throw an error', () => {
    const checkResult = check(
      property(
        gen.undefined,
        () => chai.assert.throws(() => { // (1)
          throw new Error(); // (2)
        }),
      ),
    );

    assert.isTrue(checkResult.result); // (3)
  });
});

The property function at (1) is an arrow function returning the result of chai.assert.throws which is void. According to the TypeScript declarations this is absolutely valid.
The tested function at (2) throws an error and therefore confirms the assertion at (1).

Expected behaviour
The checkResult.result at (3) should be true since the assertion was successful and the property function completed.
Actual behaviour
The checkResult.result at (3) contains an Error and the assertion fails.

Additional information
The arrow function returning void work perfectly fine with any of my other assertions, but throws seems to have some issues.

Solutions
Easiest would be to remove the void return type from the TypeScript declarations, although this might break some code and removes the ability to create simple property arrow function and requires us to change the arrow function at (1) to return true at the end of it:

        () => {
          assert.throws(() => {
            throw new Error();
          });
          return true;
        },

Alternatively testcheck could interpret undefined returned by the property function just like it would do with true.