109 lines
2.4 KiB
JavaScript
109 lines
2.4 KiB
JavaScript
|
|
function throwError(message, info) {
|
|
const error = new Error(`AssertionError: ${ message }`);
|
|
error.code = "ERR_ASSERTION";
|
|
for (const key in info) { error[key] = info[key]; }
|
|
throw error;
|
|
}
|
|
|
|
export function equal(actual, expected, reason) {
|
|
if (actual == expected) { return; }
|
|
|
|
if (reason == null) { reason = `${ actual } == ${ expected }`; }
|
|
throwError(reason, { actual, expected, operator: "==" });
|
|
}
|
|
|
|
function isDeepEqual(actual, expected, memo) {
|
|
if (actual === expected) { return true; }
|
|
|
|
// One or both things aren't objects
|
|
if (actual === null || typeof(expected) !== 'object') {
|
|
if (expected === null || typeof(expected) !== 'object') {
|
|
return actual == expected;
|
|
}
|
|
|
|
return false;
|
|
|
|
} else if (expected === null || typeof(expected) !== 'object') {
|
|
return false;
|
|
}
|
|
|
|
if (Array.isArray(actual)) {
|
|
if (!Array.isArray(expected) || actual.length !== expected.length) {
|
|
return false;
|
|
}
|
|
|
|
for (let i = 0; i < actual.length; i++) {
|
|
if (!isDeepEqual(actual[i], expected[i])) { return false; }
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Object
|
|
const keysActual = Object.keys(actual).sort(), keysExpected = Object.keys(expected).sort();
|
|
if (!isDeepEqual(keysActual, keysExpected)) { return false; }
|
|
for (const key of keysActual) {
|
|
if (!isDeepEqual(actual[key], expected[key], memo)) { return false; }
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export function deepEqual(actual, expected, reason) {
|
|
const memo = [ ];
|
|
const isOk = isDeepEqual(actual, expected, memo);
|
|
if (!isOk) {
|
|
equal(actual, expected, reason);
|
|
}
|
|
}
|
|
|
|
export function ok(check, reason) {
|
|
equal(!!check, true, reason);
|
|
}
|
|
|
|
export function throws(func, checkFunc, reason) {
|
|
try {
|
|
func();
|
|
|
|
} catch (e) {
|
|
if (checkFunc(e)) { return; }
|
|
|
|
throwError(`The expected exception validation function returned false`, {
|
|
actual: e,
|
|
expected: checkFunc,
|
|
operation: "throws"
|
|
});
|
|
}
|
|
|
|
throwError("Missing expected exception", {
|
|
operator: "throws"
|
|
});
|
|
}
|
|
|
|
export async function rejects(func, checkFunc, reason) {
|
|
try {
|
|
if (func.then) {
|
|
await func;
|
|
} else {
|
|
await func();
|
|
}
|
|
} catch (e) {
|
|
if (checkFunc(e)) { return true; }
|
|
|
|
throwError(`The rejection validation function returned false`, {
|
|
actual: e,
|
|
expected: checkFunc,
|
|
operation: "throws"
|
|
});
|
|
}
|
|
|
|
throwError("Missing rejection", {
|
|
operation: "rejects"
|
|
});
|
|
}
|
|
|
|
export default {
|
|
equal, deepEqual, ok, rejects, throws
|
|
};
|