fix(object): Update toHaveProperty matcher to support nested property paths using dot notation
This commit is contained in:
		| @@ -1,5 +1,12 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
|  | ## 2025-04-30 - 2.3.2 - fix(object) | ||||||
|  | Update toHaveProperty matcher to support nested property paths using dot notation | ||||||
|  |  | ||||||
|  | - Changed toHaveProperty implementation to split property strings on '.' and traverse nested objects | ||||||
|  | - Fixed value comparison for nested properties by comparing the final drilled value instead of direct property access | ||||||
|  | - Added tests for nested property access in test/propertyPath.ts | ||||||
|  |  | ||||||
| ## 2025-04-30 - 2.3.1 - fix(readme) | ## 2025-04-30 - 2.3.1 - fix(readme) | ||||||
| Improve README documentation with detailed 'Why SmartExpect' benefits section | Improve README documentation with detailed 'Why SmartExpect' benefits section | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								test/test.propertyPath.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								test/test.propertyPath.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | 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' } } }; | ||||||
|  |   // Existence check | ||||||
|  |   smartexpect.expect(testObject).object.toHaveProperty('level1.level2.level3'); | ||||||
|  |   // Value check | ||||||
|  |   smartexpect.expect(testObject).object.toHaveProperty('level1.level2.level3', 'value'); | ||||||
|  |   // Negation for missing deep property | ||||||
|  |   smartexpect.expect(testObject).not.object.toHaveProperty('level1.level2.missing'); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | export default tap.start(); | ||||||
| @@ -3,6 +3,6 @@ | |||||||
|  */ |  */ | ||||||
| export const commitinfo = { | export const commitinfo = { | ||||||
|   name: '@push.rocks/smartexpect', |   name: '@push.rocks/smartexpect', | ||||||
|   version: '2.3.1', |   version: '2.3.2', | ||||||
|   description: 'A testing library to manage expectations in code, offering both synchronous and asynchronous assertion methods.' |   description: 'A testing library to manage expectations in code, offering both synchronous and asynchronous assertion methods.' | ||||||
| } | } | ||||||
|   | |||||||
| @@ -62,11 +62,16 @@ export class ObjectMatchers<T extends object, M extends TExecutionType> { | |||||||
|     return this.assertion.customAssertion( |     return this.assertion.customAssertion( | ||||||
|       (v) => { |       (v) => { | ||||||
|         const obj = v as any; |         const obj = v as any; | ||||||
|         if (!(property in obj)) { |         const path = property.split('.'); | ||||||
|           return false; |         let current = obj; | ||||||
|  |         for (const key of path) { | ||||||
|  |           if (current == null || !(key in current)) { | ||||||
|  |             return false; | ||||||
|  |           } | ||||||
|  |           current = current[key]; | ||||||
|         } |         } | ||||||
|         if (arguments.length === 2) { |         if (arguments.length === 2) { | ||||||
|           return plugins.fastDeepEqual(obj[property], value); |           return plugins.fastDeepEqual(current, value); | ||||||
|         } |         } | ||||||
|         return true; |         return true; | ||||||
|       }, |       }, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user