Skip to content

Commit

Permalink
test: prep for vitest 3 (#6822)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored Jan 22, 2025
1 parent e818de2 commit 156e022
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 53 deletions.
6 changes: 3 additions & 3 deletions packages/cspell-io/src/VirtualFs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,21 @@ describe('VirtualFs', () => {
test('try unsupported readFile', async () => {
const fs = virtualFs.fs;
const result = fs.readFile(new URL('ftp://example.com/data.json'));
await expect(result).rejects.toEqual(new Error('Unsupported request: readFile'));
await expect(result).rejects.toThrowError('Unsupported request: readFile');
await expect(result).rejects.toBeInstanceOf(VFSErrorUnsupportedRequest);
});

test('try unsupported stat', async () => {
const fs = virtualFs.fs;
const result = fs.stat(new URL('ftp://example.com/data.json'));
await expect(result).rejects.toEqual(new Error('Unsupported request: stat'));
await expect(result).rejects.toThrowError('Unsupported request: stat');
await expect(result).rejects.toBeInstanceOf(VFSErrorUnsupportedRequest);
});

test('try unsupported readDirectory', async () => {
const fs = virtualFs.fs;
const result = fs.readDirectory(new URL('ftp://example.com/data.json'));
await expect(result).rejects.toEqual(new Error('Unsupported request: readDirectory'));
await expect(result).rejects.toThrowError('Unsupported request: readDirectory');
await expect(result).rejects.toBeInstanceOf(VFSErrorUnsupportedRequest);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const urlIssues = new URL('issues/', pathRepoTestFixturesURL);
const oc = <T>(obj: T) => expect.objectContaining(obj);
const sm = (m: string | RegExp) => expect.stringMatching(m);

function expectError(err: string | Error) {
const message = typeof err === 'string' ? err : err.message;
return expect.objectContaining({ message });
}

vi.mock('../../../util/logger');

const mockedLogError = vi.mocked(logError);
Expand Down Expand Up @@ -488,9 +493,9 @@ describe('Validate search/load config files', () => {

test.each`
file | expectedConfig
${samplesSrc} | ${readError(samplesSrc).error}
${s('bug-fixes')} | ${readError(s('bug-fixes')).error}
${s('js-config/cspell-bad.js')} | ${readError(s('js-config/cspell-bad.js')).error}
${samplesSrc} | ${expectError(readError(samplesSrc).error)}
${s('bug-fixes')} | ${expectError(readError(s('bug-fixes')).error)}
${s('js-config/cspell-bad.js')} | ${expectError(readError(s('js-config/cspell-bad.js')).error)}
`('readConfigFile with error $file', async ({ file, expectedConfig }: TestLoadConfig) => {
await expect(readConfigFile(file)).rejects.toEqual(expectedConfig);
expect(mockedLogWarning).toHaveBeenCalledTimes(0);
Expand All @@ -502,9 +507,9 @@ describe('Validate search/load config files', () => {
${samplesSrc} | ${readError(samplesSrc).error}
${s('bug-fixes')} | ${readError(s('bug-fixes')).error}
${s('js-config/cspell-bad.js')} | ${readError(s('js-config/cspell-bad.js')).error}
`('ReadRawSettings with error $file', async ({ file, expectedConfig }: TestLoadConfig) => {
`('ReadRawSettings with error $file', async ({ file, expectedConfig }) => {
const result = await readRawSettings(file);
expect(result).toEqual(oc({ __importRef: oc({ error: expectedConfig }) }));
expect(result).toEqual(oc({ __importRef: oc({ error: expectError(expectedConfig) }) }));
expect(mockedLogWarning).toHaveBeenCalledTimes(0);
expect(mockedLogError).toHaveBeenCalledTimes(0);
});
Expand All @@ -517,9 +522,9 @@ describe('Validate search/load config files', () => {

test.each`
file | relativeTo | expectedConfig
${samplesSrc} | ${undefined} | ${readError(samplesSrc).error}
${s('bug-fixes')} | ${undefined} | ${readError(s('bug-fixes')).error}
${s('bug-fixes/not-found/cspell.json')} | ${undefined} | ${readError(s('bug-fixes/not-found/cspell.json')).error}
${samplesSrc} | ${undefined} | ${expectError(readError(samplesSrc).error)}
${s('bug-fixes')} | ${undefined} | ${expectError(readError(s('bug-fixes')).error)}
${s('bug-fixes/not-found/cspell.json')} | ${undefined} | ${expectError(readError(s('bug-fixes/not-found/cspell.json')).error)}
${s('dot-config/.config/cspell.config.yaml')} | ${undefined} | ${oc(cf(s('dot-config/.config/cspell.config.yaml'), oc({ name: 'Nested in .config' })))}
${rp('cspell.config.json')} | ${undefined} | ${oc(cf(rp('cspell.config.json'), oc({ id: 'cspell-package-config' })))}
${s('linked/cspell.config.js')} | ${undefined} | ${cf(s('linked/cspell.config.js'), oc({ description: 'cspell.config.js file in samples/linked' }))}
Expand Down Expand Up @@ -768,7 +773,7 @@ describe('ConfigLoader with VirtualFS', () => {

expect(configFile).toBeInstanceOf(Error);
assert(configFile instanceof Error);
expect(configFile.cause).toEqual(new Error(`Untrusted URL: "${location?.href}"`));
expect(configFile.cause).toEqual(expectError(`Untrusted URL: "${location?.href}"`));
});
});

Expand Down
3 changes: 1 addition & 2 deletions packages/cspell-lib/src/lib/spellCheckFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { extendExpect } from '../test-util/test.matchers.mjs';
import type { Document } from './Document/index.js';
import { fileToDocument, fileToTextDocument } from './Document/resolveDocument.js';
import type { CSpellSettingsInternal } from './Models/CSpellSettingsInternalDef.js';
import { ImportError } from './Settings/Controller/ImportError.js';
import type { SpellCheckFileOptions, SpellCheckFileResult } from './spellCheckFile.js';
import { determineFinalDocumentSettings, spellCheckDocument, spellCheckFile } from './spellCheckFile.js';
import * as Uri from './util/Uri.js';
Expand Down Expand Up @@ -278,7 +277,7 @@ function tf(file: string) {
}

function err(msg: string): Error {
return new ImportError(msg);
return new Error(msg);
}

function errNoEnt(file: string): Error {
Expand Down
2 changes: 1 addition & 1 deletion packages/cspell-lib/src/lib/util/errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('errors', () => {
test.each`
err | expected
${new Error('hello')} | ${new Error('hello')}
${'hello'} | ${new Error('hello')}
${'hello'} | ${new UnknownError('hello')}
${'hello'} | ${expect.any(UnknownError)}
`('toError', ({ err, expected }) => {
expect(toError(err)).toEqual(expected);
Expand Down
4 changes: 2 additions & 2 deletions packages/cspell-service-bus/src/SystemServiceBus.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ describe('SystemServiceBus Behavior', () => {
${RequestFsReadFile.create({ uri: 'file://my_file.txt' })} | ${{ value: 'read file: file://my_file.txt' }}
${RequestFsReadFile.create({ uri: 'https://www.example.com/my_file.txt' })} | ${{ value: 'fetch http: https://www.example.com/my_file.txt' }}
${RequestFsReadFile.create({ uri: 'https://www.example.com/my_dict.trie.gz' })} | ${{ value: 'Inflate: fetch http: https://www.example.com/my_dict.trie.gz' }}
${{ type: 'zlib:compress' }} | ${{ error: new Error('Unhandled Request: zlib:compress') }}
`('dispatch requests', ({ request, expected }) => {
${{ type: 'zlib:compress' }} | ${{ error: expect.objectContaining({ message: 'Unhandled Request: zlib:compress' }) }}
`('dispatch requests $request', ({ request, expected }) => {
expect(serviceBus.dispatch(request)).toEqual(expected);
});
});
7 changes: 4 additions & 3 deletions packages/cspell-service-bus/src/bus.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe, expect, test } from 'vitest';
import { createServiceBus } from './bus.js';
import { createIsRequestHandler } from './createRequestHandler.js';
import type { Dispatcher } from './Dispatcher.js';
import { ErrorServiceRequestDepthExceeded, ErrorUnhandledRequest, UnhandledHandlerError } from './errors.js';
import type { Handler } from './handlers.js';
import type { ServiceRequest, ServiceResponse } from './request.js';
import { createResponse as response, ServiceRequestCls } from './request.js';
Expand Down Expand Up @@ -95,9 +96,9 @@ describe('Service Bus', () => {
${FibRequestFactory.create({ fib: 7 })} | ${response(13)}
${StringLengthRequestFactory.create({ str: 'hello' })} | ${response(5)}
${new StringToUpperRequest('hello')} | ${response('HELLO')}
${new DoNotHandleRequest()} | ${{ error: new Error('Unhandled Request: Do Not Handle') }}
${new RetryAgainRequest()} | ${{ error: new Error('Service Request Depth 10 Exceeded: Retry Again Request') }}
${new ServiceRequestCls('throw', undefined)} | ${{ error: new Error('Unhandled Error in Handler: handlerThrowErrorOnRequest') }}
${new DoNotHandleRequest()} | ${{ error: new ErrorUnhandledRequest(new DoNotHandleRequest()) }}
${new RetryAgainRequest()} | ${{ error: new ErrorServiceRequestDepthExceeded(new RetryAgainRequest(), 10) }}
${new ServiceRequestCls('throw', undefined)} | ${{ error: new UnhandledHandlerError('handlerThrowErrorOnRequest', undefined, 'error') }}
`('serviceBus handle request: $request.type', ({ request, expected }) => {
expect(bus.dispatch(request)).toEqual(expected);
});
Expand Down
9 changes: 5 additions & 4 deletions packages/cspell/src/app/cli-reporter.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Chalk } from 'chalk';
import { describe, expect, test } from 'vitest';

import { ApplicationError } from './app.mjs';
import type { ReporterIssue } from './cli-reporter.js';
import { __testing__, checkTemplate } from './cli-reporter.js';

Expand Down Expand Up @@ -40,10 +41,10 @@ describe('cli-reporter', () => {
template | expected
${''} | ${true}
${'{red $filename}'} | ${true}
${'{red $filename'} | ${new Error('Chalk template literal is missing 1 closing bracket (`}`)')}
${'{hello $filename}'} | ${new Error('Unknown Chalk style: hello')}
${'{green.bold.underline $file}'} | ${new Error(`Unresolved template variable: '$file'`)}
${'{green.bold.underline $file}:$rows:$col'} | ${new Error(`Unresolved template variables: '$file', '$rows'`)}
${'{red $filename'} | ${new ApplicationError('Chalk template literal is missing 1 closing bracket (`}`)')}
${'{hello $filename}'} | ${new ApplicationError('Unknown Chalk style: hello')}
${'{green.bold.underline $file}'} | ${new ApplicationError(`Unresolved template variable: '$file'`)}
${'{green.bold.underline $file}:$rows:$col'} | ${new ApplicationError(`Unresolved template variables: '$file', '$rows'`)}
`('checkTemplate $template', ({ template, expected }) => {
const r = checkTemplate(template);
expect(r).toEqual(expected);
Expand Down
12 changes: 11 additions & 1 deletion packages/cspell/src/app/lint/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export async function runLint(cfg: LintRequest): Promise<RunResult> {
const fileInfo = prefetch?.fileInfo || (await readFileInfo(filename, undefined, true));
if (fileInfo.errorCode) {
if (fileInfo.errorCode !== 'EISDIR' && cfg.options.mustFindFiles) {
const err = toError(`File not found: "${filename}"`);
const err = new LinterError(`File not found: "${filename}"`);
reporter.error('Linter:', err);
result.errors += 1;
}
Expand Down Expand Up @@ -754,3 +754,13 @@ async function writeDictionaryLog() {
function globPattern(g: Glob) {
return typeof g === 'string' ? g : g.glob;
}

export class LinterError extends Error {
constructor(message: string) {
super(message);
}

toString() {
return this.message;
}
}
4 changes: 2 additions & 2 deletions packages/cspell/src/app/util/cache/createCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'node:path';

import type { CacheSettings, CSpellSettings } from '@cspell/cspell-types';

import { isError } from '../errors.js';
import { isErrorLike } from '../errors.js';
import type { CacheOptions } from './CacheOptions.js';
import type { CSpellLintResultCache } from './CSpellLintResultCache.js';
import { DiskCache } from './DiskCache.js';
Expand Down Expand Up @@ -75,7 +75,7 @@ async function resolveCacheLocation(cacheLocation: string): Promise<string> {
if (s.isFile()) return cacheLocation;
return path.join(cacheLocation, DEFAULT_CACHE_LOCATION);
} catch (err) {
if (isError(err) && err.code === 'ENOENT') {
if (isErrorLike(err) && err.code === 'ENOENT') {
return cacheLocation;
}
throw err;
Expand Down
29 changes: 15 additions & 14 deletions packages/cspell/src/app/util/errors.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test } from 'vitest';

import { ApplicationError, CheckFailed, IOError, isError, toApplicationError, toError } from './errors.js';
import { ApplicationError, CheckFailed, IOError, isErrorLike, toError } from './errors.js';

const oc = <T>(obj: T) => expect.objectContaining(obj);

Expand All @@ -24,33 +24,34 @@ describe('errors', () => {
${null} | ${false}
${'hello'} | ${false}
`('isError $error', ({ error, expected }) => {
expect(isError(error)).toBe(expected);
expect(isErrorLike(error)).toBe(expected);
});

test.each`
error | expected
${new CheckFailed('CheckFailed')} | ${new Error('CheckFailed')}
${new ApplicationError('App Error')} | ${new Error('App Error')}
${{ message: 'msg', name: 'error' }} | ${oc({ message: 'msg', name: 'error' })}
${'hello'} | ${oc({ name: 'error', message: 'hello' })}
${null} | ${oc({ name: 'error', message: 'null' })}
${undefined} | ${oc({ name: 'error', message: 'undefined' })}
${42} | ${oc({ name: 'error', message: '42' })}
${{}} | ${oc({ name: 'error', message: '{}' })}
${new IOError('io', { name: 'err', message: 'msg', code: 'ENOENT' })} | ${new Error('io')}
${new CheckFailed('CheckFailed')} | ${new CheckFailed('CheckFailed')}
${new ApplicationError('App Error')} | ${new ApplicationError('App Error')}
${{ message: 'msg', name: 'error' }} | ${oc({ message: 'msg' })}
${'hello'} | ${oc({ message: 'hello' })}
${null} | ${oc({ message: 'null' })}
${undefined} | ${oc({ message: 'undefined' })}
${42} | ${oc({ message: '42' })}
${{}} | ${oc({ message: '{}' })}
${new IOError('io', { name: 'err', message: 'msg', code: 'ENOENT' })} | ${new IOError('io', { name: 'err', message: 'msg', code: 'ENOENT' })}
`('toError $error', ({ error, expected }) => {
expect(toError(error)).toEqual(expected);
});

test.each`
error | expected
${new CheckFailed('CheckFailed')} | ${new Error('CheckFailed')}
${new ApplicationError('App Error')} | ${new Error('App Error')}
${new CheckFailed('CheckFailed')} | ${new CheckFailed('CheckFailed')}
${new ApplicationError('App Error')} | ${new ApplicationError('App Error')}
${{ message: 'msg', name: 'error' }} | ${new Error('msg')}
${'hello'} | ${new Error('hello')}
${{}} | ${new Error('{}')}
`('toError $error', ({ error, expected }) => {
expect(toApplicationError(error)).toEqual(expected);
const e = toError(error);
expect(e).toEqual(expected);
});

test('IOError', () => {
Expand Down
15 changes: 10 additions & 5 deletions packages/cspell/src/app/util/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,20 @@ export class IOError extends ApplicationError {

export function toError(e: unknown): NodeError {
if (isError(e)) return e;
if (isErrorLike(e)) {
const ex: NodeError = new Error(e.message, { cause: e });
if (e.code !== undefined) ex.code = e.code;
return ex;
}
const message = format(e);
return {
name: 'error',
message,
toString: () => message,
};
return new Error(message);
}

export function isError(e: unknown): e is NodeError {
return e instanceof Error;
}

export function isErrorLike(e: unknown): e is NodeError {
if (e instanceof Error) return true;
if (!e || typeof e !== 'object') return false;
const ex = <Error>e;
Expand Down
3 changes: 2 additions & 1 deletion packages/cspell/src/app/util/reporters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { CSpellReporter, ReporterSettings } from '@cspell/cspell-types';
import { MessageTypes } from '@cspell/cspell-types';
import { describe, expect, test, vi } from 'vitest';

import { ApplicationError } from './errors.js';
import { InMemoryReporter } from './InMemoryReporter.js';
import { loadReporters, mergeReporters } from './reporters.js';

Expand Down Expand Up @@ -42,7 +43,7 @@ describe('mergeReporters', () => {

test.each`
reporter | expected
${['@cspell/cspell-json-reporter', false]} | ${new Error('Failed to load reporter @cspell/cspell-json-reporter: cspell-json-reporter settings must be an object')}
${['@cspell/cspell-json-reporter', false]} | ${new ApplicationError('Failed to load reporter @cspell/cspell-json-reporter: cspell-json-reporter settings must be an object')}
${['@cspell/cspell-unknown-reporter']} | ${oc({ message: sc("Failed to load reporter @cspell/cspell-unknown-reporter: Cannot find package '@cspell/cspell-unknown-reporter' imported from") })}
${'@cspell/cspell-unknown-reporter'} | ${oc({ message: sc("Failed to load reporter @cspell/cspell-unknown-reporter: Cannot find package '@cspell/cspell-unknown-reporter'") })}
`('loadReporters fail $reporter', async ({ reporter, expected }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
StringToUpperRequest,
} from './index.mjs';

function expectError(message: string) {
return { error: expect.objectContaining({ message }) };
}

describe('Service Bus', () => {
const bus = createBus();

Expand All @@ -21,9 +25,9 @@ describe('Service Bus', () => {
${FibRequestFactory.create({ fib: 7 })} | ${createResponse(13)}
${StringLengthRequestFactory.create({ str: 'hello' })} | ${createResponse(5)}
${new StringToUpperRequest('hello')} | ${createResponse('HELLO')}
${new DoNotHandleRequest()} | ${{ error: new Error('Unhandled Request: Do Not Handle') }}
${new RetryAgainRequest()} | ${{ error: new Error('Service Request Depth 10 Exceeded: Retry Again Request') }}
${new ServiceRequestCls('throw', undefined)} | ${{ error: new Error('Unhandled Error in Handler: handlerThrowErrorOnRequest') }}
${new DoNotHandleRequest()} | ${expectError('Unhandled Request: Do Not Handle')}
${new RetryAgainRequest()} | ${expectError('Service Request Depth 10 Exceeded: Retry Again Request')}
${new ServiceRequestCls('throw', undefined)} | ${expectError('Unhandled Error in Handler: handlerThrowErrorOnRequest')}
`('serviceBus handle request: $request.type', ({ request, expected }) => {
expect(bus.dispatch(request)).toEqual(expected);
});
Expand Down
Loading

0 comments on commit 156e022

Please sign in to comment.