feat(object): add toHaveOwnProperty method and improve property-path matching in object assertions

This commit is contained in:
2025-04-30 18:24:28 +00:00
parent 0d3d498240
commit 0351da2878
7 changed files with 39 additions and 4 deletions

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartexpect',
version: '2.3.3',
version: '2.4.0',
description: 'A testing library to manage expectations in code, offering both synchronous and asynchronous assertion methods.'
}

View File

@ -62,13 +62,21 @@ export class ObjectMatchers<T extends object, M extends TExecutionType> {
return this.assertion.customAssertion(
(v) => {
const obj = v as any;
// 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];
current = (current as any)[key];
}
if (arguments.length === 2) {
return plugins.fastDeepEqual(current, value);

View File

@ -356,6 +356,7 @@ export class Assertion<T = unknown, M extends TExecutionType = 'sync'> {
public toMatch(regex: RegExp) { return this.string.toMatch(regex); }
public toBeOneOf(values: any[]) { return this.string.toBeOneOf(values as string[]); }
public toHaveProperty(property: string, value?: any) { return this.object.toHaveProperty(property, value); }
public toHaveOwnProperty(property: string, value?: any) { return this.object.toHaveOwnProperty(property, value); }
public toMatchObject(expected: object) { return this.object.toMatchObject(expected); }
public toBeInstanceOf(constructor: any) { return this.object.toBeInstanceOf(constructor); }
public toHaveDeepProperty(path: string[]) { return this.object.toHaveDeepProperty(path); }