fantasyland / fantasy-laws

Property-based tests for FL-compatible ADTs
MIT License
33 stars 4 forks source link

Support asynchronous equality functions #13

Closed Avaq closed 5 years ago

Avaq commented 5 years ago

Testing the algebraic properties of Fluture could be done more robustly when the FutureArb's I'm passing are possibly asynchronous.

JSVerify supports async properties (handles returned Promises), and since it's already possible to customize the equals function such that it returns a Promise, the only missing element to make things work with Fantasy Laws is to return the result from jsc.assert.

This change ensures that jsverify's Promises are passed down, so that they can be handled by the party receiving them.

Avaq commented 5 years ago

Note that in Fantasy Laws' source it's not very explicit that the equals functions might return a Promise. It is in fact a lucky coincidence of the call the equals always being in the tail position of a Boolean expression, for example:

https://github.com/fantasyland/fantasy-laws/blob/52dc6fba5670241a2656d7f12a65711c462e34d3/src/Alt.js#L14-L20

We might want to modify these expressions to be more explicit, for example:

associativity: assert.forall3 (function(a, b, c) { 
  if (Z.Alt.test (a) && Z.Alt.test (b) && Z.Alt.test (c)) {
    return equals (alt (alt (a) (b)) (c), 
                   alt (a) (alt (b) (c))); 
  }
  throw new Error('Expected all three Arbitraries to provide Alts');
}),

Although I'm not sure about the rationale behind performing these type checks to begin with; It's only done to Arbitraries where we expect instances of some type class, for Arbitrary functions we don't do these checks, for example, a and b are checked, but f is not:

https://github.com/fantasyland/fantasy-laws/blob/52dc6fba5670241a2656d7f12a65711c462e34d3/src/Alt.js#L23-L28