feat(object): add toHaveOwnProperty method and improve property-path matching in object assertions
This commit is contained in:
parent
0d3d498240
commit
0351da2878
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-04-30 - 2.4.0 - feat(object)
|
||||
add toHaveOwnProperty method and improve property-path matching in object assertions
|
||||
|
||||
- Added 'toHaveOwnProperty' as a direct method on Assertion to check for own properties
|
||||
- Enhanced property path evaluation in 'toHaveProperty' to handle nested keys more robustly
|
||||
- Renamed test file to maintain consistent naming for expect.any tests
|
||||
- Introduced scratch.js for manual testing and debugging of property matchers
|
||||
|
||||
## 2025-04-30 - 2.3.3 - fix(tests)
|
||||
Fix test file naming inconsistencies
|
||||
|
||||
|
16
scratch.js
Normal file
16
scratch.js
Normal file
@ -0,0 +1,16 @@
|
||||
import * as smartexpect from './dist_ts/index.js';
|
||||
class Foo { constructor(){ this.foo='bar'; } }
|
||||
console.log('foo in instance:', 'foo' in new Foo());
|
||||
console.log('hasOwn foo:', Object.prototype.hasOwnProperty.call(new Foo(), 'foo'));
|
||||
try {
|
||||
smartexpect.expect(new Foo()).object.toHaveProperty('foo');
|
||||
console.log('toHaveProperty passed');
|
||||
} catch (err) {
|
||||
console.error('toHaveProperty failed:', err.message);
|
||||
}
|
||||
try {
|
||||
smartexpect.expect(new Foo()).object.toHaveOwnProperty('foo');
|
||||
console.log('toHaveOwnProperty passed');
|
||||
} catch (err) {
|
||||
console.error('toHaveOwnProperty failed:', err.message);
|
||||
}
|
@ -2,7 +2,9 @@ import { tap, expect as tExpect } from '@push.rocks/tapbundle';
|
||||
import * as smartexpect from '../dist_ts/index.js';
|
||||
|
||||
tap.test('toHaveProperty nested path via dot notation', async () => {
|
||||
const testObject = { level1: { level2: { level3: 'value' } } };
|
||||
const testObject = { level1: { level2: { level3: 'value' }}, publicTest: 'hi' };
|
||||
|
||||
smartexpect.expect(testObject).object.toHaveProperty('publicTest');
|
||||
// Existence check
|
||||
smartexpect.expect(testObject).object.toHaveProperty('level1.level2.level3');
|
||||
// Value check
|
||||
@ -11,4 +13,4 @@ tap.test('toHaveProperty nested path via dot notation', async () => {
|
||||
smartexpect.expect(testObject).not.object.toHaveProperty('level1.level2.missing');
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
export default tap.start();
|
||||
|
@ -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.'
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user