From 867bc0529ebb5d656bf20b07f6dfa4b95d8dcf16 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Fri, 13 Jun 2025 17:35:50 -0400 Subject: [PATCH 1/8] feat: support for mode to show only failed output --- bin/cli.js | 2 +- package-lock.json | 85 +++++++++++++++++++++++++++------------------ package.json | 1 + src/cli.ts | 21 +++++++++++ src/getSpecFiles.ts | 4 +-- src/output.ts | 21 ++++++++--- src/run.ts | 15 ++++---- 7 files changed, 101 insertions(+), 48 deletions(-) create mode 100644 src/cli.ts diff --git a/bin/cli.js b/bin/cli.js index 1ba7f0a..48db52b 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,3 +1,3 @@ #!/usr/bin/env ts-node -require('../dist/run'); +require('../dist/cli'); diff --git a/package-lock.json b/package-lock.json index c278ab3..c812a09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { - "name": "hoare", - "version": "0.0.0-semantic-release", + "name": "kizu", + "version": "0.0.0-autorel", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "hoare", - "version": "0.0.0-semantic-release", + "name": "kizu", + "version": "0.0.0-autorel", "license": "MIT", "dependencies": { + "commander": "14.0.0", "deep-object-diff": "^1.1.0", "diff": "^5.0.0", "kleur": "^4.1.4", @@ -17,7 +18,7 @@ "tiny-glob": "^0.2.9" }, "bin": { - "hoare": "bin/cli.js" + "kizu": "bin/cli.js" }, "devDependencies": { "@types/diff": "^5.0.1", @@ -541,10 +542,11 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -762,6 +764,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -784,10 +795,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1623,13 +1635,14 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -1778,10 +1791,11 @@ } }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -2730,9 +2744,9 @@ } }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -2882,6 +2896,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2904,9 +2923,9 @@ "dev": true }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -3531,13 +3550,13 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.3", + "picomatch": "^2.3.1" } }, "mimic-fn": { @@ -3647,9 +3666,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "prelude-ls": { diff --git a/package.json b/package.json index 20ff2d7..57f8a6b 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "node-tap" ], "dependencies": { + "commander": "14.0.0", "deep-object-diff": "^1.1.0", "diff": "^5.0.0", "kleur": "^4.1.4", diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..0077166 --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,21 @@ +import {Command} from 'commander'; +import {Flags, run} from './run'; + +// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires +const packageJson = require('../package.json'); +const program = new Command(); + +program + .name('kizu') + .version(packageJson.version, '-v, --version') + .description('⚫️ kizu\n\nAn easy-to-use, fast, and defensive Typescript/Javascript test runner designed to help you to write simple, readable, and maintainable tests.') + .option('--fail-only, -f', 'Only show failures in the output.', false) + .argument('', 'Glob pattern to match files to run tests on.') + .parse(process.argv); + +const flags = program.opts() as Flags; +const filesGlob = program.args[0]; + +run(flags, filesGlob).catch(console.log.bind(console)); + + diff --git a/src/getSpecFiles.ts b/src/getSpecFiles.ts index 1721d88..9c96d05 100644 --- a/src/getSpecFiles.ts +++ b/src/getSpecFiles.ts @@ -1,7 +1,7 @@ import glob from 'tiny-glob'; -export async function getSpecFiles() { +export async function getSpecFiles(arg: string) { - return glob(process.argv[2]); + return glob(arg); } diff --git a/src/output.ts b/src/output.ts index f39a679..6073de4 100644 --- a/src/output.ts +++ b/src/output.ts @@ -18,29 +18,40 @@ The following spec files do not have any attempted or completed tests: ${files.join(', ')} `); -export function printResultsByFile(resultsByFile: TestResultsByFile) { +export function printResultsByFile(resultsByFile: TestResultsByFile, showOnlyFailures: boolean = false) { const sortedResults = sortTestResults(resultsByFile); for (const [filename, tests] of sortedResults) { - printFileResults(filename, tests); + printFileResults(filename, tests, showOnlyFailures); } } -export function printFileResults(filename: string, tests: TestResults[]) { +export function printFileResults( + filename: string, + tests: TestResults[], + showOnlyFailures: boolean = false +) { - const doesFileHaveFailures = tests.some((test) => !isTestPassing(test)); - const header = `${kleur.underline().blue(filename)} ${doesFileHaveFailures ? failureSymbol : successSymbol}\n`; + const hasFailure = tests.some((test) => !isTestPassing(test)); + + if (showOnlyFailures && !hasFailure) return; + + const header = `${kleur.underline().blue(filename)} ${hasFailure ? failureSymbol : successSymbol}\n`; log(header); tests.forEach(((test) => { + if (showOnlyFailures && isTestPassing(test)) return; + log(`${test.description} ${isTestPassing(test) ? successSymbol : failureSymbol}`); test.assertions.forEach((assertion) => { + if (showOnlyFailures && assertion.pass) return; + log(kleur.gray(` ${assertion.description} ${assertion.pass ? successSymbol : failureSymbol}`)); !assertion.pass && printFailedAssertionDiag(assertion); diff --git a/src/run.ts b/src/run.ts index 3b4fd3e..c9ba4ee 100644 --- a/src/run.ts +++ b/src/run.ts @@ -9,6 +9,9 @@ import {getSpecFiles} from './getSpecFiles'; const testResultsByFile: TestResultsByFile = {}; let numCompletedTests = 0; +export type Flags = { + failOnly: boolean +}; export type TestResultsByFile = {[file: string]: TestResults[]}; export type FinalResults = { numFiles: number @@ -21,14 +24,14 @@ export type FinalResults = { const status = ora(); -async function start() { +export async function run(flags: Flags, filesGlob: string) { - const specFiles = await getSpecFiles(); + const specFiles = await getSpecFiles(filesGlob); console.log(`Found ${specFiles.length} spec files.\n`); status.start('Running tests...'); await workerPool(specFiles, addTestResults); - finish(specFiles); + showResults(flags, specFiles); } @@ -45,16 +48,14 @@ function addTestResults(file: string, results: TestResults) { } -function finish(specFiles: string[]) { +function showResults(flags: Flags, specFiles: string[]) { status.stop(); const finalResults = calculateFinalResults(specFiles, testResultsByFile); - printResultsByFile(testResultsByFile); + printResultsByFile(testResultsByFile, flags.failOnly); printSummary(finalResults); if (shouldExitWithError(finalResults)) process.exit(1); } - -start().catch(console.log.bind(console)); From d9d25b8209a943db1a91153a2c7f1d314bace29e Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Fri, 13 Jun 2025 17:52:24 -0400 Subject: [PATCH 2/8] docs: added docu for new --fail-only flag --- README.md | 12 ++++++++++-- docs/cli.md | 18 ++++++++++++++++++ src/cli.ts | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 docs/cli.md diff --git a/README.md b/README.md index cb49726..2e15cf7 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,14 @@ Designed to help you write simple, readable, and maintainable tests. For more examples, see the [examples](examples) and [src](src) folders. +```bash +# Run all tests in the src directory and its subdirectories, and only show failures in the output. +npx kizu 'src/**/*.test.ts' --fail-only +``` + ```typescript +// example.test.ts + import {test} from 'kizu'; // Basic test @@ -80,9 +87,10 @@ test('fetchData()', async (assert) => { ## Table of Contents - [Getting Started](docs/gettingStarted.md) -- [Examples](#examples) -- [API](docs/api.md) +- [CLI](docs/cli.md) +- [Test API](docs/api.md) - [Visual Diff Tool](docs/visualDiff.md) +- [Example Tests](examples) - [Best Practices](docs/bestPractices.md) - [Inspiration, Philosophy & Attribution](docs/inspiration.md) - [FAQ](docs/faq.md) diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 0000000..ccd4a72 --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,18 @@ +# CLI + +## Usage: `kizu [options] ` + +Example: + +```bash +npx kizu -f 'src/**/*.test.ts' +``` + +## Options + +- `--fail-only, -f`: Only show failures in the output. This often results in much less output. +- `--version, -v`: Show version. + +## Glob + +The glob pattern is used to match files to run tests on. It is passed to the [tiny-glob](https://github.com/terkelg/tiny-glob) library. \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts index 0077166..c7748a2 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,7 +7,7 @@ const program = new Command(); program .name('kizu') - .version(packageJson.version, '-v, --version') + .version(packageJson.version, '--version, -v') .description('⚫️ kizu\n\nAn easy-to-use, fast, and defensive Typescript/Javascript test runner designed to help you to write simple, readable, and maintainable tests.') .option('--fail-only, -f', 'Only show failures in the output.', false) .argument('', 'Glob pattern to match files to run tests on.') From b5e5bd0ee3ed1d781e2547a6d9f8b021db302820 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Fri, 13 Jun 2025 17:55:48 -0400 Subject: [PATCH 3/8] docs: smol tweaks --- README.md | 4 +++- docs/{gettingStarted.md => quickStart.md} | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename docs/{gettingStarted.md => quickStart.md} (99%) diff --git a/README.md b/README.md index 2e15cf7..e10089c 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ For more examples, see the [examples](examples) and [src](src) folders. ```bash # Run all tests in the src directory and its subdirectories, and only show failures in the output. npx kizu 'src/**/*.test.ts' --fail-only +# Run a specific test file +npx kizu 'src/example.test.ts' ``` ```typescript @@ -86,7 +88,7 @@ test('fetchData()', async (assert) => { ## Table of Contents -- [Getting Started](docs/gettingStarted.md) +- [Quick Start](docs/quickStart.md) - [CLI](docs/cli.md) - [Test API](docs/api.md) - [Visual Diff Tool](docs/visualDiff.md) diff --git a/docs/gettingStarted.md b/docs/quickStart.md similarity index 99% rename from docs/gettingStarted.md rename to docs/quickStart.md index 967c240..4467b6d 100644 --- a/docs/gettingStarted.md +++ b/docs/quickStart.md @@ -1,4 +1,4 @@ -# Getting Started +# Quick Start Using `kizu` is really easy! Here's a quick guide to get you started. From 2eb1e35ec14b02e5733b6ed01163c30a78e6c113 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Fri, 13 Jun 2025 17:58:37 -0400 Subject: [PATCH 4/8] docs: added help option to cli --- docs/cli.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/cli.md b/docs/cli.md index ccd4a72..eeb4bbf 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -12,6 +12,7 @@ npx kizu -f 'src/**/*.test.ts' - `--fail-only, -f`: Only show failures in the output. This often results in much less output. - `--version, -v`: Show version. +- `--help`: Show help menu. ## Glob From 78c09e20609ecbbaf3044633a1468b201bce9dd9 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Mon, 16 Jun 2025 17:33:57 -0400 Subject: [PATCH 5/8] fix: correct instances of old name being used --- docs/inspiration.md | 2 +- docs/mockingDeps.md | 2 +- examples/throwsFunError.spec.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/inspiration.md b/docs/inspiration.md index a0cbdbe..f933ad3 100644 --- a/docs/inspiration.md +++ b/docs/inspiration.md @@ -10,7 +10,7 @@ Good tests act as clear **specifications**. The `{P} C {Q}` structure mirrors ho > “A program is a specification of behavior.” > — C. A. R. Hoare -Modern test tools have grown complex, often compensating for design flaws instead of helping reveal them. **Hoare** aims to reverse that — with a minimal API that helps you focus on your code, not the tool. +Modern test tools have grown complex, often compensating for design flaws instead of helping reveal them. **kizu** aims to reverse that — with a minimal API that helps you focus on your code, not the tool. > “The price of reliability is the pursuit of the utmost simplicity. It is a price which the very rich find most hard to pay.” > — C. A. R. Hoare diff --git a/docs/mockingDeps.md b/docs/mockingDeps.md index 44974e7..a49feaf 100644 --- a/docs/mockingDeps.md +++ b/docs/mockingDeps.md @@ -18,7 +18,7 @@ async function getValidWords() { ``` _isValidWord.spec.ts_ ```typescript -import {test} from 'hoare'; +import {test} from 'kizu'; import {mock} from 'cjs-mock'; import * as mod from './isValidWord'; // just used for typing diff --git a/examples/throwsFunError.spec.ts b/examples/throwsFunError.spec.ts index 4f05b94..5522742 100644 --- a/examples/throwsFunError.spec.ts +++ b/examples/throwsFunError.spec.ts @@ -1,4 +1,4 @@ -import {test} from '../src'; // from 'hoare' +import {test} from '../src'; // from 'kizu' import {throwsFunError} from './throwsFunError'; // test with RegExp From d584cbe64a7bf265ebd7709d7cefe8455a7483c4 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Tue, 17 Jun 2025 13:28:06 -0400 Subject: [PATCH 6/8] docs: corrected example --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e10089c..8a02c12 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ function greet(name: string): string { return `hello, ${name}`; } -test('greet()', (assert) => { - assert.equal(hello('world'), 'hello, world'); +test('greet', (assert) => { + assert.equal(greet('world'), 'hello, world'); }); // Error handling @@ -70,7 +70,7 @@ function throwError(): never { throw new Error('oops'); } -test('throwError()', (assert) => { +test('throwError', (assert) => { assert.throws(() => throwError(), /oops/); }); @@ -80,7 +80,7 @@ async function fetchData(): Promise { return Promise.resolve('data'); } -test('fetchData()', async (assert) => { +test('fetchData', async (assert) => { const data = await fetchData(); assert.equal(data, 'data'); }); From 59a3d13de2726beb781ea02723477bf8a938c322 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Tue, 17 Jun 2025 13:34:24 -0400 Subject: [PATCH 7/8] docs: corrected link to visdiff tool --- docs/api.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api.md b/docs/api.md index 4286d79..a5cec40 100644 --- a/docs/api.md +++ b/docs/api.md @@ -30,7 +30,7 @@ Create a test. `cb` can return a Promise or be an async, and the test runner wil > `equal(actual: any, expected: any, msg?: string): void` -Asserts deep and strict equality on objects or primitives. This will give you a [visual diff](#visual-diff-tool) output for any discrepancies. _This should be used for most assertions._ +Asserts deep and strict equality on objects or primitives. This will give you a [visual diff](/docs/visualDiff.md) output for any discrepancies. _This should be used for most assertions._ --- @@ -47,7 +47,7 @@ Asserts that the given function throws an error, matching either: - No need to manually wrap code in a `try/catch` - Supports custom error types and meaningful comparisons -- Provides [visual diffs](#visual-diff-tool) on mismatch +- Provides [visual diffs](/docs/visualDiff.md) on mismatch #### Example @@ -105,7 +105,7 @@ Asserts that the test has failed. Asserts that both errors are similar. Stack traces are ignored. It checks for both non-enumerable properties (ie, `name` and `message`) and enumerable properties (anything added by extending `Error`). -Under the hood it uses `equal()` and you will get a [visual diff](#visual-diff-tool) output for any discrepancies. +Under the hood it uses `equal()` and you will get a [visual diff](/docs/visualDiff.md) output for any discrepancies. Both errors **must** be an instance of `Error`, or an error will be thrown. From c060f8bddbcebb7ecbb4b7cab3e801913fdd0725 Mon Sep 17 00:00:00 2001 From: "Marc H. Weiner" Date: Tue, 17 Jun 2025 13:35:10 -0400 Subject: [PATCH 8/8] docs: corrected link to visdiff tool --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a02c12..7bda740 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Designed to help you write simple, readable, and maintainable tests. ### **😀 Easy to Use** - Very simple functional [assertion API](docs/api.md). No need to learn a DSL or framework. -- Built-in [powerful diff visualization tool](#visual-diff-tool) +- Built-in [powerful diff visualization tool](/docs/visualDiff.md) - Clean, organized output. - Failed tests are easy to find, grouped at the end of the output. - Errors or unhandled promise rejections are buffered and grouped under the test file in the output. This helps you know where they came from.