UNPKG

@qavajs/validation

Version:

Lib that transform plain english definition to validation functions

139 lines 5.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.expect = exports.Expect = exports.SoftAssertionError = exports.AssertionError = void 0; const node_util_1 = __importDefault(require("node:util")); class AssertionError extends Error { name = 'AssertionError'; } exports.AssertionError = AssertionError; class SoftAssertionError extends AssertionError { name = 'SoftAssertionError'; } exports.SoftAssertionError = SoftAssertionError; const customMatchers = {}; class Expect { received; isSoft = false; isPoll = false; pollConfiguration = { timeout: 5000, interval: 100 }; isNot = false; constructor(received, configuration) { this.received = received; this.isSoft = configuration?.soft ?? false; this.isPoll = configuration?.poll ?? false; this.isNot = configuration?.not ?? false; } /** * Negates matcher */ get not() { this.isNot = true; return this; } /** * Enables soft matcher */ get soft() { this.isSoft = true; return this; } get Error() { return this.isSoft ? SoftAssertionError : AssertionError; } poll({ timeout, interval } = {}) { if (typeof this.received !== 'function') { throw new TypeError('Provided value must be a function'); } this.isPoll = true; this.pollConfiguration.timeout = timeout ?? 5000; this.pollConfiguration.interval = interval ?? 100; return this; } configure(options) { this.isNot = options.not ?? this.isNot; this.isSoft = options.soft ?? this.isSoft; this.isPoll = options.poll ?? this.isPoll; this.pollConfiguration.timeout = options.timeout ?? this.pollConfiguration.timeout; this.pollConfiguration.interval = options.interval ?? this.pollConfiguration.interval; return this; } /** * Format error message * @param received * @param expected * @param assert * @param isNot */ formatMessage(received, expected, assert, isNot) { return `expected ${this.asString(received)} ${isNot ? 'not ' : ''}${assert} ${this.asString(expected)}`; } asString(value) { if (typeof value === 'function') return value.toString(); return node_util_1.default.inspect(value, { depth: 1, compact: true }); } ; } exports.Expect = Expect; function createExpect() { function expect(target) { const instance = new Expect(target); const sleep = (ms) => new Promise(res => setTimeout(res, ms)); return new Proxy(instance, { get(target, prop, receiver) { if (prop in target) return Reflect.get(target, prop, receiver); const matcher = customMatchers[prop]; if (!matcher) throw new TypeError(`${prop} matcher not found`); return (...expected) => { if (target.isPoll) { return (async () => { const { timeout, interval } = target.pollConfiguration; const start = Date.now(); while (true) { try { const pollTarget = Object.create(target); pollTarget.received = await target.received(); const { pass, message } = await matcher.call(pollTarget, ...expected); if (target.isNot !== pass) return; if (Date.now() - start >= timeout) { throw new target.Error(message); } } catch (err) { if (Date.now() - start >= timeout) throw err; } await sleep(interval); } })(); } const result = matcher.call(target, ...expected); if (result instanceof Promise) { return result.then(({ pass, message }) => { if (target.isNot === pass) throw new target.Error(message); }); } else { const { pass, message } = result; if (target.isNot === pass) throw new target.Error(message); } }; }, }); } expect.extend = function (matchers) { Object.assign(customMatchers, matchers); return createExpect(); }; return expect; } exports.expect = createExpect(); //# sourceMappingURL=expect.js.map