function checkNear(actual, expected, range) { if( typeof expected !== 'number' || typeof range !== 'number' || range < 0 ) { throw new Error( 'Invalid toBeNear(' + expected + ',' + range + ')' ); } if(typeof actual !== 'number') { throw new Error('Expected a number, got ' + actual); } return Math.abs(actual - expected) <= range; } beforeAll(() => { jasmine.addMatchers({ toBeNear: () => ({ compare: (actual, expected, range) => { if(Array.isArray(expected)) { if(typeof actual !== 'object') { throw new Error('Expected an array, got ' + actual); } if(actual.length !== expected.length) { throw new Error( 'Expected an array of size ' + expected.length + ', got ' + actual ); } for(let i = 0; i < expected.length; ++ i) { if(!checkNear(actual[i], expected[i], range)) { return {pass: false}; } } return {pass: true}; } return {pass: checkNear(actual, expected, range)}; }, }), }); });