Binary function arbitrary for functions with various mathematical properties
See original GitHub issue🚀 Feature Request / Motivation
I’ve been using fast-check
’s fc.func(arb)
and fc.compareFunc()
arbitraries and they’ve been very useful because I frequently write functions that expect other functions as arguments!
However, sometimes I am testing a function that cannot accept any arbitrary function. Sometimes the function requires its input function to have certain mathematical properties. The ones I’ve run into most frequently are the following:
- Commutativity/Symmetry:
f(a, b) = f(b, a)
- Associativity:
f(f(a, b), c) = f(a, f(b, c))
Perhaps some new fc.binaryFunc(arb, { commutative: boolean, associative: boolean })
arbitrary could solve this problem.
Example
Using ava-fast-check
:
import { testProp, fc } from 'ava-fast-check'
const foldInSomeOrder = (array, initial, fn) => {
const copy = [...array]
for (let i = n - 1; i >= 1; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[copy[i], copy[j]] = [copy[j], copy[i]]
}
return array.reduce((a, b) => fn(a, b), initial)
}
testProp(
`foldInSomeOrder produces the same result as Array.prototype.reduce when the input function is commutative and associative`
[fc.array(fc.anything()), fc.anything(), fc.func(fc.anything(), { commutative: true, associative: true })],
(t, array, initial, fn) => {
t.deepEqual(
foldInSomeOrder(array, initial, fn),
array.reduce((a, b) => fn(a, b), initial)
)
}
)
In this case the function must be both commutative and associative, but there are situations where they are not both required.
I have some ideas for how to implement this functionality so I’d be happy to make a PR if you think this would be useful.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:9 (9 by maintainers)
Top GitHub Comments
At least for the
commutative
option, something like this is probably sufficient (assuming everything else is the same what you have for the currentfc.func(arb)
arbitrary):I’m still trying to wrap my head around how you’d ensure associativity… I’ll let you know if I think of anything.
No, it passed fine. But I may have been lucky 😅