@webaudiomodules/sdk
Version:
WebAudioModules Plugin SDK
126 lines (119 loc) • 4.79 kB
text/typescript
/* eslint-disable no-plusplus */
/// <reference path="jest.d.ts" />
type Expectation = 'toAllEqual'
| 'toAllBeGreaterThan' | 'toAllBeGreaterThanOrEqual'
| 'toAllBeLessThan' | 'toAllBeLessThanOrEqual'
| 'toAllIncrease' | 'toAllDecrease';
const comparators = {
'===': (a: number, b: number) => a === b,
'>=': (a: number, b: number) => a >= b,
'>': (a: number, b: number) => a > b,
'<=': (a: number, b: number) => a <= b,
'<': (a: number, b: number) => a < b,
};
/**
* Utility for validating / comparing array values.
* @param jest provides jest `MatcherContext` utilities
* @param expectation allows canonical formatting of console output
* @param received 'left-hand side' values
* @param expected 'right-hand side' value(s) if applicable
*/
function arrayExpectation(jest: jest.MatcherContext,
expectation: Expectation,
received: ArrayLike<number>,
expected?: number | ArrayLike<number>) {
if (expectation === 'toAllIncrease' || expectation === 'toAllDecrease') {
if (typeof expected !== 'undefined') throw Error('"expected" argument should not be present for "increase" or "decrease" validation.');
} else if (typeof expected !== 'number' && !expected) { throw Error('Missing "expected" argument.'); }
let pass = true;
let positiveString = '';
let negativeString = '';
/* eslint-disable-next-line */
let comparator = (a: number, b: number) => false;
switch (expectation) {
case 'toAllEqual':
positiveString = 'to equal';
negativeString = 'to not equal';
comparator = comparators['==='];
break;
case 'toAllBeGreaterThanOrEqual':
positiveString = 'to be greater than or equal to';
negativeString = 'to not be greater than or equal to';
comparator = comparators['>='];
break;
case 'toAllBeGreaterThan':
positiveString = 'to be greater than';
negativeString = 'to not be greater than';
comparator = comparators['>'];
break;
case 'toAllBeLessThanOrEqual':
positiveString = 'to be less than or equal to';
negativeString = 'to not be less than or equal to';
comparator = comparators['<='];
break;
case 'toAllBeLessThan':
positiveString = 'to be less than';
negativeString = 'to not be less than';
comparator = comparators['<'];
break;
case 'toAllIncrease':
positiveString = 'to increase';
negativeString = 'to not increase';
comparator = comparators['<'];
break;
case 'toAllDecrease':
positiveString = 'to decrease';
negativeString = 'to not decrease';
comparator = comparators['>'];
break;
default: break;
}
if (!received.length) throw Error(`Can only call ${expectation} on non-empty Array-like objects.`);
if (typeof expected !== 'number') {
if (expected) {
if (expected.length !== received.length) throw Error('Lengths must match when comparing to Array-like object.');
for (let i = 0; i < received.length; ++i) {
if (!comparator(received[i], expected[i])) {
pass = false;
break;
}
}
positiveString.concat('corresponding values of');
negativeString.concat('corresponding values of');
} else {
let previousValue = received[0];
for (let i = 1; i < received.length; ++i) {
const currentValue = received[i];
if (!comparator(previousValue, currentValue)) {
pass = false;
break;
}
previousValue = currentValue;
}
}
} else {
for (let i = 0; i < received.length; ++i) {
if (!comparator(received[i], expected)) {
pass = false;
break;
}
}
}
const differenceString = jest.utils.diff(expected, received, { expand: jest.expand });
const resultString = pass ? jest.utils.matcherHint(`.not.${expectation}`) : jest.utils.matcherHint(`.${expectation}`);
resultString.concat('\n\n', `Expected all values of ${jest.utils.printReceived(received)}`);
resultString.concat(`${pass ? positiveString : negativeString} ${jest.utils.printReceived(expected)}`);
if (differenceString) resultString.concat('\n\n', differenceString);
const message = () => resultString;
return { actual: received, message, pass };
}
expect.extend({
toAllEqual(received, expected) { return arrayExpectation(this, 'toAllEqual', received, expected); },
toAllBeGreaterThanOrEqual(received, expected) { return arrayExpectation(this, 'toAllBeGreaterThanOrEqual', received, expected); },
toAllBeGreaterThan(received, expected) { return arrayExpectation(this, 'toAllBeGreaterThan', received, expected); },
toAllBeLessThanOrEqual(received, expected) { return arrayExpectation(this, 'toAllBeLessThanOrEqual', received, expected); },
toAllBeLessThan(received, expected) { return arrayExpectation(this, 'toAllBeLessThan', received, expected); },
toAllIncrease(received) { return arrayExpectation(this, 'toAllIncrease', received); },
toAllDecrease(received) { return arrayExpectation(this, 'toAllDecrease', received); },
});
export default expect;