TheSpyder / rescript-fast-check

Home of bindings to fast-check

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to get working with `rescript-jest`?

quinn-dougherty opened this issue · comments

commented

The main bottleneck to working with rescript-jest is that propertyk functions expect predicates to return bool, whereas the Expect module from rescript-jest deals in the type Jest.assertion.

Are there any quick ideas to get up and running? Alternatively, what would a PR look like?

Edit: it doesn't look like there should be a bottleneck here because according to the examples expect works right out of the box with fast-check in javascript.

hmm, I don't use jest (I'm not really a fan) but I am aware the rescript-jest bindings enforce one assertion per test using types.

We can't make changes to rescript-fast-check to support this without adding rescript-jest as a dependency. Likewise I'm not sure a PR to support rescript-fast-check in rescript-jest is a good idea either.

A new project could be built around both rescript-fast-check and rescript-jest to adapt the types between projects (likely using %identity externals). A good foundation for this may be the jest support project created by the fast-check developer: jest-fast-check

Looking at jest-fast-check in a bit more detail, it still requires boolean property tests (using either === or .includes()). All it does is adapt the fc.assert function to make it easier to use as a jest test, in a manner similar to the assertProperty functions I created in these bindings.

This meshes with what I was thinking, that Expect assertions cannot be used inside property tests. Properties are for validation, not assertion.

So really the main thing you need is a way to convert my assertReturn and predicateReturn types to the rescript-jest Jest.assertion type. Which might be safe to do with an %identity external - certainly that's what jest-fast-check assumes.

commented

@TheSpyder My colleague @Hazelfire figured out that this dead simple strategy technically works, it raises failures when the property is incorrect.

open Jest

open FastCheck
open Arbitrary
open Property.Sync

// Code under test
let contains = (text, pattern) => text->Js.String2.indexOf(pattern) >= 0

// Properties
describe("properties", () => {
  // string text always contains itself
  test("should always contain itself", () => {
    assert_(property1(string(), text => contains(text, text)))
    pass
  })
  // string a + b + c always contains b, whatever the values of a, b and c
  test("should always contain its substrings", () => {
    assert_(
      property3(string(), string(), string(), (a, b, c) =>
        contains(a ++ b ++ c, b)
      )
    )
    pass
  })
})

That's a pretty good way to do it for sure. The only way to make that easier would be something that avoided the need for a pass after the assert_, but I don't think that would be worth the hassle.

Side note, instead of assert_(property1(string(), text => contains(text, text))) I added a shortcut method assertProperty1(string(), text => contains(text, text)) - and it has variations up to 5 values as well.