UNPKG

@zerothrow/expect

Version:

Shared test matcher logic for ZeroThrow Result types

142 lines 4.92 kB
// src/index.ts function isResult(value) { return value !== null && typeof value === "object" && "ok" in value && typeof value.ok === "boolean" && (value.ok === true ? "value" in value : "error" in value); } function formatError(error) { if (!error) return "undefined"; if (error instanceof Error) { const parts = [`${error.name}: ${error.message}`]; if ("code" in error) parts.push(`(code: ${error.code})`); return parts.join(" "); } if (typeof error === "object" && error !== null) { const obj = error; if ("code" in obj || "message" in obj) { const parts = []; if (obj["code"]) parts.push(`code: ${obj["code"]}`); if (obj["message"]) parts.push(`message: ${obj["message"]}`); return `{ ${parts.join(", ")} }`; } } return JSON.stringify(error); } function toBeOkMatcher(received, _context) { const pass = isResult(received) && received.ok === true; if (pass) { return { message: () => `expected Result not to be Ok, but it was Ok with value: ${JSON.stringify(received.value)}`, pass: true }; } else { const error = isResult(received) && !received.ok ? received.error : received; return { message: () => `expected Result to be Ok, but it was Err with error: ${formatError(error)}`, pass: false }; } } function toBeOkWithMatcher(received, expected, context) { if (!isResult(received)) { return { message: () => `expected Result type, but received ${typeof received}`, pass: false }; } if (!received.ok) { return { message: () => `expected Result to be Ok with value ${JSON.stringify(expected)}, but it was Err with error: ${formatError(received.error)}`, pass: false }; } const actual = received.value; const pass = context.equals(actual, expected); return { message: () => pass ? `expected Result not to be Ok with value ${JSON.stringify(expected)}` : `expected Result to be Ok with value ${JSON.stringify(expected)}, but was Ok with value ${JSON.stringify(actual)}`, pass }; } function toBeErrMatcher(received, _context) { const pass = isResult(received) && received.ok === false; if (pass) { return { message: () => `expected Result not to be Err, but it was Err with error: ${formatError(received.error)}`, pass: true }; } else { const value = isResult(received) && received.ok ? received.value : received; return { message: () => `expected Result to be Err, but it was Ok with value: ${JSON.stringify(value)}`, pass: false }; } } function toBeErrWithMatcher(received, expected, context) { if (!isResult(received)) { return { message: () => `expected Result type, but received ${typeof received}`, pass: false }; } if (received.ok) { return { message: () => `expected Result to be Err, but it was Ok with value: ${JSON.stringify(received.value)}`, pass: false }; } const actualError = received.error; let pass = false; if (expected instanceof Error) { pass = context.equals(actualError, expected); } else { pass = true; if (expected.code !== void 0 && actualError.code !== expected.code) { pass = false; } if (expected.message !== void 0 && actualError.message !== expected.message) { pass = false; } } return { message: () => pass ? `expected Result not to be Err with ${formatError(expected)}` : `expected Result to be Err with ${formatError(expected)}, but was Err with ${formatError(actualError)}`, pass }; } function toHaveErrorCodeMatcher(received, code) { if (!isResult(received) || received.ok) { return { message: () => `expected Result to be Err with code "${code}", but it was ${isResult(received) && received.ok ? "Ok" : "not a Result"}`, pass: false }; } const actualCode = received.error.code; const pass = actualCode === code; return { message: () => pass ? `expected Result not to have error code "${code}"` : `expected Result to have error code "${code}", but had "${actualCode}"`, pass }; } function toHaveErrorMessageMatcher(received, message) { if (!isResult(received) || received.ok) { return { message: () => `expected Result to be Err with message ${message}, but it was ${isResult(received) && received.ok ? "Ok" : "not a Result"}`, pass: false }; } const actualMessage = received.error.message; const pass = typeof message === "string" ? actualMessage === message : message.test(actualMessage); return { message: () => pass ? `expected Result not to have error message ${message}` : `expected Result to have error message ${message}, but had "${actualMessage}"`, pass }; } export { formatError, isResult, toBeErrMatcher, toBeErrWithMatcher, toBeOkMatcher, toBeOkWithMatcher, toHaveErrorCodeMatcher, toHaveErrorMessageMatcher }; //# sourceMappingURL=index.js.map