-
-
Notifications
You must be signed in to change notification settings - Fork 200
Open
Description
💡 Idea
Generates pairs of natural numbers.
You can constrain the maximum ratio between the numbers in either or
both directions. By default, zero is allowed in either or both
positions, but can be prevented with noZeroDenom.
Motivation
I developed this to help test code that was using setInterval. My code needs to support arbitrary intervals for an arbitrarily long time. To limit test execution time, I needed to enforce a maximum number of times the interval code would execute.
Are you interested in this function?
Example
const arbTestTiming = simpleFraction({ inverseMin: maxTestedIntervals })
it.only.prop([fc.scheduler(), arbTestTiming])(
'should poll at the interval',
async (scheduler, [interval, elapsed]) => {
const poll = jest.fn().mockImplementation(() =>
scheduler.schedule(Promise.resolve()),
);
const pm = new PolledValue<void>(poll, interval);
try {
poll.mockClear();
await jest.advanceTimersByTimeAsync(elapsed);
expect(poll).toHaveBeenCalledTimes(Math.floor(elapsed / interval));
} finally {
await endAndWait(pm);
}
},
);Implementation
/** Generates pairs of natural numbers.
*
* You can constrain the maximum ratio between the numbers in either or
* both directions. By default, zero is allowed in either or both
* positions, but can be prevented with `noZeroDenom`.
* */
function simpleFraction(constraints?: SimpleFractionConstraints) {
if (constraints?.inverseMin < 0) {
throw new Error(`Expected positive inverseMin; got ${constraints.inverseMin}`)
} else if (constraints?.max < 0) {
throw new Error(`Expected positive max; got ${constraints.max}`)
}
return fc.tuple(fc.nat(), fc.nat())
.filter(([, den]) => !(constraints?.noZeroDenom) || den !== 0)
.map(([num, den]) => [
constraints?.max ? Math.min(num, den * constraints.max) : num,
constraints?.inverseMin ? Math.min(den, num * constraints.inverseMin) : den,
]);
}
interface SimpleFractionConstraints {
/**
* Maximum ratio between the numerator and the denominator.
* Set higher to get bigger fractions.
* */
max?: number,
/**
* Maximum ratio between the denominator and the numerator. Set higher
* to get smaller fractions.
* */
inverseMin?: number,
/**
* Allow values with a zero denominator. Defaults to **true**.
*/
noZeroDenom?: boolean,
}Metadata
Metadata
Assignees
Labels
No labels