@push.rocks/smartexpect
Version:
A testing library to manage expectations in code, offering both synchronous and asynchronous assertion methods.
135 lines • 12.6 kB
JavaScript
import { Assertion, AnyMatcher, AnythingMatcher } from '../smartexpect.classes.assertion.js';
import * as plugins from '../plugins.js';
/**
* Namespace for object-specific matchers
*/
export class ObjectMatchers {
constructor(assertion) {
this.assertion = assertion;
}
toEqual(expected) {
return this.assertion.customAssertion((v) => plugins.fastDeepEqual(v, expected), (v) => `Expected objects to be deeply equal to ${JSON.stringify(expected, null, 2)}` +
`\nReceived: ${JSON.stringify(v, null, 2)}`);
}
toMatchObject(expected) {
return this.assertion.customAssertion((v) => {
const obj = v;
for (const key of Object.keys(expected)) {
const expectedVal = expected[key];
const actualVal = obj[key];
if (expectedVal instanceof AnyMatcher) {
const ctor = expectedVal.expectedConstructor;
if (ctor === Number) {
if (typeof actualVal !== 'number')
return false;
}
else if (ctor === String) {
if (typeof actualVal !== 'string')
return false;
}
else if (ctor === Boolean) {
if (typeof actualVal !== 'boolean')
return false;
}
else {
if (!(actualVal instanceof ctor))
return false;
}
}
else if (expectedVal instanceof AnythingMatcher) {
if (actualVal === null || actualVal === undefined) {
return false;
}
}
else if (!plugins.fastDeepEqual(actualVal, expectedVal)) {
return false;
}
}
return true;
}, (v) => `Expected object to match properties ${JSON.stringify(expected, null, 2)}` +
`\nReceived: ${JSON.stringify(v, null, 2)}`);
}
toBeInstanceOf(constructor) {
return this.assertion.customAssertion((v) => v instanceof constructor, `Expected object to be instance of ${constructor.name || constructor}`);
}
toHaveProperty(property, value) {
return this.assertion.customAssertion((v) => {
const obj = v;
// first check for a literal property (including inherited)
if (property in obj) {
if (arguments.length === 2) {
return plugins.fastDeepEqual(obj[property], value);
}
return true;
}
// no direct key, try nested path via dot notation
const path = property.split('.');
let current = obj;
for (const key of path) {
if (current == null || !(key in current)) {
return false;
}
current = current[key];
}
if (arguments.length === 2) {
return plugins.fastDeepEqual(current, value);
}
return true;
}, `Expected object to have property ${property}${value !== undefined ? ` with value ${JSON.stringify(value)}` : ''}`);
}
toHaveDeepProperty(path) {
return this.assertion.customAssertion((v) => {
let obj = v;
for (const key of path) {
if (obj == null || !(key in obj)) {
return false;
}
obj = obj[key];
}
return true;
}, `Expected object to have deep property path ${JSON.stringify(path)}`);
}
toBeNull() {
return this.assertion.customAssertion((v) => v === null, `Expected value to be null`);
}
toBeUndefined() {
return this.assertion.customAssertion((v) => v === undefined, `Expected value to be undefined`);
}
toBeNullOrUndefined() {
return this.assertion.customAssertion((v) => v === null || v === undefined, `Expected value to be null or undefined`);
}
/**
* Checks own property only (not inherited)
*/
toHaveOwnProperty(property, value) {
return this.assertion.customAssertion((v) => {
const obj = v;
if (!Object.prototype.hasOwnProperty.call(obj, property)) {
return false;
}
if (arguments.length === 2) {
return plugins.fastDeepEqual(obj[property], value);
}
return true;
}, (v) => `Expected object to have own property ${property}` +
(value !== undefined ? ` with value ${JSON.stringify(value)}` : ``) +
`\nReceived: ${JSON.stringify(v, null, 2)}`);
}
/**
* Assert object has the given keys (including inherited properties).
* @param keys Array of keys to check for presence.
*/
toHaveKeys(keys) {
return this.assertion.customAssertion((v) => keys.every((key) => key in v), (v) => `Expected object to have keys ${JSON.stringify(keys)}` +
`\nReceived keys: ${JSON.stringify(Object.keys(v), null, 2)}`);
}
/**
* Assert object has the given own keys (excluding inherited properties).
* @param keys Array of own keys to check.
*/
toHaveOwnKeys(keys) {
return this.assertion.customAssertion((v) => keys.every((key) => Object.prototype.hasOwnProperty.call(v, key)), (v) => `Expected object to have own keys ${JSON.stringify(keys)}` +
`\nReceived own keys: ${JSON.stringify(Object.keys(v), null, 2)}`);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvbmFtZXNwYWNlcy9vYmplY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFN0YsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUN6QixZQUFvQixTQUEwQjtRQUExQixjQUFTLEdBQVQsU0FBUyxDQUFpQjtJQUFHLENBQUM7SUFFbEQsT0FBTyxDQUFDLFFBQWE7UUFDbkIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FDbkMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUN6QyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ0osMENBQTBDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRTtZQUM3RSxlQUFlLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUM5QyxDQUFDO0lBQ0osQ0FBQztJQUVELGFBQWEsQ0FBQyxRQUFnQjtRQUM1QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUNuQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ0osTUFBTSxHQUFHLEdBQUcsQ0FBUSxDQUFDO1lBQ3JCLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUN4QyxNQUFNLFdBQVcsR0FBSSxRQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzNCLElBQUksV0FBVyxZ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