From 0054271de6a682e8cf1ea949369dcffd64c5da23 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Fri, 23 May 2025 18:30:47 +0000 Subject: [PATCH] feat(Assertion): Add missing alias methods for length and emptiness checks and update documentation --- changelog.md | 8 +++++ readme.hints.md | 56 ++++++++++++++++++++++++++++- ts/00_commitinfo_data.ts | 2 +- ts/smartexpect.classes.assertion.ts | 48 +++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index b17a0f3..ca0b687 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-05-23 - 2.5.0 - feat(Assertion) +Add missing alias methods for length and emptiness checks and update documentation + +- Updated readme.hints.md with detailed project hints, feature overview, and common patterns +- Added direct alias methods in smartexpect.classes.assertion.ts for string/array length checks (toHaveLength, toBeEmpty) +- Introduced additional delegations for numeric and array namespace methods (toHaveLengthGreaterThan, toHaveLengthLessThan) +- Enhanced function namespace with direct matchers for error checking (toThrowErrorMatching, toThrowErrorWithMessage) + ## 2025-05-01 - 2.4.2 - fix(cleanup) Remove unused scratch files diff --git a/readme.hints.md b/readme.hints.md index 0519ecb..896d247 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -1 +1,55 @@ - \ No newline at end of file +# SmartExpect - Project Hints + +## Project Overview +- **Name**: @push.rocks/smartexpect +- **Purpose**: A minimal, promise-first assertion library for testing with TypeScript support +- **License**: MIT +- **Version**: 2.4.2 + +## Architecture +1. **Core Assertion Class** (`ts/smartexpect.classes.assertion.ts`): + - Central `Assertion` class handles all assertion logic + - Supports sync and async execution modes + - Property drilling with `.property()` and `.arrayItem()` + - Custom matcher extension via `expect.extend()` + +2. **Namespace Organization** (`ts/namespaces/`): + - Matchers grouped by type: string, number, array, object, boolean, function, date, type + - Each namespace provides type-specific assertions + - All namespaces extend the base Assertion class + +3. **Entry Point** (`ts/index.ts`): + - Exports the main `expect()` function + - Auto-detects promises for async mode + - Provides `expect.any()` and `expect.anything()` utility matchers + +## Key Features +- **Async-first**: `.resolves` and `.rejects` modifiers for promise assertions +- **Timeout support**: `.withTimeout(ms)` for async assertions +- **Negation**: `.not` modifier inverts any assertion +- **Property navigation**: Chain `.property()` and `.arrayItem()` for nested assertions +- **Custom matchers**: Extend with `expect.extend({ matcherName: fn })` +- **Debugging**: `.log()` method to inspect values during assertion chains + +## Dependencies +- `@push.rocks/smartdelay`: For async timeout handling +- `@push.rocks/smartpromise`: For promise utilities +- `fast-deep-equal`: For deep equality comparisons + +## Testing +- Tests use `@git.zone/tstest` with tap +- Test files import from compiled `dist_ts/` directory +- Test naming: `*.both.ts` (browser+node), `*.node.ts`, `*.browser.ts` +- Run with `pnpm test` + +## Recent Changes +- v2.4.2: General maintenance +- v2.4.1: Fixed toHaveProperty alias to forward arguments correctly +- v2.4.0: Major improvements (details not specified) + +## Common Patterns +1. **Basic assertions**: `expect(value).toEqual(expected)` +2. **Async assertions**: `expect(promise).resolves.toEqual(value)` +3. **Property drilling**: `expect(obj).property('nested').property('value').toEqual(x)` +4. **Array navigation**: `expect(arr).arrayItem(0).toEqual(firstItem)` +5. **Custom messages**: `expect(x).setFailMessage('Custom error').toEqual(y)` \ No newline at end of file diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 6cf23f9..3d98bbc 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.2', + version: '2.5.0', 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 ea9e523..4dbdc59 100644 --- a/ts/smartexpect.classes.assertion.ts +++ b/ts/smartexpect.classes.assertion.ts @@ -378,6 +378,54 @@ export class Assertion { public toBeTypeOf(typeName: string) { return this.type.toBeTypeOf(typeName); } public toBeDefined() { return this.type.toBeDefined(); } + // Additional missing direct aliases for completeness + // String/Array namespace - intelligently delegate based on value type + public toHaveLength(length: number) { + // Determine if value is string or array and delegate accordingly + const value = this.getObjectToTestReference(); + if (typeof value === 'string') { + return this.string.toHaveLength(length); + } else if (Array.isArray(value)) { + return this.array.toHaveLength(length); + } else { + return this.customAssertion( + () => false, + 'Expected value to be string or array to check length' + ); + } + } + public toBeEmpty() { + // Determine if value is string or array and delegate accordingly + const value = this.getObjectToTestReference(); + if (typeof value === 'string') { + return this.string.toBeEmpty(); + } else if (Array.isArray(value)) { + return this.array.toBeEmpty(); + } else { + return this.customAssertion( + () => false, + 'Expected value to be string or array to check if empty' + ); + } + } + + // Number namespace + public toBeNaN() { return this.number.toBeNaN(); } + public toBeFinite() { return this.number.toBeFinite(); } + public toBeWithinRange(min: number, max: number) { return this.number.toBeWithinRange(min, max); } + + // Array namespace length comparisons + public toHaveLengthGreaterThan(length: number) { return this.array.toHaveLengthGreaterThan(length); } + public toHaveLengthLessThan(length: number) { return this.array.toHaveLengthLessThan(length); } + + // Object namespace + public toHaveKeys(keys: string[]) { return this.object.toHaveKeys(keys); } + public toHaveOwnKeys(keys: string[]) { return this.object.toHaveOwnKeys(keys); } + + // Function namespace + public toThrowErrorMatching(regex: RegExp) { return this.function.toThrowErrorMatching(regex); } + public toThrowErrorWithMessage(message: string) { return this.function.toThrowErrorWithMessage(message); } + // Namespaced matcher accessors /** String-specific matchers */ public get string(): StringMatchers {