From af320f9022e130f404f1c13abc4760be8bf7a9fd Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Thu, 30 Mar 2023 22:42:49 +0200 Subject: [PATCH 01/13] :sparkles: Improve formatting external assert libs --- lib/test.js | 46 +++++++++++--- .../fixtures/assert-failure.js | 7 ++ .../fixtures/expect-failure.js | 7 ++ .../external-assertions/fixtures/package.json | 11 ++++ test/external-assertions/snapshots/test.js.md | 60 ++++++++++++++++++ .../snapshots/test.js.snap | Bin 0 -> 365 bytes test/external-assertions/test.js | 13 ++++ 7 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 test/external-assertions/fixtures/assert-failure.js create mode 100644 test/external-assertions/fixtures/expect-failure.js create mode 100644 test/external-assertions/fixtures/package.json create mode 100644 test/external-assertions/snapshots/test.js.md create mode 100644 test/external-assertions/snapshots/test.js.snap create mode 100644 test/external-assertions/test.js diff --git a/lib/test.js b/lib/test.js index d6a39444a..816b7dda2 100644 --- a/lib/test.js +++ b/lib/test.js @@ -7,6 +7,16 @@ import concordanceOptions from './concordance-options.js'; import nowAndTimers from './now-and-timers.cjs'; import parseTestArgs from './parse-test-args.js'; +function isExternalAssertError(error) { + // Match errors thrown by . + if (error.matcherResult) { + return true; + } + + // Match errors thrown by and . + return error.hasOwnProperty('actual') && error.hasOwnProperty('expected'); +} + function formatErrorValue(label, error) { const formatted = concordance.format(error, concordanceOptions); return {label, formatted}; @@ -519,11 +529,19 @@ export default class Test { const result = this.callFn(); if (!result.ok) { - this.saveFirstError(new AssertionError({ - message: 'Error thrown in test', - savedError: result.error instanceof Error && result.error, - values: [formatErrorValue('Error thrown in test:', result.error)], - })); + if (isExternalAssertError(result.error)) { + this.saveFirstError(new AssertionError({ + message: 'Assertion failed', + savedError: result.error instanceof Error && result.error, + values: [{label: 'Assertion failed: ', formatted: result.error.message}] + })); + } else { + this.saveFirstError(new AssertionError({ + message: 'Error thrown in test', + savedError: result.error instanceof Error && result.error, + values: [formatErrorValue('Error thrown in test:', result.error)] + })); + } return this.finish(); } @@ -564,11 +582,19 @@ export default class Test { promise .catch(error => { - this.saveFirstError(new AssertionError({ - message: 'Rejected promise returned by test', - savedError: error instanceof Error && error, - values: [formatErrorValue('Rejected promise returned by test. Reason:', error)], - })); + if (isExternalAssertError(error)) { + this.saveFirstError(new AssertionError({ + message: 'Assertion failed', + savedError: error instanceof Error && error, + values: [{label: 'Assertion failed: ', formatted: error.message}] + })); + } else { + this.saveFirstError(new AssertionError({ + message: 'Rejected promise returned by test', + savedError: error instanceof Error && error, + values: [formatErrorValue('Rejected promise returned by test. Reason:', error)] + })); + } }) .then(() => resolve(this.finish())); }); diff --git a/test/external-assertions/fixtures/assert-failure.js b/test/external-assertions/fixtures/assert-failure.js new file mode 100644 index 000000000..7c5806c7e --- /dev/null +++ b/test/external-assertions/fixtures/assert-failure.js @@ -0,0 +1,7 @@ +import assert from 'node:assert'; + +import test from 'ava'; + +test('test', () => { + assert(false); +}); diff --git a/test/external-assertions/fixtures/expect-failure.js b/test/external-assertions/fixtures/expect-failure.js new file mode 100644 index 000000000..2825f9cad --- /dev/null +++ b/test/external-assertions/fixtures/expect-failure.js @@ -0,0 +1,7 @@ +import { expect } from 'expect'; + +import test from 'ava'; + +test('test', () => { + expect(false).toBeTruthy(); +}); diff --git a/test/external-assertions/fixtures/package.json b/test/external-assertions/fixtures/package.json new file mode 100644 index 000000000..95741ae4c --- /dev/null +++ b/test/external-assertions/fixtures/package.json @@ -0,0 +1,11 @@ +{ + "type": "module", + "ava": { + "files": [ + "*.js" + ] + }, + "dependencies": { + "expect": "^29.5.0" + } +} diff --git a/test/external-assertions/snapshots/test.js.md b/test/external-assertions/snapshots/test.js.md new file mode 100644 index 000000000..793e543ce --- /dev/null +++ b/test/external-assertions/snapshots/test.js.md @@ -0,0 +1,60 @@ +# Snapshot report for `test/external-assertions/test.js` + +The actual snapshot is saved in `test.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## node assertion + +> Snapshot 1 + + `␊ + ✘ [fail]: test Assertion failed␊ + ─␊ + ␊ + test␊ + ␊ + assert-failure.js:6␊ + ␊ + 5: test('test', () => {␊ + 6: assert(false); ␊ + 7: }); ␊ + ␊ + Assertion failed: ␊ + ␊ + false == true␊ + ␊ + › file://assert-failure.js:6:2␊ + ␊ + ─␊ + ␊ + 1 test failed` + +## expect error + +> Snapshot 1 + + `␊ + ✘ [fail]: test Assertion failed␊ + ─␊ + ␊ + test␊ + ␊ + expect-failure.js:6␊ + ␊ + 5: test('test', () => { ␊ + 6: expect(false).toBeTruthy();␊ + 7: }); ␊ + ␊ + Assertion failed: ␊ + ␊ + expect(received).toBeTruthy()␊ + ␊ + Received: false␊ + ␊ + › Received: false␊ + › file://expect-failure.js:6:16␊ + ␊ + ─␊ + ␊ + 1 test failed` diff --git a/test/external-assertions/snapshots/test.js.snap b/test/external-assertions/snapshots/test.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..b8fe8e9e6ac5089df627e2a9f817c8634911ead2 GIT binary patch literal 365 zcmV-z0h0bfRzV@Ml00000000A>k-m-aDyoIZ${=_ZtvD8)VOvj4yH@6NZgWR$7s-n`9`QpzyTRg55wK~1U3 zQB3?l}8f-%bZ$@%aHaiA=Lw0fdI&tgZ)EG3GPx(@wdt z&8xlPknKWa@6L#TWjMA8UYF9Qu?CbZ+V(H>a1EA*dA?Mg)PI!2}T5{wbCunMh$3}?*E|KOE!kK z;!xAG0TsO-sdK#21&yCPfA|N+4R}_;8Y4^}Fm7h^fs4u!7JZF;U2c3tOS@ta{Pq(+ LDG)D}$^rlYAt|qK literal 0 HcmV?d00001 diff --git a/test/external-assertions/test.js b/test/external-assertions/test.js new file mode 100644 index 000000000..4695dc28b --- /dev/null +++ b/test/external-assertions/test.js @@ -0,0 +1,13 @@ +import test from '@ava/test'; + +import {fixture} from '../helpers/exec.js'; + +test('node assertion ', async t => { + const result = await t.throwsAsync(fixture(['assert-failure.js'])); + t.snapshot(result.stdout); +}); + +test('expect error ', async t => { + const result = await t.throwsAsync(fixture(['expect-failure.js'])); + t.snapshot(result.stdout); +}); From 8225c6b1276b6232f151ea7375f32e2f397ffaf9 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 12:49:28 +0200 Subject: [PATCH 02/13] :heavy_plus_sign: add expect dep --- package-lock.json | 468 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 2 files changed, 467 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2ef9080b9..1e31e9876 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "c8": "^7.12.0", "delay": "^5.0.0", "execa": "^6.1.0", + "expect": "^29.5.0", "fs-extra": "^11.1.0", "get-stream": "^6.0.1", "replace-string": "^4.0.0", @@ -1042,6 +1043,96 @@ "node": ">=8" } }, + "node_modules/@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -1147,6 +1238,12 @@ "node": ">= 8" } }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, "node_modules/@sindresorhus/tsconfig": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sindresorhus/tsconfig/-/tsconfig-3.0.1.tgz", @@ -1230,6 +1327,24 @@ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -1252,8 +1367,7 @@ "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1267,6 +1381,27 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -2542,6 +2677,15 @@ "node": ">=0.3.1" } }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3693,6 +3837,22 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5079,6 +5239,278 @@ "node": ">=8" } }, + "node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -6838,6 +7270,32 @@ "node": ">=6.0.0" } }, + "node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/pretty-ms": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", @@ -6920,6 +7378,12 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", diff --git a/package.json b/package.json index 3e5caa15c..7f6ea4910 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "c8": "^7.12.0", "delay": "^5.0.0", "execa": "^6.1.0", + "expect": "^29.5.0", "fs-extra": "^11.1.0", "get-stream": "^6.0.1", "replace-string": "^4.0.0", From e14aa0acfa3f5079c88a991ba4ddfee9102a455c Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 12:51:40 +0200 Subject: [PATCH 03/13] :ribbon: lint --- lib/assert.js | 2 +- lib/test.js | 12 ++++++------ test/external-assertions/fixtures/expect-failure.js | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 15818739c..a55a06721 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -27,7 +27,7 @@ function formatWithLabel(label, value) { return formatDescriptorWithLabel(label, concordance.describe(value, concordanceOptions)); } -const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); +export const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); const noop = () => {}; const notImplemented = () => { throw new Error('not implemented'); diff --git a/lib/test.js b/lib/test.js index 816b7dda2..6f7827bb2 100644 --- a/lib/test.js +++ b/lib/test.js @@ -2,7 +2,7 @@ import concordance from 'concordance'; import isPromise from 'is-promise'; import plur from 'plur'; -import {AssertionError, Assertions, checkAssertionMessage} from './assert.js'; +import {AssertionError, Assertions, checkAssertionMessage, hasOwnProperty} from './assert.js'; import concordanceOptions from './concordance-options.js'; import nowAndTimers from './now-and-timers.cjs'; import parseTestArgs from './parse-test-args.js'; @@ -14,7 +14,7 @@ function isExternalAssertError(error) { } // Match errors thrown by and . - return error.hasOwnProperty('actual') && error.hasOwnProperty('expected'); + return hasOwnProperty(error, 'actual') && hasOwnProperty(error, 'expected'); } function formatErrorValue(label, error) { @@ -533,13 +533,13 @@ export default class Test { this.saveFirstError(new AssertionError({ message: 'Assertion failed', savedError: result.error instanceof Error && result.error, - values: [{label: 'Assertion failed: ', formatted: result.error.message}] + values: [{label: 'Assertion failed: ', formatted: result.error.message}], })); } else { this.saveFirstError(new AssertionError({ message: 'Error thrown in test', savedError: result.error instanceof Error && result.error, - values: [formatErrorValue('Error thrown in test:', result.error)] + values: [formatErrorValue('Error thrown in test:', result.error)], })); } @@ -586,13 +586,13 @@ export default class Test { this.saveFirstError(new AssertionError({ message: 'Assertion failed', savedError: error instanceof Error && error, - values: [{label: 'Assertion failed: ', formatted: error.message}] + values: [{label: 'Assertion failed: ', formatted: error.message}], })); } else { this.saveFirstError(new AssertionError({ message: 'Rejected promise returned by test', savedError: error instanceof Error && error, - values: [formatErrorValue('Rejected promise returned by test. Reason:', error)] + values: [formatErrorValue('Rejected promise returned by test. Reason:', error)], })); } }) diff --git a/test/external-assertions/fixtures/expect-failure.js b/test/external-assertions/fixtures/expect-failure.js index 2825f9cad..b410bc858 100644 --- a/test/external-assertions/fixtures/expect-failure.js +++ b/test/external-assertions/fixtures/expect-failure.js @@ -1,6 +1,5 @@ -import { expect } from 'expect'; - import test from 'ava'; +import {expect} from 'expect'; test('test', () => { expect(false).toBeTruthy(); From 6e121ef1139d7e68c6d3cbf4c07b0eb9c0b7c787 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 13:18:34 +0200 Subject: [PATCH 04/13] :white_check_mark: update tests --- test/builtin-nodejs-assert/test.js | 4 ++-- test/external-assertions/snapshots/test.js.md | 10 +++++----- test/external-assertions/snapshots/test.js.snap | Bin 365 -> 373 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/builtin-nodejs-assert/test.js b/test/builtin-nodejs-assert/test.js index 1954b3a17..3419d4951 100644 --- a/test/builtin-nodejs-assert/test.js +++ b/test/builtin-nodejs-assert/test.js @@ -15,12 +15,12 @@ test('node assertion failures are reported to the console when running in a term const result = await t.throwsAsync(fixture(['assert-failure.js'], options)); const error = result.stats.getError(result.stats.failed[0]); - t.true(error.values.every(value => value.formatted.includes('AssertionError'))); + t.true(error.values.every(value => value.label.includes('Assertion failed'))); }); test('node assertion failures are reported to the console when not running in a terminal', async t => { const result = await t.throwsAsync(fixture(['assert-failure.js'])); const error = result.stats.getError(result.stats.failed[0]); - t.true(error.values.every(value => value.formatted.includes('AssertionError'))); + t.true(error.values.every(value => value.label.includes('Assertion failed'))); }); diff --git a/test/external-assertions/snapshots/test.js.md b/test/external-assertions/snapshots/test.js.md index 793e543ce..1f1000aef 100644 --- a/test/external-assertions/snapshots/test.js.md +++ b/test/external-assertions/snapshots/test.js.md @@ -40,11 +40,11 @@ Generated by [AVA](https://avajs.dev). ␊ test␊ ␊ - expect-failure.js:6␊ + expect-failure.js:5␊ ␊ - 5: test('test', () => { ␊ - 6: expect(false).toBeTruthy();␊ - 7: }); ␊ + 4: test('test', () => { ␊ + 5: expect(false).toBeTruthy();␊ + 6: }); ␊ ␊ Assertion failed: ␊ ␊ @@ -53,7 +53,7 @@ Generated by [AVA](https://avajs.dev). Received: false␊ ␊ › Received: false␊ - › file://expect-failure.js:6:16␊ + › file://expect-failure.js:5:16␊ ␊ ─␊ ␊ diff --git a/test/external-assertions/snapshots/test.js.snap b/test/external-assertions/snapshots/test.js.snap index b8fe8e9e6ac5089df627e2a9f817c8634911ead2..3f12b7ab15c89933a182d753a84b961313316bb9 100644 GIT binary patch literal 373 zcmV-*0gC=XRzVk-@Ml00000000A>k-m-aDyoIZ${=_ZtvD8)VOvj4yH@6NZgWR$7s-n`9`QpzyTRg55wK~1U3 zQB3?l}8f-%bZ$@%aHaiA=Lw0fdI&tgZ)EG3GPx(@wdt z&8xlPknKWa@6L#TWjMA8UYF9Qu?CbZ+V(H>a1EA*dA?Mg)PI!2}T5{wbCunMh$3}?*E|KOE!kK z;!xAG0TsO-sdK#21&yCPfA|N+4R}_;8Y4^}Fm7h^fs4u!7JZF;U2c3tOS@ta{Pq(+ LDG)D}$^rlYAt|qK From 78c62f98e3a5a78f5e9306819bc6ddd0709e28f4 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 17:52:16 +0200 Subject: [PATCH 05/13] :white_check_mark: update tap reporters --- test-tap/reporters/default.edgecases.v16.log | 4 -- test-tap/reporters/default.regular.v14.log | 26 ++++++----- test-tap/reporters/default.regular.v16.log | 26 ++++++----- test-tap/reporters/default.regular.v18.log | 26 ++++++----- test-tap/reporters/tap.edgecases.v16.log | 6 +-- test-tap/reporters/tap.regular.v14.log | 47 ++++++++++++-------- test-tap/reporters/tap.regular.v16.log | 47 ++++++++++++-------- test-tap/reporters/tap.regular.v18.log | 47 ++++++++++++-------- 8 files changed, 133 insertions(+), 96 deletions(-) diff --git a/test-tap/reporters/default.edgecases.v16.log b/test-tap/reporters/default.edgecases.v16.log index b3c1b8057..489c5d133 100644 --- a/test-tap/reporters/default.edgecases.v16.log +++ b/test-tap/reporters/default.edgecases.v16.log @@ -7,10 +7,6 @@ ---tty-stream-chunk-separator Uncaught exception in ast-syntax-error.cjs - ~/test-tap/fixture/report/edgecases/ast-syntax-error.cjs:3 - const fn = do { - ^^ - SyntaxError: Unexpected token 'do' ---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.regular.v14.log b/test-tap/reporters/default.regular.v14.log index 9b9a969d3..20475f590 100644 --- a/test-tap/reporters/default.regular.v14.log +++ b/test-tap/reporters/default.regular.v14.log @@ -62,7 +62,21 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ [fail]: test › implementation throws non-error Error thrown in test + ✘ Internal error when running test.cjs + TypeError: Cannot read property 'matcherResult' of null + TypeError: Cannot read property 'matcherResult' of null +  at isExternalAssertError (file://~/lib/test.js:12:12) +  at Test.run (file://~/lib/test.js:532:8) +  at Runner.runSingle (file://~/lib/runner.js:285:33) +  at Runner.runTest (file://~/lib/runner.js:367:30) +  at processTicksAndRejections (internal/process/task_queues.js:95:5) +  at async Promise.all (index 6) +  at async file://~/lib/runner.js:532:21 +  at async Runner.start (file://~/lib/runner.js:540:15) + + +---tty-stream-chunk-separator + ✘ test.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -233,14 +247,6 @@ - test › implementation throws non-error - - Error thrown in test: - - null - - - traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -348,7 +354,7 @@ ─ - 13 tests failed + 12 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/default.regular.v16.log b/test-tap/reporters/default.regular.v16.log index 9b9a969d3..8c9a76be5 100644 --- a/test-tap/reporters/default.regular.v16.log +++ b/test-tap/reporters/default.regular.v16.log @@ -62,7 +62,21 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ [fail]: test › implementation throws non-error Error thrown in test + ✘ Internal error when running test.cjs + TypeError: Cannot read properties of null (reading 'matcherResult') + TypeError: Cannot read properties of null (reading 'matcherResult') +  at isExternalAssertError (file://~/lib/test.js:12:12) +  at Test.run (file://~/lib/test.js:532:8) +  at Runner.runSingle (file://~/lib/runner.js:285:33) +  at Runner.runTest (file://~/lib/runner.js:367:30) +  at processTicksAndRejections (node:internal/process/task_queues:96:5) +  at async Promise.all (index 6) +  at async file://~/lib/runner.js:532:21 +  at async Runner.start (file://~/lib/runner.js:540:15) + + +---tty-stream-chunk-separator + ✘ test.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -233,14 +247,6 @@ - test › implementation throws non-error - - Error thrown in test: - - null - - - traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -348,7 +354,7 @@ ─ - 13 tests failed + 12 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/default.regular.v18.log b/test-tap/reporters/default.regular.v18.log index 9b9a969d3..3a982ae33 100644 --- a/test-tap/reporters/default.regular.v18.log +++ b/test-tap/reporters/default.regular.v18.log @@ -62,7 +62,21 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ [fail]: test › implementation throws non-error Error thrown in test + ✘ Internal error when running test.cjs + TypeError: Cannot read properties of null (reading 'matcherResult') + TypeError: Cannot read properties of null (reading 'matcherResult') +  at isExternalAssertError (file://~/lib/test.js:12:12) +  at Test.run (file://~/lib/test.js:532:8) +  at Runner.runSingle (file://~/lib/runner.js:285:33) +  at Runner.runTest (file://~/lib/runner.js:367:30) +  at process.processTicksAndRejections (node:internal/process/task_queues:95:5) +  at async Promise.all (index 6) +  at async file://~/lib/runner.js:532:21 +  at async Runner.start (file://~/lib/runner.js:540:15) + + +---tty-stream-chunk-separator + ✘ test.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -233,14 +247,6 @@ - test › implementation throws non-error - - Error thrown in test: - - null - - - traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -348,7 +354,7 @@ ─ - 13 tests failed + 12 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/tap.edgecases.v16.log b/test-tap/reporters/tap.edgecases.v16.log index 0b7bcf535..ba4f57781 100644 --- a/test-tap/reporters/tap.edgecases.v16.log +++ b/test-tap/reporters/tap.edgecases.v16.log @@ -1,10 +1,6 @@ TAP version 13 ---tty-stream-chunk-separator -not ok 1 - ~/test-tap/fixture/report/edgecases/ast-syntax-error.cjs:3 -const fn = do { - ^^ - -SyntaxError: Unexpected token 'do' +not ok 1 - SyntaxError: Unexpected token 'do' --- name: SyntaxError message: Unexpected token 'do' diff --git a/test-tap/reporters/tap.regular.v14.log b/test-tap/reporters/tap.regular.v14.log index 3fd8b13c2..4f3db7b9e 100644 --- a/test-tap/reporters/tap.regular.v14.log +++ b/test-tap/reporters/tap.regular.v14.log @@ -135,16 +135,25 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - test › implementation throws non-error +not ok 15 - TypeError: Cannot read property 'matcherResult' of null --- - name: AssertionError - message: Error thrown in test - values: - 'Error thrown in test:': 'null' - at: '' + name: TypeError + message: Cannot read property 'matcherResult' of null + at: |- + TypeError: Cannot read property 'matcherResult' of null + at isExternalAssertError (file://~/lib/test.js:12:12) + at Test.run (file://~/lib/test.js:532:8) + at Runner.runSingle (file://~/lib/runner.js:285:33) + at Runner.runTest (file://~/lib/runner.js:367:30) + at processTicksAndRejections (internal/process/task_queues.js:95:5) + at async Promise.all (index 6) + at async file://~/lib/runner.js:532:21 + at async Runner.start (file://~/lib/runner.js:540:15) ... ---tty-stream-chunk-separator -not ok 16 - traces-in-t-throws › throws +not ok 16 - test.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 17 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -163,7 +172,7 @@ not ok 16 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › notThrows +not ok 18 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -178,7 +187,7 @@ not ok 17 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrowsAsync +not ok 19 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -193,7 +202,7 @@ not ok 18 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › throwsAsync +not ok 20 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -211,7 +220,7 @@ not ok 19 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync different error +not ok 21 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -228,9 +237,9 @@ not ok 20 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 21 - uncaught-exception › passes +ok 22 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 22 - Error: Can’t catch me +not ok 23 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -239,20 +248,20 @@ not ok 22 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 24 - unhandled-rejection › passes +ok 25 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › unhandled non-error rejection +ok 26 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 26 - Error: Can’t catch me +not ok 27 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 27 - unhandled-rejection +not ok 28 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -263,6 +272,6 @@ not ok 27 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 20 +# fail 22 ---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.regular.v16.log b/test-tap/reporters/tap.regular.v16.log index 3fd8b13c2..6c45a0561 100644 --- a/test-tap/reporters/tap.regular.v16.log +++ b/test-tap/reporters/tap.regular.v16.log @@ -135,16 +135,25 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - test › implementation throws non-error +not ok 15 - TypeError: Cannot read properties of null (reading 'matcherResult') --- - name: AssertionError - message: Error thrown in test - values: - 'Error thrown in test:': 'null' - at: '' + name: TypeError + message: Cannot read properties of null (reading 'matcherResult') + at: |- + TypeError: Cannot read properties of null (reading 'matcherResult') + at isExternalAssertError (file://~/lib/test.js:12:12) + at Test.run (file://~/lib/test.js:532:8) + at Runner.runSingle (file://~/lib/runner.js:285:33) + at Runner.runTest (file://~/lib/runner.js:367:30) + at processTicksAndRejections (node:internal/process/task_queues:96:5) + at async Promise.all (index 6) + at async file://~/lib/runner.js:532:21 + at async Runner.start (file://~/lib/runner.js:540:15) ... ---tty-stream-chunk-separator -not ok 16 - traces-in-t-throws › throws +not ok 16 - test.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 17 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -163,7 +172,7 @@ not ok 16 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › notThrows +not ok 18 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -178,7 +187,7 @@ not ok 17 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrowsAsync +not ok 19 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -193,7 +202,7 @@ not ok 18 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › throwsAsync +not ok 20 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -211,7 +220,7 @@ not ok 19 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync different error +not ok 21 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -228,9 +237,9 @@ not ok 20 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 21 - uncaught-exception › passes +ok 22 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 22 - Error: Can’t catch me +not ok 23 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -239,20 +248,20 @@ not ok 22 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 24 - unhandled-rejection › passes +ok 25 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › unhandled non-error rejection +ok 26 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 26 - Error: Can’t catch me +not ok 27 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 27 - unhandled-rejection +not ok 28 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -263,6 +272,6 @@ not ok 27 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 20 +# fail 22 ---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.regular.v18.log b/test-tap/reporters/tap.regular.v18.log index 3fd8b13c2..46a55f4ca 100644 --- a/test-tap/reporters/tap.regular.v18.log +++ b/test-tap/reporters/tap.regular.v18.log @@ -135,16 +135,25 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - test › implementation throws non-error +not ok 15 - TypeError: Cannot read properties of null (reading 'matcherResult') --- - name: AssertionError - message: Error thrown in test - values: - 'Error thrown in test:': 'null' - at: '' + name: TypeError + message: Cannot read properties of null (reading 'matcherResult') + at: |- + TypeError: Cannot read properties of null (reading 'matcherResult') + at isExternalAssertError (file://~/lib/test.js:12:12) + at Test.run (file://~/lib/test.js:532:8) + at Runner.runSingle (file://~/lib/runner.js:285:33) + at Runner.runTest (file://~/lib/runner.js:367:30) + at process.processTicksAndRejections (node:internal/process/task_queues:95:5) + at async Promise.all (index 6) + at async file://~/lib/runner.js:532:21 + at async Runner.start (file://~/lib/runner.js:540:15) ... ---tty-stream-chunk-separator -not ok 16 - traces-in-t-throws › throws +not ok 16 - test.cjs exited with a non-zero exit code: 1 +---tty-stream-chunk-separator +not ok 17 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -163,7 +172,7 @@ not ok 16 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › notThrows +not ok 18 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -178,7 +187,7 @@ not ok 17 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrowsAsync +not ok 19 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -193,7 +202,7 @@ not ok 18 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › throwsAsync +not ok 20 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -211,7 +220,7 @@ not ok 19 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync different error +not ok 21 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -228,9 +237,9 @@ not ok 20 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 21 - uncaught-exception › passes +ok 22 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 22 - Error: Can’t catch me +not ok 23 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -239,20 +248,20 @@ not ok 22 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 24 - unhandled-rejection › passes +ok 25 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › unhandled non-error rejection +ok 26 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 26 - Error: Can’t catch me +not ok 27 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 27 - unhandled-rejection +not ok 28 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -263,6 +272,6 @@ not ok 27 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 20 +# fail 22 ---tty-stream-chunk-separator From 8a5b07c1a80f9a7b1000f3a5d831da44fb33a766 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 18:40:10 +0200 Subject: [PATCH 06/13] :partly_sunny: improve error check --- lib/test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/test.js b/lib/test.js index 6f7827bb2..f6b1a968e 100644 --- a/lib/test.js +++ b/lib/test.js @@ -8,10 +8,9 @@ import nowAndTimers from './now-and-timers.cjs'; import parseTestArgs from './parse-test-args.js'; function isExternalAssertError(error) { + if (typeof error !== 'object' || error === null) return false; // Match errors thrown by . - if (error.matcherResult) { - return true; - } + if (hasOwnProperty(error, 'matcherResult')) return true; // Match errors thrown by and . return hasOwnProperty(error, 'actual') && hasOwnProperty(error, 'expected'); From 82062a40f86d8eedc459ae73ba2f79fbf07e48a4 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 18:43:08 +0200 Subject: [PATCH 07/13] :white_check_mark: update tap reporters --- test-tap/reporters/default.edgecases.v16.log | 4 ++ test-tap/reporters/default.regular.v14.log | 26 +++++------ test-tap/reporters/default.regular.v16.log | 26 +++++------ test-tap/reporters/default.regular.v18.log | 26 +++++------ test-tap/reporters/tap.edgecases.v16.log | 6 ++- test-tap/reporters/tap.regular.v14.log | 47 ++++++++------------ test-tap/reporters/tap.regular.v16.log | 47 ++++++++------------ test-tap/reporters/tap.regular.v18.log | 47 ++++++++------------ 8 files changed, 96 insertions(+), 133 deletions(-) diff --git a/test-tap/reporters/default.edgecases.v16.log b/test-tap/reporters/default.edgecases.v16.log index 489c5d133..b3c1b8057 100644 --- a/test-tap/reporters/default.edgecases.v16.log +++ b/test-tap/reporters/default.edgecases.v16.log @@ -7,6 +7,10 @@ ---tty-stream-chunk-separator Uncaught exception in ast-syntax-error.cjs + ~/test-tap/fixture/report/edgecases/ast-syntax-error.cjs:3 + const fn = do { + ^^ + SyntaxError: Unexpected token 'do' ---tty-stream-chunk-separator diff --git a/test-tap/reporters/default.regular.v14.log b/test-tap/reporters/default.regular.v14.log index 20475f590..9b9a969d3 100644 --- a/test-tap/reporters/default.regular.v14.log +++ b/test-tap/reporters/default.regular.v14.log @@ -62,21 +62,7 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ Internal error when running test.cjs - TypeError: Cannot read property 'matcherResult' of null - TypeError: Cannot read property 'matcherResult' of null -  at isExternalAssertError (file://~/lib/test.js:12:12) -  at Test.run (file://~/lib/test.js:532:8) -  at Runner.runSingle (file://~/lib/runner.js:285:33) -  at Runner.runTest (file://~/lib/runner.js:367:30) -  at processTicksAndRejections (internal/process/task_queues.js:95:5) -  at async Promise.all (index 6) -  at async file://~/lib/runner.js:532:21 -  at async Runner.start (file://~/lib/runner.js:540:15) - - ----tty-stream-chunk-separator - ✘ test.cjs exited with a non-zero exit code: 1 + ✘ [fail]: test › implementation throws non-error Error thrown in test ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -247,6 +233,14 @@ + test › implementation throws non-error + + Error thrown in test: + + null + + + traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -354,7 +348,7 @@ ─ - 12 tests failed + 13 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/default.regular.v16.log b/test-tap/reporters/default.regular.v16.log index 8c9a76be5..9b9a969d3 100644 --- a/test-tap/reporters/default.regular.v16.log +++ b/test-tap/reporters/default.regular.v16.log @@ -62,21 +62,7 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ Internal error when running test.cjs - TypeError: Cannot read properties of null (reading 'matcherResult') - TypeError: Cannot read properties of null (reading 'matcherResult') -  at isExternalAssertError (file://~/lib/test.js:12:12) -  at Test.run (file://~/lib/test.js:532:8) -  at Runner.runSingle (file://~/lib/runner.js:285:33) -  at Runner.runTest (file://~/lib/runner.js:367:30) -  at processTicksAndRejections (node:internal/process/task_queues:96:5) -  at async Promise.all (index 6) -  at async file://~/lib/runner.js:532:21 -  at async Runner.start (file://~/lib/runner.js:540:15) - - ----tty-stream-chunk-separator - ✘ test.cjs exited with a non-zero exit code: 1 + ✘ [fail]: test › implementation throws non-error Error thrown in test ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -247,6 +233,14 @@ + test › implementation throws non-error + + Error thrown in test: + + null + + + traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -354,7 +348,7 @@ ─ - 12 tests failed + 13 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/default.regular.v18.log b/test-tap/reporters/default.regular.v18.log index 3a982ae33..9b9a969d3 100644 --- a/test-tap/reporters/default.regular.v18.log +++ b/test-tap/reporters/default.regular.v18.log @@ -62,21 +62,7 @@ ---tty-stream-chunk-separator ✘ [fail]: test › formatted ---tty-stream-chunk-separator - ✘ Internal error when running test.cjs - TypeError: Cannot read properties of null (reading 'matcherResult') - TypeError: Cannot read properties of null (reading 'matcherResult') -  at isExternalAssertError (file://~/lib/test.js:12:12) -  at Test.run (file://~/lib/test.js:532:8) -  at Runner.runSingle (file://~/lib/runner.js:285:33) -  at Runner.runTest (file://~/lib/runner.js:367:30) -  at process.processTicksAndRejections (node:internal/process/task_queues:95:5) -  at async Promise.all (index 6) -  at async file://~/lib/runner.js:532:21 -  at async Runner.start (file://~/lib/runner.js:540:15) - - ----tty-stream-chunk-separator - ✘ test.cjs exited with a non-zero exit code: 1 + ✘ [fail]: test › implementation throws non-error Error thrown in test ---tty-stream-chunk-separator ✘ [fail]: traces-in-t-throws › throws ---tty-stream-chunk-separator @@ -247,6 +233,14 @@ + test › implementation throws non-error + + Error thrown in test: + + null + + + traces-in-t-throws › throws traces-in-t-throws.cjs:12 @@ -354,7 +348,7 @@ ─ - 12 tests failed + 13 tests failed 1 known failure 1 test skipped 1 test todo diff --git a/test-tap/reporters/tap.edgecases.v16.log b/test-tap/reporters/tap.edgecases.v16.log index ba4f57781..0b7bcf535 100644 --- a/test-tap/reporters/tap.edgecases.v16.log +++ b/test-tap/reporters/tap.edgecases.v16.log @@ -1,6 +1,10 @@ TAP version 13 ---tty-stream-chunk-separator -not ok 1 - SyntaxError: Unexpected token 'do' +not ok 1 - ~/test-tap/fixture/report/edgecases/ast-syntax-error.cjs:3 +const fn = do { + ^^ + +SyntaxError: Unexpected token 'do' --- name: SyntaxError message: Unexpected token 'do' diff --git a/test-tap/reporters/tap.regular.v14.log b/test-tap/reporters/tap.regular.v14.log index 4f3db7b9e..3fd8b13c2 100644 --- a/test-tap/reporters/tap.regular.v14.log +++ b/test-tap/reporters/tap.regular.v14.log @@ -135,25 +135,16 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - TypeError: Cannot read property 'matcherResult' of null +not ok 15 - test › implementation throws non-error --- - name: TypeError - message: Cannot read property 'matcherResult' of null - at: |- - TypeError: Cannot read property 'matcherResult' of null - at isExternalAssertError (file://~/lib/test.js:12:12) - at Test.run (file://~/lib/test.js:532:8) - at Runner.runSingle (file://~/lib/runner.js:285:33) - at Runner.runTest (file://~/lib/runner.js:367:30) - at processTicksAndRejections (internal/process/task_queues.js:95:5) - at async Promise.all (index 6) - at async file://~/lib/runner.js:532:21 - at async Runner.start (file://~/lib/runner.js:540:15) + name: AssertionError + message: Error thrown in test + values: + 'Error thrown in test:': 'null' + at: '' ... ---tty-stream-chunk-separator -not ok 16 - test.cjs exited with a non-zero exit code: 1 ----tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › throws +not ok 16 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -172,7 +163,7 @@ not ok 17 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrows +not ok 17 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -187,7 +178,7 @@ not ok 18 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › notThrowsAsync +not ok 18 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -202,7 +193,7 @@ not ok 19 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync +not ok 19 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -220,7 +211,7 @@ not ok 20 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 21 - traces-in-t-throws › throwsAsync different error +not ok 20 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -237,9 +228,9 @@ not ok 21 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 22 - uncaught-exception › passes +ok 21 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 23 - Error: Can’t catch me +not ok 22 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -248,20 +239,20 @@ not ok 23 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › passes +ok 24 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 26 - unhandled-rejection › unhandled non-error rejection +ok 25 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 27 - Error: Can’t catch me +not ok 26 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 28 - unhandled-rejection +not ok 27 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -272,6 +263,6 @@ not ok 28 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 22 +# fail 20 ---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.regular.v16.log b/test-tap/reporters/tap.regular.v16.log index 6c45a0561..3fd8b13c2 100644 --- a/test-tap/reporters/tap.regular.v16.log +++ b/test-tap/reporters/tap.regular.v16.log @@ -135,25 +135,16 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - TypeError: Cannot read properties of null (reading 'matcherResult') +not ok 15 - test › implementation throws non-error --- - name: TypeError - message: Cannot read properties of null (reading 'matcherResult') - at: |- - TypeError: Cannot read properties of null (reading 'matcherResult') - at isExternalAssertError (file://~/lib/test.js:12:12) - at Test.run (file://~/lib/test.js:532:8) - at Runner.runSingle (file://~/lib/runner.js:285:33) - at Runner.runTest (file://~/lib/runner.js:367:30) - at processTicksAndRejections (node:internal/process/task_queues:96:5) - at async Promise.all (index 6) - at async file://~/lib/runner.js:532:21 - at async Runner.start (file://~/lib/runner.js:540:15) + name: AssertionError + message: Error thrown in test + values: + 'Error thrown in test:': 'null' + at: '' ... ---tty-stream-chunk-separator -not ok 16 - test.cjs exited with a non-zero exit code: 1 ----tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › throws +not ok 16 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -172,7 +163,7 @@ not ok 17 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrows +not ok 17 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -187,7 +178,7 @@ not ok 18 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › notThrowsAsync +not ok 18 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -202,7 +193,7 @@ not ok 19 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync +not ok 19 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -220,7 +211,7 @@ not ok 20 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 21 - traces-in-t-throws › throwsAsync different error +not ok 20 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -237,9 +228,9 @@ not ok 21 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 22 - uncaught-exception › passes +ok 21 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 23 - Error: Can’t catch me +not ok 22 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -248,20 +239,20 @@ not ok 23 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › passes +ok 24 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 26 - unhandled-rejection › unhandled non-error rejection +ok 25 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 27 - Error: Can’t catch me +not ok 26 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 28 - unhandled-rejection +not ok 27 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -272,6 +263,6 @@ not ok 28 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 22 +# fail 20 ---tty-stream-chunk-separator diff --git a/test-tap/reporters/tap.regular.v18.log b/test-tap/reporters/tap.regular.v18.log index 46a55f4ca..3fd8b13c2 100644 --- a/test-tap/reporters/tap.regular.v18.log +++ b/test-tap/reporters/tap.regular.v18.log @@ -135,25 +135,16 @@ not ok 14 - test › formatted at: 'test-tap/fixture/report/regular/test.cjs:22:4' ... ---tty-stream-chunk-separator -not ok 15 - TypeError: Cannot read properties of null (reading 'matcherResult') +not ok 15 - test › implementation throws non-error --- - name: TypeError - message: Cannot read properties of null (reading 'matcherResult') - at: |- - TypeError: Cannot read properties of null (reading 'matcherResult') - at isExternalAssertError (file://~/lib/test.js:12:12) - at Test.run (file://~/lib/test.js:532:8) - at Runner.runSingle (file://~/lib/runner.js:285:33) - at Runner.runTest (file://~/lib/runner.js:367:30) - at process.processTicksAndRejections (node:internal/process/task_queues:95:5) - at async Promise.all (index 6) - at async file://~/lib/runner.js:532:21 - at async Runner.start (file://~/lib/runner.js:540:15) + name: AssertionError + message: Error thrown in test + values: + 'Error thrown in test:': 'null' + at: '' ... ---tty-stream-chunk-separator -not ok 16 - test.cjs exited with a non-zero exit code: 1 ----tty-stream-chunk-separator -not ok 17 - traces-in-t-throws › throws +not ok 16 - traces-in-t-throws › throws --- name: AssertionError assertion: throws @@ -172,7 +163,7 @@ not ok 17 - traces-in-t-throws › throws test-tap/fixture/report/regular/traces-in-t-throws.cjs:12:4 ... ---tty-stream-chunk-separator -not ok 18 - traces-in-t-throws › notThrows +not ok 17 - traces-in-t-throws › notThrows --- name: AssertionError assertion: notThrows @@ -187,7 +178,7 @@ not ok 18 - traces-in-t-throws › notThrows test-tap/fixture/report/regular/traces-in-t-throws.cjs:16:4 ... ---tty-stream-chunk-separator -not ok 19 - traces-in-t-throws › notThrowsAsync +not ok 18 - traces-in-t-throws › notThrowsAsync --- name: AssertionError assertion: notThrowsAsync @@ -202,7 +193,7 @@ not ok 19 - traces-in-t-throws › notThrowsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:20:4 ... ---tty-stream-chunk-separator -not ok 20 - traces-in-t-throws › throwsAsync +not ok 19 - traces-in-t-throws › throwsAsync --- name: AssertionError assertion: throwsAsync @@ -220,7 +211,7 @@ not ok 20 - traces-in-t-throws › throwsAsync test-tap/fixture/report/regular/traces-in-t-throws.cjs:24:4 ... ---tty-stream-chunk-separator -not ok 21 - traces-in-t-throws › throwsAsync different error +not ok 20 - traces-in-t-throws › throwsAsync different error --- name: AssertionError assertion: throwsAsync @@ -237,9 +228,9 @@ not ok 21 - traces-in-t-throws › throwsAsync different error test-tap/fixture/report/regular/traces-in-t-throws.cjs:27:44 ... ---tty-stream-chunk-separator -ok 22 - uncaught-exception › passes +ok 21 - uncaught-exception › passes ---tty-stream-chunk-separator -not ok 23 - Error: Can’t catch me +not ok 22 - Error: Can’t catch me --- name: Error message: Can’t catch me @@ -248,20 +239,20 @@ not ok 23 - Error: Can’t catch me (test-tap/fixture/report/regular/uncaught-exception.cjs:5:9) ... ---tty-stream-chunk-separator -not ok 24 - uncaught-exception.cjs exited with a non-zero exit code: 1 +not ok 23 - uncaught-exception.cjs exited with a non-zero exit code: 1 ---tty-stream-chunk-separator -ok 25 - unhandled-rejection › passes +ok 24 - unhandled-rejection › passes ---tty-stream-chunk-separator -ok 26 - unhandled-rejection › unhandled non-error rejection +ok 25 - unhandled-rejection › unhandled non-error rejection ---tty-stream-chunk-separator -not ok 27 - Error: Can’t catch me +not ok 26 - Error: Can’t catch me --- name: Error message: Can’t catch me at: 'passes (test-tap/fixture/report/regular/unhandled-rejection.cjs:4:17)' ... ---tty-stream-chunk-separator -not ok 28 - unhandled-rejection +not ok 27 - unhandled-rejection --- message: Non-error object formatted: 'null' @@ -272,6 +263,6 @@ not ok 28 - unhandled-rejection # tests 20 # pass 6 # skip 1 -# fail 22 +# fail 20 ---tty-stream-chunk-separator From 1c45b23537022b92c3142f19fe64c393542e11dd Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Wed, 12 Apr 2023 19:37:34 +0200 Subject: [PATCH 08/13] :ribbon: lint --- lib/test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/test.js b/lib/test.js index f6b1a968e..896f253b3 100644 --- a/lib/test.js +++ b/lib/test.js @@ -8,9 +8,14 @@ import nowAndTimers from './now-and-timers.cjs'; import parseTestArgs from './parse-test-args.js'; function isExternalAssertError(error) { - if (typeof error !== 'object' || error === null) return false; + if (typeof error !== 'object' || error === null) { + return false; + } + // Match errors thrown by . - if (hasOwnProperty(error, 'matcherResult')) return true; + if (hasOwnProperty(error, 'matcherResult')) { + return true; + } // Match errors thrown by and . return hasOwnProperty(error, 'actual') && hasOwnProperty(error, 'expected'); From 581c78927361760cf313306d8a4292c7978d78b0 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Mon, 17 Apr 2023 08:51:49 +0200 Subject: [PATCH 09/13] :white_check_mark: fix test --- test/external-assertions/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/external-assertions/test.js b/test/external-assertions/test.js index 4695dc28b..a50deabf9 100644 --- a/test/external-assertions/test.js +++ b/test/external-assertions/test.js @@ -4,10 +4,10 @@ import {fixture} from '../helpers/exec.js'; test('node assertion ', async t => { const result = await t.throwsAsync(fixture(['assert-failure.js'])); - t.snapshot(result.stdout); + t.snapshot(result.stdout.replace(/\r/g, '')); }); test('expect error ', async t => { const result = await t.throwsAsync(fixture(['expect-failure.js'])); - t.snapshot(result.stdout); + t.snapshot(result.stdout.replace(/\r/g, '')); }); From 40e6eeeccb917f5f0d65a7dafe2a3025d9e674b6 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Mon, 17 Apr 2023 08:52:54 +0200 Subject: [PATCH 10/13] duplicate hasOwnProperty --- lib/assert.js | 2 +- lib/test.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index a55a06721..15818739c 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -27,7 +27,7 @@ function formatWithLabel(label, value) { return formatDescriptorWithLabel(label, concordance.describe(value, concordanceOptions)); } -export const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); +const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); const noop = () => {}; const notImplemented = () => { throw new Error('not implemented'); diff --git a/lib/test.js b/lib/test.js index 896f253b3..d130e233f 100644 --- a/lib/test.js +++ b/lib/test.js @@ -2,11 +2,13 @@ import concordance from 'concordance'; import isPromise from 'is-promise'; import plur from 'plur'; -import {AssertionError, Assertions, checkAssertionMessage, hasOwnProperty} from './assert.js'; +import {AssertionError, Assertions, checkAssertionMessage} from './assert.js'; import concordanceOptions from './concordance-options.js'; import nowAndTimers from './now-and-timers.cjs'; import parseTestArgs from './parse-test-args.js'; +const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); + function isExternalAssertError(error) { if (typeof error !== 'object' || error === null) { return false; From 5e52c46a6a6b91b54633bfe7c7edd66fea32a1a4 Mon Sep 17 00:00:00 2001 From: Irven Aelbrecht Date: Mon, 17 Apr 2023 09:22:31 +0200 Subject: [PATCH 11/13] :white_check_mark: fix windows test --- test/external-assertions/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/external-assertions/test.js b/test/external-assertions/test.js index a50deabf9..65b2ddfc7 100644 --- a/test/external-assertions/test.js +++ b/test/external-assertions/test.js @@ -4,10 +4,10 @@ import {fixture} from '../helpers/exec.js'; test('node assertion ', async t => { const result = await t.throwsAsync(fixture(['assert-failure.js'])); - t.snapshot(result.stdout.replace(/\r/g, '')); + t.snapshot(result.stdout.replace(/\r/g, '').replace(/\/{3}/g, '//')); }); test('expect error ', async t => { const result = await t.throwsAsync(fixture(['expect-failure.js'])); - t.snapshot(result.stdout.replace(/\r/g, '')); + t.snapshot(result.stdout.replace(/\r/g, '').replace(/\/{3}/g, '//')); }); From b6769f182a271bf3eec3cf9787ba925664e35186 Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 21 May 2023 18:41:39 +0200 Subject: [PATCH 12/13] Test async codepath --- .../fixtures/assert-failure.js | 4 ++ .../fixtures/expect-failure.js | 4 ++ test/external-assertions/snapshots/test.js.md | 41 +++++++++++++++++- .../snapshots/test.js.snap | Bin 373 -> 448 bytes 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/test/external-assertions/fixtures/assert-failure.js b/test/external-assertions/fixtures/assert-failure.js index 7c5806c7e..564a15dff 100644 --- a/test/external-assertions/fixtures/assert-failure.js +++ b/test/external-assertions/fixtures/assert-failure.js @@ -5,3 +5,7 @@ import test from 'ava'; test('test', () => { assert(false); }); + +test('test async', async () => { + assert(false); +}); diff --git a/test/external-assertions/fixtures/expect-failure.js b/test/external-assertions/fixtures/expect-failure.js index b410bc858..9b05ab96e 100644 --- a/test/external-assertions/fixtures/expect-failure.js +++ b/test/external-assertions/fixtures/expect-failure.js @@ -4,3 +4,7 @@ import {expect} from 'expect'; test('test', () => { expect(false).toBeTruthy(); }); + +test('test async', async () => { + expect(false).toBeTruthy(); +}); diff --git a/test/external-assertions/snapshots/test.js.md b/test/external-assertions/snapshots/test.js.md index 1f1000aef..d6b65ab3b 100644 --- a/test/external-assertions/snapshots/test.js.md +++ b/test/external-assertions/snapshots/test.js.md @@ -10,6 +10,7 @@ Generated by [AVA](https://avajs.dev). `␊ ✘ [fail]: test Assertion failed␊ + ✘ [fail]: test async Assertion failed␊ ─␊ ␊ test␊ @@ -25,10 +26,26 @@ Generated by [AVA](https://avajs.dev). false == true␊ ␊ › file://assert-failure.js:6:2␊ + ␊ + ␊ + ␊ + test async␊ + ␊ + assert-failure.js:10␊ + ␊ + 9: test('test async', async () => {␊ + 10: assert(false); ␊ + 11: }); ␊ + ␊ + Assertion failed: ␊ + ␊ + false == true␊ + ␊ + › file://assert-failure.js:10:2␊ ␊ ─␊ ␊ - 1 test failed` + 2 tests failed` ## expect error @@ -36,6 +53,7 @@ Generated by [AVA](https://avajs.dev). `␊ ✘ [fail]: test Assertion failed␊ + ✘ [fail]: test async Assertion failed␊ ─␊ ␊ test␊ @@ -54,7 +72,26 @@ Generated by [AVA](https://avajs.dev). ␊ › Received: false␊ › file://expect-failure.js:5:16␊ + ␊ + ␊ + ␊ + test async␊ + ␊ + expect-failure.js:9␊ + ␊ + 8: test('test async', async () => {␊ + 9: expect(false).toBeTruthy(); ␊ + 10: }); ␊ + ␊ + Assertion failed: ␊ + ␊ + expect(received).toBeTruthy()␊ + ␊ + Received: false␊ + ␊ + › Received: false␊ + › file://expect-failure.js:9:16␊ ␊ ─␊ ␊ - 1 test failed` + 2 tests failed` diff --git a/test/external-assertions/snapshots/test.js.snap b/test/external-assertions/snapshots/test.js.snap index 3f12b7ab15c89933a182d753a84b961313316bb9..ce0f4db5f077351c4c8daef95853ab334dd47cb0 100644 GIT binary patch literal 448 zcmV;x0YCmhRzV2d1 z%mya1avzHb00000000BMQcX(3KoqVO5wdgR`fa2sXxkK9&6Emy1aTwcVoY8z8j>4l0Zd<>;Vj@`bk0DbRB%}I14Yp{)o?kA zJ!9q5*h(KNqF3*-L+PQw#+77U3PVTFv1@eKw!yAL{{ZeN)n!oh*#VCv)_Z9HD7DAn zUjIsmCeE+IvS`*1{XQr$L<&sD?+~PU)@&M9V{OYSw$~8N7@SrH0^C^?x*^4)xtT%a zw9Jr77^u!M<68#Sbf>oUsaHD#BJ+W{og%y)pr-(ZNQA*mZzVHLmTo4!&Mb;fro*n; zOeJnRB!M1~OVCis5uS*lx*XZ{Uhcea>0iu!K3JfK;SKub*;H_xXPB0$kY_$z63qaY qIbD-OzgD^#G5f#sr~3mpg*{t;vFATgk- Date: Sun, 21 May 2023 18:48:55 +0200 Subject: [PATCH 13/13] Respect linting --- .../fixtures/assert-failure.js | 2 +- .../fixtures/expect-failure.js | 2 +- test/external-assertions/snapshots/test.js.md | 14 +++++++------- test/external-assertions/snapshots/test.js.snap | Bin 448 -> 478 bytes 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/external-assertions/fixtures/assert-failure.js b/test/external-assertions/fixtures/assert-failure.js index 564a15dff..74a0d043f 100644 --- a/test/external-assertions/fixtures/assert-failure.js +++ b/test/external-assertions/fixtures/assert-failure.js @@ -7,5 +7,5 @@ test('test', () => { }); test('test async', async () => { - assert(false); + assert(await Promise.resolve(false)); }); diff --git a/test/external-assertions/fixtures/expect-failure.js b/test/external-assertions/fixtures/expect-failure.js index 9b05ab96e..e0364a264 100644 --- a/test/external-assertions/fixtures/expect-failure.js +++ b/test/external-assertions/fixtures/expect-failure.js @@ -6,5 +6,5 @@ test('test', () => { }); test('test async', async () => { - expect(false).toBeTruthy(); + expect(await Promise.resolve(false)).toBeTruthy(); }); diff --git a/test/external-assertions/snapshots/test.js.md b/test/external-assertions/snapshots/test.js.md index d6b65ab3b..a6981b7e0 100644 --- a/test/external-assertions/snapshots/test.js.md +++ b/test/external-assertions/snapshots/test.js.md @@ -33,9 +33,9 @@ Generated by [AVA](https://avajs.dev). ␊ assert-failure.js:10␊ ␊ - 9: test('test async', async () => {␊ - 10: assert(false); ␊ - 11: }); ␊ + 9: test('test async', async () => { ␊ + 10: assert(await Promise.resolve(false));␊ + 11: }); ␊ ␊ Assertion failed: ␊ ␊ @@ -79,9 +79,9 @@ Generated by [AVA](https://avajs.dev). ␊ expect-failure.js:9␊ ␊ - 8: test('test async', async () => {␊ - 9: expect(false).toBeTruthy(); ␊ - 10: }); ␊ + 8: test('test async', async () => { ␊ + 9: expect(await Promise.resolve(false)).toBeTruthy();␊ + 10: }); ␊ ␊ Assertion failed: ␊ ␊ @@ -90,7 +90,7 @@ Generated by [AVA](https://avajs.dev). Received: false␊ ␊ › Received: false␊ - › file://expect-failure.js:9:16␊ + › file://expect-failure.js:9:39␊ ␊ ─␊ ␊ diff --git a/test/external-assertions/snapshots/test.js.snap b/test/external-assertions/snapshots/test.js.snap index ce0f4db5f077351c4c8daef95853ab334dd47cb0..e9ee42e2a7584aa7b927c77503249797eeb5487e 100644 GIT binary patch literal 478 zcmV<40U`cDRzVf;>wrg|*^((Eu2|Jj1C+{oss%KrUcE>jxP{S64&% zZP?aUJ`Ifcl11`XyKKsIk74D46I+I%q2`z+`7UjMS%%gg+{u(pAnP+d8gMK(;{eFi z4uO01l{<3c^eQBYCjHQAfnYt9fzjX%yf{y)Rn2OoZW!723Zfo^RZBpCGl@bq#8?zJ zDWYt}__1me$mlio1st;I%I8>N$fKZ-Dc*83DYx`!HRrboh&QYoV-f2KI-U+pJr>|i z7uy1mv509L_K|bg`=2{Ztuu+Dk%+Ucci5OS<-%-0N_|B{2YAeSqH}918SEcan9qGW zm|+|JKDznYvfwDq5G7M4&vZB^ng%YhY@KaqE1iUx-Gxn?$Ep1O1?yV_&(bK(zo47{ U7rhSIa_0UMpR6X9=79wO0E!{m+W-In literal 448 zcmV;x0YCmhRzV2d1 z%mya1avzHb00000000BMQcX(3KoqVO5wdgR`fa2sXxkK9&6Emy1aTwcVoY8z8j>4l0Zd<>;Vj@`bk0DbRB%}I14Yp{)o?kA zJ!9q5*h(KNqF3*-L+PQw#+77U3PVTFv1@eKw!yAL{{ZeN)n!oh*#VCv)_Z9HD7DAn zUjIsmCeE+IvS`*1{XQr$L<&sD?+~PU)@&M9V{OYSw$~8N7@SrH0^C^?x*^4)xtT%a zw9Jr77^u!M<68#Sbf>oUsaHD#BJ+W{og%y)pr-(ZNQA*mZzVHLmTo4!&Mb;fro*n; zOeJnRB!M1~OVCis5uS*lx*XZ{Uhcea>0iu!K3JfK;SKub*;H_xXPB0$kY_$z63qaY qIbD-OzgD^#G5f#sr~3mpg*{t;vFATg