diff --git a/changelog.md b/changelog.md index 92215f5..450aead 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2025-04-30 - 2.4.1 - fix(Assertion) +Improve toHaveProperty alias by forwarding arguments correctly for intuitive object property assertions + +- Updated the toHaveProperty method in the Assertion class to check the number of arguments and call the appropriate object matcher +- Added several scratch alias files to demonstrate and test the alias usage +- Enhanced test cases in test/propertypath to cover alias behavior + ## 2025-04-30 - 2.4.0 - feat(object) add toHaveOwnProperty method and improve property-path matching in object assertions diff --git a/scratch-alias.js b/scratch-alias.js new file mode 100644 index 0000000..34bf04a --- /dev/null +++ b/scratch-alias.js @@ -0,0 +1,14 @@ +import * as smartexpect from './dist_ts/index.js'; +const obj = { topLevel: 'hello' }; +try { + smartexpect.expect(obj).toHaveProperty('topLevel'); + console.log('alias toHaveProperty succeeded'); +} catch(err) { + console.error('alias toHaveProperty failed:', err.message); +} +try { + smartexpect.expect(obj).not.toHaveProperty('missing'); + console.log('alias not.toHaveProperty succeeded'); +} catch(err) { + console.error('alias not.toHaveProperty failed:', err.message); +} diff --git a/scratch-alias2.js b/scratch-alias2.js new file mode 100644 index 0000000..f0e7c55 --- /dev/null +++ b/scratch-alias2.js @@ -0,0 +1,20 @@ +import * as smartexpect from './dist_ts/index.js'; +console.log('script start'); +const obj = { topLevel: 'hello' }; +console.log('script: after obj'); +console.log('script: test for alias toHaveProperty'); +try { + smartexpect.expect(obj).toHaveProperty('topLevel'); + console.log('alias toHaveProperty succeeded'); +} catch(err) { + console.error('alias toHaveProperty failed:', err.message); +} +console.log('script: after first try'); +console.log('script: test for alias not.toHaveProperty'); +try { + smartexpect.expect(obj).not.toHaveProperty('missing'); + console.log('alias not.toHaveProperty succeeded'); +} catch(err) { + console.error('alias not.toHaveProperty failed:', err.message); +} +console.log('script end'); diff --git a/scratch-alias3.js b/scratch-alias3.js new file mode 100644 index 0000000..9c2acc1 --- /dev/null +++ b/scratch-alias3.js @@ -0,0 +1,8 @@ +import * as smartexpect from './dist_ts/index.js'; +console.log('script start'); +const obj = { topLevel: 'hello' }; +console.log('script: test alias toHaveProperty'); +const ret = smartexpect.expect(obj).toHaveProperty('topLevel'); +console.log('got ret:', ret, 'typeof', typeof ret); +console.log('ret.then?', ret && typeof (ret as any).then); +console.log('script end'); diff --git a/scratch-alias4.js b/scratch-alias4.js new file mode 100644 index 0000000..8a0a5d3 --- /dev/null +++ b/scratch-alias4.js @@ -0,0 +1,8 @@ +import * as smartexpect from './dist_ts/index.js'; +console.log('script start'); +const obj = { topLevel: 'hello' }; +console.log('script: test alias toHaveProperty'); +const ret = smartexpect.expect(obj).toHaveProperty('topLevel'); +console.log('got ret:', ret, 'typeof', typeof ret); +console.log('ret.then?', ret && ret.then); +console.log('script end'); diff --git a/scratch-alias5.js b/scratch-alias5.js new file mode 100644 index 0000000..da1e61e --- /dev/null +++ b/scratch-alias5.js @@ -0,0 +1,10 @@ +import * as smartexpect from './dist_ts/index.js'; +console.log('start'); +const obj = { topLevel: 'hello' }; +try { + smartexpect.expect(obj).toHaveProperty('topLevel'); + console.log('success'); +} catch (e) { + console.log('caught in catch:', e, e.message); +} +console.log('end'); diff --git a/test/test.propertypath.ts b/test/test.propertypath.ts index a0239bb..cfe0f79 100644 --- a/test/test.propertypath.ts +++ b/test/test.propertypath.ts @@ -5,6 +5,7 @@ tap.test('toHaveProperty nested path via dot notation', async () => { const testObject = { level1: { level2: { level3: 'value' }}, publicTest: 'hi' }; smartexpect.expect(testObject).object.toHaveProperty('publicTest'); + smartexpect.expect(testObject).toHaveProperty('publicTest'); // Existence check smartexpect.expect(testObject).object.toHaveProperty('level1.level2.level3'); // Value check diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 17214d9..2e0d19f 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartexpect', - version: '2.4.0', + version: '2.4.1', description: 'A testing library to manage expectations in code, offering both synchronous and asynchronous assertion methods.' } diff --git a/ts/smartexpect.classes.assertion.ts b/ts/smartexpect.classes.assertion.ts index 7518aab..ea9e523 100644 --- a/ts/smartexpect.classes.assertion.ts +++ b/ts/smartexpect.classes.assertion.ts @@ -355,7 +355,13 @@ export class Assertion { public toInclude(substring: string) { return this.string.toInclude(substring); } 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 toHaveProperty(property: string, value?: any) { + // Forward only provided arguments to object matcher to preserve argument count + if (arguments.length === 2) { + return this.object.toHaveProperty(property, value); + } + return this.object.toHaveProperty(property); + } 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); }