From ce6185eecaf496dd28eaa47c468b22d8f20c72ad Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 10 Mar 2023 16:16:04 +0530 Subject: [PATCH] refactor: assertion messages --- src/base.ts | 7 ++-- src/mocked_prompt.ts | 59 +++++++++++++++++++++++++------- tests/traps/autocomplete.spec.ts | 6 ++-- tests/traps/confirmation.spec.ts | 9 +++-- tests/traps/input.spec.ts | 11 +++--- tests/traps/list.spec.ts | 6 ++-- tests/traps/multi_select.spec.ts | 6 ++-- tests/traps/secure.spec.ts | 9 +++-- tests/traps/select.spec.ts | 6 ++-- tests/traps/toggle.spec.ts | 6 ++-- 10 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/base.ts b/src/base.ts index 2561999..32a97e7 100644 --- a/src/base.ts +++ b/src/base.ts @@ -7,6 +7,7 @@ * file that was distributed with this source code. */ +import { AssertionError } from 'node:assert' import { ObjectBuilder } from '@poppinss/utils' import { @@ -30,7 +31,7 @@ import { promptHiglight, promptPrefix, promptStyles } from './prompt_options.js' */ export abstract class BasePrompt { traps: { - prompts: Map + prompts: Map verify: () => void } = { prompts: new Map(), @@ -311,7 +312,9 @@ export abstract class BasePrompt { * Trigger error is raised when the prompt is not triggered but * trapped */ - const triggerError = new Error(`Expected prompt "${message}" to get triggered`) + const triggerError = new AssertionError({ + message: `Expected prompt "${message}" to get triggered`, + }) const mockedPrompt = new MockedPrompt() this.traps.prompts.set(message, { prompt: mockedPrompt, triggerError }) diff --git a/src/mocked_prompt.ts b/src/mocked_prompt.ts index df58754..4cb8c54 100644 --- a/src/mocked_prompt.ts +++ b/src/mocked_prompt.ts @@ -7,6 +7,8 @@ * file that was distributed with this source code. */ +import { inspect } from 'node:util' +import { AssertionError } from 'node:assert' import { PromptState } from './types.js' export class MockedPrompt { @@ -32,7 +34,7 @@ export class MockedPrompt { value: string expectsError: boolean // Does assertion expects error? expectedErrorMessage?: string | RegExp - error: Error + error: AssertionError }[] = [] /** @@ -167,20 +169,23 @@ export class MockedPrompt { if (result !== true) { throw assertion.error } - + } else { /** * Expected the value to fail the assertion, but the * validation method returned true */ - } else { if (result === true) { throw assertion.error } + /** + * Validation failed but the error message is different + */ if ( typeof assertion.expectedErrorMessage === 'string' && result !== assertion.expectedErrorMessage ) { + assertion.error.actual = result throw assertion.error } @@ -300,18 +305,46 @@ export class MockedPrompt { * Expect the given value to fail the prompt validation */ assertFails(value: string, message?: string | RegExp): this { - const error = new Error( - message - ? typeof message === 'string' - ? `Expected assertion to fail with message "${message}"` - : `Expected assertion messages to match "${message}"` - : 'Expected assertion to fail' - ) + if (!message) { + this.#assertions.push({ + value, + expectsError: true, + expectedErrorMessage: message, + error: new AssertionError({ + message: 'Expected prompt validation to fail', + stackStartFn: this.assertFails, + }), + }) + return this + } + + if (typeof message === 'string') { + const error = new AssertionError({ + message: `Expected prompt validation message to equal ${inspect(message)}`, + expected: message, + operator: 'strictEqual', + stackStartFn: this.assertFails, + }) + Object.defineProperty(error, 'showDiff', { value: true }) + + this.#assertions.push({ + value, + expectsError: true, + expectedErrorMessage: message, + error, + }) + + return this + } + this.#assertions.push({ value, expectsError: true, expectedErrorMessage: message, - error: error, + error: new AssertionError({ + message: `Expected prompt validation message to match ${inspect(message)}`, + expected: message, + }), }) return this @@ -321,7 +354,9 @@ export class MockedPrompt { * Expect the given value to pass the prompt validation */ assertPasses(value: string): this { - const error = new Error('Expected assertion to pass, instead it failed') + const error = new AssertionError({ + message: 'Expected assertion to pass, instead it failed', + }) this.#assertions.push({ value, expectsError: false, diff --git a/tests/traps/autocomplete.spec.ts b/tests/traps/autocomplete.spec.ts index 99698cc..5fd189e 100644 --- a/tests/traps/autocomplete.spec.ts +++ b/tests/traps/autocomplete.spec.ts @@ -58,7 +58,7 @@ test.group('Prompts | autocomplete', () => { await assert.rejects( () => prompt.autocomplete('Select the installation client', ['npm', 'yarn']), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -73,7 +73,7 @@ test.group('Prompts | autocomplete', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -105,7 +105,7 @@ test.group('Prompts | autocomplete', () => { return 'Enter client' }, }), - 'Expected assertion to fail with message "client is required"' + `Expected prompt validation message to equal 'client is required'` ) }) diff --git a/tests/traps/confirmation.spec.ts b/tests/traps/confirmation.spec.ts index 9562e47..3d43a32 100644 --- a/tests/traps/confirmation.spec.ts +++ b/tests/traps/confirmation.spec.ts @@ -44,7 +44,10 @@ test.group('Prompts | confirm', () => { const prompt = new Prompt() prompt.trap('Delete the file?').assertFails('').replyWith('virk') - await assert.rejects(() => prompt.confirm('Delete the file?'), 'Expected assertion to fail') + await assert.rejects( + () => prompt.confirm('Delete the file?'), + 'Expected prompt validation to fail' + ) }) test('fail when expected failing assertion passes', async ({ assert }) => { @@ -58,7 +61,7 @@ test.group('Prompts | confirm', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -90,7 +93,7 @@ test.group('Prompts | confirm', () => { return 'Do not delete files' }, }), - 'Expected assertion to fail with message "You should not delete files"' + `Expected prompt validation message to equal 'You should not delete files'` ) }) diff --git a/tests/traps/input.spec.ts b/tests/traps/input.spec.ts index 03dbc40..4d63e9e 100644 --- a/tests/traps/input.spec.ts +++ b/tests/traps/input.spec.ts @@ -35,7 +35,10 @@ test.group('Prompts | input', () => { const prompt = new Prompt() prompt.trap("What's your username?").assertFails('').replyWith('virk') - await assert.rejects(() => prompt.ask("What's your username?"), 'Expected assertion to fail') + await assert.rejects( + () => prompt.ask("What's your username?"), + 'Expected prompt validation to fail' + ) }) test('fail when expected failing assertion passes', async ({ assert }) => { @@ -49,7 +52,7 @@ test.group('Prompts | input', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -80,7 +83,7 @@ test.group('Prompts | input', () => { return 'Enter username' }, }), - 'Expected assertion to fail with message "Username is required"' + `Expected prompt validation message to equal 'Username is required'` ) }) @@ -127,7 +130,7 @@ test.group('Prompts | input', () => { return 'Enter username' }, }), - 'Expected assertion messages to match "/\\w+ is required/"' + 'Expected prompt validation message to match /\\w+ is required/' ) }) diff --git a/tests/traps/list.spec.ts b/tests/traps/list.spec.ts index 7ae8e4f..89e9d7e 100644 --- a/tests/traps/list.spec.ts +++ b/tests/traps/list.spec.ts @@ -44,7 +44,7 @@ test.group('Prompts | list', () => { const prompt = new Prompt() prompt.trap('Enter tags').assertFails('').replyWith('node,js') - await assert.rejects(() => prompt.list('Enter tags'), 'Expected assertion to fail') + await assert.rejects(() => prompt.list('Enter tags'), 'Expected prompt validation to fail') }) test('fail when expected failing assertion passes', async ({ assert }) => { @@ -58,7 +58,7 @@ test.group('Prompts | list', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -89,7 +89,7 @@ test.group('Prompts | list', () => { return 'Enter tags' }, }), - 'Expected assertion to fail with message "Tags are required"' + `Expected prompt validation message to equal 'Tags are required'` ) }) diff --git a/tests/traps/multi_select.spec.ts b/tests/traps/multi_select.spec.ts index cc534a6..8370d8e 100644 --- a/tests/traps/multi_select.spec.ts +++ b/tests/traps/multi_select.spec.ts @@ -73,7 +73,7 @@ test.group('Prompts | multiselect', () => { await assert.rejects( () => prompt.multiple('Select the installation client', ['npm', 'yarn']), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -88,7 +88,7 @@ test.group('Prompts | multiselect', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -120,7 +120,7 @@ test.group('Prompts | multiselect', () => { return 'Enter client' }, }), - 'Expected assertion to fail with message "client is required"' + `Expected prompt validation message to equal 'client is required'` ) }) diff --git a/tests/traps/secure.spec.ts b/tests/traps/secure.spec.ts index 399cc89..c76d955 100644 --- a/tests/traps/secure.spec.ts +++ b/tests/traps/secure.spec.ts @@ -35,7 +35,10 @@ test.group('Prompts | secure', () => { const prompt = new Prompt() prompt.trap('Choose password').assertFails('').replyWith('secret') - await assert.rejects(() => prompt.secure('Choose password'), 'Expected assertion to fail') + await assert.rejects( + () => prompt.secure('Choose password'), + 'Expected prompt validation to fail' + ) }) test('fail when expected failing assertion passes', async ({ assert }) => { @@ -49,7 +52,7 @@ test.group('Prompts | secure', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -80,7 +83,7 @@ test.group('Prompts | secure', () => { return 'Enter password' }, }), - 'Expected assertion to fail with message "Password is required"' + `Expected prompt validation message to equal 'Password is required'` ) }) diff --git a/tests/traps/select.spec.ts b/tests/traps/select.spec.ts index 3bb1ec8..e5c6dd2 100644 --- a/tests/traps/select.spec.ts +++ b/tests/traps/select.spec.ts @@ -73,7 +73,7 @@ test.group('Prompts | select', () => { await assert.rejects( () => prompt.choice('Select the installation client', ['npm', 'yarn']), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -88,7 +88,7 @@ test.group('Prompts | select', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -120,7 +120,7 @@ test.group('Prompts | select', () => { return 'Enter client' }, }), - 'Expected assertion to fail with message "client is required"' + `Expected prompt validation message to equal 'client is required'` ) }) diff --git a/tests/traps/toggle.spec.ts b/tests/traps/toggle.spec.ts index 1615e58..72562e1 100644 --- a/tests/traps/toggle.spec.ts +++ b/tests/traps/toggle.spec.ts @@ -55,7 +55,7 @@ test.group('Prompts | toggle', () => { await assert.rejects( () => prompt.toggle('Delete the file?', ['Yep', 'Nope']), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -70,7 +70,7 @@ test.group('Prompts | toggle', () => { return true }, }), - 'Expected assertion to fail' + 'Expected prompt validation to fail' ) }) @@ -102,7 +102,7 @@ test.group('Prompts | toggle', () => { return 'Do not delete files' }, }), - 'Expected assertion to fail with message "You should not delete files"' + `Expected prompt validation message to equal 'You should not delete files'` ) })