diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 4143bf84..00000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -source/test/fixtures diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 0b50c44d..00000000 --- a/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "root": true, - "extends": ["xo", "xo-typescript"], - "parserOptions": { - "project": "tsconfig.tsd.json" - }, - "rules": { - "@typescript-eslint/comma-dangle": "off" - } -} diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yml similarity index 77% rename from .github/workflows/main.yaml rename to .github/workflows/main.yml index d5cb8dcf..a768beba 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yml @@ -10,13 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 21 - 20 - 18 - - 16 - - 14 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/.gitignore b/.gitignore index 4dbf822c..b820119d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules yarn.lock dist/ +.tsimp diff --git a/package.json b/package.json index 4f8889bd..90aa5258 100644 --- a/package.json +++ b/package.json @@ -9,20 +9,19 @@ "email": "sam.verschueren@gmail.com", "url": "https://github.com/SamVerschueren" }, - "exports": "./dist/index.js", - "types": "./dist/index.d.ts", + "type": "module", + "exports": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, "bin": "./dist/cli.js", "engines": { - "node": ">=14.16" + "node": ">=18" }, "scripts": { "prepublishOnly": "npm run build", - "pretest": "npm run build && cpy \"./**/**\" \"../../../dist/test/fixtures/\" --parents --cwd=source/test/fixtures", - "test": "npm run lint && ava", - "build": "npm run clean && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js", - "clean": "del-cli dist", - "lint": "eslint \"source/**/*\"", - "lint:fix": "eslint --fix \"source/**/*\"" + "test": "xo && tsc --project tsconfig.tsd.json --noEmit && ava", + "build": "tsc --project tsconfig.build.json && chmod +x dist/cli.js && tsup" }, "files": [ "dist/**/*.js", @@ -40,41 +39,57 @@ ], "dependencies": { "@tsd/typescript": "~5.3.3", - "eslint-formatter-pretty": "^4.1.0", - "globby": "^11.0.1", - "jest-diff": "^29.0.3", - "meow": "^9.0.0", - "path-exists": "^4.0.0", - "read-pkg-up": "^7.0.0" + "eslint-formatter-pretty": "^6.0.1", + "globby": "^14.0.1", + "jest-diff": "^29.7.0", + "meow": "^13.2.0", + "p-map": "^7.0.1", + "path-exists": "^5.0.0", + "read-package-up": "^11.0.0" }, "devDependencies": { - "@ava/typescript": "^1.1.1", - "@types/node": "^14.18.21", - "@types/react": "^16.9.2", - "@typescript-eslint/eslint-plugin": "^4.26.0", - "@typescript-eslint/parser": "^4.26.0", - "ava": "^3.8.2", - "cpy-cli": "^3.0.0", - "del-cli": "^3.0.0", - "eslint": "^7.27.0", - "eslint-config-xo": "^0.36.0", - "eslint-config-xo-typescript": "^0.41.1", - "execa": "^5.0.0", + "@sindresorhus/tsconfig": "^5.0.0", + "@types/common-tags": "^1.8.4", + "@types/node": "^18", + "@types/react": "^18", + "ava": "^6.1.1", + "common-tags": "^1.8.2", + "eslint": "^8.56.0", + "execa": "^8.0.1", "react": "^16.9.0", "resolve-from": "^5.0.0", "rxjs": "^6.5.3", - "typescript": "~4.9.5" + "tsimp": "^2.0.11", + "tsup": "^8.0.2", + "typescript": "~5.3.3", + "xo": "^0.57.0" }, "ava": { "timeout": "2m", - "files": [ - "source/test/**/*", - "!source/test/fixtures/**/*" + "extensions": { + "ts": "module" + }, + "nodeArguments": [ + "--import=tsimp" + ], + "environmentVariables": { + "ESBK_TSCONFIG_PATH": "tsconfig.tsd.json" + } + }, + "xo": { + "ignores": [ + "source/test/fixtures" ], - "typescript": { - "rewritePaths": { - "source/": "dist/" - } + "parserOptions": { + "project": "./tsconfig.tsd.json" + }, + "rules": { + "no-bitwise": "off", + "unicorn/prevent-abbreviations": ["error", { + "replacements": { + "doc": false + } + }] } } } diff --git a/source/cli.ts b/source/cli.ts old mode 100644 new mode 100755 index 23098407..12ee036e --- a/source/cli.ts +++ b/source/cli.ts @@ -1,42 +1,39 @@ -#!/usr/bin/env node +#!/usr/bin/env tsimp +import process from 'node:process'; import meow from 'meow'; -import {TsdError} from './lib/interfaces'; -import formatter from './lib/formatter'; -import tsd from './lib'; +import {TsdError} from './lib/interfaces.js'; +import formatter from './lib/formatter.js'; +import tsd from './lib/index.js'; const cli = meow(` Usage $ tsd [path] - The given directory must contain a package.json and a typings file. + The given directory must contain a package.json. Info --help Display help text --version Display version info Options - --typings -t Type definition file to test [Default: "types" property in package.json] - --files -f Glob of files to test [Default: '/path/test-d/**/*.test-d.ts' or '.tsx'] - --show-diff Show type error diffs [Default: don't show] + --files -f Glob of files to test [Default: 'path/test-d/**/*.test-d.ts'] + --show-diff Show type error diffs [Default: don't show] Examples - $ tsd /path/to/project + $ tsd path/to/project - $ tsd --files /test/some/folder/*.ts --files /test/other/folder/*.tsx + $ tsd --files test/some/folder/*.ts --files test/other/folder/*.tsx $ tsd index.test-d.ts ✖ 10:20 Argument of type string is not assignable to parameter of type number. `, { + importMeta: import.meta, flags: { - typings: { - type: 'string', - alias: 't', - }, files: { type: 'string', - alias: 'f', + shortFlag: 'f', isMultiple: true, }, showDiff: { @@ -61,28 +58,26 @@ const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => { } }; -(async () => { - try { - const cwd = cli.input.length > 0 ? cli.input[0] : process.cwd(); - const {typings: typingsFile, files: testFiles, showDiff} = cli.flags; +try { + const cwd = cli.input.at(0) ?? process.cwd(); + const {files: testFiles, showDiff} = cli.flags; - const diagnostics = await tsd({cwd, typingsFile, testFiles}); + const diagnostics = await tsd({cwd, testFiles}); - if (diagnostics.length > 0) { - const hasErrors = diagnostics.some(diagnostic => diagnostic.severity === 'error'); - const formattedDiagnostics = formatter(diagnostics, showDiff); + if (diagnostics.length > 0) { + const hasErrors = diagnostics.some(diagnostic => diagnostic.severity === 'error'); + const formattedDiagnostics = formatter(diagnostics, showDiff); - exit(formattedDiagnostics, {isError: hasErrors}); - } - } catch (error: unknown) { - const potentialError = error as Error | undefined; + exit(formattedDiagnostics, {isError: hasErrors}); + } +} catch (error) { + const potentialError = error as Error | undefined; - if (potentialError instanceof TsdError) { - exit(potentialError.message); - } + if (potentialError instanceof TsdError) { + exit(potentialError.message); + } - const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.'; + const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.'; - exit(`Error running tsd:\n${errorMessage}`); - } -})(); + exit(`Error running tsd:\n${errorMessage}`); +} diff --git a/source/index.ts b/source/index.ts index 4a8f4193..6da289a4 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,5 +1,3 @@ -import tsd from './lib'; - -export * from './lib/assertions/assert'; -export {default as formatter} from './lib/formatter'; -export default tsd; +export * from './lib/assertions/assert.js'; +export {default as formatter} from './lib/formatter.js'; +export {default} from './lib/index.js'; diff --git a/source/lib/assertions/assert.ts b/source/lib/assertions/assert.ts index 36f2e8b1..b8fce95e 100644 --- a/source/lib/assertions/assert.ts +++ b/source/lib/assertions/assert.ts @@ -1,76 +1,53 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ - /** * Asserts that the type of `expression` is identical to type `T`. * * @param expression - Expression that should be identical to type `T`. */ -// @ts-expect-error -export const expectType = (expression: T) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectType: (expression: T) => void; /** * Asserts that the type of `expression` is not identical to type `T`. * * @param expression - Expression that should not be identical to type `T`. - */ -// @ts-expect-error -export const expectNotType = (expression: any) => { - // eslint-disable-next-line no-warning-comments - // TODO Use a `not T` type when possible https://github.com/microsoft/TypeScript/pull/29317 - // Do nothing, the TypeScript compiler handles this for us -}; +*/ +// eslint-disable-next-line no-warning-comments +// TODO Use a `not T` type when possible https://github.com/microsoft/TypeScript/pull/29317 +export declare const expectNotType: (expression: any) => void; /** * Asserts that the type of `expression` is assignable to type `T`. * * @param expression - Expression that should be assignable to type `T`. */ -// @ts-expect-error -export const expectAssignable = (expression: T) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectAssignable: (expression: T) => void; /** * Asserts that the type of `expression` is not assignable to type `T`. * * @param expression - Expression that should not be assignable to type `T`. */ -// @ts-expect-error -export const expectNotAssignable = (expression: any) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectNotAssignable: (expression: any) => void; /** * Asserts that `expression` throws an error. Will not ignore syntax errors. * * @param expression - Expression that should throw an error. */ -// @ts-expect-error -export const expectError = (expression: T) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectError: (expression: T) => void; /** * Asserts that `expression` is marked as `@deprecated`. * * @param expression - Expression that should be marked as `@deprecated`. */ -// @ts-expect-error -export const expectDeprecated = (expression: any) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectDeprecated: (expression: any) => void; /** * Asserts that `expression` is not marked as `@deprecated`. * * @param expression - Expression that should not be marked as `@deprecated`. */ -// @ts-expect-error -export const expectNotDeprecated = (expression: any) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectNotDeprecated: (expression: any) => void; /** * Asserts that the type and return type of `expression` is `never`. @@ -79,26 +56,18 @@ export const expectNotDeprecated = (expression: any) => { * * @param expression - Expression that should be `never`. */ -export const expectNever = (expression: never): never => { - return expression; -}; +export const expectNever = (expression: never): never => expression; /** * Prints the type of `expression` as a warning. * * @param expression - Expression whose type should be printed as a warning. */ -// @ts-expect-error -export const printType = (expression: any) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const printType: (expression: any) => void; /** * Asserts that the documentation comment of `expression` includes string literal type `T`. * * @param expression - Expression whose documentation comment should include string literal type `T`. */ -// @ts-expect-error -export const expectDocCommentIncludes = (expression: any) => { - // Do nothing, the TypeScript compiler handles this for us -}; +export declare const expectDocCommentIncludes: (expression: any) => void; diff --git a/source/lib/assertions/handlers/assignability.ts b/source/lib/assertions/handlers/assignability.ts index e9e7be0a..01e5428a 100644 --- a/source/lib/assertions/handlers/assignability.ts +++ b/source/lib/assertions/handlers/assignability.ts @@ -1,6 +1,6 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {makeDiagnosticWithDiff} from '../../utils'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; +import {makeDiagnosticWithDiff} from '../../utils/index.js'; /** * Asserts that the argument of the assertion is not assignable to the generic type of the assertion. diff --git a/source/lib/assertions/handlers/expect-deprecated.ts b/source/lib/assertions/handlers/expect-deprecated.ts index 138346ca..93c9575d 100644 --- a/source/lib/assertions/handlers/expect-deprecated.ts +++ b/source/lib/assertions/handlers/expect-deprecated.ts @@ -1,39 +1,38 @@ -import {JSDocTagInfo} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {Handler} from './handler'; -import {makeDiagnostic, tsutils} from '../../utils'; +import type {JSDocTagInfo} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; +import {makeDiagnostic, tsutils} from '../../utils/index.js'; +import {type Handler} from './handler.js'; -interface Options { +type Options = { filter(tags: Map): boolean; message(signature: string): string; -} +}; -const expectDeprecatedHelper = (options: Options): Handler => { - return (checker, nodes) => { - const diagnostics: Diagnostic[] = []; +const expectDeprecatedHelper = (options: Options): Handler => (checker, nodes) => { + const diagnostics: Diagnostic[] = []; - if (!nodes) { - // Bail out if we don't have any nodes - return diagnostics; - } + if (!nodes) { + // Bail out if we don't have any nodes + return diagnostics; + } - for (const node of nodes) { - const argument = node.arguments[0]; + for (const node of nodes) { + const argument = node.arguments[0]; - const tags = tsutils.resolveJSDocTags(checker, argument); + const tags = tsutils.resolveJsDocTags(checker, argument); - if (!tags || !options.filter(tags)) { - // Bail out if not tags couldn't be resolved or when the node matches the filter expression - continue; - } + // eslint-disable-next-line unicorn/no-array-callback-reference + if (!tags || !options.filter(tags)) { + // Bail out if not tags couldn't be resolved or when the node matches the filter expression + continue; + } - const message = tsutils.expressionToString(checker, argument); + const message = tsutils.expressionToString(checker, argument); - diagnostics.push(makeDiagnostic(node, options.message(message ?? '?'))); - } + diagnostics.push(makeDiagnostic(node, options.message(message ?? '?'))); + } - return diagnostics; - }; + return diagnostics; }; /** @@ -46,7 +45,7 @@ const expectDeprecatedHelper = (options: Options): Handler => { */ export const expectDeprecated = expectDeprecatedHelper({ filter: tags => !tags.has('deprecated'), - message: signature => `Expected \`${signature}\` to be marked as \`@deprecated\`` + message: signature => `Expected \`${signature}\` to be marked as \`@deprecated\``, }); /** @@ -59,5 +58,5 @@ export const expectDeprecated = expectDeprecatedHelper({ */ export const expectNotDeprecated = expectDeprecatedHelper({ filter: tags => tags.has('deprecated'), - message: signature => `Expected \`${signature}\` to not be marked as \`@deprecated\`` + message: signature => `Expected \`${signature}\` to not be marked as \`@deprecated\``, }); diff --git a/source/lib/assertions/handlers/handler.ts b/source/lib/assertions/handlers/handler.ts index e3f7e089..954b99cc 100644 --- a/source/lib/assertions/handlers/handler.ts +++ b/source/lib/assertions/handlers/handler.ts @@ -1,5 +1,5 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; /** * A handler is a method which accepts the TypeScript type checker together with a set of assertion nodes. The type checker diff --git a/source/lib/assertions/handlers/identicality.ts b/source/lib/assertions/handlers/identicality.ts index 9d884d21..4fb07118 100644 --- a/source/lib/assertions/handlers/identicality.ts +++ b/source/lib/assertions/handlers/identicality.ts @@ -1,6 +1,6 @@ -import {CallExpression, TypeChecker, TypeFlags} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {makeDiagnostic, makeDiagnosticWithDiff} from '../../utils'; +import ts, {type CallExpression, type TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; +import {makeDiagnostic, makeDiagnosticWithDiff} from '../../utils/index.js'; /** * Asserts that the argument of the assertion is identical to the generic type of the assertion. @@ -112,7 +112,7 @@ export const isNever = (checker: TypeChecker, nodes: Set): Diagn for (const node of nodes) { const argumentType = checker.getTypeAtLocation(node.arguments[0]); - if (argumentType.flags !== TypeFlags.Never) { + if (argumentType.flags !== ts.TypeFlags.Never) { diagnostics.push(makeDiagnostic(node, `Argument of type \`${checker.typeToString(argumentType)}\` is not \`never\`.`)); } } diff --git a/source/lib/assertions/handlers/index.ts b/source/lib/assertions/handlers/index.ts index 8386e765..e31a417d 100644 --- a/source/lib/assertions/handlers/index.ts +++ b/source/lib/assertions/handlers/index.ts @@ -1,7 +1,7 @@ -export {Handler} from './handler'; +export type {Handler} from './handler.js'; // Handlers -export {isIdentical, isNotIdentical, isNever} from './identicality'; -export {isNotAssignable} from './assignability'; -export {expectDeprecated, expectNotDeprecated} from './expect-deprecated'; -export {printTypeWarning, expectDocCommentIncludes} from './informational'; +export {isIdentical, isNotIdentical, isNever} from './identicality.js'; +export {isNotAssignable} from './assignability.js'; +export {expectDeprecated, expectNotDeprecated} from './expect-deprecated.js'; +export {printTypeWarning, expectDocCommentIncludes} from './informational.js'; diff --git a/source/lib/assertions/handlers/informational.ts b/source/lib/assertions/handlers/informational.ts index e7570fe8..72485d8f 100644 --- a/source/lib/assertions/handlers/informational.ts +++ b/source/lib/assertions/handlers/informational.ts @@ -1,16 +1,16 @@ -import {CallExpression, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils'; +import ts, {type CallExpression, type TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; +import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils/index.js'; /** * Default formatting flags set by TS plus the {@link TypeFormatFlags.NoTruncation NoTruncation} flag. * * @see {@link https://github.dev/microsoft/TypeScript/blob/b975dfa1027d1f3073fa7cbe6f7045bf4c882785/src/compiler/checker.ts#L4717 TypeChecker.typeToString} */ -const typeToStringFormatFlags = - TypeFormatFlags.AllowUniqueESSymbolType | - TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | - TypeFormatFlags.NoTruncation; +const typeToStringFormatFlags + = ts.TypeFormatFlags.AllowUniqueESSymbolType + | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope + | ts.TypeFormatFlags.NoTruncation; /** * Prints the type of the argument of the assertion as a warning. diff --git a/source/lib/assertions/handlers/strict-assertion.ts b/source/lib/assertions/handlers/strict-assertion.ts index 5ecc096e..c7fdefba 100644 --- a/source/lib/assertions/handlers/strict-assertion.ts +++ b/source/lib/assertions/handlers/strict-assertion.ts @@ -1,6 +1,6 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {makeDiagnostic} from '../../utils'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; +import {makeDiagnostic} from '../../utils/index.js'; /** * Performs strict type assertion between the argument if the assertion, and the generic type of the assertion. diff --git a/source/lib/assertions/index.ts b/source/lib/assertions/index.ts index 6cf6f8e9..75b8f108 100644 --- a/source/lib/assertions/index.ts +++ b/source/lib/assertions/index.ts @@ -1,7 +1,7 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../interfaces'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../interfaces.js'; import { - Handler, + type Handler, isIdentical, isNotIdentical, isNotAssignable, @@ -10,7 +10,7 @@ import { isNever, printTypeWarning, expectDocCommentIncludes, -} from './handlers'; +} from './handlers/index.js'; export enum Assertion { EXPECT_TYPE = 'expectType', diff --git a/source/lib/compiler.ts b/source/lib/compiler.ts index 7c06a7f0..9bceaa64 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,17 +1,18 @@ +import ts, {type Diagnostic as TSDiagnostic} from '@tsd/typescript'; +import {type ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; import { - flattenDiagnosticMessageText, - createProgram, - Diagnostic as TSDiagnostic -} from '@tsd/typescript'; -import {ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser'; -import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces'; -import {handle} from './assertions'; + DiagnosticCode, + type Diagnostic, + type Context, + type Location, +} from './interfaces.js'; +import {handle} from './assertions/index.js'; // List of diagnostic codes that should be ignored in general const ignoredDiagnostics = new Set([ // Older TS version report 'await expression only allowed within async function DiagnosticCode.AwaitExpressionOnlyAllowedWithinAsyncFunction, - DiagnosticCode.TopLevelAwaitOnlyAllowedWhenModuleESNextOrSystem + DiagnosticCode.TopLevelAwaitOnlyAllowedWhenModuleESNextOrSystem, ]); // List of diagnostic codes which should be ignored inside `expectError` statements @@ -71,18 +72,16 @@ type IgnoreDiagnosticResult = 'preserve' | 'ignore' | Location; */ const ignoreDiagnostic = ( diagnostic: TSDiagnostic, - expectedErrors: Map + expectedErrors: Map, ): IgnoreDiagnosticResult => { if (ignoredDiagnostics.has(diagnostic.code)) { // Filter out diagnostics which are present in the `ignoredDiagnostics` set return 'ignore'; } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const diagnosticFileName = diagnostic.file!.fileName; for (const [location, error] of expectedErrors) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const start = diagnostic.start!; // Diagnostic is inside of `expectError` clause @@ -115,11 +114,12 @@ const ignoreDiagnostic = ( export const getDiagnostics = (context: Context): Diagnostic[] => { const diagnostics: Diagnostic[] = []; - const program = createProgram(context.testFiles, context.config.compilerOptions); + const program = ts.createProgram(context.testFiles, context.config.compilerOptions); - const tsDiagnostics = program - .getSemanticDiagnostics() - .concat(program.getSyntacticDiagnostics()); + const tsDiagnostics = [ + ...program.getSemanticDiagnostics(), + ...program.getSyntacticDiagnostics(), + ]; const assertions = extractAssertions(program); @@ -146,15 +146,14 @@ export const getDiagnostics = (context: Context): Diagnostic[] => { continue; } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); diagnostics.push({ fileName: diagnostic.file.fileName, - message: flattenDiagnosticMessageText(diagnostic.messageText, '\n'), + message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'), severity: 'error', line: position.line + 1, - column: position.character + column: position.character, }); } @@ -163,14 +162,14 @@ export const getDiagnostics = (context: Context): Diagnostic[] => { } for (const [, diagnostic] of expectedErrors) { - const message = diagnostic.code ? - `Found an error that tsd does not currently support (\`ts${diagnostic.code}\`), consider creating an issue on GitHub.` : - 'Expected an error, but found none.'; + const message = diagnostic.code + ? `Found an error that tsd does not currently support (\`ts${diagnostic.code}\`), consider creating an issue on GitHub.` + : 'Expected an error, but found none.'; diagnostics.push({ ...diagnostic, message, - severity: 'error' + severity: 'error', }); } diff --git a/source/lib/config.ts b/source/lib/config.ts index 4e347557..0df6a678 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -1,16 +1,7 @@ -import { - JsxEmit, - ScriptTarget, - ModuleResolutionKind, - parseJsonConfigFileContent, - CompilerOptions, - findConfigFile, - sys, - readJsonConfigFile, - parseJsonSourceFileConfigFileContent, - ModuleKind -} from '@tsd/typescript'; -import {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces'; +import ts, {type CompilerOptions} from '@tsd/typescript'; +import type {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; + +// TODO: update this /** * Load the configuration settings. @@ -18,13 +9,13 @@ import {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces * @param pkg - The package.json object. * @returns The config object. */ -export default (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { - const pkgConfig = pkg.tsd ?? {}; +const loadConfig = (package_: PackageJsonWithTsdConfig, cwd: string): Config => { + const packageConfig = package_.tsd ?? {}; const tsConfigCompilerOptions = getOptionsFromTsConfig(cwd); const packageJsonCompilerOptions = parseCompilerConfigObject( - pkgConfig.compilerOptions ?? {}, - cwd + packageConfig.compilerOptions ?? {}, + cwd, ); const combinedCompilerOptions = { @@ -32,40 +23,42 @@ export default (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { ...packageJsonCompilerOptions, }; - const module = combinedCompilerOptions.module ?? ModuleKind.CommonJS; + const module = combinedCompilerOptions.module ?? ts.ModuleKind.CommonJS; return { directory: 'test-d', - ...pkgConfig, + ...packageConfig, compilerOptions: { strict: true, - jsx: JsxEmit.React, - lib: parseRawLibs(['es2020', 'dom', 'dom.iterable'], cwd), + jsx: ts.JsxEmit.React, + lib: parseRawLibs(['es2022', 'dom', 'dom.iterable'], cwd), module, - target: ScriptTarget.ES2020, + target: ts.ScriptTarget.ES2020, esModuleInterop: true, noUnusedLocals: false, ...combinedCompilerOptions, - moduleResolution: module === ModuleKind.NodeNext ? - ModuleResolutionKind.NodeNext : - module === ModuleKind.Node16 ? - ModuleResolutionKind.Node16 : - ModuleResolutionKind.NodeJs, - skipLibCheck: false - } + moduleResolution: module === ts.ModuleKind.NodeNext + ? ts.ModuleResolutionKind.NodeNext + : (module === ts.ModuleKind.Node16 + ? ts.ModuleResolutionKind.Node16 + : ts.ModuleResolutionKind.Node10), + skipLibCheck: false, + }, }; }; +export default loadConfig; + function getOptionsFromTsConfig(cwd: string): CompilerOptions { - const configPath = findConfigFile(cwd, sys.fileExists); + const configPath = ts.findConfigFile(cwd, ts.sys.fileExists); if (!configPath) { return {}; } - return parseJsonSourceFileConfigFileContent( - readJsonConfigFile(configPath, sys.readFile), - sys, + return ts.parseJsonSourceFileConfigFileContent( + ts.readJsonConfigFile(configPath, ts.sys.readFile), + ts.sys, cwd, undefined, configPath, @@ -73,10 +66,10 @@ function getOptionsFromTsConfig(cwd: string): CompilerOptions { } function parseCompilerConfigObject(compilerOptions: RawCompilerOptions, cwd: string): CompilerOptions { - return parseJsonConfigFileContent( + return ts.parseJsonConfigFileContent( {compilerOptions: compilerOptions || {}}, - sys, - cwd + ts.sys, + cwd, ).options; } diff --git a/source/lib/formatter.ts b/source/lib/formatter.ts index 9c393275..1b18c90a 100644 --- a/source/lib/formatter.ts +++ b/source/lib/formatter.ts @@ -1,8 +1,8 @@ -import formatter from 'eslint-formatter-pretty'; -import {Diagnostic} from './interfaces'; +import prettyFormatter from 'eslint-formatter-pretty'; import {diffStringsUnified} from 'jest-diff'; +import {type Diagnostic} from './interfaces.js'; -interface FileWithDiagnostics { +type FileWithDiagnostics = { filePath: string; errorCount: number; warningCount: number; @@ -11,7 +11,7 @@ interface FileWithDiagnostics { expected: string; received: string; }; -} +}; /** * Format the TypeScript diagnostics to a human readable output. @@ -20,7 +20,7 @@ interface FileWithDiagnostics { * @param showDiff - Display difference between expected and received types. * @returns Beautiful diagnostics output */ -export default (diagnostics: Diagnostic[], showDiff = false): string => { +const formatter = (diagnostics: Diagnostic[], showDiff = false): string => { const fileMap = new Map(); for (const diagnostic of diagnostics) { @@ -31,7 +31,7 @@ export default (diagnostics: Diagnostic[], showDiff = false): string => { filePath: diagnostic.fileName, errorCount: 0, warningCount: 0, - messages: [] + messages: [], }; fileMap.set(diagnostic.fileName, entry); @@ -41,7 +41,7 @@ export default (diagnostics: Diagnostic[], showDiff = false): string => { let difference = diffStringsUnified( diagnostic.diff.expected, diagnostic.diff.received, - {omitAnnotationLines: true} + {omitAnnotationLines: true}, ); if (difference) { @@ -59,5 +59,8 @@ export default (diagnostics: Diagnostic[], showDiff = false): string => { entry.messages.push(diagnostic); } - return String(formatter([...fileMap.values()])); + // @ts-expect-error + return String(prettyFormatter([...fileMap.values()])); }; + +export default formatter; diff --git a/source/lib/index.ts b/source/lib/index.ts index e59193c0..3696d7bc 100644 --- a/source/lib/index.ts +++ b/source/lib/index.ts @@ -1,75 +1,55 @@ -import path from 'path'; -import readPkgUp from 'read-pkg-up'; -import pathExists from 'path-exists'; -import globby from 'globby'; -import {getDiagnostics as getTSDiagnostics} from './compiler'; -import loadConfig from './config'; -import getCustomDiagnostics from './rules'; -import {Context, Config, Diagnostic, PackageJsonWithTsdConfig, TsdError} from './interfaces'; - -export interface Options { +import path from 'node:path'; +import process from 'node:process'; +import {readPackageUp} from 'read-package-up'; +import {pathExists} from 'path-exists'; +import {globby} from 'globby'; +import {getDiagnostics as getTSDiagnostics} from './compiler.js'; +import loadConfig from './config.js'; +import getCustomDiagnostics from './rules/index.js'; +import { + TsdError, + type Context, + type Config, + type Diagnostic, + type PackageJsonWithTsdConfig, +} from './interfaces.js'; + +export type Options = { cwd: string; - typingsFile?: string; testFiles?: readonly string[]; -} - -const findTypingsFile = async (pkg: PackageJsonWithTsdConfig, options: Options): Promise => { - const typings = - options.typingsFile || - pkg.types || - pkg.typings || - (pkg.main && path.parse(pkg.main).name + '.d.ts') || - 'index.d.ts'; - - const typingsPath = path.join(options.cwd, typings); - const typingsExist = await pathExists(typingsPath); - - if (!typingsExist) { - throw new TsdError(`The type definition \`${typings}\` does not exist at \`${typingsPath}\`. Is the path correct? Create one and try again.`); - } - - return typings; }; -const normalizeTypingsFilePath = (typingsFilePath: string, options: Options) => { - if (options.typingsFile) { - return path.basename(typingsFilePath); - } - - return typingsFilePath; -}; +// eslint-disable-next-line @typescript-eslint/naming-convention +const TS_EXTENSIONS = ['ts', 'cts', 'mts', 'tsx', 'ctsx', 'mtsx']; const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: string) => { const testFiles = await globby(testFilesPattern, {cwd}); if (testFiles.length === 0) { - throw new TsdError('Could not find any test files with the given pattern(s). Create one and try again.'); + throw new TsdError('Could not find any test files with the given pattern(s).'); } return testFiles.map(file => path.join(cwd, file)); }; -const findTestFiles = async (typingsFilePath: string, options: Options & {config: Config}) => { +const findTestFiles = async (options: Options & {config: Config}) => { if (options.testFiles?.length) { return findCustomTestFiles(options.testFiles, options.cwd); } - // Return only the filename if the `typingsFile` option is used. - const typingsFile = normalizeTypingsFilePath(typingsFilePath, options); - - const testFile = typingsFile.replace(/\.d\.ts$/, '.test-d.ts'); - const tsxTestFile = typingsFile.replace(/\.d\.ts$/, '.test-d.tsx'); - const testDir = options.config.directory; + const cwdGlobs = TS_EXTENSIONS.map(extension => `**/*.test-d.${extension}`); + const testDirectory = options.config.directory; - let testFiles = await globby([testFile, tsxTestFile], {cwd: options.cwd}); - const testDirExists = await pathExists(path.join(options.cwd, testDir)); + let testFiles = await globby(cwdGlobs, {cwd: options.cwd}); + const testDirectoryExists = await pathExists(path.join(options.cwd, testDirectory)); - if (testFiles.length === 0 && !testDirExists) { - throw new TsdError(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`); + if (testFiles.length === 0 && !testDirectoryExists) { + throw new TsdError(`No test files were found in \`${options.cwd}\` or in any of its subdirectories.`); } if (testFiles.length === 0) { - testFiles = await globby([`${testDir}/**/*.ts`, `${testDir}/**/*.tsx`], {cwd: options.cwd}); + const testDirectoryGlobs = TS_EXTENSIONS.map(extension => `${testDirectory}/**/*.${extension}`); + testFiles = await globby(testDirectoryGlobs, {cwd: options.cwd}); } return testFiles.map(fileName => path.join(options.cwd, fileName)); @@ -80,34 +60,33 @@ const findTestFiles = async (typingsFilePath: string, options: Options & {config * * @returns A promise which resolves the diagnostics of the type definition. */ -export default async (options: Options = {cwd: process.cwd()}): Promise => { - const pkgResult = await readPkgUp({cwd: options.cwd}); +// eslint-disable-next-line unicorn/no-object-as-default-parameter +const tsd = async (options: Options = {cwd: process.cwd()}): Promise => { + const packageResult = await readPackageUp({cwd: options.cwd}); - if (!pkgResult) { + if (!packageResult) { throw new TsdError(`No \`package.json\` file found in \`${options.cwd}\`. Make sure you are running the command in a Node.js project.`); } - const pkg = pkgResult.packageJson as PackageJsonWithTsdConfig; - const config = loadConfig(pkg, options.cwd); + const package_ = packageResult.packageJson as PackageJsonWithTsdConfig; + const config = loadConfig(package_, options.cwd); - // Look for a typings file, otherwise use `index.d.ts` in the root directory. If the file is not found, throw an error. - const typingsFile = await findTypingsFile(pkg, options); - - const testFiles = await findTestFiles(typingsFile, { + const testFiles = await findTestFiles({ ...options, - config + config, }); const context: Context = { cwd: options.cwd, - pkg, - typingsFile, + pkg: package_, testFiles, - config + config, }; return [ - ...getCustomDiagnostics(context), - ...getTSDiagnostics(context) + ...await getCustomDiagnostics(context), + ...getTSDiagnostics(context), ]; }; + +export default tsd; diff --git a/source/lib/interfaces.ts b/source/lib/interfaces.ts index f48de480..4d1b1950 100644 --- a/source/lib/interfaces.ts +++ b/source/lib/interfaces.ts @@ -1,12 +1,12 @@ -import {CompilerOptions} from '@tsd/typescript'; -import {NormalizedPackageJson} from 'read-pkg-up'; +import type {CompilerOptions} from '@tsd/typescript'; +import type {NormalizedPackageJson} from 'read-package-up'; export type RawCompilerOptions = Record; -export interface Config { +export type Config = { directory: string; compilerOptions: Options; -} +}; export type RawConfig = Partial>; @@ -14,13 +14,12 @@ export type PackageJsonWithTsdConfig = NormalizedPackageJson & { tsd?: RawConfig; }; -export interface Context { +export type Context = { cwd: string; pkg: PackageJsonWithTsdConfig; - typingsFile: string; testFiles: string[]; config: Config; -} +}; export enum DiagnosticCode { UnableToResolveSignatureOfClassDecorator = 1238, @@ -67,7 +66,7 @@ export enum DiagnosticCode { NewExpressionTargetLackingConstructSignatureHasAnyType = 7009, } -export interface Diagnostic { +export type Diagnostic = { fileName: string; message: string; severity: 'error' | 'warning'; @@ -77,13 +76,13 @@ export interface Diagnostic { expected: string; received: string; }; -} +}; -export interface Location { +export type Location = { fileName: string; start: number; end: number; -} +}; export class TsdError extends Error { constructor(message: string) { diff --git a/source/lib/parser.ts b/source/lib/parser.ts index 56175c7d..40b9bb94 100644 --- a/source/lib/parser.ts +++ b/source/lib/parser.ts @@ -1,8 +1,8 @@ -import {Program, Node, CallExpression, forEachChild, isCallExpression, isPropertyAccessExpression, SymbolFlags} from '@tsd/typescript'; -import {Assertion} from './assertions'; -import {Location, Diagnostic} from './interfaces'; +import ts, {type Program, type Node, type CallExpression} from '@tsd/typescript'; +import {Assertion} from './assertions/index.js'; +import {type Location, type Diagnostic} from './interfaces.js'; -const assertionFnNames = new Set(Object.values(Assertion)); +const assertionFunctionNames = new Set(Object.values(Assertion)); /** * Extract all assertions. @@ -17,9 +17,9 @@ export const extractAssertions = (program: Program): Map(); @@ -53,11 +53,11 @@ export const extractAssertions = (program: Program): Map & { * @param assertions - Assertion map. */ export const parseErrorAssertionToLocation = ( - assertions: Map> + assertions: Map>, ): Map => { const nodes = assertions.get(Assertion.EXPECT_ERROR); @@ -91,7 +91,7 @@ export const parseErrorAssertionToLocation = ( const location = { fileName: node.getSourceFile().fileName, start: node.getStart(), - end: node.getEnd() + 1 + end: node.getEnd() + 1, }; const pos = node @@ -101,7 +101,7 @@ export const parseErrorAssertionToLocation = ( expectedErrors.set(location, { fileName: location.fileName, line: pos.line + 1, - column: pos.character + column: pos.character, }); } diff --git a/source/lib/rules/files-property.ts b/source/lib/rules/files-property.ts deleted file mode 100644 index efcb6961..00000000 --- a/source/lib/rules/files-property.ts +++ /dev/null @@ -1,62 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import globby from 'globby'; -import {Context, Diagnostic} from '../interfaces'; -import {getJSONPropertyPosition} from '../utils'; - -/** - * Rule which enforces the typings file to be present in the `files` list in `package.json`. - * - * @param context - The context object. - * @returns A list of custom diagnostics. - */ -export default (context: Context): Diagnostic[] => { - const {pkg, typingsFile} = context; - - const packageFiles = pkg.files; - if (!Array.isArray(packageFiles)) { - return []; - } - - const normalizedTypingsFile = path.normalize(typingsFile); - - const patternProcessedPackageFiles = processGitIgnoreStylePatterns(packageFiles); - const normalizedFiles = globby.sync(patternProcessedPackageFiles, {cwd: context.cwd}).map(path.normalize); - - if (normalizedFiles.includes(normalizedTypingsFile)) { - return []; - } - - const packageJsonFullPath = path.join(context.cwd, 'package.json'); - const content = fs.readFileSync(packageJsonFullPath, 'utf8'); - - return [ - { - fileName: packageJsonFullPath, - message: `TypeScript type definition \`${normalizedTypingsFile}\` is not part of the \`files\` list.`, - severity: 'error', - ...getJSONPropertyPosition(content, 'files') - } - ]; -}; - -function processGitIgnoreStylePatterns(patterns: readonly string[]): string[] { - const processedPatterns = patterns - .map(pattern => { - const [negatePatternMatch] = /^!+/.exec(pattern) ?? []; - const negationMarkersCount = negatePatternMatch ? negatePatternMatch.length : 0; - - return [ - pattern - .slice(negationMarkersCount) - // Strip off `/` from the start of the pattern - .replace(/^\/+/, ''), - negationMarkersCount % 2 === 0 - ] as const; - }) - // Only include pattern if it has an even count of negation markers - .filter(([, hasEvenCountOfNegationMarkers]) => hasEvenCountOfNegationMarkers) - .map(([processedPattern]) => processedPattern); - - return [...new Set(processedPatterns)]; -} diff --git a/source/lib/rules/index.ts b/source/lib/rules/index.ts index a4229e0a..b0579937 100644 --- a/source/lib/rules/index.ts +++ b/source/lib/rules/index.ts @@ -1,14 +1,9 @@ -import filesProperty from './files-property'; -import typesProperty from './types-property'; -import {Diagnostic, Context} from '../interfaces'; +import type {Diagnostic, Context} from '../interfaces.js'; -type RuleFunction = (context: Context) => Diagnostic[]; +type RuleFunction = (context: Context) => Promise; // List of custom rules -const rules = new Set([ - filesProperty, - typesProperty -]); +const rules: RuleFunction[] = []; /** * Get a list of custom diagnostics within the current context. @@ -16,12 +11,11 @@ const rules = new Set([ * @param context - The context object. * @returns List of diagnostics */ -export default (context: Context) => { - const diagnostics: Diagnostic[] = []; +const getCustomDiagnostics = async (context: Context): Promise => { + const diagnostics = await Promise.all(rules.map(async rule => rule(context))); + return diagnostics.flat(); +}; - for (const rule of rules) { - diagnostics.push(...rule(context)); - } +export default getCustomDiagnostics; - return diagnostics; -}; +// TODO: add rules for modern best practices? diff --git a/source/lib/rules/types-property.ts b/source/lib/rules/types-property.ts deleted file mode 100644 index a9c7e237..00000000 --- a/source/lib/rules/types-property.ts +++ /dev/null @@ -1,30 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import {Context, Diagnostic} from '../interfaces'; -import {getJSONPropertyPosition} from '../utils'; - -/** - * Rule which enforces the use of a `types` property over a `typings` property. - * - * @param context - The context object. - * @returns A list of custom diagnostics. - */ -export default (context: Context): Diagnostic[] => { - const {pkg} = context; - - if (!pkg.types && pkg.typings) { - const packageJsonFullPath = path.join(context.cwd, 'package.json'); - const content = fs.readFileSync(packageJsonFullPath, 'utf8'); - - return [ - { - fileName: packageJsonFullPath, - message: 'Use property `types` instead of `typings`.', - severity: 'error', - ...getJSONPropertyPosition(content, 'typings') - } - ]; - } - - return []; -}; diff --git a/source/lib/utils/get-json-property-position.ts b/source/lib/utils/get-json-property-position.ts index a17fe12f..714e13dd 100644 --- a/source/lib/utils/get-json-property-position.ts +++ b/source/lib/utils/get-json-property-position.ts @@ -5,7 +5,7 @@ * @param property - Property to search for. * @returns Position of the property or `undefined` if the property could not be found. */ -export default (content: string, property: string) => { +const getJsonPropertyPosition = (content: string, property: string) => { const match = new RegExp(`([\\s\\S]*?)"${property}"`, 'm').exec(content); if (!match) { @@ -13,10 +13,12 @@ export default (content: string, property: string) => { } const lines = match[0].split('\n'); - const lastLine = lines[lines.length - 1]; + const lastLine = lines.at(-1); return { line: lines.length, - column: lastLine ? lastLine.indexOf(`"${property}"`) : 0 + column: lastLine ? lastLine.indexOf(`"${property}"`) : 0, }; }; + +export default getJsonPropertyPosition; diff --git a/source/lib/utils/index.ts b/source/lib/utils/index.ts index 81c060aa..284f914f 100644 --- a/source/lib/utils/index.ts +++ b/source/lib/utils/index.ts @@ -1,11 +1,4 @@ -import makeDiagnostic from './make-diagnostic'; -import makeDiagnosticWithDiff from './make-diagnostic-with-diff'; -import getJSONPropertyPosition from './get-json-property-position'; -import * as tsutils from './typescript'; - -export { - getJSONPropertyPosition, - makeDiagnostic, - makeDiagnosticWithDiff, - tsutils -}; +export {default as makeDiagnostic} from './make-diagnostic.js'; +export {default as makeDiagnosticWithDiff} from './make-diagnostic-with-diff.js'; +export {default as getJsonPropertyPosition} from './get-json-property-position.js'; +export * as tsutils from './typescript.js'; diff --git a/source/lib/utils/make-diagnostic-with-diff.ts b/source/lib/utils/make-diagnostic-with-diff.ts index c97a036a..a15d8490 100644 --- a/source/lib/utils/make-diagnostic-with-diff.ts +++ b/source/lib/utils/make-diagnostic-with-diff.ts @@ -1,26 +1,26 @@ -import {Node, Type, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; -import {Diagnostic} from '../interfaces'; +import ts, {type Node, type Type, type TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../interfaces.js'; -interface DiagnosticWithDiffOptions { +type DiagnosticWithDiffOptions = { checker: TypeChecker; node: Node; message: string; expectedType: Type | string; receivedType: Type | string; severity?: Diagnostic['severity']; -} +}; -const typeToStringFormatFlags = - TypeFormatFlags.NoTruncation | - TypeFormatFlags.WriteArrayAsGenericType | - TypeFormatFlags.UseStructuralFallback | - TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | - TypeFormatFlags.NoTypeReduction | - TypeFormatFlags.AllowUniqueESSymbolType | - TypeFormatFlags.InArrayType | - TypeFormatFlags.InElementType | - TypeFormatFlags.InFirstTypeArgument | - TypeFormatFlags.InTypeAlias; +const typeToStringFormatFlags + = ts.TypeFormatFlags.NoTruncation + | ts.TypeFormatFlags.WriteArrayAsGenericType + | ts.TypeFormatFlags.UseStructuralFallback + | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope + | ts.TypeFormatFlags.NoTypeReduction + | ts.TypeFormatFlags.AllowUniqueESSymbolType + | ts.TypeFormatFlags.InArrayType + | ts.TypeFormatFlags.InElementType + | ts.TypeFormatFlags.InFirstTypeArgument + | ts.TypeFormatFlags.InTypeAlias; /** * Create a diagnostic with type error diffs from the given `options`, see {@link DiagnosticWithDiffOptions}. @@ -28,7 +28,7 @@ const typeToStringFormatFlags = * @param options - Options for creating the diagnostic. * @returns Diagnostic with diffs */ -export default (options: DiagnosticWithDiffOptions): Diagnostic => { +const makeDiagnosticWithDiff = (options: DiagnosticWithDiffOptions): Diagnostic => { const {checker, node, expectedType, receivedType} = options; const position = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); const message = options.message @@ -43,7 +43,9 @@ export default (options: DiagnosticWithDiffOptions): Diagnostic => { column: position.character, diff: { expected: typeof expectedType === 'string' ? expectedType : checker.typeToString(expectedType, node, typeToStringFormatFlags), - received: typeof receivedType === 'string' ? receivedType : checker.typeToString(receivedType, node, typeToStringFormatFlags) - } + received: typeof receivedType === 'string' ? receivedType : checker.typeToString(receivedType, node, typeToStringFormatFlags), + }, }; }; + +export default makeDiagnosticWithDiff; diff --git a/source/lib/utils/make-diagnostic.ts b/source/lib/utils/make-diagnostic.ts index f148cfb4..c238e3a4 100644 --- a/source/lib/utils/make-diagnostic.ts +++ b/source/lib/utils/make-diagnostic.ts @@ -1,5 +1,5 @@ -import {Node} from '@tsd/typescript'; -import {Diagnostic} from '../interfaces'; +import type {Node} from '@tsd/typescript'; +import type {Diagnostic} from '../interfaces.js'; /** * Create a diagnostic from the given `node`, `message` and optional `severity`. @@ -8,7 +8,7 @@ import {Diagnostic} from '../interfaces'; * @param message - Message of the diagnostic. * @param severity - Severity of the diagnostic. */ -export default (node: Node, message: string, severity: 'error' | 'warning' = 'error'): Diagnostic => { +const makeDiagnostic = (node: Node, message: string, severity: 'error' | 'warning' = 'error'): Diagnostic => { const position = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); return { @@ -19,3 +19,5 @@ export default (node: Node, message: string, severity: 'error' | 'warning' = 'er column: position.character, }; }; + +export default makeDiagnostic; diff --git a/source/lib/utils/typescript.ts b/source/lib/utils/typescript.ts index 7cc126c8..a24e7b90 100644 --- a/source/lib/utils/typescript.ts +++ b/source/lib/utils/typescript.ts @@ -1,24 +1,29 @@ -import {TypeChecker, Expression, isCallLikeExpression, JSDocTagInfo, displayPartsToString} from '@tsd/typescript'; +import ts from '@tsd/typescript'; const resolveCommentHelper = (resolve: R) => { - type ConditionalResolveReturn = (R extends 'JSDoc' ? Map : string) | undefined; + type ConditionalResolveReturn = (R extends 'JSDoc' ? Map : string) | undefined; - const handler = (checker: TypeChecker, expression: Expression): ConditionalResolveReturn => { - const ref = isCallLikeExpression(expression) ? - checker.getResolvedSignature(expression) : - checker.getSymbolAtLocation(expression); + const handler = (checker: ts.TypeChecker, expression: ts.Expression): ConditionalResolveReturn => { + const reference = ts.isCallLikeExpression(expression) + ? checker.getResolvedSignature(expression) + : checker.getSymbolAtLocation(expression); - if (!ref) { + if (!reference) { return; } switch (resolve) { - case 'JSDoc': - return new Map(ref.getJsDocTags().map(tag => [tag.name, tag])) as ConditionalResolveReturn; - case 'DocComment': - return displayPartsToString(ref.getDocumentationComment(checker)) as ConditionalResolveReturn; - default: + case 'JSDoc': { + return new Map(reference.getJsDocTags().map(tag => [tag.name, tag])) as ConditionalResolveReturn; + } + + case 'DocComment': { + return ts.displayPartsToString(reference.getDocumentationComment(checker)) as ConditionalResolveReturn; + } + + default: { return undefined; + } } }; @@ -32,7 +37,7 @@ const resolveCommentHelper = (resolve: R) => { * @param expression - The expression to resolve the JSDoc tags for. * @return A unique Set of JSDoc tags or `undefined` if they couldn't be resolved. */ -export const resolveJSDocTags = resolveCommentHelper('JSDoc'); +export const resolveJsDocTags = resolveCommentHelper('JSDoc'); /** * Resolve the documentation comment from the expression. If the comment can't be found, it will return `undefined`. @@ -50,8 +55,8 @@ export const resolveDocComment = resolveCommentHelper('DocComment'); * @param expression - The expression to convert. * @return The string representation of the expression or `undefined` if it couldn't be resolved. */ -export const expressionToString = (checker: TypeChecker, expression: Expression): string | undefined => { - if (isCallLikeExpression(expression)) { +export const expressionToString = (checker: ts.TypeChecker, expression: ts.Expression): string | undefined => { + if (ts.isCallLikeExpression(expression)) { const signature = checker.getResolvedSignature(expression); if (!signature) { diff --git a/source/test/_utils.ts b/source/test/_utils.ts new file mode 100644 index 00000000..d4afc699 --- /dev/null +++ b/source/test/_utils.ts @@ -0,0 +1,267 @@ +import process from 'node:process'; +import path from 'node:path'; +import {fileURLToPath} from 'node:url'; +import test, {type ExecutionContext} from 'ava'; +import { + type ExecaError, execa, execaNode, execaCommand, +} from 'execa'; +import tsd, {type Options} from '../lib/index.js'; +import type {Diagnostic} from '../lib/interfaces.js'; + +// TODO: switch to URL when execa is updated +export const binPath = fileURLToPath(new URL('../cli.ts', import.meta.url)); + +type Expectation = [ + line: number, + column: number, + severity: 'error' | 'warning', + message: string, +]; + +type ExpectationWithFileName = [ + line: number, + column: number, + severity: 'error' | 'warning', + message: string, + fileName: string, +]; + +type ExpectationWithDiff = [ + line: number, + column: number, + severity: 'error' | 'warning', + message: string, + diff: { + expected: string; + received: string; + }, +]; + +/** + * Verify a list of diagnostics. + * + * @param t - The AVA execution context. + * @param diagnostics - List of diagnostics to verify. + * @param expectations - Expected diagnostics. + */ +export const verify = (t: ExecutionContext, diagnostics: Diagnostic[], expectations: Expectation[]) => { + const diagnosticObjs = diagnostics.map(({line, column, severity, message}) => ({ + line, + column, + severity, + message, + })); + + const expectationObjs = expectations.map(([line, column, severity, message]) => ({ + line, + column, + severity, + message, + })); + + t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); +}; + +/** + * Verify a list of diagnostics including file paths. + * + * @param t - The AVA execution context. + * @param cwd - The working directory as passed to `tsd`. + * @param diagnostics - List of diagnostics to verify. + * @param expectations - Expected diagnostics. + */ +export const verifyWithFileName = ( + t: ExecutionContext, + cwd: string, + diagnostics: Diagnostic[], + expectations: ExpectationWithFileName[], +) => { + const diagnosticObjs = diagnostics.map(({line, column, severity, message, fileName}) => ({ + line, + column, + severity, + message, + fileName: path.relative(cwd, fileName), + })); + + const expectationObjs = expectations.map(([line, column, severity, message, fileName]) => ({ + line, + column, + severity, + message, + fileName, + })); + + t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); +}; + +/** + * Verify a list of diagnostics including diff. + * + * @param t - The AVA execution context. + * @param cwd - The working directory as passed to `tsd`. + * @param diagnostics - List of diagnostics to verify. + * @param expectations - Expected diagnostics. + */ +export const verifyWithDiff = ( + t: ExecutionContext, + diagnostics: Diagnostic[], + expectations: ExpectationWithDiff[], +) => { + const diagnosticObjs = diagnostics.map(({line, column, severity, message, diff}) => ({ + line, + column, + severity, + message, + diff, + })); + + const expectationObjs = expectations.map(([line, column, severity, message, diff]) => ({ + line, + column, + severity, + message, + diff, + })); + + t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); +}; + +type VerifyCliOptions = { + startLine: number; +}; + +/** + * Verify a list of diagnostics reported from the CLI. + * + * @param t - The AVA execution context. + * @param diagnostics - List of diagnostics to verify. + * @param expectations - Expected diagnostics. + * @param startLine - Optionally specify how many lines to skip from start. + */ +export const verifyCli = ( + t: ExecutionContext, + diagnostics: string, + expectedLines: string[], + // eslint-disable-next-line unicorn/no-object-as-default-parameter + {startLine}: VerifyCliOptions = {startLine: 1}, // Skip file location. +) => { + const receivedLines = diagnostics.trim().split('\n').slice(startLine).map(line => line.trim()); + + t.deepEqual(receivedLines, expectedLines, 'Received diagnostics that are different from expectations!'); +}; + +export const getFixture = (fixtureName: string) => fixtureName.length > 0 + ? fileURLToPath(new URL(`fixtures/${fixtureName}`, import.meta.url)) + : process.cwd(); + +type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff'; + +type ExpectationType = ( + Type extends 'verify' + ? Expectation[] + : Type extends 'verifyWithFileName' + ? ExpectationWithFileName[] + : ExpectationWithDiff[] +); + +type VerifyTsdOptions = { + fixtureName: string; + tsdOptions?: Omit; +}; + +type FixtureName = string; + +const parseOptions = (options: FixtureName | VerifyTsdOptions) => { + const [fixtureName, tsdOptions] = typeof options === 'string' + ? [options, {}] + : [options.fixtureName, options.tsdOptions ?? {}]; + + const cwd = getFixture(fixtureName); + + return {cwd, tsdOptions}; +}; + +const _verifyTsd = (verifyType: Type) => ( + test.macro(async (t, options: FixtureName | VerifyTsdOptions, expectations: ExpectationType) => { + const {cwd, tsdOptions} = parseOptions(options); + const diagnostics = await tsd({cwd, ...tsdOptions}); + + const assertions = await t.try(tt => { + tt.log('cwd:', cwd); + + switch (verifyType) { + case 'verify': { + verify(tt, diagnostics, expectations as ExpectationType<'verify'>); + break; + } + + case 'verifyWithFileName': { + verifyWithFileName(tt, cwd, diagnostics, expectations as ExpectationType<'verifyWithFileName'>); + break; + } + + case 'verifyWithDiff': { + verifyWithDiff(tt, diagnostics, expectations as ExpectationType<'verifyWithDiff'>); + break; + } + + default: { + break; + } + } + }); + + assertions.commit({retainLogs: !assertions.passed}); + }) +); + +export const verifyTsd = _verifyTsd('verify'); +export const verifyTsdWithFileNames = _verifyTsd('verifyWithFileName'); +export const verifyTsdWithDiff = _verifyTsd('verifyWithDiff'); + +export const noDiagnostics = test.macro(async (t, fixtureName: string) => { + const cwd = getFixture(fixtureName); + const diagnostics = await tsd({cwd}); + + const assertions = await t.try(tt => { + tt.log('cwd:', cwd); + verify(tt, diagnostics, []); + }); + + assertions.commit({retainLogs: !assertions.passed}); +}); + +// TODO: maybe use TsdError in generic +export const verifyTsdFails = test.macro(async (t, options: FixtureName | VerifyTsdOptions, message: (cwd: string) => string) => { + const {cwd, tsdOptions} = parseOptions(options); + await t.throwsAsync(tsd({cwd, ...tsdOptions}), {message: message(cwd)}); +}); + +const _verifyCli = (shouldPass: boolean) => ( + test.macro(async (t, fixtureName: string, arguments_: string[], expectations: string[] | ((cwd: string) => string[]), options?: VerifyCliOptions) => { + const cwd = getFixture(fixtureName); + + const assertions = await t.try(async tt => { + tt.log('cwd:', cwd); + + const result = shouldPass + ? await execa(binPath, arguments_, {cwd}) + : await tt.throwsAsync(execa(binPath, arguments_, {cwd, preferLocal: true})); + + tt.log(result); + + const expectedLines = typeof expectations === 'function' + ? expectations(cwd) + : expectations; + + verifyCli(tt, result.stdout ?? result.stderr ?? '', expectedLines, options); + tt.is(result?.exitCode, shouldPass ? 0 : 1, 'CLI exited with the wrong exit code!'); + }); + + assertions.commit({retainLogs: !assertions.passed}); + }) +); + +export const verifyCliPasses = _verifyCli(true); +export const verifyCliFails = _verifyCli(false); diff --git a/source/test/assignability.ts b/source/test/assignability.ts index 56136bf2..62a1c269 100644 --- a/source/test/assignability.ts +++ b/source/test/assignability.ts @@ -1,21 +1,11 @@ -import path from 'path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import {verifyTsd} from './_utils.js'; -test('assignable', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/assignability/assignable')}); +test('assignable', verifyTsd, 'assignability/assignable', [ + [8, 26, 'error', 'Argument of type \'string\' is not assignable to parameter of type \'boolean\'.'], +]); - verify(t, diagnostics, [ - [8, 26, 'error', 'Argument of type \'string\' is not assignable to parameter of type \'boolean\'.'] - ]); -}); - -test('not assignable', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/assignability/not-assignable')}); - - verify(t, diagnostics, [ - [4, 0, 'error', 'Argument of type `string` is assignable to parameter of type `string | number`.'], - [5, 0, 'error', 'Argument of type `string` is assignable to parameter of type `any`.'], - ]); -}); +test('not assignable', verifyTsd, 'assignability/not-assignable', [ + [4, 0, 'error', 'Argument of type `string` is assignable to parameter of type `string | number`.'], + [5, 0, 'error', 'Argument of type `string` is assignable to parameter of type `any`.'], +]); diff --git a/source/test/cli.ts b/source/test/cli.ts index b499fe7f..11b6a3a4 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -1,152 +1,76 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import execa from 'execa'; -import readPkgUp from 'read-pkg-up'; -import tsd, {formatter} from '..'; -import {verifyCli} from './fixtures/utils'; +import {execa, type ExecaError} from 'execa'; +import {readPackageUp} from 'read-package-up'; import resolveFrom from 'resolve-from'; - -interface ExecaError extends Error { - readonly exitCode: number; - readonly stderr: string; -} - -test('fail if errors are found', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/failure') - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); -}); - -test('succeed if no errors are found', async t => { - const {exitCode} = await execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/success') - }); - - t.is(exitCode, 0); -}); - -test('provide a path', async t => { - const file = path.join(__dirname, 'fixtures/failure'); - - const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file])); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); -}); - -test('cli help flag', async t => { - const {exitCode} = await execa('dist/cli.js', ['--help']); - - t.is(exitCode, 0); -}); - -test('cli version flag', async t => { - const pkg = readPkgUp.sync({normalize: false})?.packageJson ?? {}; - - const {exitCode, stdout} = await execa('dist/cli.js', ['--version']); - - t.is(exitCode, 0); - t.is(stdout, pkg.version); -}); - -test('cli typings flag', async t => { - const runTest = async (arg: '--typings' | '-t') => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', [arg, 'utils/index.d.ts'], { - cwd: path.join(__dirname, 'fixtures/typings-custom-dir') - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); - }; - - await runTest('--typings'); - await runTest('-t'); -}); - -test('cli files flag', async t => { - const runTest = async (arg: '--files' | '-f') => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', [arg, 'unknown.test.ts'], { - cwd: path.join(__dirname, 'fixtures/specify-test-files') - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); - }; - - await runTest('--files'); - await runTest('-f'); -}); - -test('cli files flag array', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', ['--files', 'unknown.test.ts', '--files', 'second.test.ts'], { - cwd: path.join(__dirname, 'fixtures/specify-test-files') - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); -}); - -test('cli typings and files flags', async t => { - const typingsFile = 'dist/test/fixtures/typings-custom-dir/utils/index.d.ts'; - const testFile = 'dist/test/fixtures/typings-custom-dir/index.test-d.ts'; - - const {exitCode, stderr} = t.throws(() => execa.commandSync(`dist/cli.js -t ${typingsFile} -f ${testFile}`)); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); -}); - -test('tsd logs stacktrace on failure', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/empty-package-json') - })); - +import tsd, {formatter} from '../index.js'; +import { + binPath, + getFixture, + verifyCli, + verifyCliPasses, + verifyCliFails, +} from './_utils.js'; + +// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain, unicorn/no-await-expression-member +const package_ = (await readPackageUp())?.packageJson!; + +test('fail if errors are found', verifyCliFails, 'failure', [], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('succeed if no errors are found', verifyCliPasses, 'success', [], []); + +test('provide a path', verifyCliFails, '', [getFixture('failure')], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('cli help flag: --help', verifyCliPasses, '', ['--help'], [ + 'Usage', +]); + +test('cli version flag: --version', verifyCliPasses, '', ['--version'], [package_.version]); + +test('cli files flag: --files', verifyCliFails, 'specify-test-files', ['--files', 'unknown.test.ts'], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('cli files flag: -f', verifyCliFails, 'specify-test-files', ['-f', 'unknown.test.ts'], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('cli files flag: array', verifyCliFails, 'specify-test-files', ['--files', 'unknown.test.ts', '--files', 'second.test.ts'], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('tsd logs stacktrace on failure', verifyCliFails, 'empty-package-json', [], () => { const nodeModulesPath = path.resolve('node_modules'); const parseJsonPath = resolveFrom.silent(`${nodeModulesPath}/read-pkg`, 'parse-json') ?? `${nodeModulesPath}/index.js`; - t.is(exitCode, 1); - verifyCli(t, stderr, [ + return [ 'Error running tsd:', 'JSONError: Unexpected end of JSON input while parsing empty string', `at parseJson (${parseJsonPath}:29:21)`, `at module.exports (${nodeModulesPath}/read-pkg/index.js:17:15)`, - `at async module.exports (${nodeModulesPath}/read-pkg-up/index.js:14:16)`, - ], {startLine: 0}); -}); + `at async module.exports (${nodeModulesPath}/read-package-up/index.js:14:16)`, + ]; +}, {startLine: 0}); test('exported formatter matches cli results', async t => { - const options = { - cwd: path.join(__dirname, 'fixtures/failure'), - }; + const options = {cwd: getFixture('failure')}; - const {stderr: cliResults} = await t.throwsAsync(execa('../../../cli.js', options)); + const {stderr: cliResults} = await t.throwsAsync(execa(binPath, options)); + const formattedTsdResults = formatter(await tsd(options)); verifyCli(t, cliResults, [ '✖ 5:19 Argument of type number is not assignable to parameter of type string.', @@ -154,49 +78,27 @@ test('exported formatter matches cli results', async t => { '1 error', ]); - const tsdResults = await tsd(options); - const formattedResults = formatter(tsdResults); - - verifyCli(t, formattedResults, [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', - ]); -}); - -test('warnings are reported correctly and do not fail', async t => { - const {exitCode, stdout} = await execa('../../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/warnings/only-warnings'), - }); - - t.is(exitCode, 0); - verifyCli(t, stdout, [ - '⚠ 4:0 Type for expression one(1, 1) is: number', - '', - '1 warning', - ]); -}); - -test('warnings are reported with errors', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/warnings/with-errors'), - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ + verifyCli(t, formattedTsdResults, [ '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '⚠ 4:0 Type for expression one(1, 1) is: number', '', - '1 warning', '1 error', ]); }); -test('tsd failures (not crashes) report only the message', async t => { - const cwd = path.join(__dirname, 'fixtures/no-tsd'); - - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', {cwd})); - - t.is(exitCode, 1); - t.is(stderr, `The type definition \`index.d.ts\` does not exist at \`${cwd}/index.d.ts\`. Is the path correct? Create one and try again.`); -}); +test('warnings are reported correctly and do not fail', verifyCliPasses, 'warnings/only-warnings', [], [ + '⚠ 4:0 Type for expression one(1, 1) is: number', + '', + '1 warning', +]); + +test('warnings are reported with errors', verifyCliFails, 'warnings/with-errors', [], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '⚠ 4:0 Type for expression one(1, 1) is: number', + '', + '1 warning', + '1 error', +]); + +test('tsd failures (not crashes) report only the message', verifyCliFails, 'no-tsd', [], cwd => [ + `The type definition \`index.d.ts\` does not exist at \`${cwd}/index.d.ts\`. Is the path correct? Create one and try again.`, +]); diff --git a/source/test/deprecated.ts b/source/test/deprecated.ts index fed893b4..a052f19b 100644 --- a/source/test/deprecated.ts +++ b/source/test/deprecated.ts @@ -1,26 +1,16 @@ -import path from 'path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import {verifyTsd} from './_utils.js'; -test('deprecated', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/deprecated/expect-deprecated')}); +test('deprecated', verifyTsd, 'deprecated/expect-deprecated', [ + [6, 0, 'error', 'Expected `(foo: number, bar: number): number` to be marked as `@deprecated`'], + [15, 0, 'error', 'Expected `Options.delimiter` to be marked as `@deprecated`'], + [19, 0, 'error', 'Expected `Unicorn.RAINBOW` to be marked as `@deprecated`'], + [34, 0, 'error', 'Expected `RainbowClass` to be marked as `@deprecated`'], +]); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected `(foo: number, bar: number): number` to be marked as `@deprecated`'], - [15, 0, 'error', 'Expected `Options.delimiter` to be marked as `@deprecated`'], - [19, 0, 'error', 'Expected `Unicorn.RAINBOW` to be marked as `@deprecated`'], - [34, 0, 'error', 'Expected `RainbowClass` to be marked as `@deprecated`'] - ]); -}); - -test('not deprecated', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/deprecated/expect-not-deprecated')}); - - verify(t, diagnostics, [ - [5, 0, 'error', 'Expected `(foo: string, bar: string): string` to not be marked as `@deprecated`'], - [14, 0, 'error', 'Expected `Options.separator` to not be marked as `@deprecated`'], - [18, 0, 'error', 'Expected `Unicorn.UNICORN` to not be marked as `@deprecated`'], - [33, 0, 'error', 'Expected `UnicornClass` to not be marked as `@deprecated`'] - ]); -}); +test('not deprecated', verifyTsd, 'deprecated/expect-not-deprecated', [ + [5, 0, 'error', 'Expected `(foo: string, bar: string): string` to not be marked as `@deprecated`'], + [14, 0, 'error', 'Expected `Options.separator` to not be marked as `@deprecated`'], + [18, 0, 'error', 'Expected `Unicorn.UNICORN` to not be marked as `@deprecated`'], + [33, 0, 'error', 'Expected `UnicornClass` to not be marked as `@deprecated`'], +]); diff --git a/source/test/diff.ts b/source/test/diff.ts index b8867618..b3dab628 100644 --- a/source/test/diff.ts +++ b/source/test/diff.ts @@ -1,72 +1,58 @@ -import {verifyWithDiff, verifyCli} from './fixtures/utils'; -import execa, {ExecaError} from 'execa'; -import path from 'path'; import test from 'ava'; -import tsd from '..'; +import {verifyTsdWithDiff, verifyCliFails} from './_utils.js'; -test('diff', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/diff')}); +test('diff', verifyTsdWithDiff, 'diff', [ + [8, 0, 'error', 'Parameter type `{ life?: number | undefined; }` is declared too wide for argument type `{ life: number; }`.', { + expected: '{ life?: number | undefined; }', + received: '{ life: number; }', + }], + [9, 0, 'error', 'Parameter type `FooFunction` is not identical to argument type `() => number`.', { + expected: '(x?: string | undefined) => number', + received: '() => number', + }], + [10, 0, 'error', 'Parameter type `FooType` is declared too wide for argument type `Required`.', { + expected: '{ foo?: "foo" | undefined; }', + received: '{ foo: "foo"; }', + }], + [11, 0, 'error', 'Parameter type `Partial` is declared too wide for argument type `Required`.', { + expected: '{ [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', + received: '{ [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', + }], + [13, 0, 'error', 'Argument of type `{ life: number; }` is assignable to parameter of type `{ life?: number | undefined; }`.', { + expected: '{ life?: number | undefined; }', + received: '{ life: number; }', + }], + [18, 0, 'error', 'Documentation comment `This is a comment.` for expression `commented` does not include expected `This is not the same comment!`.', { + expected: 'This is not the same comment!', + received: 'This is a comment.', + }], +]); - verifyWithDiff(t, diagnostics, [ - [8, 0, 'error', 'Parameter type `{ life?: number | undefined; }` is declared too wide for argument type `{ life: number; }`.', { - expected: '{ life?: number | undefined; }', - received: '{ life: number; }', - }], - [9, 0, 'error', 'Parameter type `FooFunction` is not identical to argument type `() => number`.', { - expected: '(x?: string | undefined) => number', - received: '() => number', - }], - [10, 0, 'error', 'Parameter type `FooType` is declared too wide for argument type `Required`.', { - expected: '{ foo?: "foo" | undefined; }', - received: '{ foo: "foo"; }', - }], - [11, 0, 'error', 'Parameter type `Partial` is declared too wide for argument type `Required`.', { - expected: '{ [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', - received: '{ [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', - }], - [13, 0, 'error', 'Argument of type `{ life: number; }` is assignable to parameter of type `{ life?: number | undefined; }`.', { - expected: '{ life?: number | undefined; }', - received: '{ life: number; }', - }], - [18, 0, 'error', 'Documentation comment `This is a comment.` for expression `commented` does not include expected `This is not the same comment!`.', { - expected: 'This is not the same comment!', - received: 'This is a comment.', - }] - ]); -}); - -test('diff cli', async t => { - const file = path.join(__dirname, 'fixtures/diff'); - - const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file, '--show-diff'])); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 8:0 Parameter type { life?: number | undefined; } is declared too wide for argument type { life: number; }.', - '', - '- { life?: number | undefined; }', - '+ { life: number; }', - '✖ 9:0 Parameter type FooFunction is not identical to argument type () => number.', - '', - '- (x?: string | undefined) => number', - '+ () => number', - '✖ 10:0 Parameter type FooType is declared too wide for argument type Required.', - '', - '- { foo?: "foo" | undefined; }', - '+ { foo: "foo"; }', - '✖ 11:0 Parameter type Partial is declared too wide for argument type Required.', - '', - '- { [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', - '+ { [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', - '✖ 13:0 Argument of type { life: number; } is assignable to parameter of type { life?: number | undefined; }.', - '', - '- { life?: number | undefined; }', - '+ { life: number; }', - '✖ 18:0 Documentation comment This is a comment. for expression commented does not include expected This is not the same comment!.', - '', - '- This is not the same comment!', - '+ This is a comment.', - '', - '6 errors' - ]); -}); +test('diff cli', verifyCliFails, 'diff', ['--show-diff'], [ + '✖ 8:0 Parameter type { life?: number | undefined; } is declared too wide for argument type { life: number; }.', + '', + '- { life?: number | undefined; }', + '+ { life: number; }', + '✖ 9:0 Parameter type FooFunction is not identical to argument type () => number.', + '', + '- (x?: string | undefined) => number', + '+ () => number', + '✖ 10:0 Parameter type FooType is declared too wide for argument type Required.', + '', + '- { foo?: "foo" | undefined; }', + '+ { foo: "foo"; }', + '✖ 11:0 Parameter type Partial is declared too wide for argument type Required.', + '', + '- { [x: string]: unknown; readonly protected?: boolean | undefined; fooType?: FooType | undefined; id?: "foo-interface" | undefined; }', + '+ { [x: string]: unknown; readonly protected: boolean; fooType: FooType; id: "foo-interface"; }', + '✖ 13:0 Argument of type { life: number; } is assignable to parameter of type { life?: number | undefined; }.', + '', + '- { life?: number | undefined; }', + '+ { life: number; }', + '✖ 18:0 Documentation comment This is a comment. for expression commented does not include expected This is not the same comment!.', + '', + '- This is not the same comment!', + '+ This is a comment.', + '', + '6 errors', +]); diff --git a/source/test/eslint-compatibility.ts b/source/test/eslint-compatibility.ts index 19d329ca..80158d53 100644 --- a/source/test/eslint-compatibility.ts +++ b/source/test/eslint-compatibility.ts @@ -1,29 +1,19 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import execa from 'execa'; +import {execa} from 'execa'; +import {stripIndent} from 'common-tags'; -test('`expectType` is compatible with eslint @typescript-eslint/no-unsafe-call rule', t => { - try { - execa.sync( - 'node_modules/.bin/eslint', - ['source/test/fixtures/eslint-compatibility', '--no-ignore'], - { - cwd: path.join(__dirname, '../../') - } - ); +test('`expectType` is compatible with eslint @typescript-eslint/no-unsafe-call rule', async t => { + await t.throwsAsync( + execa('eslint', ['source/test/fixtures/eslint-compatibility', '--no-ignore']), + { + message: stripIndent` + ${path.resolve('fixtures/eslint-compatibility')}/index.test-d.ts + 9:1 error Unsafe call of an \`any\` typed value @typescript-eslint/no-unsafe-call - t.fail('eslint should have found an error!'); - } catch (error: unknown) { - if (!error) { - t.fail('Thrown error is falsy!'); - } - - const execaError = error as execa.ExecaError; - - const outLines = execaError.stdout.trim().split('\n'); - - t.regex(outLines[0], /fixtures[/\\]eslint-compatibility[/\\]index.test-d.ts$/, 'Lint error found in unexpected file'); - t.is(outLines[1], ' 9:1 error Unsafe call of an `any` typed value @typescript-eslint/no-unsafe-call'); - t.is(outLines[3], '✖ 1 problem (1 error, 0 warnings)'); - } + ✖ 1 problem (1 error, 0 warnings) + `, + }, + 'eslint should have found an error!', + ); }); diff --git a/source/test/expect-error.ts b/source/test/expect-error.ts index b5a65480..7821091b 100644 --- a/source/test/expect-error.ts +++ b/source/test/expect-error.ts @@ -1,75 +1,33 @@ -import path from 'path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import {verifyTsd, noDiagnostics} from './_utils.js'; -test('expectError for classes', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/classes')}); +test('expectError for classes', noDiagnostics, 'expect-error/classes'); - verify(t, diagnostics, []); -}); +test('expectError for functions', verifyTsd, 'expect-error/functions', [ + [5, 0, 'error', 'Expected an error, but found none.'], +]); -test('expectError for functions', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/functions')}); +test('expectError for generics', noDiagnostics, 'expect-error/generics'); - verify(t, diagnostics, [ - [5, 0, 'error', 'Expected an error, but found none.'] - ]); -}); +test('expectError should not ignore syntactical errors', verifyTsd, 'expect-errors/syntax', [ + [4, 29, 'error', '\')\' expected.'], + [5, 22, 'error', '\',\' expected.'], +]); -test('expectError for generics', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/generics')}); +test('expectError for values', verifyTsd, 'expect-error/values', [ + [5, 0, 'error', 'Expected an error, but found none.'], +]); - verify(t, diagnostics, []); -}); +test('expectError for values (noImplicitAny disabled)', noDiagnostics, 'expect-error/values-disabled-no-implicit-any'); -test('expectError should not ignore syntactical errors', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/syntax')}); +test('expectError for values (exactOptionalPropertyTypes enabled)', noDiagnostics, 'expect-error/enabled-exact-optional-property-types'); - verify(t, diagnostics, [ - [4, 29, 'error', '\')\' expected.'], - [5, 22, 'error', '\',\' expected.'], - ]); -}); +test('expectError for decorators', noDiagnostics, 'expect-error/decorators'); -test('expectError for values', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/values')}); +test('expectError for experimental decorators', noDiagnostics, 'expect-error/experimental-decorators'); - verify(t, diagnostics, [ - [5, 0, 'error', 'Expected an error, but found none.'] - ]); -}); - -test('expectError for values (noImplicitAny disabled)', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/values-disabled-no-implicit-any')}); - - verify(t, diagnostics, []); -}); - -test('expectError for values (exactOptionalPropertyTypes enabled)', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/enabled-exact-optional-property-types')}); - - verify(t, diagnostics, []); -}); - -test('expectError for decorators', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/decorators')}); - - verify(t, diagnostics, []); -}); - -test('expectError for experimental decorators', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/experimental-decorators')}); - - verify(t, diagnostics, []); -}); - -test('expectError should report missing diagnostic codes', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/missing-diagnostic-code')}); - - verify(t, diagnostics, [ - [8, 12, 'error', 'Cannot find name \'undeclared\'.'], - [5, 0, 'error', 'Expected an error, but found none.'], - [8, 0, 'error', 'Found an error that tsd does not currently support (`ts2304`), consider creating an issue on GitHub.'], - ]); -}); +test('expectError should report missing diagnostic codes', verifyTsd, 'expect-error/missing-diagnostic-code', [ + [8, 12, 'error', 'Cannot find name \'undeclared\'.'], + [5, 0, 'error', 'Expected an error, but found none.'], + [8, 0, 'error', 'Found an error that tsd does not currently support (`ts2304`), consider creating an issue on GitHub.'], +]); diff --git a/source/test/fixtures/aliased/aliased-assertion/index.js b/source/test/fixtures/aliased/aliased-assertion/index.js index dfe501b3..015e62e1 100644 --- a/source/test/fixtures/aliased/aliased-assertion/index.js +++ b/source/test/fixtures/aliased/aliased-assertion/index.js @@ -1 +1 @@ -module.exports.default = (foo, bar) => foo + bar; +export default (foo, bar) => foo + bar; diff --git a/source/test/fixtures/aliased/aliased-assertion/index.test-d.ts b/source/test/fixtures/aliased/aliased-assertion/index.test-d.ts index 628490df..1caf355e 100644 --- a/source/test/fixtures/aliased/aliased-assertion/index.test-d.ts +++ b/source/test/fixtures/aliased/aliased-assertion/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType as et} from '../../../..'; -import one from '.'; +import {expectType as et} from '../../../../index.js'; +import one from './index.js'; et(one(1, 1)); diff --git a/source/test/fixtures/aliased/aliased-assertion/package.json b/source/test/fixtures/aliased/aliased-assertion/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/aliased/aliased-assertion/package.json +++ b/source/test/fixtures/aliased/aliased-assertion/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/aliased/aliased-const/index.js b/source/test/fixtures/aliased/aliased-const/index.js index dfe501b3..015e62e1 100644 --- a/source/test/fixtures/aliased/aliased-const/index.js +++ b/source/test/fixtures/aliased/aliased-const/index.js @@ -1 +1 @@ -module.exports.default = (foo, bar) => foo + bar; +export default (foo, bar) => foo + bar; diff --git a/source/test/fixtures/aliased/aliased-const/index.test-d.ts b/source/test/fixtures/aliased/aliased-const/index.test-d.ts index 49d2bda9..4e7cca38 100644 --- a/source/test/fixtures/aliased/aliased-const/index.test-d.ts +++ b/source/test/fixtures/aliased/aliased-const/index.test-d.ts @@ -1,5 +1,5 @@ -import * as tsd from '../../../..'; -import one from '.'; +import * as tsd from '../../../../index.js'; +import one from './index.js'; const x = tsd; x.expectError(one(true, true)); diff --git a/source/test/fixtures/aliased/aliased-const/package.json b/source/test/fixtures/aliased/aliased-const/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/aliased/aliased-const/package.json +++ b/source/test/fixtures/aliased/aliased-const/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/aliased/aliased-module/index.js b/source/test/fixtures/aliased/aliased-module/index.js index dfe501b3..015e62e1 100644 --- a/source/test/fixtures/aliased/aliased-module/index.js +++ b/source/test/fixtures/aliased/aliased-module/index.js @@ -1 +1 @@ -module.exports.default = (foo, bar) => foo + bar; +export default (foo, bar) => foo + bar; diff --git a/source/test/fixtures/aliased/aliased-module/index.test-d.ts b/source/test/fixtures/aliased/aliased-module/index.test-d.ts index 7edf9c07..c9250cfd 100644 --- a/source/test/fixtures/aliased/aliased-module/index.test-d.ts +++ b/source/test/fixtures/aliased/aliased-module/index.test-d.ts @@ -1,6 +1,6 @@ -import * as tsd from '../../../..'; -import {expectType, expectError} from '../../../..'; -import one from '.'; +import * as tsd from '../../../../index.js'; +import {expectType, expectError} from '../../../../index.js'; +import one from './index.js'; expectType(one(1, 1)); tsd.expectType(one(1, 1)); diff --git a/source/test/fixtures/aliased/aliased-module/package.json b/source/test/fixtures/aliased/aliased-module/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/aliased/aliased-module/package.json +++ b/source/test/fixtures/aliased/aliased-module/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/assignability/assignable/index.js b/source/test/fixtures/assignability/assignable/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/assignability/assignable/index.js +++ b/source/test/fixtures/assignability/assignable/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/assignability/assignable/index.test-d.ts b/source/test/fixtures/assignability/assignable/index.test-d.ts index d0583acf..7ea1b43c 100644 --- a/source/test/fixtures/assignability/assignable/index.test-d.ts +++ b/source/test/fixtures/assignability/assignable/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectAssignable} from '../../../..'; -import concat from '.'; +import {expectAssignable} from '../../../../index.js'; +import concat from './index.js'; expectAssignable(concat('foo', 'bar')); expectAssignable(concat(1, 2)); diff --git a/source/test/fixtures/assignability/assignable/package.json b/source/test/fixtures/assignability/assignable/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/assignability/assignable/package.json +++ b/source/test/fixtures/assignability/assignable/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/assignability/not-assignable/index.js b/source/test/fixtures/assignability/not-assignable/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/assignability/not-assignable/index.js +++ b/source/test/fixtures/assignability/not-assignable/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/assignability/not-assignable/index.test-d.ts b/source/test/fixtures/assignability/not-assignable/index.test-d.ts index 39dfbab2..22bddd46 100644 --- a/source/test/fixtures/assignability/not-assignable/index.test-d.ts +++ b/source/test/fixtures/assignability/not-assignable/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectNotAssignable} from '../../../..'; -import concat from '.'; +import {expectNotAssignable} from '../../../../index.js'; +import concat from './index.js'; expectNotAssignable(concat('foo', 'bar')); expectNotAssignable(concat('foo', 'bar')); diff --git a/source/test/fixtures/assignability/not-assignable/package.json b/source/test/fixtures/assignability/not-assignable/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/assignability/not-assignable/package.json +++ b/source/test/fixtures/assignability/not-assignable/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/deprecated/expect-deprecated/index.js b/source/test/fixtures/deprecated/expect-deprecated/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/deprecated/expect-deprecated/index.js +++ b/source/test/fixtures/deprecated/expect-deprecated/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/deprecated/expect-deprecated/index.test-d.ts b/source/test/fixtures/deprecated/expect-deprecated/index.test-d.ts index 5bbdff5e..1f718588 100644 --- a/source/test/fixtures/deprecated/expect-deprecated/index.test-d.ts +++ b/source/test/fixtures/deprecated/expect-deprecated/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectDeprecated} from '../../../..'; -import concat, {Unicorn, Options} from '.'; +import {expectDeprecated} from '../../../../index.js'; +import concat, {Unicorn, Options} from './index.js'; // Methods expectDeprecated(concat('foo', 'bar')); diff --git a/source/test/fixtures/deprecated/expect-deprecated/package.json b/source/test/fixtures/deprecated/expect-deprecated/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/deprecated/expect-deprecated/package.json +++ b/source/test/fixtures/deprecated/expect-deprecated/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/deprecated/expect-not-deprecated/index.js b/source/test/fixtures/deprecated/expect-not-deprecated/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/deprecated/expect-not-deprecated/index.js +++ b/source/test/fixtures/deprecated/expect-not-deprecated/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/deprecated/expect-not-deprecated/index.test-d.ts b/source/test/fixtures/deprecated/expect-not-deprecated/index.test-d.ts index 7255827e..61ca3b93 100644 --- a/source/test/fixtures/deprecated/expect-not-deprecated/index.test-d.ts +++ b/source/test/fixtures/deprecated/expect-not-deprecated/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectNotDeprecated} from '../../../..'; -import concat, {Unicorn, Options} from '.'; +import {expectNotDeprecated} from '../../../../index.js'; +import concat, {Unicorn, Options} from './index.js'; // Methods expectNotDeprecated(concat('foo', 'bar')); diff --git a/source/test/fixtures/deprecated/expect-not-deprecated/package.json b/source/test/fixtures/deprecated/expect-not-deprecated/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/deprecated/expect-not-deprecated/package.json +++ b/source/test/fixtures/deprecated/expect-not-deprecated/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/diff/index.js b/source/test/fixtures/diff/index.js index 20a52356..4f66073b 100644 --- a/source/test/fixtures/diff/index.js +++ b/source/test/fixtures/diff/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo) => { +export default (foo) => { return foo; }; diff --git a/source/test/fixtures/diff/index.test-d.ts b/source/test/fixtures/diff/index.test-d.ts index c40defd2..fa7e69ff 100644 --- a/source/test/fixtures/diff/index.test-d.ts +++ b/source/test/fixtures/diff/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectDocCommentIncludes, expectNotAssignable, expectType} from '../../..'; -import foo, { FooFunction, FooInterface, FooType } from '.'; +import {expectDocCommentIncludes, expectNotAssignable, expectType} from '../../../index.js'; +import foo, { FooFunction, FooInterface, FooType } from './index.js'; // Should pass expectType<{life: number}>(foo({life: 42})); diff --git a/source/test/fixtures/diff/package.json b/source/test/fixtures/diff/package.json index 06ea168a..aefa016e 100644 --- a/source/test/fixtures/diff/package.json +++ b/source/test/fixtures/diff/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" diff --git a/source/test/fixtures/dom/index.js b/source/test/fixtures/dom/index.js index 9b86b161..5b6044b5 100644 --- a/source/test/fixtures/dom/index.js +++ b/source/test/fixtures/dom/index.js @@ -1,3 +1,3 @@ -exports.default = (parent, child) => { +export default (parent, child) => { parent.appendChild(child); }; diff --git a/source/test/fixtures/dom/index.test-d.ts b/source/test/fixtures/dom/index.test-d.ts index 59ff367d..e7b56307 100644 --- a/source/test/fixtures/dom/index.test-d.ts +++ b/source/test/fixtures/dom/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../../..'; -import append from '.'; +import {expectType} from '../../../index.js'; +import append from './index.js'; const parent = document.createElement('div'); const child = document.createElement('p'); diff --git a/source/test/fixtures/dom/package.json b/source/test/fixtures/dom/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/dom/package.json +++ b/source/test/fixtures/dom/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/eslint-compatibility/.eslintrc b/source/test/fixtures/eslint-compatibility/.eslintrc index 33a8ebb5..b3ca1cec 100644 --- a/source/test/fixtures/eslint-compatibility/.eslintrc +++ b/source/test/fixtures/eslint-compatibility/.eslintrc @@ -1,9 +1,10 @@ { - "root": false, + "root": true, "parserOptions": { "project": "source/test/fixtures/eslint-compatibility/tsconfig.json" }, "rules": { "@typescript-eslint/no-unsafe-call": "error" } + // TODO: fix config now that tsd is using xo } diff --git a/source/test/fixtures/eslint-compatibility/index.js b/source/test/fixtures/eslint-compatibility/index.js index a26b76e2..095da138 100644 --- a/source/test/fixtures/eslint-compatibility/index.js +++ b/source/test/fixtures/eslint-compatibility/index.js @@ -1,4 +1,3 @@ -module.exports.default = (foo, bar) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/restrict-plus-operands +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/eslint-compatibility/index.test-d.ts b/source/test/fixtures/eslint-compatibility/index.test-d.ts index 514411bd..c4dc54c8 100644 --- a/source/test/fixtures/eslint-compatibility/index.test-d.ts +++ b/source/test/fixtures/eslint-compatibility/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/eslint-compatibility/package.json b/source/test/fixtures/eslint-compatibility/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/eslint-compatibility/package.json +++ b/source/test/fixtures/eslint-compatibility/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/esm/index.d.ts b/source/test/fixtures/esm/index.d.ts deleted file mode 100644 index 110b2b75..00000000 --- a/source/test/fixtures/esm/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare const one: { - (foo: string, bar: string): string; - (foo: number, bar: number): number; - (foo: T, bar: T): string; -}; - -export = one; diff --git a/source/test/fixtures/esm/index.js b/source/test/fixtures/esm/index.js deleted file mode 100644 index 0d28b4c1..00000000 --- a/source/test/fixtures/esm/index.js +++ /dev/null @@ -1,3 +0,0 @@ -const one = (foo, bar) => foo + bar; - -export default one; diff --git a/source/test/fixtures/esm/index.test-d.ts b/source/test/fixtures/esm/index.test-d.ts deleted file mode 100644 index 67eb5ed0..00000000 --- a/source/test/fixtures/esm/index.test-d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import {expectType} from '../../../..'; -import one from './index.js'; - -expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/esm/package.json b/source/test/fixtures/esm/package.json deleted file mode 100644 index 75bc3f28..00000000 --- a/source/test/fixtures/esm/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "foo", - "type": "module", - "exports": "./index.js" -} diff --git a/source/test/fixtures/exclude-node-modules/index.js b/source/test/fixtures/exclude-node-modules/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/exclude-node-modules/index.js +++ b/source/test/fixtures/exclude-node-modules/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/exclude-node-modules/index.test-d.ts b/source/test/fixtures/exclude-node-modules/index.test-d.ts index aadb8043..ba879850 100644 --- a/source/test/fixtures/exclude-node-modules/index.test-d.ts +++ b/source/test/fixtures/exclude-node-modules/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; -import aboveZero from '.'; +import {expectType} from '../../../index.js'; +import aboveZero from './index.js'; expectType(aboveZero(1)); diff --git a/source/test/fixtures/exclude-node-modules/package.json b/source/test/fixtures/exclude-node-modules/package.json index 132da0f4..93d2f639 100644 --- a/source/test/fixtures/exclude-node-modules/package.json +++ b/source/test/fixtures/exclude-node-modules/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "noLib": true diff --git a/source/test/fixtures/expect-error/classes/index.js b/source/test/fixtures/expect-error/classes/index.js index 901c6151..f47dda0c 100644 --- a/source/test/fixtures/expect-error/classes/index.js +++ b/source/test/fixtures/expect-error/classes/index.js @@ -1,9 +1,7 @@ -class Foo { +export class Foo { bar(value) { if (value) { this.val = value; } } } - -module.exports.Foo = Foo; diff --git a/source/test/fixtures/expect-error/classes/index.test-d.ts b/source/test/fixtures/expect-error/classes/index.test-d.ts index 66052486..567b5fa4 100644 --- a/source/test/fixtures/expect-error/classes/index.test-d.ts +++ b/source/test/fixtures/expect-error/classes/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import {Foo} from '.'; +import {expectError} from '../../../../index.js'; +import {Foo} from './index.js'; const numberFoo = new Foo(); diff --git a/source/test/fixtures/expect-error/classes/package.json b/source/test/fixtures/expect-error/classes/package.json index 60fcb065..b69a9bfd 100644 --- a/source/test/fixtures/expect-error/classes/package.json +++ b/source/test/fixtures/expect-error/classes/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "noImplicitOverride": true diff --git a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.js b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.js +++ b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.test-d.ts b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.test-d.ts index ef8743f6..2ba45442 100644 --- a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.test-d.ts +++ b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import {OptionalProperty, setWithOptionalProperty} from '.'; +import {expectError} from '../../../../index.js'; +import {OptionalProperty, setWithOptionalProperty} from './index.js'; expectError(() => { const obj: OptionalProperty = { diff --git a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/package.json b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/package.json index 52e19d2e..9583df1e 100644 --- a/source/test/fixtures/expect-error/enabled-exact-optional-property-types/package.json +++ b/source/test/fixtures/expect-error/enabled-exact-optional-property-types/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "exactOptionalPropertyTypes": true diff --git a/source/test/fixtures/expect-error/functions/index.js b/source/test/fixtures/expect-error/functions/index.js index 88de192a..8b95ffaa 100644 --- a/source/test/fixtures/expect-error/functions/index.js +++ b/source/test/fixtures/expect-error/functions/index.js @@ -1,6 +1,6 @@ -module.exports.default = (foo, bar) => foo + bar; +export default (foo, bar) => foo + bar; -module.exports.two = (foo, bar, baz) => { +export const two = (foo, bar, baz) => { if (foo!= null && bar != null && baz != null) { return foo + bar + baz; } else { @@ -8,4 +8,4 @@ module.exports.two = (foo, bar, baz) => { } }; -exports.three = (foo) => 'a'; +export const three = (foo) => 'a'; diff --git a/source/test/fixtures/expect-error/functions/index.test-d.ts b/source/test/fixtures/expect-error/functions/index.test-d.ts index b42506cd..afa1a9f4 100644 --- a/source/test/fixtures/expect-error/functions/index.test-d.ts +++ b/source/test/fixtures/expect-error/functions/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import one, {two, three} from '.'; +import {expectError} from '../../../../index.js'; +import one, {two, three} from './index.js'; expectError(one(true, true)); expectError(one('foo', 'bar')); diff --git a/source/test/fixtures/expect-error/functions/package.json b/source/test/fixtures/expect-error/functions/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/expect-error/functions/package.json +++ b/source/test/fixtures/expect-error/functions/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/expect-error/generics/index.js b/source/test/fixtures/expect-error/generics/index.js index 78dadca0..b3f10891 100644 --- a/source/test/fixtures/expect-error/generics/index.js +++ b/source/test/fixtures/expect-error/generics/index.js @@ -1,8 +1,8 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; -exports.two = (foo, bar) => { +export const two = (foo, bar) => { if (foo != null && bar != null) { return bar; } else { diff --git a/source/test/fixtures/expect-error/generics/index.test-d.ts b/source/test/fixtures/expect-error/generics/index.test-d.ts index dc181493..f7720576 100644 --- a/source/test/fixtures/expect-error/generics/index.test-d.ts +++ b/source/test/fixtures/expect-error/generics/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import one, {two, type Three} from '.'; +import {expectError} from '../../../../index.js'; +import one, {two, type Three} from './index.js'; expectError(one(true, true)); diff --git a/source/test/fixtures/expect-error/generics/package.json b/source/test/fixtures/expect-error/generics/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/expect-error/generics/package.json +++ b/source/test/fixtures/expect-error/generics/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/expect-error/missing-diagnostic-code/index.js b/source/test/fixtures/expect-error/missing-diagnostic-code/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/expect-error/missing-diagnostic-code/index.js +++ b/source/test/fixtures/expect-error/missing-diagnostic-code/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/expect-error/missing-diagnostic-code/index.test-d.ts b/source/test/fixtures/expect-error/missing-diagnostic-code/index.test-d.ts index 5b6a7d59..b1f475ca 100644 --- a/source/test/fixtures/expect-error/missing-diagnostic-code/index.test-d.ts +++ b/source/test/fixtures/expect-error/missing-diagnostic-code/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import one from '.'; +import {expectError} from '../../../../index.js'; +import one from './index.js'; // 'Expected an error, but found none.' expectError(one('foo', 'bar')); diff --git a/source/test/fixtures/expect-error/missing-diagnostic-code/package.json b/source/test/fixtures/expect-error/missing-diagnostic-code/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/expect-error/missing-diagnostic-code/package.json +++ b/source/test/fixtures/expect-error/missing-diagnostic-code/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/expect-error/syntax/index.js b/source/test/fixtures/expect-error/syntax/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/expect-error/syntax/index.js +++ b/source/test/fixtures/expect-error/syntax/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/expect-error/syntax/index.test-d.ts b/source/test/fixtures/expect-error/syntax/index.test-d.ts index a2ae2605..b1e87c3d 100644 --- a/source/test/fixtures/expect-error/syntax/index.test-d.ts +++ b/source/test/fixtures/expect-error/syntax/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import one from '.'; +import {expectError} from '../../../../index.js'; +import one from './index.js'; expectError(one('foo', 'bar'); expectError(one('foo' 'bar')); diff --git a/source/test/fixtures/expect-error/syntax/package.json b/source/test/fixtures/expect-error/syntax/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/expect-error/syntax/package.json +++ b/source/test/fixtures/expect-error/syntax/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.js b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.js +++ b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.test-d.ts b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.test-d.ts index cf25e541..c182a887 100644 --- a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.test-d.ts +++ b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import {hasProperty} from '.'; +import {expectError} from '../../../../index.js'; +import {hasProperty} from './index.js'; // Only a void function can be called with the 'new' keyword. expectError(new hasProperty({name: 'foo'})); diff --git a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/package.json b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/package.json index 34bf4263..5e26c3ab 100644 --- a/source/test/fixtures/expect-error/values-disabled-no-implicit-any/package.json +++ b/source/test/fixtures/expect-error/values-disabled-no-implicit-any/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "noImplicitAny": false diff --git a/source/test/fixtures/expect-error/values/index.js b/source/test/fixtures/expect-error/values/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/expect-error/values/index.js +++ b/source/test/fixtures/expect-error/values/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/expect-error/values/index.test-d.ts b/source/test/fixtures/expect-error/values/index.test-d.ts index 70bc65f7..69e07dee 100644 --- a/source/test/fixtures/expect-error/values/index.test-d.ts +++ b/source/test/fixtures/expect-error/values/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectError} from '../../../..'; -import {default as one, atLeastOne, foo, getFoo, HasKey, hasProperty, MyClass, Options, triggerSuggestion, ReadonlyKeys} from '.'; +import {expectError} from '../../../../index.js'; +import {default as one, atLeastOne, foo, getFoo, HasKey, hasProperty, MyClass, Options, triggerSuggestion, ReadonlyKeys} from './index.js'; expectError(1); expectError('fo'); diff --git a/source/test/fixtures/expect-error/values/package.json b/source/test/fixtures/expect-error/values/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/expect-error/values/package.json +++ b/source/test/fixtures/expect-error/values/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/failure-nested/child.test-d.ts b/source/test/fixtures/failure-nested/child.test-d.ts index 080ee4ca..0b832a5e 100644 --- a/source/test/fixtures/failure-nested/child.test-d.ts +++ b/source/test/fixtures/failure-nested/child.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/failure-nested/index.js b/source/test/fixtures/failure-nested/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/failure-nested/index.js +++ b/source/test/fixtures/failure-nested/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/failure-nested/index.test-d.ts b/source/test/fixtures/failure-nested/index.test-d.ts index c4e149a5..d72a746b 100644 --- a/source/test/fixtures/failure-nested/index.test-d.ts +++ b/source/test/fixtures/failure-nested/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; import './child.test-d'; // tslint:disable-line:no-import-side-effect expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/failure-nested/package.json b/source/test/fixtures/failure-nested/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/failure-nested/package.json +++ b/source/test/fixtures/failure-nested/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/failure-strict-null-checks/index.js b/source/test/fixtures/failure-strict-null-checks/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/failure-strict-null-checks/index.js +++ b/source/test/fixtures/failure-strict-null-checks/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/failure-strict-null-checks/index.test-d.ts b/source/test/fixtures/failure-strict-null-checks/index.test-d.ts index 873542d5..7699aa02 100644 --- a/source/test/fixtures/failure-strict-null-checks/index.test-d.ts +++ b/source/test/fixtures/failure-strict-null-checks/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; -import aboveZero from '.'; +import {expectType} from '../../../index.js'; +import aboveZero from './index.js'; expectType(aboveZero(1)); diff --git a/source/test/fixtures/failure-strict-null-checks/package.json b/source/test/fixtures/failure-strict-null-checks/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/failure-strict-null-checks/package.json +++ b/source/test/fixtures/failure-strict-null-checks/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/failure/index.js b/source/test/fixtures/failure/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/failure/index.js +++ b/source/test/fixtures/failure/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/failure/index.test-d.ts b/source/test/fixtures/failure/index.test-d.ts index 080ee4ca..0b832a5e 100644 --- a/source/test/fixtures/failure/index.test-d.ts +++ b/source/test/fixtures/failure/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/failure/package.json b/source/test/fixtures/failure/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/failure/package.json +++ b/source/test/fixtures/failure/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/files-folder/out/index.js b/source/test/fixtures/files-folder/out/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/files-folder/out/index.js +++ b/source/test/fixtures/files-folder/out/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/files-folder/out/index.test-d.ts b/source/test/fixtures/files-folder/out/index.test-d.ts index 66ad1b38..5a145e01 100644 --- a/source/test/fixtures/files-folder/out/index.test-d.ts +++ b/source/test/fixtures/files-folder/out/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../../..'; -import concat from '.'; +import {expectType} from '../../../../index.js'; +import concat from './index.js'; expectType(concat('foo', 'bar')); expectType(concat(1, 2)); diff --git a/source/test/fixtures/files-folder/package.json b/source/test/fixtures/files-folder/package.json index 8c8701df..9cefa8c2 100644 --- a/source/test/fixtures/files-folder/package.json +++ b/source/test/fixtures/files-folder/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "out" ], diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json index 05642a5b..0d65579e 100644 --- a/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern-negated/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "!!types/index.d.ts" ], diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts index 66ad1b38..5a145e01 100644 --- a/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../../..'; -import concat from '.'; +import {expectType} from '../../../../index.js'; +import concat from './index.js'; expectType(concat('foo', 'bar')); expectType(concat(1, 2)); diff --git a/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json b/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json index 2895c927..8b9a285c 100644 --- a/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json +++ b/source/test/fixtures/files-gitignore-patterns/negative-pattern/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "!index.d.ts" ] diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json index a17c09ab..054cf4e6 100644 --- a/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json +++ b/source/test/fixtures/files-gitignore-patterns/root-marker-pattern/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "/types/index.d.ts" ], diff --git a/source/test/fixtures/files-glob/out/index.js b/source/test/fixtures/files-glob/out/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/files-glob/out/index.js +++ b/source/test/fixtures/files-glob/out/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/files-glob/out/index.test-d.ts b/source/test/fixtures/files-glob/out/index.test-d.ts index 66ad1b38..5a145e01 100644 --- a/source/test/fixtures/files-glob/out/index.test-d.ts +++ b/source/test/fixtures/files-glob/out/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../../..'; -import concat from '.'; +import {expectType} from '../../../../index.js'; +import concat from './index.js'; expectType(concat('foo', 'bar')); expectType(concat(1, 2)); diff --git a/source/test/fixtures/files-glob/package.json b/source/test/fixtures/files-glob/package.json index f2d92f28..f41de500 100644 --- a/source/test/fixtures/files-glob/package.json +++ b/source/test/fixtures/files-glob/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "out/**/*.d.ts", "out/**/*.js" diff --git a/source/test/fixtures/identicality/identical/index.js b/source/test/fixtures/identicality/identical/index.js index 0162a427..f2f38e94 100644 --- a/source/test/fixtures/identicality/identical/index.js +++ b/source/test/fixtures/identicality/identical/index.js @@ -1,5 +1,5 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; -module.exports.returnsNever = () => {}; +export const returnsNever = () => {}; diff --git a/source/test/fixtures/identicality/identical/index.test-d.ts b/source/test/fixtures/identicality/identical/index.test-d.ts index 940734b1..d344b453 100644 --- a/source/test/fixtures/identicality/identical/index.test-d.ts +++ b/source/test/fixtures/identicality/identical/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType, expectNever} from '../../../..'; -import concat, {returnsNever} from '.'; +import {expectType, expectNever} from '../../../../index.js'; +import concat, {returnsNever} from './index.js'; expectType(concat('foo', 'bar')); expectType(concat(1, 2)); diff --git a/source/test/fixtures/identicality/identical/package.json b/source/test/fixtures/identicality/identical/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/identicality/identical/package.json +++ b/source/test/fixtures/identicality/identical/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/identicality/not-identical/index.js b/source/test/fixtures/identicality/not-identical/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/identicality/not-identical/index.js +++ b/source/test/fixtures/identicality/not-identical/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/identicality/not-identical/index.test-d.ts b/source/test/fixtures/identicality/not-identical/index.test-d.ts index 09c08c3c..7fb62e2e 100644 --- a/source/test/fixtures/identicality/not-identical/index.test-d.ts +++ b/source/test/fixtures/identicality/not-identical/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectNotType} from '../../../..'; -import concat from '.'; +import {expectNotType} from '../../../../index.js'; +import concat from './index.js'; expectNotType(concat('foo', 'bar')); expectNotType(concat('foo', 'bar')); diff --git a/source/test/fixtures/identicality/not-identical/package.json b/source/test/fixtures/identicality/not-identical/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/identicality/not-identical/package.json +++ b/source/test/fixtures/identicality/not-identical/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/informational/expect-doc-comment/index.js b/source/test/fixtures/informational/expect-doc-comment/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/informational/expect-doc-comment/index.js +++ b/source/test/fixtures/informational/expect-doc-comment/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/informational/expect-doc-comment/index.test-d.ts b/source/test/fixtures/informational/expect-doc-comment/index.test-d.ts index dced520c..076fac6c 100644 --- a/source/test/fixtures/informational/expect-doc-comment/index.test-d.ts +++ b/source/test/fixtures/informational/expect-doc-comment/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectDocCommentIncludes} from '../../../..'; +import {expectDocCommentIncludes} from '../../../../index.js'; const noDocComment = 'no doc comment'; diff --git a/source/test/fixtures/informational/expect-doc-comment/package.json b/source/test/fixtures/informational/expect-doc-comment/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/informational/expect-doc-comment/package.json +++ b/source/test/fixtures/informational/expect-doc-comment/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/informational/print-type/index.js b/source/test/fixtures/informational/print-type/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/informational/print-type/index.js +++ b/source/test/fixtures/informational/print-type/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/informational/print-type/index.test-d.ts b/source/test/fixtures/informational/print-type/index.test-d.ts index efe2fd54..7880d371 100644 --- a/source/test/fixtures/informational/print-type/index.test-d.ts +++ b/source/test/fixtures/informational/print-type/index.test-d.ts @@ -1,5 +1,5 @@ -import {printType} from '../../../..'; -import {aboveZero, bigType} from '.'; +import {printType} from '../../../../index.js'; +import {aboveZero, bigType} from './index.js'; printType(aboveZero); printType(null); diff --git a/source/test/fixtures/informational/print-type/package.json b/source/test/fixtures/informational/print-type/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/informational/print-type/package.json +++ b/source/test/fixtures/informational/print-type/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/lib-config/failure-missing-lib/index.js b/source/test/fixtures/lib-config/failure-missing-lib/index.js index 92505d8a..76f1ace4 100644 --- a/source/test/fixtures/lib-config/failure-missing-lib/index.js +++ b/source/test/fixtures/lib-config/failure-missing-lib/index.js @@ -1 +1 @@ -module.exports.default = window; +export default window; diff --git a/source/test/fixtures/lib-config/failure-missing-lib/index.test-d.ts b/source/test/fixtures/lib-config/failure-missing-lib/index.test-d.ts index ef7346a0..f8a5aedd 100644 --- a/source/test/fixtures/lib-config/failure-missing-lib/index.test-d.ts +++ b/source/test/fixtures/lib-config/failure-missing-lib/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import window from '.'; +import {expectType} from '../../../../index.js'; +import window from './index.js'; expectType(window); diff --git a/source/test/fixtures/lib-config/failure-missing-lib/package.json b/source/test/fixtures/lib-config/failure-missing-lib/package.json index 6e90f8d8..3dde17c5 100644 --- a/source/test/fixtures/lib-config/failure-missing-lib/package.json +++ b/source/test/fixtures/lib-config/failure-missing-lib/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "lib": [] diff --git a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.js b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.js index 92505d8a..76f1ace4 100644 --- a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.js +++ b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.js @@ -1 +1 @@ -module.exports.default = window; +export default window; diff --git a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.test-d.ts b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.test-d.ts index ef7346a0..f8a5aedd 100644 --- a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.test-d.ts +++ b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import window from '.'; +import {expectType} from '../../../../index.js'; +import window from './index.js'; expectType(window); diff --git a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/package.json b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/lib-config/lib-as-triple-slash-reference/package.json +++ b/source/test/fixtures/lib-config/lib-as-triple-slash-reference/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.js b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.js index 674f77d5..db89b687 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.js +++ b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.js @@ -1 +1 @@ -module.exports.default = window.document; +export default window.document; diff --git a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.test-d.ts b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.test-d.ts index d7585f79..e35b263d 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.test-d.ts +++ b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import document from '.'; +import {expectType} from '../../../../index.js'; +import document from './index.js'; expectType(document); diff --git a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/package.json b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/package.json index 2af470f2..dfe9dd1c 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/package.json +++ b/source/test/fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "lib": [ diff --git a/source/test/fixtures/lib-config/lib-from-package-json/index.js b/source/test/fixtures/lib-config/lib-from-package-json/index.js index 674f77d5..db89b687 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json/index.js +++ b/source/test/fixtures/lib-config/lib-from-package-json/index.js @@ -1 +1 @@ -module.exports.default = window.document; +export default window.document; diff --git a/source/test/fixtures/lib-config/lib-from-package-json/index.test-d.ts b/source/test/fixtures/lib-config/lib-from-package-json/index.test-d.ts index d7585f79..e35b263d 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json/index.test-d.ts +++ b/source/test/fixtures/lib-config/lib-from-package-json/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import document from '.'; +import {expectType} from '../../../../index.js'; +import document from './index.js'; expectType(document); diff --git a/source/test/fixtures/lib-config/lib-from-package-json/package.json b/source/test/fixtures/lib-config/lib-from-package-json/package.json index 2af470f2..dfe9dd1c 100644 --- a/source/test/fixtures/lib-config/lib-from-package-json/package.json +++ b/source/test/fixtures/lib-config/lib-from-package-json/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "lib": [ diff --git a/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.js b/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.js index 674f77d5..db89b687 100644 --- a/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.js +++ b/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.js @@ -1 +1 @@ -module.exports.default = window.document; +export default window.document; diff --git a/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.test-d.ts b/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.test-d.ts index d7585f79..e35b263d 100644 --- a/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.test-d.ts +++ b/source/test/fixtures/lib-config/lib-from-tsconfig-json/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import document from '.'; +import {expectType} from '../../../../index.js'; +import document from './index.js'; expectType(document); diff --git a/source/test/fixtures/lib-config/lib-from-tsconfig-json/package.json b/source/test/fixtures/lib-config/lib-from-tsconfig-json/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/lib-config/lib-from-tsconfig-json/package.json +++ b/source/test/fixtures/lib-config/lib-from-tsconfig-json/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/missing-import/index.test-d.ts b/source/test/fixtures/missing-import/index.test-d.ts index 24061468..718ec39f 100644 --- a/source/test/fixtures/missing-import/index.test-d.ts +++ b/source/test/fixtures/missing-import/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import {LiteralUnion} from '.'; +import {expectType} from '../../../index.js'; +import {LiteralUnion} from './index.js'; type Pet = LiteralUnion<'dog' | 'cat', string>; diff --git a/source/test/fixtures/missing-import/package.json b/source/test/fixtures/missing-import/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/missing-import/package.json +++ b/source/test/fixtures/missing-import/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/module-resolution/node16-from-package-json/index.js b/source/test/fixtures/module-resolution/node16-from-package-json/index.js index 7f0fda40..d02ba545 100644 --- a/source/test/fixtures/module-resolution/node16-from-package-json/index.js +++ b/source/test/fixtures/module-resolution/node16-from-package-json/index.js @@ -1 +1 @@ -module.exports.default = 'foo'; +export default 'foo'; diff --git a/source/test/fixtures/module-resolution/node16-from-tsconfig-json/index.js b/source/test/fixtures/module-resolution/node16-from-tsconfig-json/index.js index 7f0fda40..d02ba545 100644 --- a/source/test/fixtures/module-resolution/node16-from-tsconfig-json/index.js +++ b/source/test/fixtures/module-resolution/node16-from-tsconfig-json/index.js @@ -1 +1 @@ -module.exports.default = 'foo'; +export default 'foo'; diff --git a/source/test/fixtures/module-resolution/nodenext-from-package-json/index.js b/source/test/fixtures/module-resolution/nodenext-from-package-json/index.js index 7f0fda40..d02ba545 100644 --- a/source/test/fixtures/module-resolution/nodenext-from-package-json/index.js +++ b/source/test/fixtures/module-resolution/nodenext-from-package-json/index.js @@ -1 +1 @@ -module.exports.default = 'foo'; +export default 'foo'; diff --git a/source/test/fixtures/module-resolution/nodenext-from-tsconfig-json/index.js b/source/test/fixtures/module-resolution/nodenext-from-tsconfig-json/index.js index 7f0fda40..d02ba545 100644 --- a/source/test/fixtures/module-resolution/nodenext-from-tsconfig-json/index.js +++ b/source/test/fixtures/module-resolution/nodenext-from-tsconfig-json/index.js @@ -1 +1 @@ -module.exports.default = 'foo'; +export default 'foo'; diff --git a/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.js b/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.js +++ b/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.test-d.ts b/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.test-d.ts index d06d20f9..9b37cd64 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.test-d.ts +++ b/source/test/fixtures/no-explicit-types-property/with-main-barrel/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType, expectError} from '../../../..'; +import {expectType, expectError} from '../../../../index.js'; import one from './'; expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/no-explicit-types-property/with-main-barrel/package.json b/source/test/fixtures/no-explicit-types-property/with-main-barrel/package.json index c1152c5e..b8a3d788 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-barrel/package.json +++ b/source/test/fixtures/no-explicit-types-property/with-main-barrel/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "main": "index.js", "files": [ "index.d.ts" diff --git a/source/test/fixtures/no-explicit-types-property/with-main-other/foo.js b/source/test/fixtures/no-explicit-types-property/with-main-other/foo.js index f17717f5..095da138 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-other/foo.js +++ b/source/test/fixtures/no-explicit-types-property/with-main-other/foo.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/no-explicit-types-property/with-main-other/foo.test-d.ts b/source/test/fixtures/no-explicit-types-property/with-main-other/foo.test-d.ts index 60fe51a3..16392602 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-other/foo.test-d.ts +++ b/source/test/fixtures/no-explicit-types-property/with-main-other/foo.test-d.ts @@ -1,4 +1,4 @@ -import {expectType, expectError} from '../../../..'; +import {expectType, expectError} from '../../../../index.js'; import one from './foo'; expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/no-explicit-types-property/with-main-other/package.json b/source/test/fixtures/no-explicit-types-property/with-main-other/package.json index ef89ee5f..4c72b687 100644 --- a/source/test/fixtures/no-explicit-types-property/with-main-other/package.json +++ b/source/test/fixtures/no-explicit-types-property/with-main-other/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "main": "foo.js", "files": [ "foo.d.ts" diff --git a/source/test/fixtures/no-explicit-types-property/without-main/index.js b/source/test/fixtures/no-explicit-types-property/without-main/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/no-explicit-types-property/without-main/index.js +++ b/source/test/fixtures/no-explicit-types-property/without-main/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/no-explicit-types-property/without-main/index.test-d.ts b/source/test/fixtures/no-explicit-types-property/without-main/index.test-d.ts index d06d20f9..9b37cd64 100644 --- a/source/test/fixtures/no-explicit-types-property/without-main/index.test-d.ts +++ b/source/test/fixtures/no-explicit-types-property/without-main/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType, expectError} from '../../../..'; +import {expectType, expectError} from '../../../../index.js'; import one from './'; expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/no-explicit-types-property/without-main/package.json b/source/test/fixtures/no-explicit-types-property/without-main/package.json index e3e72041..1420b0dc 100644 --- a/source/test/fixtures/no-explicit-types-property/without-main/package.json +++ b/source/test/fixtures/no-explicit-types-property/without-main/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.d.ts" ] diff --git a/source/test/fixtures/no-files/index.js b/source/test/fixtures/no-files/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/no-files/index.js +++ b/source/test/fixtures/no-files/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/no-files/index.test-d.ts b/source/test/fixtures/no-files/index.test-d.ts index 0627dc33..8d7f59cc 100644 --- a/source/test/fixtures/no-files/index.test-d.ts +++ b/source/test/fixtures/no-files/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/no-files/package.json b/source/test/fixtures/no-files/package.json index 3bdebc77..ab5f16b9 100644 --- a/source/test/fixtures/no-files/package.json +++ b/source/test/fixtures/no-files/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js" ] diff --git a/source/test/fixtures/no-test/index.js b/source/test/fixtures/no-test/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/no-test/index.js +++ b/source/test/fixtures/no-test/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/no-test/package.json b/source/test/fixtures/no-test/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/no-test/package.json +++ b/source/test/fixtures/no-test/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/non-strict-check-with-config/index.js b/source/test/fixtures/non-strict-check-with-config/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/non-strict-check-with-config/index.js +++ b/source/test/fixtures/non-strict-check-with-config/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/non-strict-check-with-config/index.test-d.ts b/source/test/fixtures/non-strict-check-with-config/index.test-d.ts index 873542d5..7699aa02 100644 --- a/source/test/fixtures/non-strict-check-with-config/index.test-d.ts +++ b/source/test/fixtures/non-strict-check-with-config/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; -import aboveZero from '.'; +import {expectType} from '../../../index.js'; +import aboveZero from './index.js'; expectType(aboveZero(1)); diff --git a/source/test/fixtures/non-strict-check-with-config/package.json b/source/test/fixtures/non-strict-check-with-config/package.json index c0d2691d..7c030062 100644 --- a/source/test/fixtures/non-strict-check-with-config/package.json +++ b/source/test/fixtures/non-strict-check-with-config/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { "strict": false diff --git a/source/test/fixtures/root-dir/package.json b/source/test/fixtures/root-dir/package.json index fb215246..b912d89f 100644 --- a/source/test/fixtures/root-dir/package.json +++ b/source/test/fixtures/root-dir/package.json @@ -1,4 +1,5 @@ { "name": "test", + "type": "module", "types": "ts-dist/index.d.ts" } diff --git a/source/test/fixtures/root-dir/test-d/index.test-d.ts b/source/test/fixtures/root-dir/test-d/index.test-d.ts index bf1dd794..f7f831b9 100644 --- a/source/test/fixtures/root-dir/test-d/index.test-d.ts +++ b/source/test/fixtures/root-dir/test-d/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; -import {a} from '../src'; +import {expectType} from '#tsd'; +import {a} from '../src/index.js'; expectType<2>(a); diff --git a/source/test/fixtures/root-dir/ts-dist/index.js b/source/test/fixtures/root-dir/ts-dist/index.cjs similarity index 100% rename from source/test/fixtures/root-dir/ts-dist/index.js rename to source/test/fixtures/root-dir/ts-dist/index.cjs diff --git a/source/test/fixtures/root-dir/tsconfig.json b/source/test/fixtures/root-dir/tsconfig.json index 1de8c051..621d5b17 100644 --- a/source/test/fixtures/root-dir/tsconfig.json +++ b/source/test/fixtures/root-dir/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "./src", "outDir": "ts-dist" diff --git a/source/test/fixtures/specify-test-files/index.js b/source/test/fixtures/specify-test-files/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/specify-test-files/index.js +++ b/source/test/fixtures/specify-test-files/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/specify-test-files/package.json b/source/test/fixtures/specify-test-files/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/specify-test-files/package.json +++ b/source/test/fixtures/specify-test-files/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/specify-test-files/second.test.ts b/source/test/fixtures/specify-test-files/second.test.ts index caa13911..317b2141 100644 --- a/source/test/fixtures/specify-test-files/second.test.ts +++ b/source/test/fixtures/specify-test-files/second.test.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one(1, 1)); diff --git a/source/test/fixtures/specify-test-files/unknown.test.ts b/source/test/fixtures/specify-test-files/unknown.test.ts index 080ee4ca..0b832a5e 100644 --- a/source/test/fixtures/specify-test-files/unknown.test.ts +++ b/source/test/fixtures/specify-test-files/unknown.test.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/strict-null-checks-as-default-config-value/index.js b/source/test/fixtures/strict-null-checks-as-default-config-value/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/strict-null-checks-as-default-config-value/index.js +++ b/source/test/fixtures/strict-null-checks-as-default-config-value/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/strict-null-checks-as-default-config-value/index.test-d.ts b/source/test/fixtures/strict-null-checks-as-default-config-value/index.test-d.ts index 873542d5..7699aa02 100644 --- a/source/test/fixtures/strict-null-checks-as-default-config-value/index.test-d.ts +++ b/source/test/fixtures/strict-null-checks-as-default-config-value/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; -import aboveZero from '.'; +import {expectType} from '../../../index.js'; +import aboveZero from './index.js'; expectType(aboveZero(1)); diff --git a/source/test/fixtures/strict-null-checks-as-default-config-value/package.json b/source/test/fixtures/strict-null-checks-as-default-config-value/package.json index 7ec6b7ba..fbf77d25 100644 --- a/source/test/fixtures/strict-null-checks-as-default-config-value/package.json +++ b/source/test/fixtures/strict-null-checks-as-default-config-value/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "compilerOptions": { } diff --git a/source/test/fixtures/strict-types/loose/index.js b/source/test/fixtures/strict-types/loose/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/strict-types/loose/index.js +++ b/source/test/fixtures/strict-types/loose/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/strict-types/loose/index.test-d.ts b/source/test/fixtures/strict-types/loose/index.test-d.ts index a5472a0a..13feb8be 100644 --- a/source/test/fixtures/strict-types/loose/index.test-d.ts +++ b/source/test/fixtures/strict-types/loose/index.test-d.ts @@ -1,6 +1,6 @@ import {Observable} from 'rxjs'; -import {expectType} from '../../../..'; -import one from '.'; +import {expectType} from '../../../../index.js'; +import one from './index.js'; expectType('cat'); diff --git a/source/test/fixtures/strict-types/loose/package.json b/source/test/fixtures/strict-types/loose/package.json index 8392a5e3..ceb4f992 100644 --- a/source/test/fixtures/strict-types/loose/package.json +++ b/source/test/fixtures/strict-types/loose/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "dependencies": { "rxjs": "^6.5.3" } diff --git a/source/test/fixtures/strict-types/strict/index.js b/source/test/fixtures/strict-types/strict/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/strict-types/strict/index.js +++ b/source/test/fixtures/strict-types/strict/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/strict-types/strict/index.test-d.ts b/source/test/fixtures/strict-types/strict/index.test-d.ts index a74aa46d..1d5af4d7 100644 --- a/source/test/fixtures/strict-types/strict/index.test-d.ts +++ b/source/test/fixtures/strict-types/strict/index.test-d.ts @@ -1,6 +1,6 @@ import {Observable} from 'rxjs'; -import {expectType} from '../../../..'; -import one from '.'; +import {expectType} from '../../../../index.js'; +import one from './index.js'; abstract class Foo { abstract unicorn(): T; diff --git a/source/test/fixtures/strict-types/strict/package.json b/source/test/fixtures/strict-types/strict/package.json index 8392a5e3..ceb4f992 100644 --- a/source/test/fixtures/strict-types/strict/package.json +++ b/source/test/fixtures/strict-types/strict/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "dependencies": { "rxjs": "^6.5.3" } diff --git a/source/test/fixtures/success/index.js b/source/test/fixtures/success/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/success/index.js +++ b/source/test/fixtures/success/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/success/index.test-d.ts b/source/test/fixtures/success/index.test-d.ts index 0627dc33..8d7f59cc 100644 --- a/source/test/fixtures/success/index.test-d.ts +++ b/source/test/fixtures/success/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/success/package.json b/source/test/fixtures/success/package.json index 06ea168a..aefa016e 100644 --- a/source/test/fixtures/success/package.json +++ b/source/test/fixtures/success/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" diff --git a/source/test/fixtures/test-directory/custom/index.js b/source/test/fixtures/test-directory/custom/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/test-directory/custom/index.js +++ b/source/test/fixtures/test-directory/custom/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/test-directory/custom/package.json b/source/test/fixtures/test-directory/custom/package.json index 7262e8d2..88d964f0 100644 --- a/source/test/fixtures/test-directory/custom/package.json +++ b/source/test/fixtures/test-directory/custom/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "tsd": { "directory": "test" } diff --git a/source/test/fixtures/test-directory/custom/test/unknown.ts b/source/test/fixtures/test-directory/custom/test/unknown.ts index c590ae29..b6fc3f37 100644 --- a/source/test/fixtures/test-directory/custom/test/unknown.ts +++ b/source/test/fixtures/test-directory/custom/test/unknown.ts @@ -1,4 +1,4 @@ -import {expectError} from '../../../../..'; -import one from '..'; +import {expectError} from '../../../../../index.js'; +import one from '../index.js'; expectError(one(1, 2)); diff --git a/source/test/fixtures/test-directory/default/index.js b/source/test/fixtures/test-directory/default/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/test-directory/default/index.js +++ b/source/test/fixtures/test-directory/default/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/test-directory/default/package.json b/source/test/fixtures/test-directory/default/package.json index 8f51f801..0e991595 100644 --- a/source/test/fixtures/test-directory/default/package.json +++ b/source/test/fixtures/test-directory/default/package.json @@ -1,4 +1,5 @@ { "name": "foo", + "type": "module", "types": "index.d.ts" } diff --git a/source/test/fixtures/test-directory/default/test-d/numbers.ts b/source/test/fixtures/test-directory/default/test-d/numbers.ts index 2e875a2c..62fab8fb 100644 --- a/source/test/fixtures/test-directory/default/test-d/numbers.ts +++ b/source/test/fixtures/test-directory/default/test-d/numbers.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../../..'; -import one from '..'; +import {expectType} from '../../../../../index.js'; +import one from '../index.js'; expectType(one(1, 2)); diff --git a/source/test/fixtures/test-directory/default/test-d/strings.ts b/source/test/fixtures/test-directory/default/test-d/strings.ts index 2dc5be91..3fddc7c9 100644 --- a/source/test/fixtures/test-directory/default/test-d/strings.ts +++ b/source/test/fixtures/test-directory/default/test-d/strings.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../../..'; -import one from '..'; +import {expectType} from '../../../../../index.js'; +import one from '../index.js'; expectType(one('foo', 'bar')); diff --git a/source/test/fixtures/test-directory/default/test-d/unknown.ts b/source/test/fixtures/test-directory/default/test-d/unknown.ts index 2cb6da30..c531c089 100644 --- a/source/test/fixtures/test-directory/default/test-d/unknown.ts +++ b/source/test/fixtures/test-directory/default/test-d/unknown.ts @@ -1,4 +1,4 @@ -import {expectError} from '../../../../..'; -import one from '..'; +import {expectError} from '../../../../../index.js'; +import one from '../index.js'; expectError(one(true, false)); diff --git a/source/test/fixtures/test-directory/tsx/package.json b/source/test/fixtures/test-directory/tsx/package.json index 09392033..4b4ec164 100644 --- a/source/test/fixtures/test-directory/tsx/package.json +++ b/source/test/fixtures/test-directory/tsx/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" diff --git a/source/test/fixtures/test-directory/tsx/test-d/unicorn.tsx b/source/test/fixtures/test-directory/tsx/test-d/unicorn.tsx index 24473abf..1eb6411d 100644 --- a/source/test/fixtures/test-directory/tsx/test-d/unicorn.tsx +++ b/source/test/fixtures/test-directory/tsx/test-d/unicorn.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import {expectType, expectError} from '../../../../..'; -import {Unicorn} from '..'; +import {expectType, expectError} from '../../../../../index.js'; +import {Unicorn} from '../index.js'; expectType(); diff --git a/source/test/fixtures/test-in-subdir/package.json b/source/test/fixtures/test-in-subdir/package.json index 7bbde119..3ed167cc 100644 --- a/source/test/fixtures/test-in-subdir/package.json +++ b/source/test/fixtures/test-in-subdir/package.json @@ -1,6 +1,7 @@ { "name": "foo", - "main": "src/index.js", + "type": "module", + "exports": "./src/index.js", "types": "src/index.d.ts", "files": [ "src/index.js", diff --git a/source/test/fixtures/test-in-subdir/src/index.js b/source/test/fixtures/test-in-subdir/src/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/test-in-subdir/src/index.js +++ b/source/test/fixtures/test-in-subdir/src/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/test-in-subdir/src/index.test-d.ts b/source/test/fixtures/test-in-subdir/src/index.test-d.ts index 448f75cc..dfb99fed 100644 --- a/source/test/fixtures/test-in-subdir/src/index.test-d.ts +++ b/source/test/fixtures/test-in-subdir/src/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../../..'; -import one from '.'; +import {expectType} from '../../../../index.js'; +import one from './index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/test-non-barrel-main/foo.js b/source/test/fixtures/test-non-barrel-main/foo.js index f17717f5..095da138 100644 --- a/source/test/fixtures/test-non-barrel-main/foo.js +++ b/source/test/fixtures/test-non-barrel-main/foo.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/test-non-barrel-main/foo.test-d.ts b/source/test/fixtures/test-non-barrel-main/foo.test-d.ts index 91ea5821..b0e9a585 100644 --- a/source/test/fixtures/test-non-barrel-main/foo.test-d.ts +++ b/source/test/fixtures/test-non-barrel-main/foo.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from './foo'; +import {expectType} from '../../../index.js'; +import one from './foo.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/test-non-barrel-main/package.json b/source/test/fixtures/test-non-barrel-main/package.json index e2b33494..b3739496 100644 --- a/source/test/fixtures/test-non-barrel-main/package.json +++ b/source/test/fixtures/test-non-barrel-main/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "main": "foo.js", "types": "foo.d.ts", "files": [ diff --git a/source/test/fixtures/top-level-await/index.js b/source/test/fixtures/top-level-await/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/top-level-await/index.js +++ b/source/test/fixtures/top-level-await/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/top-level-await/index.test-d.ts b/source/test/fixtures/top-level-await/index.test-d.ts index db17fe37..da62e3af 100644 --- a/source/test/fixtures/top-level-await/index.test-d.ts +++ b/source/test/fixtures/top-level-await/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from '.'; +import {expectType} from '../../../index.js'; +import one from './index.js'; expectType(await one('foo', 'bar')); expectType(await one(1, 2)); diff --git a/source/test/fixtures/top-level-await/package.json b/source/test/fixtures/top-level-await/package.json index 06ea168a..aefa016e 100644 --- a/source/test/fixtures/top-level-await/package.json +++ b/source/test/fixtures/top-level-await/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" diff --git a/source/test/fixtures/ts-config-extends/index.js b/source/test/fixtures/ts-config-extends/index.js index 0d06f8dd..65a2d53c 100644 --- a/source/test/fixtures/ts-config-extends/index.js +++ b/source/test/fixtures/ts-config-extends/index.js @@ -1,3 +1,3 @@ -module.exports.default = foo => { +export default foo => { return foo > 0 ? foo : null; }; diff --git a/source/test/fixtures/ts-config-extends/index.test-d.ts b/source/test/fixtures/ts-config-extends/index.test-d.ts index 58042641..bc05ba91 100644 --- a/source/test/fixtures/ts-config-extends/index.test-d.ts +++ b/source/test/fixtures/ts-config-extends/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import aboveZero from '.'; +import {expectType} from '../../../index.js'; +import aboveZero from './index.js'; expectType(aboveZero(1)); diff --git a/source/test/fixtures/ts-config-extends/package.json b/source/test/fixtures/ts-config-extends/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/ts-config-extends/package.json +++ b/source/test/fixtures/ts-config-extends/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/ts-config-extends/tsconfig.json b/source/test/fixtures/ts-config-extends/tsconfig.json index d8776207..084e9319 100644 --- a/source/test/fixtures/ts-config-extends/tsconfig.json +++ b/source/test/fixtures/ts-config-extends/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "./config/base-config", + "extends": "./config/base-config.json", "compilerOptions": { "noImplicitReturns": true } diff --git a/source/test/fixtures/tsconfig.json b/source/test/fixtures/tsconfig.json new file mode 100644 index 00000000..c765a42c --- /dev/null +++ b/source/test/fixtures/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "jsx": "react", + "paths": { + "#tsd": ["../../index.js"] + } + } +} diff --git a/source/test/fixtures/tsx/component-type/index.d.ts b/source/test/fixtures/tsx/component-type/index.d.ts deleted file mode 100644 index 7ca61da8..00000000 --- a/source/test/fixtures/tsx/component-type/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {ComponentType} from 'react'; - -interface UnicornProps { - unicorn: number; - rainbow: string; -} - -export const Unicorn: ComponentType; diff --git a/source/test/fixtures/tsx/component-type/index.js b/source/test/fixtures/tsx/component-type/index.js deleted file mode 100644 index 6db2eca6..00000000 --- a/source/test/fixtures/tsx/component-type/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; -const React = require('react'); - -export class Unicorn extends React.Component { - constructor(props) { - super(props); - } - - render() { - return

{this.props.rainbow}

; - } -} diff --git a/source/test/fixtures/tsx/component-type/index.test-d.tsx b/source/test/fixtures/tsx/component-type/index.test-d.tsx deleted file mode 100644 index 9a566007..00000000 --- a/source/test/fixtures/tsx/component-type/index.test-d.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; -import {expectType, expectError} from '../../../..'; -import {Unicorn} from '.'; - -expectType(); - -expectError(); -expectError(); -expectError(); diff --git a/source/test/fixtures/tsx/component/index.d.ts b/source/test/fixtures/tsx/component/index.d.ts deleted file mode 100644 index 23bacd5a..00000000 --- a/source/test/fixtures/tsx/component/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {Component} from 'react'; - -interface UnicornProps { - unicorn: number; - rainbow: string; -} - -export class Unicorn extends Component {} diff --git a/source/test/fixtures/tsx/component/index.js b/source/test/fixtures/tsx/component/index.js deleted file mode 100644 index 6db2eca6..00000000 --- a/source/test/fixtures/tsx/component/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; -const React = require('react'); - -export class Unicorn extends React.Component { - constructor(props) { - super(props); - } - - render() { - return

{this.props.rainbow}

; - } -} diff --git a/source/test/fixtures/tsx/component/package.json b/source/test/fixtures/tsx/component/package.json deleted file mode 100644 index 09392033..00000000 --- a/source/test/fixtures/tsx/component/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "foo", - "files": [ - "index.js", - "index.d.ts" - ], - "dependencies": { - "react": "*" - } -} diff --git a/source/test/fixtures/tsx/component/index.test-d.tsx b/source/test/fixtures/tsx/index.test-d.tsx similarity index 61% rename from source/test/fixtures/tsx/component/index.test-d.tsx rename to source/test/fixtures/tsx/index.test-d.tsx index 9a566007..8d8cc0bd 100644 --- a/source/test/fixtures/tsx/component/index.test-d.tsx +++ b/source/test/fixtures/tsx/index.test-d.tsx @@ -1,6 +1,6 @@ -import * as React from 'react'; -import {expectType, expectError} from '../../../..'; -import {Unicorn} from '.'; +import React from 'react'; +import {expectType, expectError} from '#tsd'; +import {Unicorn} from './index.js'; expectType(); diff --git a/source/test/fixtures/tsx/index.tsx b/source/test/fixtures/tsx/index.tsx new file mode 100644 index 00000000..69ca8e4e --- /dev/null +++ b/source/test/fixtures/tsx/index.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +interface UnicornProps { + unicorn: number; + rainbow: string; +} + +export const Unicorn = ({ rainbow }: UnicornProps) => ( +

{rainbow}

+); diff --git a/source/test/fixtures/tsx/component-type/package.json b/source/test/fixtures/tsx/package.json similarity index 51% rename from source/test/fixtures/tsx/component-type/package.json rename to source/test/fixtures/tsx/package.json index 09392033..4e76501a 100644 --- a/source/test/fixtures/tsx/component-type/package.json +++ b/source/test/fixtures/tsx/package.json @@ -1,10 +1,14 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" ], "dependencies": { - "react": "*" + "react": "18" + }, + "imports": { + "#tsd": "../../../index.js" } } diff --git a/source/test/fixtures/types-property/no-property/package.json b/source/test/fixtures/types-property/no-property/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/types-property/no-property/package.json +++ b/source/test/fixtures/types-property/no-property/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/types-property/typings/package.json b/source/test/fixtures/types-property/typings/package.json index 94aef4fa..ed7f0155 100644 --- a/source/test/fixtures/types-property/typings/package.json +++ b/source/test/fixtures/types-property/typings/package.json @@ -1,4 +1,5 @@ { "name": "foo", + "type": "module", "typings": "index.d.ts" } diff --git a/source/test/fixtures/typings-custom-dir/index.js b/source/test/fixtures/typings-custom-dir/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/typings-custom-dir/index.js +++ b/source/test/fixtures/typings-custom-dir/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/typings-custom-dir/index.test-d.ts b/source/test/fixtures/typings-custom-dir/index.test-d.ts index a6fedd96..f9752ec0 100644 --- a/source/test/fixtures/typings-custom-dir/index.test-d.ts +++ b/source/test/fixtures/typings-custom-dir/index.test-d.ts @@ -1,5 +1,5 @@ -import {expectType} from '../../..'; -import one from './utils'; +import {expectType} from '../../../index.js'; +import one from './utils/index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/typings-custom-dir/package.json b/source/test/fixtures/typings-custom-dir/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/typings-custom-dir/package.json +++ b/source/test/fixtures/typings-custom-dir/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/undefined-symbol/index.test-d.ts b/source/test/fixtures/undefined-symbol/index.test-d.ts index 810a76b8..ee74ca27 100644 --- a/source/test/fixtures/undefined-symbol/index.test-d.ts +++ b/source/test/fixtures/undefined-symbol/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; +import {expectType} from '../../../index.js'; // Identifier `bar` has no Symbol const anyCall = (foo: any) => foo.bar(); diff --git a/source/test/fixtures/undefined-symbol/package.json b/source/test/fixtures/undefined-symbol/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/undefined-symbol/package.json +++ b/source/test/fixtures/undefined-symbol/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/utils.ts b/source/test/fixtures/utils.ts deleted file mode 100644 index a65fdfd5..00000000 --- a/source/test/fixtures/utils.ts +++ /dev/null @@ -1,138 +0,0 @@ -import path from 'path'; -import {ExecutionContext} from 'ava'; -import {Diagnostic} from '../../lib/interfaces'; - -type Expectation = [ - line: number, - column: number, - severity: 'error' | 'warning', - message: string, -]; - -type ExpectationWithFileName = [ - line: number, - column: number, - severity: 'error' | 'warning', - message: string, - fileName: string, -]; - -type ExpectationWithDiff = [ - line: number, - column: number, - severity: 'error' | 'warning', - message: string, - diff: { - expected: string; - received: string; - } -]; - -/** - * Verify a list of diagnostics. - * - * @param t - The AVA execution context. - * @param diagnostics - List of diagnostics to verify. - * @param expectations - Expected diagnostics. - */ -export const verify = (t: ExecutionContext, diagnostics: Diagnostic[], expectations: Expectation[]) => { - const diagnosticObjs = diagnostics.map(({line, column, severity, message}) => ({ - line, - column, - severity, - message, - })); - - const expectationObjs = expectations.map(([line, column, severity, message]) => ({ - line, - column, - severity, - message, - })); - - t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); -}; - -/** - * Verify a list of diagnostics including file paths. - * - * @param t - The AVA execution context. - * @param cwd - The working directory as passed to `tsd`. - * @param diagnostics - List of diagnostics to verify. - * @param expectations - Expected diagnostics. - */ -export const verifyWithFileName = ( - t: ExecutionContext, - cwd: string, - diagnostics: Diagnostic[], - expectations: ExpectationWithFileName[] -) => { - const diagnosticObjs = diagnostics.map(({line, column, severity, message, fileName}) => ({ - line, - column, - severity, - message, - fileName: path.relative(cwd, fileName), - })); - - const expectationObjs = expectations.map(([line, column, severity, message, fileName]) => ({ - line, - column, - severity, - message, - fileName, - })); - - t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); -}; - -/** - * Verify a list of diagnostics including diff. - * - * @param t - The AVA execution context. - * @param cwd - The working directory as passed to `tsd`. - * @param diagnostics - List of diagnostics to verify. - * @param expectations - Expected diagnostics. - */ -export const verifyWithDiff = ( - t: ExecutionContext, - diagnostics: Diagnostic[], - expectations: ExpectationWithDiff[] -) => { - const diagnosticObjs = diagnostics.map(({line, column, severity, message, diff}) => ({ - line, - column, - severity, - message, - diff - })); - - const expectationObjs = expectations.map(([line, column, severity, message, diff]) => ({ - line, - column, - severity, - message, - diff, - })); - - t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); -}; - -/** - * Verify a list of diagnostics reported from the CLI. - * - * @param t - The AVA execution context. - * @param diagnostics - List of diagnostics to verify. - * @param expectations - Expected diagnostics. - * @param startLine - Optionally specify how many lines to skip from start. - */ -export const verifyCli = ( - t: ExecutionContext, - diagnostics: string, - expectedLines: string[], - {startLine}: {startLine: number} = {startLine: 1} // Skip file location. -) => { - const receivedLines = diagnostics.trim().split('\n').slice(startLine).map(line => line.trim()); - - t.deepEqual(receivedLines, expectedLines, 'Received diagnostics that are different from expectations!'); -}; diff --git a/source/test/fixtures/warnings/only-warnings/index.js b/source/test/fixtures/warnings/only-warnings/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/warnings/only-warnings/index.js +++ b/source/test/fixtures/warnings/only-warnings/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/warnings/only-warnings/index.test-d.ts b/source/test/fixtures/warnings/only-warnings/index.test-d.ts index 51347575..43be7ffa 100644 --- a/source/test/fixtures/warnings/only-warnings/index.test-d.ts +++ b/source/test/fixtures/warnings/only-warnings/index.test-d.ts @@ -1,4 +1,4 @@ -import {printType} from '../../../..'; -import one from '.'; +import {printType} from '../../../../index.js'; +import one from './index.js'; printType(one(1, 1)); diff --git a/source/test/fixtures/warnings/only-warnings/package.json b/source/test/fixtures/warnings/only-warnings/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/warnings/only-warnings/package.json +++ b/source/test/fixtures/warnings/only-warnings/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/fixtures/warnings/with-errors/index.js b/source/test/fixtures/warnings/with-errors/index.js index f17717f5..095da138 100644 --- a/source/test/fixtures/warnings/with-errors/index.js +++ b/source/test/fixtures/warnings/with-errors/index.js @@ -1,3 +1,3 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { return foo + bar; }; diff --git a/source/test/fixtures/warnings/with-errors/index.test-d.ts b/source/test/fixtures/warnings/with-errors/index.test-d.ts index 65ccce61..440e6cef 100644 --- a/source/test/fixtures/warnings/with-errors/index.test-d.ts +++ b/source/test/fixtures/warnings/with-errors/index.test-d.ts @@ -1,5 +1,5 @@ -import {printType, expectType} from '../../../..'; -import one from '.'; +import {printType, expectType} from '../../../../index.js'; +import one from './index.js'; printType(one(1, 1)); expectType(one(1, 2)); diff --git a/source/test/fixtures/warnings/with-errors/package.json b/source/test/fixtures/warnings/with-errors/package.json index de6dc1db..b55415b7 100644 --- a/source/test/fixtures/warnings/with-errors/package.json +++ b/source/test/fixtures/warnings/with-errors/package.json @@ -1,3 +1,4 @@ { - "name": "foo" + "name": "foo", + "type": "module" } diff --git a/source/test/identicality.ts b/source/test/identicality.ts index 4d9abec4..ad7d262d 100644 --- a/source/test/identicality.ts +++ b/source/test/identicality.ts @@ -1,27 +1,17 @@ -import path from 'path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import {verifyTsd} from './_utils.js'; -test('identical', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/identicality/identical')}); +test('identical', verifyTsd, 'identicality/identical', [ + [7, 0, 'error', 'Parameter type `any` is not identical to argument type `number`.'], + [8, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `string`.'], + [10, 0, 'error', 'Parameter type `false` is not identical to argument type `any`.'], + [12, 0, 'error', 'Parameter type `string` is declared too wide for argument type `never`.'], + [13, 0, 'error', 'Parameter type `any` is declared too wide for argument type `never`.'], + [16, 0, 'error', 'Argument of type `number` is not `never`.'], + [16, 12, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'never\'.'], +]); - verify(t, diagnostics, [ - [7, 0, 'error', 'Parameter type `any` is not identical to argument type `number`.'], - [8, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `string`.'], - [10, 0, 'error', 'Parameter type `false` is not identical to argument type `any`.'], - [12, 0, 'error', 'Parameter type `string` is declared too wide for argument type `never`.'], - [13, 0, 'error', 'Parameter type `any` is declared too wide for argument type `never`.'], - [16, 0, 'error', 'Argument of type `number` is not `never`.'], - [16, 12, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'never\'.'], - ]); -}); - -test('not identical', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/identicality/not-identical')}); - - verify(t, diagnostics, [ - [7, 0, 'error', 'Parameter type `string` is identical to argument type `string`.'], - [10, 0, 'error', 'Parameter type `any` is identical to argument type `any`.'], - ]); -}); +test('not identical', verifyTsd, 'identicality/not-identical', [ + [7, 0, 'error', 'Parameter type `string` is identical to argument type `string`.'], + [10, 0, 'error', 'Parameter type `any` is identical to argument type `any`.'], +]); diff --git a/source/test/informational.ts b/source/test/informational.ts index 1f364d4e..23a1bc52 100644 --- a/source/test/informational.ts +++ b/source/test/informational.ts @@ -1,30 +1,20 @@ -import path from 'path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import {verifyTsd} from './_utils.js'; -test('print type', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/informational/print-type')}); +test('print type', verifyTsd, 'informational/print-type', [ + [4, 0, 'warning', 'Type for expression `aboveZero` is: `(foo: number) => number | null`'], + [5, 0, 'warning', 'Type for expression `null` is: `null`'], + [6, 0, 'warning', 'Type for expression `undefined` is: `undefined`'], + [7, 0, 'warning', 'Type for expression `null as any` is: `any`'], + [8, 0, 'warning', 'Type for expression `null as never` is: `never`'], + [9, 0, 'warning', 'Type for expression `null as unknown` is: `unknown`'], + [10, 0, 'warning', 'Type for expression `\'foo\'` is: `"foo"`'], + [11, 0, 'warning', 'Type for expression `bigType` is: `{ prop1: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop2: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop3: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop4: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop5: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop6: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop7: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop8: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop9: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; }`'], +]); - verify(t, diagnostics, [ - [4, 0, 'warning', 'Type for expression `aboveZero` is: `(foo: number) => number | null`'], - [5, 0, 'warning', 'Type for expression `null` is: `null`'], - [6, 0, 'warning', 'Type for expression `undefined` is: `undefined`'], - [7, 0, 'warning', 'Type for expression `null as any` is: `any`'], - [8, 0, 'warning', 'Type for expression `null as never` is: `never`'], - [9, 0, 'warning', 'Type for expression `null as unknown` is: `unknown`'], - [10, 0, 'warning', 'Type for expression `\'foo\'` is: `"foo"`'], - [11, 0, 'warning', 'Type for expression `bigType` is: `{ prop1: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop2: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop3: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop4: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop5: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop6: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop7: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop8: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; prop9: SuperTypeWithAnExessiveLongNameThatTakesUpTooMuchSpace; }`'], - ]); -}); - -test('expect doc comment includes', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/informational/expect-doc-comment')}); - - verify(t, diagnostics, [ - [5, 0, 'error', 'Documentation comment for expression `noDocComment` not found.'], - [10, 0, 'error', 'Expected documentation comment for expression `foo` not specified.'], - [11, 0, 'error', 'Expected documentation comment for expression `foo` should be a string literal.'], - [12, 0, 'error', 'Documentation comment `FooBar` for expression `foo` does not include expected `BarFoo`.'], - ]); -}); +test('expect doc comment includes', verifyTsd, 'informational/expect-doc-comment', [ + [5, 0, 'error', 'Documentation comment for expression `noDocComment` not found.'], + [10, 0, 'error', 'Expected documentation comment for expression `foo` not specified.'], + [11, 0, 'error', 'Expected documentation comment for expression `foo` should be a string literal.'], + [12, 0, 'error', 'Documentation comment `FooBar` for expression `foo` does not include expected `BarFoo`.'], +]); diff --git a/source/test/test.ts b/source/test/test.ts index 9349d751..1356c68e 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -1,361 +1,125 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify, verifyWithFileName} from './fixtures/utils'; -import tsd from '..'; -import {Diagnostic, TsdError} from '../lib/interfaces'; +import tsd from '../index.js'; +import {type Diagnostic, TsdError} from '../lib/interfaces.js'; +import { + verify, + verifyTsd, + verifyTsdFails, + verifyTsdWithFileNames, + noDiagnostics, +} from './_utils.js'; -test('throw if no type definition was found', async t => { - const cwd = path.join(__dirname, 'fixtures/no-tsd'); - const index = path.join(cwd, 'index.d.ts'); +// TODO: remove unused fixtures - await t.throwsAsync(tsd({cwd}), {message: `The type definition \`index.d.ts\` does not exist at \`${index}\`. Is the path correct? Create one and try again.`}); -}); - -test('throw if no test is found', async t => { - const cwd = path.join(__dirname, 'fixtures/no-test'); - await t.throwsAsync(tsd({cwd}), {message: `The test file \`index.test-d.ts\` or \`index.test-d.tsx\` does not exist in \`${cwd}\`. Create one and try again.`}); -}); - -test('return diagnostics', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/failure')}); - - verify(t, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'] - ]); -}); - -test('return diagnostics from imported files as well', async t => { - const cwd = path.join(__dirname, 'fixtures/failure-nested'); - const diagnostics = await tsd({cwd}); - - verifyWithFileName(t, cwd, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.', 'child.test-d.ts'], - [6, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.', 'index.test-d.ts'], - ]); -}); - -test('fail if typings file is not part of `files` list', async t => { - const cwd = path.join(__dirname, 'fixtures/no-files'); - const diagnostics = await tsd({cwd}); - - verifyWithFileName(t, cwd, diagnostics, [ - [3, 1, 'error', 'TypeScript type definition `index.d.ts` is not part of the `files` list.', 'package.json'], - ]); -}); - -test('allow specifying folders containing typings file in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-folder')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying negative gitignore-style patterns in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/negative-pattern')}); - - verify(t, diagnostics, [ - [3, 1, 'error', 'TypeScript type definition `index.d.ts` is not part of the `files` list.'], - ]); -}); - -test('allow specifying negated negative (positive) gitignore-style patterns in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/negative-pattern-negated')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying root marker (/) gitignore-style patterns in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-gitignore-patterns/root-marker-pattern')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying glob patterns containing typings file in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-glob')}); - - verify(t, diagnostics, []); -}); - -test('fail if `typings` property is used instead of `types`', async t => { - const cwd = path.join(__dirname, 'fixtures/types-property/typings'); - const diagnostics = await tsd({cwd}); - - verifyWithFileName(t, cwd, diagnostics, [ - [3, 1, 'error', 'Use property `types` instead of `typings`.', 'package.json'], - ]); -}); +test('throw if no test is found', verifyTsdFails, 'no-test', cwd => ( + `No test files were found in \`${cwd}\` or in any of its subdirectories.` +)); -test('fail if tests don\'t pass in strict mode', async t => { - const cwd = path.join(__dirname, 'fixtures/failure-strict-null-checks'); - const diagnostics = await tsd({cwd}); - - verifyWithFileName(t, cwd, diagnostics, [ - [ - 4, - 19, - 'error', - 'Argument of type \'number | null\' is not assignable to parameter of type \'number\'.\n Type \'null\' is not assignable to type \'number\'.', - 'index.test-d.ts', - ], - ]); -}); +test('return diagnostics', verifyTsd, 'failure', [ + [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], +]); -test('overridden config defaults to `strict` if `strict` is not explicitly overridden', async t => { - const cwd = path.join(__dirname, 'fixtures/strict-null-checks-as-default-config-value'); - const diagnostics = await tsd({cwd}); - - verifyWithFileName(t, cwd, diagnostics, [ - [ - 4, - 19, - 'error', - 'Argument of type \'number | null\' is not assignable to parameter of type \'number\'.\n Type \'null\' is not assignable to type \'number\'.', - 'index.test-d.ts', - ], - ]); -}); +test('return diagnostics from imported files as well', verifyTsdWithFileNames, 'failure-nested', [ + [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.', 'child.test-d.ts'], + [6, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.', 'index.test-d.ts'], +]); -test('fail if types are used from a lib that was not explicitly specified', async t => { - const cwd = path.join(__dirname, 'fixtures/lib-config/failure-missing-lib'); - const diagnostics = await tsd({cwd}); +test('fail if tests don\'t pass in strict mode', verifyTsdWithFileNames, 'failure-strict-null-checks', [ + [4, 19, 'error', 'Argument of type \'number | null\' is not assignable to parameter of type \'number\'.\n Type \'null\' is not assignable to type \'number\'.', 'index.test-d.ts'], +]); - verifyWithFileName(t, cwd, diagnostics, [ - [1, 22, 'error', 'Cannot find name \'Window\'.', 'index.d.ts'], - [4, 11, 'error', 'Cannot find name \'Window\'.', 'index.test-d.ts'], - ]); -}); +test('overridden config defaults to `strict` if `strict` is not explicitly overridden', verifyTsdWithFileNames, 'strict-null-checks-as-default-config-value', [ + [4, 19, 'error', 'Argument of type \'number | null\' is not assignable to parameter of type \'number\'.\n Type \'null\' is not assignable to type \'number\'.', 'index.test-d.ts'], +]); -test('allow specifying a lib as a triple-slash-reference', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/lib-config/lib-as-triple-slash-reference')}); +test('fail if types are used from a lib that was not explicitly specified', verifyTsdWithFileNames, 'lib-config/failure-missing-lib', [ + [1, 22, 'error', 'Cannot find name \'Window\'.', 'index.d.ts'], + [4, 11, 'error', 'Cannot find name \'Window\'.', 'index.test-d.ts'], +]); - verify(t, diagnostics, []); -}); +test('allow specifying a lib as a triple-slash-reference', noDiagnostics, 'lib-config/lib-as-triple-slash-reference'); -test('allow specifying a lib in package.json\'s `tsd` field', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/lib-config/lib-from-package-json')}); +test('allow specifying a lib in package.json\'s `tsd` field', noDiagnostics, 'lib-config/lib-from-package-json'); - verify(t, diagnostics, []); -}); +test('allow specifying a lib in tsconfig.json', noDiagnostics, 'lib-config/lib-from-tsconfig-json'); -test('allow specifying a lib in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/lib-config/lib-from-tsconfig-json')}); +test('use moduleResolution `nodenext` when module is `nodenext` in tsconfig.json', noDiagnostics, 'module-resolution/nodenext-from-tsconfig-json'); - verify(t, diagnostics, []); -}); +test('use moduleResolution `nodenext` when module is `nodenext` in package.json', noDiagnostics, 'module-resolution/nodenext-from-package-json'); -test('use moduleResolution `nodenext` when module is `nodenext` in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/module-resolution/nodenext-from-tsconfig-json')}); +test('use moduleResolution `node16` when module is `node16` in tsconfig.json', noDiagnostics, 'module-resolution/node16-from-tsconfig-json'); - verify(t, diagnostics, []); -}); +test('use moduleResolution `node16` when module is `node16` in package.json', noDiagnostics, 'module-resolution/node16-from-package-json'); -test('use moduleResolution `nodenext` when module is `nodenext` in package.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/module-resolution/nodenext-from-package-json')}); +test('add DOM support by default', noDiagnostics, 'dom'); - verify(t, diagnostics, []); -}); +test('a lib option in package.json overrdides a lib option in tsconfig.json', noDiagnostics, 'lib-config/lib-from-package-json-overrides-tsconfig-json'); -test('use moduleResolution `node16` when module is `node16` in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/module-resolution/node16-from-tsconfig-json')}); +test('pass in loose mode when strict mode is disabled in settings', noDiagnostics, 'non-strict-check-with-config'); - verify(t, diagnostics, []); -}); +test('return no diagnostics', noDiagnostics, 'success'); -test('use moduleResolution `node16` when module is `node16` in package.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/module-resolution/node16-from-package-json')}); +test('support non-barrel main', noDiagnostics, 'test-non-barrel-main'); - verify(t, diagnostics, []); -}); +test('support testing in sub-directories', noDiagnostics, 'test-in-subdir'); -test('add support for esm with esModuleInterop', async t => { - const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/esm') - }); +test('support top-level await', noDiagnostics, 'top-level-await'); - verify(t, diagnostics, []); -}); +test('support default test directory', noDiagnostics, 'test-directory/default'); -test('add DOM support by default', async t => { - const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/dom') - }); - - verify(t, diagnostics, []); -}); - -test('a lib option in package.json overrdides a lib option in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json')}); - - verify(t, diagnostics, []); -}); - -test('pass in loose mode when strict mode is disabled in settings', async t => { - const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/non-strict-check-with-config') - }); +test('support tsx in subdirectory', noDiagnostics, 'test-directory/tsx'); - verify(t, diagnostics, []); -}); - -test('return no diagnostics', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/success')}); +test('support setting a custom test directory', verifyTsd, 'test-directory/custom', [ + [4, 0, 'error', 'Expected an error, but found none.'], +]); - verify(t, diagnostics, []); -}); +test('missing import', verifyTsd, 'missing-import', [ + [3, 18, 'error', 'Cannot find name \'Primitive\'.'], +]); -test('support non-barrel main', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-non-barrel-main')}); +test('tsx component', noDiagnostics, 'tsx'); - verify(t, diagnostics, []); -}); +test('loose types', verifyTsd, 'strict-types/loose', [ + [5, 0, 'error', 'Parameter type `string` is declared too wide for argument type `"cat"`.'], + [7, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `string`.'], + [8, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `number`.'], + [10, 0, 'error', 'Parameter type `string | Date` is declared too wide for argument type `Date`.'], + [11, 0, 'error', 'Parameter type `Promise` is declared too wide for argument type `Promise`.'], + [12, 0, 'error', 'Parameter type `string | Promise` is declared too wide for argument type `Promise`.'], + [14, 0, 'error', 'Parameter type `Promise` is declared too wide for argument type `Promise`.'], + [16, 0, 'error', 'Parameter type `Observable` is declared too wide for argument type `Observable`.'], + [20, 0, 'error', 'Parameter type `Observable | Observable` is declared too wide for argument type `Observable | Observable`.'], + [28, 0, 'error', 'Parameter type `Foo> | Foo | Foo` is declared too wide for argument type `Foo | Foo | Foo>`.'], + [32, 0, 'error', 'Parameter type `string | number` is not identical to argument type `any`.'], + [34, 0, 'error', 'Parameter type `Observable | Observable | Observable` is not identical to argument type `Observable | Observable | Observable`.'], +]); -test('allow omitting `types` property when `main` property is missing but main is a barrel (`index.js`) and .d.ts file matches main', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/no-explicit-types-property/without-main')}); +test('strict types', noDiagnostics, 'strict-types/strict'); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] - ]); -}); +test('typings in custom directory', verifyTsd, 'typings-custom-dir', [ + [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], +]); -test('allow omitting `types` property when `main` property is set to a barrel (`index.js`) and .d.ts file matches main', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/no-explicit-types-property/with-main-barrel')}); +test('specify test files manually', verifyTsd, + {fixtureName: 'specify-test-files', tsdOptions: {testFiles: ['unknown.test.ts', 'second.test.ts']}}, [ + [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], + ], +); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] - ]); -}); +test('fails if typings file is not found in the specified path', verifyTsdFails, + {fixtureName: 'typings-custom-dir', tsdOptions: {testFiles: ['unknown.test.ts']}}, + () => 'Could not find any test files with the given pattern(s).', +); -test('allow omitting `types` property when `main` property is set to non-barrel (`foo.js`) and .d.ts file matches main', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/no-explicit-types-property/with-main-other')}); - - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] - ]); -}); - -test('support testing in sub-directories', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-in-subdir')}); - - verify(t, diagnostics, []); -}); - -test('support top-level await', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/top-level-await')}); - - verify(t, diagnostics, []); -}); - -test('support default test directory', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-directory/default')}); - - verify(t, diagnostics, []); -}); - -test('support tsx in subdirectory', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-directory/tsx')}); - - verify(t, diagnostics, []); -}); - -test('support setting a custom test directory', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-directory/custom')}); - - verify(t, diagnostics, [ - [4, 0, 'error', 'Expected an error, but found none.'] - ]); -}); - -test('missing import', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/missing-import')}); - - verify(t, diagnostics, [ - [3, 18, 'error', 'Cannot find name \'Primitive\'.'] - ]); -}); - -test('tsx component', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/tsx/component')}); - - verify(t, diagnostics, []); -}); - -test('tsx component type', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/tsx/component-type')}); - - verify(t, diagnostics, []); -}); - -test('loose types', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/strict-types/loose')}); - - verify(t, diagnostics, [ - [5, 0, 'error', 'Parameter type `string` is declared too wide for argument type `"cat"`.'], - [7, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `string`.'], - [8, 0, 'error', 'Parameter type `string | number` is declared too wide for argument type `number`.'], - [10, 0, 'error', 'Parameter type `string | Date` is declared too wide for argument type `Date`.'], - [11, 0, 'error', 'Parameter type `Promise` is declared too wide for argument type `Promise`.'], - [12, 0, 'error', 'Parameter type `string | Promise` is declared too wide for argument type `Promise`.'], - [14, 0, 'error', 'Parameter type `Promise` is declared too wide for argument type `Promise`.'], - [16, 0, 'error', 'Parameter type `Observable` is declared too wide for argument type `Observable`.'], - [20, 0, 'error', 'Parameter type `Observable | Observable` is declared too wide for argument type `Observable | Observable`.'], - [28, 0, 'error', 'Parameter type `Foo> | Foo | Foo` is declared too wide for argument type `Foo | Foo | Foo>`.'], - [32, 0, 'error', 'Parameter type `string | number` is not identical to argument type `any`.'], - [34, 0, 'error', 'Parameter type `Observable | Observable | Observable` is not identical to argument type `Observable | Observable | Observable`.'] - ]); -}); - -test('strict types', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/strict-types/strict')}); - - verify(t, diagnostics, []); -}); - -test('typings in custom directory', async t => { - const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/typings-custom-dir'), - typingsFile: 'utils/index.d.ts' - }); - - verify(t, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'] - ]); -}); - -test('specify test files manually', async t => { - const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/specify-test-files'), - testFiles: [ - 'unknown.test.ts', - 'second.test.ts' - ] - }); - - verify(t, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'] - ]); -}); - -test('fails if typings file is not found in the specified path', async t => { - const cwd = path.join(__dirname, 'fixtures/typings-custom-dir'); - - const error = await t.throwsAsync(tsd({ - cwd, - typingsFile: 'unknown.d.ts' - })); - - t.is(error.message, `The type definition \`unknown.d.ts\` does not exist at \`${path.join(cwd, 'unknown.d.ts')}\`. Is the path correct? Create one and try again.`); -}); - -test('includes extended config files along with found ones', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/ts-config-extends')}); - - verify(t, diagnostics, [ - [6, 64, 'error', 'Not all code paths return a value.'], - ]); -}); +test('includes extended config files along with found ones', verifyTsd, 'ts-config-extends', [ + [6, 64, 'error', 'Not all code paths return a value.'], +]); test('errors in libs from node_modules are not reported', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/exclude-node-modules')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/exclude-node-modules')}); + // eslint-disable-next-line unicorn/no-array-reduce const [nodeModuleDiagnostics, testFileDiagnostics, otherDiagnostics] = diagnostics.reduce( ([nodeModuleDiags, testFileDiags, otherDiags], diagnostic) => { if (/[/\\]node_modules[/\\]/.test(diagnostic.fileName)) { @@ -368,10 +132,10 @@ test('errors in libs from node_modules are not reported', async t => { return [nodeModuleDiags, testFileDiags, otherDiags]; }, - [[], [], []] + [[], [], []], ); - t.deepEqual( + t.is( nodeModuleDiagnostics.length, 0, 'There must be no errors from node_modules folders when standard lib is not available (option `"noLib": true`).', @@ -386,47 +150,27 @@ test('errors in libs from node_modules are not reported', async t => { /[/\\]lib[/\\]index.d.ts$/, /[/\\]lib[/\\]interfaces.d.ts$/, ]; - otherDiagnostics.forEach(diagnostic => { + for (const diagnostic of otherDiagnostics) { t.true( alloweOtherFileFailures.some(allowedFileRe => allowedFileRe.test(diagnostic.fileName)), `Found diagnostic from an unexpected file: ${diagnostic.fileName} - ${diagnostic.message}`, ); - }); + } verify(t, testFileDiagnostics, [ - [3, 18, 'error', 'Cannot find name \'Bar\'.'] + [3, 18, 'error', 'Cannot find name \'Bar\'.'], ]); }); -test('allow specifying `rootDir` option in `tsconfig.json`', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/root-dir')}); - - verify(t, diagnostics, []); -}); - -test('assertions should be identified if imported as an aliased module', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/aliased/aliased-module')}); +test('allow specifying `rootDir` option in `tsconfig.json`', noDiagnostics, 'root-dir'); - verify(t, diagnostics, []); -}); - -test('assertions should be identified if imported as an alias', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/aliased/aliased-assertion')}); - - verify(t, diagnostics, []); -}); +test('assertions should be identified if imported as an aliased module', noDiagnostics, 'aliased/aliased-module'); -test('assertions should be identified if aliased', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/aliased/aliased-const')}); +test('assertions should be identified if imported as an alias', noDiagnostics, 'aliased/aliased-assertion'); - verify(t, diagnostics, []); -}); - -test('parsing undefined symbol should not fail', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/undefined-symbol')}); +test('assertions should be identified if aliased', noDiagnostics, 'aliased/aliased-const'); - verify(t, diagnostics, []); -}); +test('parsing undefined symbol should not fail', noDiagnostics, 'undefined-symbol'); test('custom tsd errors are created correctly', t => { const tsdError = t.throws(() => { @@ -435,6 +179,8 @@ test('custom tsd errors are created correctly', t => { t.true(tsdError instanceof Error); t.true(tsdError instanceof TsdError); - t.is(tsdError.name, 'TsdError'); - t.is(tsdError.message, 'foo'); + t.is(tsdError?.name, 'TsdError'); + t.is(tsdError?.message, 'foo'); }); + +// TODO: provide export like tsd/assertions? diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..b839b011 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.tsd.json", + "include": ["source"], + "exclude": ["source/test"], + "compilerOptions": { + "outDir": "dist", + "removeComments": true, + "declaration": false, + }, +} diff --git a/tsconfig.tsd.json b/tsconfig.tsd.json index 9f8bc340..a49bd0bc 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -1,24 +1,8 @@ { + "extends": "@sindresorhus/tsconfig", "compilerOptions": { - "outDir": "dist", - "target": "es6", - "lib": [ - "es2015" - ], - "module": "commonjs", - "moduleResolution": "node", - "declaration": true, - "pretty": true, - "newLine": "lf", - "stripInternal": true, - "strict": true, - "noImplicitReturns": true, - "noImplicitOverride": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noEmitOnError": true, - "forceConsistentCasingInFileNames": true, + // TODO: enable this rule + "noUncheckedIndexedAccess": false, "esModuleInterop": true, }, "exclude": [ diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 00000000..003ee892 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,13 @@ +import type {Options} from 'tsup'; + +export default { + tsconfig: 'tsconfig.tsd.json', + entry: ['source/index.ts'], + dts: { + entry: 'source/index.ts', + resolve: true, + only: true, + }, + format: 'esm', + clean: true, +} satisfies Options;