From 6224ac28c6f6ecc45917abd35c6b817d917ac8d4 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 14 Mar 2023 23:28:05 -0500 Subject: [PATCH 01/18] chore(`esm`): update `tsconfig` --- tsconfig.tsd.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tsconfig.tsd.json b/tsconfig.tsd.json index 9f8bc340..a230cea9 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -1,12 +1,12 @@ { "compilerOptions": { "outDir": "dist", - "target": "es6", + "target": "ES2020", // Node.js 14 "lib": [ - "es2015" + "ES2020" ], - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "declaration": true, "pretty": true, "newLine": "lf", From 88f2e6d42ef44255b00759a84be18ebe4d000b65 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 14 Mar 2023 23:32:02 -0500 Subject: [PATCH 02/18] chore(`esm`): update `package.json`, add `tsx` for testing --- package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 1bc87b81..268f9a66 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "email": "sam.verschueren@gmail.com", "url": "https://github.com/SamVerschueren" }, + "type": "module", "exports": "./dist/index.js", "types": "./dist/index.d.ts", "bin": "./dist/cli.js", @@ -17,10 +18,8 @@ }, "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", + "build": "del-cli dist && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js", "lint": "eslint \"source/**/*\"", "lint:fix": "eslint --fix \"source/**/*\"" }, @@ -48,7 +47,6 @@ "read-pkg-up": "^7.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", @@ -62,6 +60,7 @@ "execa": "^5.0.0", "react": "^16.9.0", "rxjs": "^6.5.3", + "tsx": "^3.12.5", "typescript": "~4.9.5" }, "ava": { @@ -70,10 +69,11 @@ "source/test/**/*", "!source/test/fixtures/**/*" ], - "typescript": { - "rewritePaths": { - "source/": "dist/" - } - } + "extensions": { + "ts": "module" + }, + "nodeArguments": [ + "--loader=tsx" + ] } } From 79789f1cfbee07c9edba29d52d8cc592396ff834 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 14 Mar 2023 23:40:23 -0500 Subject: [PATCH 03/18] chore(`ava`): upgrade to v5.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 268f9a66..19a2e977 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@types/react": "^16.9.2", "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", - "ava": "^3.8.2", + "ava": "^5.2.0", "cpy-cli": "^3.0.0", "del-cli": "^3.0.0", "eslint": "^7.27.0", From 28843f47fa3fceb7ac9c11afb1142bebe97f55f5 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 14 Mar 2023 23:45:50 -0500 Subject: [PATCH 04/18] chore(`esm`): update relative imports in `source` --- source/cli.ts | 4 ++-- source/index.ts | 6 +++--- source/lib/assertions/handlers/assignability.ts | 4 ++-- source/lib/assertions/handlers/expect-deprecated.ts | 6 +++--- source/lib/assertions/handlers/handler.ts | 2 +- source/lib/assertions/handlers/identicality.ts | 4 ++-- source/lib/assertions/handlers/index.ts | 10 +++++----- source/lib/assertions/handlers/informational.ts | 4 ++-- source/lib/assertions/handlers/strict-assertion.ts | 4 ++-- source/lib/assertions/index.ts | 4 ++-- source/lib/compiler.ts | 6 +++--- source/lib/config.ts | 2 +- source/lib/formatter.ts | 2 +- source/lib/index.ts | 8 ++++---- source/lib/parser.ts | 4 ++-- source/lib/rules/files-property.ts | 4 ++-- source/lib/rules/index.ts | 6 +++--- source/lib/rules/types-property.ts | 4 ++-- source/lib/utils/index.ts | 8 ++++---- source/lib/utils/make-diagnostic-with-diff.ts | 2 +- source/lib/utils/make-diagnostic.ts | 2 +- 21 files changed, 48 insertions(+), 48 deletions(-) diff --git a/source/cli.ts b/source/cli.ts index c6dbed5f..5abf22c7 100644 --- a/source/cli.ts +++ b/source/cli.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node import meow from 'meow'; -import formatter from './lib/formatter'; -import tsd from './lib'; +import formatter from './lib/formatter.js'; +import tsd from './lib/index.js'; const cli = meow(` Usage diff --git a/source/index.ts b/source/index.ts index 2007424e..c5407be0 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,6 +1,6 @@ -import tsd from './lib'; -import formatter from './lib/formatter'; +import tsd from './lib/index.js'; +import formatter from './lib/formatter.js'; -export * from './lib/assertions/assert'; +export * from './lib/assertions/assert.js'; export {formatter}; export default tsd; diff --git a/source/lib/assertions/handlers/assignability.ts b/source/lib/assertions/handlers/assignability.ts index e9e7be0a..8631fc0a 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 {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..8f5462ce 100644 --- a/source/lib/assertions/handlers/expect-deprecated.ts +++ b/source/lib/assertions/handlers/expect-deprecated.ts @@ -1,7 +1,7 @@ import {JSDocTagInfo} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {Handler} from './handler'; -import {makeDiagnostic, tsutils} from '../../utils'; +import {Diagnostic} from '../../interfaces.js'; +import {Handler} from './handler.js'; +import {makeDiagnostic, tsutils} from '../../utils/index.js'; interface Options { filter(tags: Map): boolean; diff --git a/source/lib/assertions/handlers/handler.ts b/source/lib/assertions/handlers/handler.ts index e3f7e089..d7c55e0a 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 {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..0ff84d9c 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 {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. diff --git a/source/lib/assertions/handlers/index.ts b/source/lib/assertions/handlers/index.ts index 8386e765..1de335c1 100644 --- a/source/lib/assertions/handlers/index.ts +++ b/source/lib/assertions/handlers/index.ts @@ -1,7 +1,7 @@ -export {Handler} from './handler'; +export {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..5b7cfc6d 100644 --- a/source/lib/assertions/handlers/informational.ts +++ b/source/lib/assertions/handlers/informational.ts @@ -1,6 +1,6 @@ import {CallExpression, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces'; -import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils'; +import {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. diff --git a/source/lib/assertions/handlers/strict-assertion.ts b/source/lib/assertions/handlers/strict-assertion.ts index 5ecc096e..32636ce3 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 {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..ce0ab024 100644 --- a/source/lib/assertions/index.ts +++ b/source/lib/assertions/index.ts @@ -1,5 +1,5 @@ import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../interfaces'; +import {Diagnostic} from '../interfaces.js'; import { Handler, isIdentical, @@ -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 91f69ef1..9eae36f7 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -3,9 +3,9 @@ import { createProgram, Diagnostic as TSDiagnostic } from '@tsd/typescript'; -import {ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser'; -import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces'; -import {handle} from './assertions'; +import {ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; +import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces.js'; +import {handle} from './assertions/index.js'; // List of diagnostic codes that should be ignored in general const ignoredDiagnostics = new Set([ diff --git a/source/lib/config.ts b/source/lib/config.ts index 5f076f3f..c1987c66 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -10,7 +10,7 @@ import { parseJsonSourceFileConfigFileContent, ModuleKind } from '@tsd/typescript'; -import {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces'; +import {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; /** * Load the configuration settings. diff --git a/source/lib/formatter.ts b/source/lib/formatter.ts index 3a67c123..8051171a 100644 --- a/source/lib/formatter.ts +++ b/source/lib/formatter.ts @@ -1,5 +1,5 @@ import formatter from 'eslint-formatter-pretty'; -import {Diagnostic} from './interfaces'; +import {Diagnostic} from './interfaces.js'; import {diffStringsUnified} from 'jest-diff'; interface FileWithDiagnostics { diff --git a/source/lib/index.ts b/source/lib/index.ts index 9aad2485..b9b99893 100644 --- a/source/lib/index.ts +++ b/source/lib/index.ts @@ -2,10 +2,10 @@ 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} from './interfaces'; +import {getDiagnostics as getTSDiagnostics} from './compiler.js'; +import loadConfig from './config.js'; +import getCustomDiagnostics from './rules/index.js'; +import {Context, Config, Diagnostic, PackageJsonWithTsdConfig} from './interfaces.js'; export interface Options { cwd: string; diff --git a/source/lib/parser.ts b/source/lib/parser.ts index 56175c7d..543d66ef 100644 --- a/source/lib/parser.ts +++ b/source/lib/parser.ts @@ -1,6 +1,6 @@ import {Program, Node, CallExpression, forEachChild, isCallExpression, isPropertyAccessExpression, SymbolFlags} from '@tsd/typescript'; -import {Assertion} from './assertions'; -import {Location, Diagnostic} from './interfaces'; +import {Assertion} from './assertions/index.js'; +import {Location, Diagnostic} from './interfaces.js'; const assertionFnNames = new Set(Object.values(Assertion)); diff --git a/source/lib/rules/files-property.ts b/source/lib/rules/files-property.ts index efcb6961..dee1224a 100644 --- a/source/lib/rules/files-property.ts +++ b/source/lib/rules/files-property.ts @@ -1,8 +1,8 @@ import path from 'path'; import fs from 'fs'; import globby from 'globby'; -import {Context, Diagnostic} from '../interfaces'; -import {getJSONPropertyPosition} from '../utils'; +import {Context, Diagnostic} from '../interfaces.js'; +import {getJSONPropertyPosition} from '../utils/index.js'; /** * Rule which enforces the typings file to be present in the `files` list in `package.json`. diff --git a/source/lib/rules/index.ts b/source/lib/rules/index.ts index a4229e0a..51f51d5e 100644 --- a/source/lib/rules/index.ts +++ b/source/lib/rules/index.ts @@ -1,6 +1,6 @@ -import filesProperty from './files-property'; -import typesProperty from './types-property'; -import {Diagnostic, Context} from '../interfaces'; +import filesProperty from './files-property.js'; +import typesProperty from './types-property.js'; +import {Diagnostic, Context} from '../interfaces.js'; type RuleFunction = (context: Context) => Diagnostic[]; diff --git a/source/lib/rules/types-property.ts b/source/lib/rules/types-property.ts index a9c7e237..aef070d1 100644 --- a/source/lib/rules/types-property.ts +++ b/source/lib/rules/types-property.ts @@ -1,7 +1,7 @@ import path from 'path'; import fs from 'fs'; -import {Context, Diagnostic} from '../interfaces'; -import {getJSONPropertyPosition} from '../utils'; +import {Context, Diagnostic} from '../interfaces.js'; +import {getJSONPropertyPosition} from '../utils/index.js'; /** * Rule which enforces the use of a `types` property over a `typings` property. diff --git a/source/lib/utils/index.ts b/source/lib/utils/index.ts index 81c060aa..adfdb91b 100644 --- a/source/lib/utils/index.ts +++ b/source/lib/utils/index.ts @@ -1,7 +1,7 @@ -import makeDiagnostic from './make-diagnostic'; -import makeDiagnosticWithDiff from './make-diagnostic-with-diff'; -import getJSONPropertyPosition from './get-json-property-position'; -import * as tsutils from './typescript'; +import makeDiagnostic from './make-diagnostic.js'; +import makeDiagnosticWithDiff from './make-diagnostic-with-diff.js'; +import getJSONPropertyPosition from './get-json-property-position.js'; +import * as tsutils from './typescript.js'; export { getJSONPropertyPosition, diff --git a/source/lib/utils/make-diagnostic-with-diff.ts b/source/lib/utils/make-diagnostic-with-diff.ts index c97a036a..a2bc9b41 100644 --- a/source/lib/utils/make-diagnostic-with-diff.ts +++ b/source/lib/utils/make-diagnostic-with-diff.ts @@ -1,5 +1,5 @@ import {Node, Type, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; -import {Diagnostic} from '../interfaces'; +import {Diagnostic} from '../interfaces.js'; interface DiagnosticWithDiffOptions { checker: TypeChecker; diff --git a/source/lib/utils/make-diagnostic.ts b/source/lib/utils/make-diagnostic.ts index f148cfb4..3ae54237 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 {Diagnostic} from '../interfaces.js'; /** * Create a diagnostic from the given `node`, `message` and optional `severity`. From 8a395db1038cd2eb8c0bceac63602a097187c01e Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Sun, 2 Apr 2023 21:52:50 -0500 Subject: [PATCH 05/18] chore: update deps, move to `xo` --- .eslintignore | 1 - .eslintrc | 10 -- package.json | 48 +++--- source/cli.ts | 38 ++--- source/index.ts | 7 +- source/lib/assertions/assert.ts | 24 ++- .../lib/assertions/handlers/assignability.ts | 4 +- .../assertions/handlers/expect-deprecated.ts | 51 +++--- source/lib/assertions/handlers/handler.ts | 4 +- .../lib/assertions/handlers/identicality.ts | 4 +- source/lib/assertions/handlers/index.ts | 2 +- .../lib/assertions/handlers/informational.ts | 12 +- .../assertions/handlers/strict-assertion.ts | 4 +- source/lib/assertions/index.ts | 6 +- source/lib/compiler.ts | 30 ++-- source/lib/config.ts | 28 ++-- source/lib/formatter.ts | 18 ++- source/lib/index.ts | 43 ++--- source/lib/interfaces.ts | 20 +-- source/lib/parser.ts | 30 ++-- source/lib/rules/files-property.ts | 26 +-- source/lib/rules/index.ts | 23 ++- source/lib/rules/types-property.ts | 18 ++- .../lib/utils/get-json-property-position.ts | 6 +- source/lib/utils/index.ts | 15 +- source/lib/utils/make-diagnostic-with-diff.ts | 38 ++--- source/lib/utils/make-diagnostic.ts | 8 +- source/lib/utils/typescript.ts | 21 ++- source/test/assignability.ts | 12 +- source/test/cli.ts | 34 ++-- source/test/deprecated.ts | 14 +- source/test/diff.ts | 18 +-- source/test/eslint-compatibility.ts | 38 ++--- source/test/expect-error.ts | 26 +-- .../fixtures/eslint-compatibility/index.js | 2 +- .../eslint-compatibility/package.json | 3 +- source/test/fixtures/utils.ts | 2 +- source/test/identicality.ts | 10 +- source/test/informational.ts | 10 +- source/test/test.ts | 151 +++++++++--------- 40 files changed, 428 insertions(+), 431 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc 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/package.json b/package.json index 19a2e977..16063c5c 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,12 @@ "types": "./dist/index.d.ts", "bin": "./dist/cli.js", "engines": { - "node": ">=14.16" + "node": ">=16" }, "scripts": { "prepublishOnly": "npm run build", - "test": "npm run lint && ava", - "build": "del-cli dist && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js", - "lint": "eslint \"source/**/*\"", - "lint:fix": "eslint --fix \"source/**/*\"" + "test": "xo && tsc --project tsconfig.tsd.json --noEmit && ava", + "build": "del-cli dist && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js" }, "files": [ "dist/**/*.js", @@ -38,30 +36,28 @@ "typedefinitions" ], "dependencies": { - "@tsd/typescript": "~4.9.5", - "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" + "@tsd/typescript": "~5.0.3", + "eslint-formatter-pretty": "^5.0.0", + "globby": "^13.1.3", + "jest-diff": "^29.5.0", + "meow": "^11.0.0", + "p-map": "^5.5.0", + "path-exists": "^5.0.0", + "read-pkg-up": "^9.1.0" }, "devDependencies": { - "@types/node": "^14.18.21", + "@types/common-tags": "^1.8.1", + "@types/node": "^16", "@types/react": "^16.9.2", - "@typescript-eslint/eslint-plugin": "^4.26.0", - "@typescript-eslint/parser": "^4.26.0", "ava": "^5.2.0", - "cpy-cli": "^3.0.0", + "common-tags": "^1.8.2", "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", + "execa": "^7.1.1", "react": "^16.9.0", "rxjs": "^6.5.3", - "tsx": "^3.12.5", - "typescript": "~4.9.5" + "tsx": "^3.12.6", + "typescript": "~5.0.3", + "xo": "^0.53.1" }, "ava": { "timeout": "2m", @@ -75,5 +71,13 @@ "nodeArguments": [ "--loader=tsx" ] + }, + "xo": { + "ignores": [ + "source/test/fixtures" + ], + "rules": { + "no-bitwise": "off" + } } } diff --git a/source/cli.ts b/source/cli.ts index 5abf22c7..850e2634 100644 --- a/source/cli.ts +++ b/source/cli.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node +import process from 'node:process'; import meow from 'meow'; -import formatter from './lib/formatter.js'; +import prettyFormatter from './lib/formatter.js'; import tsd from './lib/index.js'; const cli = meow(` @@ -28,6 +29,7 @@ const cli = meow(` 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', @@ -44,26 +46,24 @@ const cli = meow(` }, }); -(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 {typings: typingsFile, files: testFiles, showDiff} = cli.flags; - const options = {cwd, typingsFile, testFiles}; + const options = {cwd, typingsFile, testFiles}; - const diagnostics = await tsd(options); + const diagnostics = await tsd(options); - if (diagnostics.length > 0) { - throw new Error(formatter(diagnostics, showDiff)); - } - } catch (error: unknown) { - const potentialError = error as Error | undefined; - const errorMessage = potentialError?.stack ?? potentialError?.message; - - if (errorMessage) { - console.error(`Error running tsd: ${errorMessage}`); - } + if (diagnostics.length > 0) { + throw new Error(prettyFormatter(diagnostics, showDiff)); + } +} catch (error: unknown) { + const potentialError = error as Error | undefined; + const errorMessage = potentialError?.stack ?? potentialError?.message; - process.exit(1); + if (errorMessage) { + console.error(`Error running tsd: ${errorMessage}`); } -})(); + + process.exit(1); +} diff --git a/source/index.ts b/source/index.ts index c5407be0..6da289a4 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,6 +1,3 @@ -import tsd from './lib/index.js'; -import formatter from './lib/formatter.js'; - export * from './lib/assertions/assert.js'; -export {formatter}; -export default tsd; +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..2fcebec5 100644 --- a/source/lib/assertions/assert.ts +++ b/source/lib/assertions/assert.ts @@ -1,11 +1,9 @@ -/* 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 +// @ts-expect-error: "expression is never read" export const expectType = (expression: T) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -15,7 +13,7 @@ export const expectType = (expression: T) => { * * @param expression - Expression that should not be identical to type `T`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" 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 @@ -27,7 +25,7 @@ export const expectNotType = (expression: any) => { * * @param expression - Expression that should be assignable to type `T`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectAssignable = (expression: T) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -37,7 +35,7 @@ export const expectAssignable = (expression: T) => { * * @param expression - Expression that should not be assignable to type `T`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectNotAssignable = (expression: any) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -47,7 +45,7 @@ export const expectNotAssignable = (expression: any) => { * * @param expression - Expression that should throw an error. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectError = (expression: T) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -57,7 +55,7 @@ export const expectError = (expression: T) => { * * @param expression - Expression that should be marked as `@deprecated`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectDeprecated = (expression: any) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -67,7 +65,7 @@ export const expectDeprecated = (expression: any) => { * * @param expression - Expression that should not be marked as `@deprecated`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectNotDeprecated = (expression: any) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -79,16 +77,14 @@ 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 +// @ts-expect-error: "expression is never read" export const printType = (expression: any) => { // Do nothing, the TypeScript compiler handles this for us }; @@ -98,7 +94,7 @@ export const printType = (expression: any) => { * * @param expression - Expression whose documentation comment should include string literal type `T`. */ -// @ts-expect-error +// @ts-expect-error: "expression is never read" export const expectDocCommentIncludes = (expression: any) => { // Do nothing, the TypeScript compiler handles this for us }; diff --git a/source/lib/assertions/handlers/assignability.ts b/source/lib/assertions/handlers/assignability.ts index 8631fc0a..01e5428a 100644 --- a/source/lib/assertions/handlers/assignability.ts +++ b/source/lib/assertions/handlers/assignability.ts @@ -1,5 +1,5 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces.js'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnosticWithDiff} from '../../utils/index.js'; /** diff --git a/source/lib/assertions/handlers/expect-deprecated.ts b/source/lib/assertions/handlers/expect-deprecated.ts index 8f5462ce..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.js'; -import {Handler} from './handler.js'; +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 d7c55e0a..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.js'; +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 0ff84d9c..804f6b11 100644 --- a/source/lib/assertions/handlers/identicality.ts +++ b/source/lib/assertions/handlers/identicality.ts @@ -1,5 +1,5 @@ -import {CallExpression, TypeChecker, TypeFlags} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces.js'; +import {type CallExpression, type TypeChecker, TypeFlags} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnostic, makeDiagnosticWithDiff} from '../../utils/index.js'; /** diff --git a/source/lib/assertions/handlers/index.ts b/source/lib/assertions/handlers/index.ts index 1de335c1..e31a417d 100644 --- a/source/lib/assertions/handlers/index.ts +++ b/source/lib/assertions/handlers/index.ts @@ -1,4 +1,4 @@ -export {Handler} from './handler.js'; +export type {Handler} from './handler.js'; // Handlers export {isIdentical, isNotIdentical, isNever} from './identicality.js'; diff --git a/source/lib/assertions/handlers/informational.ts b/source/lib/assertions/handlers/informational.ts index 5b7cfc6d..e8ed0698 100644 --- a/source/lib/assertions/handlers/informational.ts +++ b/source/lib/assertions/handlers/informational.ts @@ -1,5 +1,5 @@ -import {CallExpression, TypeChecker, TypeFormatFlags} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces.js'; +import {type CallExpression, type TypeChecker, TypeFormatFlags} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils/index.js'; /** @@ -7,10 +7,10 @@ import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils/index * * @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 + = TypeFormatFlags.AllowUniqueESSymbolType + | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope + | 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 32636ce3..c7fdefba 100644 --- a/source/lib/assertions/handlers/strict-assertion.ts +++ b/source/lib/assertions/handlers/strict-assertion.ts @@ -1,5 +1,5 @@ -import {CallExpression, TypeChecker} from '@tsd/typescript'; -import {Diagnostic} from '../../interfaces.js'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnostic} from '../../utils/index.js'; /** diff --git a/source/lib/assertions/index.ts b/source/lib/assertions/index.ts index ce0ab024..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.js'; +import type {CallExpression, TypeChecker} from '@tsd/typescript'; +import type {Diagnostic} from '../interfaces.js'; import { - Handler, + type Handler, isIdentical, isNotIdentical, isNotAssignable, diff --git a/source/lib/compiler.ts b/source/lib/compiler.ts index 9eae36f7..497949f3 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,17 +1,17 @@ import { flattenDiagnosticMessageText, createProgram, - Diagnostic as TSDiagnostic + type Diagnostic as TSDiagnostic, } from '@tsd/typescript'; -import {ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; -import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces.js'; +import {type ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; +import {type Diagnostic, DiagnosticCode, 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 @@ -58,18 +58,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 @@ -104,9 +102,10 @@ export const getDiagnostics = (context: Context): Diagnostic[] => { const program = createProgram(context.testFiles, context.config.compilerOptions); - const tsDiagnostics = program - .getSemanticDiagnostics() - .concat(program.getSyntacticDiagnostics()); + const tsDiagnostics = [ + ...program.getSemanticDiagnostics(), + ...program.getSyntacticDiagnostics(), + ]; const assertions = extractAssertions(program); @@ -133,7 +132,6 @@ 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({ @@ -141,7 +139,7 @@ export const getDiagnostics = (context: Context): Diagnostic[] => { message: flattenDiagnosticMessageText(diagnostic.messageText, '\n'), severity: 'error', line: position.line + 1, - column: position.character + column: position.character, }); } @@ -150,14 +148,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 c1987c66..ccf61491 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -1,16 +1,16 @@ import { + type CompilerOptions, JsxEmit, ScriptTarget, ModuleResolutionKind, parseJsonConfigFileContent, - CompilerOptions, findConfigFile, sys, readJsonConfigFile, parseJsonSourceFileConfigFileContent, - ModuleKind + ModuleKind, } from '@tsd/typescript'; -import {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; +import type {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; /** * Load the configuration settings. @@ -18,13 +18,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 loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { const pkgConfig = pkg.tsd ?? {}; const tsConfigCompilerOptions = getOptionsFromTsConfig(cwd); const packageJsonCompilerOptions = parseCompilerConfigObject( pkgConfig.compilerOptions ?? {}, - cwd + cwd, ); const combinedCompilerOptions = { @@ -45,16 +45,18 @@ export default (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { target: ScriptTarget.ES2020, esModuleInterop: true, ...combinedCompilerOptions, - moduleResolution: module === ModuleKind.NodeNext ? - ModuleResolutionKind.NodeNext : - module === ModuleKind.Node16 ? - ModuleResolutionKind.Node16 : - ModuleResolutionKind.NodeJs, - skipLibCheck: false - } + moduleResolution: module === ModuleKind.NodeNext + ? ModuleResolutionKind.NodeNext + : (module === ModuleKind.Node16 + ? ModuleResolutionKind.Node16 + : ModuleResolutionKind.NodeJs), + skipLibCheck: false, + }, }; }; +export default loadConfig; + function getOptionsFromTsConfig(cwd: string): CompilerOptions { const configPath = findConfigFile(cwd, sys.fileExists); @@ -75,7 +77,7 @@ function parseCompilerConfigObject(compilerOptions: RawCompilerOptions, cwd: str return parseJsonConfigFileContent( {compilerOptions: compilerOptions || {}}, sys, - cwd + cwd, ).options; } diff --git a/source/lib/formatter.ts b/source/lib/formatter.ts index 8051171a..051e3d7d 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.js'; +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) { @@ -54,5 +54,7 @@ export default (diagnostics: Diagnostic[], showDiff = false): string => { entry.messages.push(diagnostic); } - return String(formatter([...fileMap.values()])); + return String(prettyFormatter([...fileMap.values()])); }; + +export default formatter; diff --git a/source/lib/index.ts b/source/lib/index.ts index b9b99893..59022ae6 100644 --- a/source/lib/index.ts +++ b/source/lib/index.ts @@ -1,25 +1,27 @@ -import path from 'path'; -import readPkgUp from 'read-pkg-up'; -import pathExists from 'path-exists'; -import globby from 'globby'; +import path from 'node:path'; +import process from 'node:process'; +import {readPackageUp} from 'read-pkg-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 {Context, Config, Diagnostic, PackageJsonWithTsdConfig} from './interfaces.js'; +import {type Context, type Config, type Diagnostic, type PackageJsonWithTsdConfig} from './interfaces.js'; -export interface Options { +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'; + /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ + const typings = options.typingsFile + || pkg.types + || pkg.typings + || (pkg.main && path.parse(pkg.main).name + '.d.ts') + || 'index.d.ts'; + /* eslint-enable @typescript-eslint/prefer-nullish-coalescing */ const typingsPath = path.join(options.cwd, typings); const typingsExist = await pathExists(typingsPath); @@ -80,8 +82,9 @@ 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 pkgResult = await readPackageUp({cwd: options.cwd}); if (!pkgResult) { throw new Error(`No \`package.json\` file found in \`${options.cwd}\`. Make sure you are running the command in a Node.js project.`); @@ -95,7 +98,7 @@ export default async (options: Options = {cwd: process.cwd()}): Promise; -export interface Config { +export type Config = { directory: string; compilerOptions: Options; -} +}; export type RawConfig = Partial>; @@ -14,13 +14,13 @@ 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 { AwaitExpressionOnlyAllowedWithinAsyncFunction = 1308, @@ -54,7 +54,7 @@ export enum DiagnosticCode { NewExpressionTargetLackingConstructSignatureHasAnyType = 7009, } -export interface Diagnostic { +export type Diagnostic = { fileName: string; message: string; severity: 'error' | 'warning'; @@ -64,10 +64,10 @@ export interface Diagnostic { expected: string; received: string; }; -} +}; -export interface Location { +export type Location = { fileName: string; start: number; end: number; -} +}; diff --git a/source/lib/parser.ts b/source/lib/parser.ts index 543d66ef..19b85293 100644 --- a/source/lib/parser.ts +++ b/source/lib/parser.ts @@ -1,6 +1,14 @@ -import {Program, Node, CallExpression, forEachChild, isCallExpression, isPropertyAccessExpression, SymbolFlags} from '@tsd/typescript'; +import { + type Program, + type Node, + type CallExpression, + forEachChild, + isCallExpression, + isPropertyAccessExpression, + SymbolFlags, +} from '@tsd/typescript'; import {Assertion} from './assertions/index.js'; -import {Location, Diagnostic} from './interfaces.js'; +import {type Location, type Diagnostic} from './interfaces.js'; const assertionFnNames = new Set(Object.values(Assertion)); @@ -17,9 +25,9 @@ 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 +99,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 +109,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 index dee1224a..9530e79e 100644 --- a/source/lib/rules/files-property.ts +++ b/source/lib/rules/files-property.ts @@ -1,8 +1,9 @@ -import path from 'path'; -import fs from 'fs'; -import globby from 'globby'; -import {Context, Diagnostic} from '../interfaces.js'; -import {getJSONPropertyPosition} from '../utils/index.js'; +import path from 'node:path'; +import fs from 'node:fs'; +import pMap from 'p-map'; +import {globby} from 'globby'; +import {type Context, type Diagnostic} from '../interfaces.js'; +import {getJsonPropertyPosition} from '../utils/index.js'; /** * Rule which enforces the typings file to be present in the `files` list in `package.json`. @@ -10,7 +11,7 @@ import {getJSONPropertyPosition} from '../utils/index.js'; * @param context - The context object. * @returns A list of custom diagnostics. */ -export default (context: Context): Diagnostic[] => { +const filesProperty = async (context: Context): Promise => { const {pkg, typingsFile} = context; const packageFiles = pkg.files; @@ -21,7 +22,10 @@ export default (context: Context): Diagnostic[] => { const normalizedTypingsFile = path.normalize(typingsFile); const patternProcessedPackageFiles = processGitIgnoreStylePatterns(packageFiles); - const normalizedFiles = globby.sync(patternProcessedPackageFiles, {cwd: context.cwd}).map(path.normalize); + const normalizedFiles = await pMap( + await globby(patternProcessedPackageFiles, {cwd: context.cwd}), + glob => path.normalize(glob), + ); if (normalizedFiles.includes(normalizedTypingsFile)) { return []; @@ -35,11 +39,13 @@ export default (context: Context): Diagnostic[] => { fileName: packageJsonFullPath, message: `TypeScript type definition \`${normalizedTypingsFile}\` is not part of the \`files\` list.`, severity: 'error', - ...getJSONPropertyPosition(content, 'files') - } + ...getJsonPropertyPosition(content, 'files'), + }, ]; }; +export default filesProperty; + function processGitIgnoreStylePatterns(patterns: readonly string[]): string[] { const processedPatterns = patterns .map(pattern => { @@ -51,7 +57,7 @@ function processGitIgnoreStylePatterns(patterns: readonly string[]): string[] { .slice(negationMarkersCount) // Strip off `/` from the start of the pattern .replace(/^\/+/, ''), - negationMarkersCount % 2 === 0 + negationMarkersCount % 2 === 0, ] as const; }) // Only include pattern if it has an even count of negation markers diff --git a/source/lib/rules/index.ts b/source/lib/rules/index.ts index 51f51d5e..aed2bd16 100644 --- a/source/lib/rules/index.ts +++ b/source/lib/rules/index.ts @@ -1,14 +1,14 @@ +import type {Diagnostic, Context} from '../interfaces.js'; import filesProperty from './files-property.js'; import typesProperty from './types-property.js'; -import {Diagnostic, Context} from '../interfaces.js'; -type RuleFunction = (context: Context) => Diagnostic[]; +type RuleFunction = (context: Context) => Promise; // List of custom rules -const rules = new Set([ +const rules: RuleFunction[] = [ filesProperty, - typesProperty -]); + typesProperty, +]; /** * Get a list of custom diagnostics within the current context. @@ -16,12 +16,9 @@ const rules = new Set([ * @param context - The context object. * @returns List of diagnostics */ -export default (context: Context) => { - const diagnostics: Diagnostic[] = []; - - for (const rule of rules) { - diagnostics.push(...rule(context)); - } - - return diagnostics; +const getCustomDiagnostics = async (context: Context): Promise => { + const diagnostics = await Promise.all(rules.map(async rule => rule(context))); + return diagnostics.flat(); }; + +export default getCustomDiagnostics; diff --git a/source/lib/rules/types-property.ts b/source/lib/rules/types-property.ts index aef070d1..25db7bb3 100644 --- a/source/lib/rules/types-property.ts +++ b/source/lib/rules/types-property.ts @@ -1,7 +1,7 @@ -import path from 'path'; -import fs from 'fs'; -import {Context, Diagnostic} from '../interfaces.js'; -import {getJSONPropertyPosition} from '../utils/index.js'; +import path from 'node:path'; +import fs from 'node:fs/promises'; +import type {Context, Diagnostic} from '../interfaces.js'; +import {getJsonPropertyPosition} from '../utils/index.js'; /** * Rule which enforces the use of a `types` property over a `typings` property. @@ -9,22 +9,24 @@ import {getJSONPropertyPosition} from '../utils/index.js'; * @param context - The context object. * @returns A list of custom diagnostics. */ -export default (context: Context): Diagnostic[] => { +const typesProperty = async (context: Context): Promise => { const {pkg} = context; if (!pkg.types && pkg.typings) { const packageJsonFullPath = path.join(context.cwd, 'package.json'); - const content = fs.readFileSync(packageJsonFullPath, 'utf8'); + const content = await fs.readFile(packageJsonFullPath, 'utf8'); return [ { fileName: packageJsonFullPath, message: 'Use property `types` instead of `typings`.', severity: 'error', - ...getJSONPropertyPosition(content, 'typings') - } + ...getJsonPropertyPosition(content, 'typings'), + }, ]; } return []; }; + +export default typesProperty; diff --git a/source/lib/utils/get-json-property-position.ts b/source/lib/utils/get-json-property-position.ts index a17fe12f..ae649201 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) { @@ -17,6 +17,8 @@ export default (content: string, property: string) => { 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 adfdb91b..284f914f 100644 --- a/source/lib/utils/index.ts +++ b/source/lib/utils/index.ts @@ -1,11 +1,4 @@ -import makeDiagnostic from './make-diagnostic.js'; -import makeDiagnosticWithDiff from './make-diagnostic-with-diff.js'; -import getJSONPropertyPosition from './get-json-property-position.js'; -import * as tsutils from './typescript.js'; - -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 a2bc9b41..05889fe6 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.js'; +import {type Node, type Type, type TypeChecker, TypeFormatFlags} 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 + = TypeFormatFlags.NoTruncation + | TypeFormatFlags.WriteArrayAsGenericType + | TypeFormatFlags.UseStructuralFallback + | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope + | TypeFormatFlags.NoTypeReduction + | TypeFormatFlags.AllowUniqueESSymbolType + | TypeFormatFlags.InArrayType + | TypeFormatFlags.InElementType + | TypeFormatFlags.InFirstTypeArgument + | 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 3ae54237..08eb771f 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.js'; +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.js'; * @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..8292b4dc 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 {type TypeChecker, type Expression, isCallLikeExpression, type JSDocTagInfo, displayPartsToString} from '@tsd/typescript'; const resolveCommentHelper = (resolve: R) => { 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 ref = isCallLikeExpression(expression) + ? checker.getResolvedSignature(expression) + : checker.getSymbolAtLocation(expression); if (!ref) { return; } switch (resolve) { - case 'JSDoc': + case 'JSDoc': { return new Map(ref.getJsDocTags().map(tag => [tag.name, tag])) as ConditionalResolveReturn; - case 'DocComment': + } + + case 'DocComment': { return displayPartsToString(ref.getDocumentationComment(checker)) as ConditionalResolveReturn; - default: + } + + 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`. diff --git a/source/test/assignability.ts b/source/test/assignability.ts index 56136bf2..7f8fff36 100644 --- a/source/test/assignability.ts +++ b/source/test/assignability.ts @@ -1,18 +1,18 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import tsd from '../index.js'; +import {verify} from './fixtures/utils.js'; test('assignable', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/assignability/assignable')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/assignability/assignable')}); verify(t, diagnostics, [ - [8, 26, 'error', 'Argument of type \'string\' is not assignable to parameter of type \'boolean\'.'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/assignability/not-assignable')}); verify(t, diagnostics, [ [4, 0, 'error', 'Argument of type `string` is assignable to parameter of type `string | number`.'], diff --git a/source/test/cli.ts b/source/test/cli.ts index a549d98b..35567020 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -1,38 +1,38 @@ -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 {execa} from 'execa'; +import {readPackageUp} from 'read-pkg-up'; +import tsd, {formatter} from '../index.js'; -interface ExecaError extends Error { +type ExecaError = { readonly exitCode: number; readonly stderr: string; -} +} & Error; test('fail if errors are found', async t => { const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/failure') + cwd: path.resolve('fixtures/failure'), })); t.is(exitCode, 1); - t.regex(stderr, /5:19[ ]{2}Argument of type number is not assignable to parameter of type string./); + t.regex(stderr, /5:19 {2}Argument of type number is not assignable to parameter of type string./); }); test('succeed if no errors are found', async t => { const {exitCode} = await execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/success') + cwd: path.resolve('fixtures/success'), }); t.is(exitCode, 0); }); test('provide a path', async t => { - const file = path.join(__dirname, 'fixtures/failure'); + const file = path.resolve('fixtures/failure'); const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file])); t.is(exitCode, 1); - t.regex(stderr, /5:19[ ]{2}Argument of type number is not assignable to parameter of type string./); + t.regex(stderr, /5:19 {2}Argument of type number is not assignable to parameter of type string./); }); test('cli help flag', async t => { @@ -42,7 +42,7 @@ test('cli help flag', async t => { }); test('cli version flag', async t => { - const pkg = readPkgUp.sync({normalize: false})?.packageJson ?? {}; + const pkg = await readPackageUp({normalize: false})?.packageJson ?? {}; const {exitCode, stdout} = await execa('dist/cli.js', ['--version']); @@ -53,7 +53,7 @@ test('cli version flag', async t => { 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') + cwd: path.resolve('fixtures/typings-custom-dir'), })); t.is(exitCode, 1); @@ -67,7 +67,7 @@ test('cli typings flag', async 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') + cwd: path.resolve('fixtures/specify-test-files'), })); t.is(exitCode, 1); @@ -80,7 +80,7 @@ test('cli files flag', async t => { 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') + cwd: path.resolve('fixtures/specify-test-files'), })); t.is(exitCode, 1); @@ -99,7 +99,7 @@ test('cli typings and files flags', async t => { test('tsd logs stacktrace on failure', async t => { const {exitCode, stderr, stack} = await t.throwsAsync(execa('../../../cli.js', { - cwd: path.join(__dirname, 'fixtures/empty-package-json') + cwd: path.resolve('fixtures/empty-package-json'), })); t.is(exitCode, 1); @@ -109,7 +109,7 @@ test('tsd logs stacktrace on failure', async t => { test('exported formatter matches cli results', async t => { const options = { - cwd: path.join(__dirname, 'fixtures/failure'), + cwd: path.resolve('fixtures/failure'), }; const {stderr: cliResults} = await t.throwsAsync(execa('../../../cli.js', options)); diff --git a/source/test/deprecated.ts b/source/test/deprecated.ts index fed893b4..24d2a1ad 100644 --- a/source/test/deprecated.ts +++ b/source/test/deprecated.ts @@ -1,26 +1,26 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import tsd from '../index.js'; +import {verify} from './fixtures/utils.js'; test('deprecated', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/deprecated/expect-deprecated')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/deprecated/expect-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`'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('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`'] + [33, 0, 'error', 'Expected `UnicornClass` to not be marked as `@deprecated`'], ]); }); diff --git a/source/test/diff.ts b/source/test/diff.ts index e2a26a1a..af8b90a7 100644 --- a/source/test/diff.ts +++ b/source/test/diff.ts @@ -1,11 +1,11 @@ -import {verifyWithDiff} from './fixtures/utils'; -import execa, {ExecaError} from 'execa'; -import path from 'path'; +import path from 'node:path'; +import {execa, type ExecaError} from 'execa'; import test from 'ava'; -import tsd from '..'; +import tsd from '../index.js'; +import {verifyWithDiff} from './fixtures/utils.js'; test('diff', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/diff')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/diff')}); verifyWithDiff(t, diagnostics, [ [8, 0, 'error', 'Parameter type `{ life?: number | undefined; }` is declared too wide for argument type `{ life: number; }`.', { @@ -31,14 +31,14 @@ test('diff', async t => { [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 file = path.resolve('fixtures/diff'); - const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file, '--show-diff'])); + const {exitCode, stderr} = await t.throwsAsync(execa('tsx ../cli.js', [file, '--show-diff'])); t.is(exitCode, 1); @@ -68,7 +68,7 @@ test('diff cli', async t => { '- This is not the same comment!', '+ This is a comment.', '', - '6 errors' + '6 errors', ]; // NOTE: If lines are added to the output in the future startLine and endLine should be adjusted. diff --git a/source/test/eslint-compatibility.ts b/source/test/eslint-compatibility.ts index 19d329ca..9e31bf07 100644 --- a/source/test/eslint-compatibility.ts +++ b/source/test/eslint-compatibility.ts @@ -1,29 +1,17 @@ -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', ['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 38b3e6d6..758ef302 100644 --- a/source/test/expect-error.ts +++ b/source/test/expect-error.ts @@ -1,30 +1,30 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import tsd from '../index.js'; +import {verify} from './fixtures/utils.js'; test('expectError for classes', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/classes')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/classes')}); verify(t, diagnostics, []); }); test('expectError for functions', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/functions')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/functions')}); verify(t, diagnostics, [ - [5, 0, 'error', 'Expected an error, but found none.'] + [5, 0, 'error', 'Expected an error, but found none.'], ]); }); test('expectError for generics', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/generics')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/generics')}); verify(t, diagnostics, []); }); test('expectError should not ignore syntactical errors', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/syntax')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/syntax')}); verify(t, diagnostics, [ [4, 29, 'error', '\')\' expected.'], @@ -33,27 +33,27 @@ test('expectError should not ignore syntactical errors', async t => { }); test('expectError for values', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/values')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/values')}); verify(t, diagnostics, [ - [5, 0, 'error', 'Expected an error, but found none.'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/enabled-exact-optional-property-types')}); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/missing-diagnostic-code')}); verify(t, diagnostics, [ [8, 12, 'error', 'Cannot find name \'undeclared\'.'], diff --git a/source/test/fixtures/eslint-compatibility/index.js b/source/test/fixtures/eslint-compatibility/index.js index a26b76e2..7721e422 100644 --- a/source/test/fixtures/eslint-compatibility/index.js +++ b/source/test/fixtures/eslint-compatibility/index.js @@ -1,4 +1,4 @@ -module.exports.default = (foo, bar) => { +export default (foo, bar) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/restrict-plus-operands return foo + bar; }; 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/utils.ts b/source/test/fixtures/utils.ts index 4cbea202..e1a3c536 100644 --- a/source/test/fixtures/utils.ts +++ b/source/test/fixtures/utils.ts @@ -1,6 +1,6 @@ import path from 'path'; import {ExecutionContext} from 'ava'; -import {Diagnostic} from '../../lib/interfaces'; +import type {Diagnostic} from '../../lib/interfaces.js'; type Expectation = [ line: number, diff --git a/source/test/identicality.ts b/source/test/identicality.ts index 4d9abec4..afde12cc 100644 --- a/source/test/identicality.ts +++ b/source/test/identicality.ts @@ -1,10 +1,10 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import tsd from '../index.js'; +import {verify} from './fixtures/utils.js'; test('identical', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/identicality/identical')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/identicality/identical')}); verify(t, diagnostics, [ [7, 0, 'error', 'Parameter type `any` is not identical to argument type `number`.'], @@ -18,7 +18,7 @@ test('identical', async t => { }); test('not identical', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/identicality/not-identical')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/identicality/not-identical')}); verify(t, diagnostics, [ [7, 0, 'error', 'Parameter type `string` is identical to argument type `string`.'], diff --git a/source/test/informational.ts b/source/test/informational.ts index 1f364d4e..dbffeaae 100644 --- a/source/test/informational.ts +++ b/source/test/informational.ts @@ -1,10 +1,10 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify} from './fixtures/utils'; -import tsd from '..'; +import tsd from '../index.js'; +import {verify} from './fixtures/utils.js'; test('print type', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/informational/print-type')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/informational/print-type')}); verify(t, diagnostics, [ [4, 0, 'warning', 'Type for expression `aboveZero` is: `(foo: number) => number | null`'], @@ -19,7 +19,7 @@ test('print type', async t => { }); test('expect doc comment includes', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/informational/expect-doc-comment')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/informational/expect-doc-comment')}); verify(t, diagnostics, [ [5, 0, 'error', 'Documentation comment for expression `noDocComment` not found.'], diff --git a/source/test/test.ts b/source/test/test.ts index 67bba0ed..3ae4ed26 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -1,31 +1,31 @@ -import path from 'path'; +import path from 'node:path'; import test from 'ava'; -import {verify, verifyWithFileName} from './fixtures/utils'; -import tsd from '..'; -import {Diagnostic} from '../lib/interfaces'; +import tsd from '../index.js'; +import type {Diagnostic} from '../lib/interfaces.js'; +import {verify, verifyWithFileName} from './fixtures/utils.js'; test('throw if no type definition was found', async t => { - const cwd = path.join(__dirname, 'fixtures/no-tsd'); + const cwd = path.resolve('fixtures/no-tsd'); const index = path.join(cwd, 'index.d.ts'); 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'); + const cwd = path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/failure')}); verify(t, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'] + [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 cwd = path.resolve('fixtures/failure-nested'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -35,7 +35,7 @@ test('return diagnostics from imported files as well', async t => { }); test('fail if typings file is not part of `files` list', async t => { - const cwd = path.join(__dirname, 'fixtures/no-files'); + const cwd = path.resolve('fixtures/no-files'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -44,13 +44,13 @@ test('fail if typings file is not part of `files` list', async t => { }); test('allow specifying folders containing typings file in `files` list', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/files-folder')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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.'], @@ -58,25 +58,25 @@ test('allow specifying negative gitignore-style patterns in `files` list', async }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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 cwd = path.resolve('fixtures/types-property/typings'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -85,7 +85,7 @@ test('fail if `typings` property is used instead of `types`', async t => { }); test('fail if tests don\'t pass in strict mode', async t => { - const cwd = path.join(__dirname, 'fixtures/failure-strict-null-checks'); + const cwd = path.resolve('fixtures/failure-strict-null-checks'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -100,7 +100,7 @@ test('fail if tests don\'t pass in strict mode', async t => { }); 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 cwd = path.resolve('fixtures/strict-null-checks-as-default-config-value'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -115,7 +115,7 @@ test('overridden config defaults to `strict` if `strict` is not explicitly overr }); 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 cwd = path.resolve('fixtures/lib-config/failure-missing-lib'); const diagnostics = await tsd({cwd}); verifyWithFileName(t, cwd, diagnostics, [ @@ -125,50 +125,50 @@ test('fail if types are used from a lib that was not explicitly specified', asyn }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-as-triple-slash-reference')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-from-package-json')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-from-tsconfig-json')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/nodenext-from-tsconfig-json')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/nodenext-from-package-json')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/node16-from-tsconfig-json')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/node16-from-package-json')}); verify(t, diagnostics, []); }); test('add support for esm with esModuleInterop', async t => { const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/esm') + cwd: path.resolve('fixtures/esm'), }); verify(t, diagnostics, []); @@ -176,116 +176,116 @@ test('add support for esm with esModuleInterop', async t => { test('add DOM support by default', async t => { const diagnostics = await tsd({ - cwd: path.join(__dirname, 'fixtures/dom') + cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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') + cwd: path.resolve('fixtures/non-strict-check-with-config'), }); verify(t, diagnostics, []); }); test('return no diagnostics', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/success')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/success')}); verify(t, diagnostics, []); }); test('support non-barrel main', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/test-non-barrel-main')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/test-non-barrel-main')}); verify(t, diagnostics, []); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/no-explicit-types-property/without-main')}); verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] + [6, 0, 'error', 'Expected an error, but found none.'], ]); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/no-explicit-types-property/with-main-barrel')}); verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] + [6, 0, 'error', 'Expected an error, but found none.'], ]); }); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/no-explicit-types-property/with-main-other')}); verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/test-directory/custom')}); verify(t, diagnostics, [ - [4, 0, 'error', 'Expected an error, but found none.'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/missing-import')}); verify(t, diagnostics, [ - [3, 18, 'error', 'Cannot find name \'Primitive\'.'] + [3, 18, 'error', 'Cannot find name \'Primitive\'.'], ]); }); test('tsx component', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/tsx/component')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/tsx/component')}); verify(t, diagnostics, []); }); test('tsx component type', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/tsx/component-type')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/tsx/component-type')}); verify(t, diagnostics, []); }); test('loose types', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/strict-types/loose')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/strict-types/loose')}); verify(t, diagnostics, [ [5, 0, 'error', 'Parameter type `string` is declared too wide for argument type `"cat"`.'], @@ -299,54 +299,52 @@ test('loose types', async t => { [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`.'] + [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')}); + const diagnostics = await tsd({cwd: path.resolve('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' + cwd: path.resolve('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\'.'] + [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'), + cwd: path.resolve('fixtures/specify-test-files'), testFiles: [ 'unknown.test.ts', - 'second.test.ts' - ] + 'second.test.ts', + ], }); verify(t, diagnostics, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'] + [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 cwd = path.resolve('fixtures/typings-custom-dir'); - const error = await t.throwsAsync(tsd({ + 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.`); + typingsFile: 'unknown.d.ts', + }), {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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/ts-config-extends')}); verify(t, diagnostics, [ [6, 64, 'error', 'Not all code paths return a value.'], @@ -354,8 +352,9 @@ test('includes extended config files along with found ones', async t => { }); 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 +367,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,44 +385,44 @@ 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')}); + const diagnostics = await tsd({cwd: path.resolve('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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-module')}); 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')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-assertion')}); verify(t, diagnostics, []); }); test('assertions should be identified if aliased', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/aliased/aliased-const')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-const')}); verify(t, diagnostics, []); }); test('parsing undefined symbol should not fail', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/undefined-symbol')}); + const diagnostics = await tsd({cwd: path.resolve('fixtures/undefined-symbol')}); verify(t, diagnostics, []); }); From 723cb474c514ddde1c559d2b3ec799e71bb58805 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Mon, 3 Apr 2023 22:32:41 -0500 Subject: [PATCH 06/18] chore: merge, update, lint, add test macros --- package.json | 4 +- readme.md | 11 +- source/cli.ts | 37 +- source/lib/config.ts | 1 + source/lib/formatter.ts | 7 +- source/lib/index.ts | 10 +- source/lib/interfaces.ts | 7 + source/test/_utils.ts | 196 +++++++++ source/test/assignability.ts | 26 +- source/test/cli.ts | 107 ++++- source/test/deprecated.ts | 36 +- source/test/diff.ts | 72 ++-- source/test/expect-error.ts | 74 +--- source/test/fixtures/utils.ts | 119 ----- .../warnings/only-warnings/index.d.ts | 6 + .../fixtures/warnings/only-warnings/index.js | 3 + .../warnings/only-warnings/index.test-d.ts | 4 + .../warnings/only-warnings/package.json | 3 + .../fixtures/warnings/with-errors/index.d.ts | 6 + .../fixtures/warnings/with-errors/index.js | 3 + .../warnings/with-errors/index.test-d.ts | 5 + .../warnings/with-errors/package.json | 3 + source/test/identicality.ts | 38 +- source/test/informational.ts | 44 +- source/test/test.ts | 406 +++++------------- tsconfig.tsd.json | 10 +- 26 files changed, 600 insertions(+), 638 deletions(-) create mode 100644 source/test/_utils.ts delete mode 100644 source/test/fixtures/utils.ts create mode 100644 source/test/fixtures/warnings/only-warnings/index.d.ts create mode 100644 source/test/fixtures/warnings/only-warnings/index.js create mode 100644 source/test/fixtures/warnings/only-warnings/index.test-d.ts create mode 100644 source/test/fixtures/warnings/only-warnings/package.json create mode 100644 source/test/fixtures/warnings/with-errors/index.d.ts create mode 100644 source/test/fixtures/warnings/with-errors/index.js create mode 100644 source/test/fixtures/warnings/with-errors/index.test-d.ts create mode 100644 source/test/fixtures/warnings/with-errors/package.json diff --git a/package.json b/package.json index 16063c5c..52ca26cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tsd", - "version": "0.27.0", + "version": "0.28.1", "description": "Check TypeScript type definitions", "license": "MIT", "repository": "SamVerschueren/tsd", @@ -54,7 +54,9 @@ "del-cli": "^3.0.0", "execa": "^7.1.1", "react": "^16.9.0", + "resolve-from": "^5.0.0", "rxjs": "^6.5.3", + "ts-node": "^10.9.1", "tsx": "^3.12.6", "typescript": "~5.0.3", "xo": "^0.53.1" diff --git a/readme.md b/readme.md index 2e7962bc..5e94ff03 100644 --- a/readme.md +++ b/readme.md @@ -218,9 +218,12 @@ By default, `tsd` applies the following configuration: "dom.iterable" ], "module": "commonjs", - // The following option is set and is not overridable. - // It is set to `nodenext` if `module` is `nodenext`, `node16` if `module` is `node16` or `node` otherwise. - "moduleResolution": "node" | "node16" | "nodenext" + "esModuleInterop": true, + "noUnusedLocals": false, + // The following options are set and are not overridable. + // Set to `nodenext` if `module` is `nodenext`, `node16` if `module` is `node16` or `node` otherwise. + "moduleResolution": "node" | "node16" | "nodenext", + "skipLibCheck": false } ``` @@ -237,7 +240,7 @@ These options will be overridden if a `tsconfig.json` file is found in your proj } ``` -*Default options will apply if you don't override them explicitly.* You can't override the `moduleResolution` option. +*Default options will apply if you don't override them explicitly. You can't override the `moduleResolution` or `skipLibCheck` options.* ### Via the CLI diff --git a/source/cli.ts b/source/cli.ts index 850e2634..4a737bf4 100644 --- a/source/cli.ts +++ b/source/cli.ts @@ -1,7 +1,8 @@ #!/usr/bin/env node import process from 'node:process'; import meow from 'meow'; -import prettyFormatter from './lib/formatter.js'; +import {TsdError} from './lib/interfaces.js'; +import formatter from './lib/formatter.js'; import tsd from './lib/index.js'; const cli = meow(` @@ -46,24 +47,42 @@ const cli = meow(` }, }); +/** + * Displays a message and exits, conditionally erroring. + * + * @param message The message to display. + * @param isError Whether or not to fail on exit. + */ +const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => { + if (isError) { + console.error(message); + process.exit(1); + } else { + console.log(message); + process.exit(0); + } +}; + try { const cwd = cli.input.at(0) ?? process.cwd(); const {typings: typingsFile, files: testFiles, showDiff} = cli.flags; - const options = {cwd, typingsFile, testFiles}; - - const diagnostics = await tsd(options); + const diagnostics = await tsd({cwd, typingsFile, testFiles}); if (diagnostics.length > 0) { - throw new Error(prettyFormatter(diagnostics, showDiff)); + 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; - const errorMessage = potentialError?.stack ?? potentialError?.message; - if (errorMessage) { - console.error(`Error running tsd: ${errorMessage}`); + if (potentialError instanceof TsdError) { + exit(potentialError.message); } - process.exit(1); + const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.'; + + exit(`Error running tsd:\n${errorMessage}`); } diff --git a/source/lib/config.ts b/source/lib/config.ts index ccf61491..155823ea 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -44,6 +44,7 @@ const loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { module, target: ScriptTarget.ES2020, esModuleInterop: true, + noUnusedLocals: false, ...combinedCompilerOptions, moduleResolution: module === ModuleKind.NodeNext ? ModuleResolutionKind.NodeNext diff --git a/source/lib/formatter.ts b/source/lib/formatter.ts index 051e3d7d..3985b857 100644 --- a/source/lib/formatter.ts +++ b/source/lib/formatter.ts @@ -50,7 +50,12 @@ const formatter = (diagnostics: Diagnostic[], showDiff = false): string => { } } - entry.errorCount++; + if (diagnostic.severity === 'error') { + entry.errorCount++; + } else if (diagnostic.severity === 'warning') { + entry.warningCount++; + } + entry.messages.push(diagnostic); } diff --git a/source/lib/index.ts b/source/lib/index.ts index 59022ae6..3868ce55 100644 --- a/source/lib/index.ts +++ b/source/lib/index.ts @@ -6,7 +6,7 @@ import {globby} from 'globby'; import {getDiagnostics as getTSDiagnostics} from './compiler.js'; import loadConfig from './config.js'; import getCustomDiagnostics from './rules/index.js'; -import {type Context, type Config, type Diagnostic, type PackageJsonWithTsdConfig} from './interfaces.js'; +import {type Context, type Config, type Diagnostic, type PackageJsonWithTsdConfig, TsdError} from './interfaces.js'; export type Options = { cwd: string; @@ -27,7 +27,7 @@ const findTypingsFile = async (pkg: PackageJsonWithTsdConfig, options: Options): const typingsExist = await pathExists(typingsPath); if (!typingsExist) { - throw new Error(`The type definition \`${typings}\` does not exist at \`${typingsPath}\`. Is the path correct? Create one and try again.`); + throw new TsdError(`The type definition \`${typings}\` does not exist at \`${typingsPath}\`. Is the path correct? Create one and try again.`); } return typings; @@ -45,7 +45,7 @@ const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: str const testFiles = await globby(testFilesPattern, {cwd}); if (testFiles.length === 0) { - throw new Error('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). Create one and try again.'); } return testFiles.map(file => path.join(cwd, file)); @@ -67,7 +67,7 @@ const findTestFiles = async (typingsFilePath: string, options: Options & {config const testDirExists = await pathExists(path.join(options.cwd, testDir)); if (testFiles.length === 0 && !testDirExists) { - throw new Error(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`); + throw new TsdError(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`); } if (testFiles.length === 0) { @@ -87,7 +87,7 @@ const tsd = async (options: Options = {cwd: process.cwd()}): Promise { + 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[], + // eslint-disable-next-line unicorn/no-object-as-default-parameter + {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!'); +}; + +type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff' | 'verifyCli'; + +type ExpectationType = ( + Type extends 'verify' + ? Expectation[] + : Type extends 'verifyWithFileName' + ? ExpectationWithFileName[] + : Type extends 'verifyWithDiff' + ? ExpectationWithDiff[] + : string[] +); + +const _verifyTsd = (verifyType: Type) => ( + test.macro(async (t, fixtureName: string, expectations: ExpectationType) => { + const cwd = path.resolve('fixtures', fixtureName); + const diagnostics = await tsd({cwd}); + + switch (verifyType) { + case 'verify': { + verify(t, diagnostics, expectations as ExpectationType<'verify'>); + break; + } + + case 'verifyWithFileName': { + verifyWithFileName(t, cwd, diagnostics, expectations as ExpectationType<'verifyWithFileName'>); + break; + } + + case 'verifyWithDiff': { + verifyWithDiff(t, diagnostics, expectations as ExpectationType<'verifyWithDiff'>); + break; + } + + // Case 'verifyCli': { + // verifyCli(t, diagnostics, expectations as ExpectationType<'verifyCli'>); + // break; + // } + default: { + break; + } + } + }) +); + +export const verifyTsd = _verifyTsd('verify'); +export const verifyTsdWithFileNames = _verifyTsd('verifyWithFileName'); +export const verifyTsdWithDiff = _verifyTsd('verifyWithDiff'); +// Export const verifyCli = _verifyTsd('verifyCli'); + +export const noDiagnostics = test.macro(async (t, fixtureName: string) => { + const cwd = path.resolve('fixtures', fixtureName); + const diagnostics = await tsd({cwd}); + + verify(t, diagnostics, []); +}); diff --git a/source/test/assignability.ts b/source/test/assignability.ts index 7f8fff36..62a1c269 100644 --- a/source/test/assignability.ts +++ b/source/test/assignability.ts @@ -1,21 +1,11 @@ -import path from 'node:path'; import test from 'ava'; -import tsd from '../index.js'; -import {verify} from './fixtures/utils.js'; +import {verifyTsd} from './_utils.js'; -test('assignable', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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 35567020..1d4119c2 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -1,8 +1,10 @@ import path from 'node:path'; import test from 'ava'; -import {execa} from 'execa'; +import {execa, $} from 'execa'; import {readPackageUp} from 'read-pkg-up'; +import resolveFrom from 'resolve-from'; import tsd, {formatter} from '../index.js'; +import {verifyCli} from './_utils.js'; type ExecaError = { readonly exitCode: number; @@ -15,7 +17,11 @@ test('fail if errors are found', async t => { })); t.is(exitCode, 1); - t.regex(stderr, /5:19 {2}Argument of type number is not assignable to parameter of type string./); + 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 => { @@ -32,7 +38,11 @@ test('provide a path', async t => { const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file])); t.is(exitCode, 1); - t.regex(stderr, /5:19 {2}Argument of type number is not assignable to parameter of type string./); + 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 => { @@ -42,7 +52,7 @@ test('cli help flag', async t => { }); test('cli version flag', async t => { - const pkg = await readPackageUp({normalize: false})?.packageJson ?? {}; + const {packageJson: pkg} = await readPackageUp() ?? {packageJson: {}}; const {exitCode, stdout} = await execa('dist/cli.js', ['--version']); @@ -57,7 +67,11 @@ test('cli typings flag', async t => { })); t.is(exitCode, 1); - t.true(stderr.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + verifyCli(t, stderr, [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', + ]); }; await runTest('--typings'); @@ -71,7 +85,11 @@ test('cli files flag', async t => { })); t.is(exitCode, 1); - t.true(stderr.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + verifyCli(t, stderr, [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', + ]); }; await runTest('--files'); @@ -84,27 +102,43 @@ test('cli files flag array', async t => { })); t.is(exitCode, 1); - t.true(stderr.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + 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}`)); + const {exitCode, stderr} = await t.throwsAsync($`dist/cli.js -t ${typingsFile} -f ${testFile}`); t.is(exitCode, 1); - t.true(stderr.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + 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, stack} = await t.throwsAsync(execa('../../../cli.js', { + const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', { cwd: path.resolve('fixtures/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); - t.true(stderr.includes('Error running tsd: JSONError: Unexpected end of JSON input while parsing empty string')); - t.truthy(stack); + verifyCli(t, stderr, [ + '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}); }); test('exported formatter matches cli results', async t => { @@ -114,10 +148,55 @@ test('exported formatter matches cli results', async t => { const {stderr: cliResults} = await t.throwsAsync(execa('../../../cli.js', options)); - t.true(cliResults.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + verifyCli(t, cliResults, [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', + ]); const tsdResults = await tsd(options); const formattedResults = formatter(tsdResults); - t.true(formattedResults.includes('✖ 5:19 Argument of type number is not assignable to parameter of type string.')); + 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.resolve('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.resolve('fixtures/warnings/with-errors'), + })); + + t.is(exitCode, 1); + verifyCli(t, stderr, [ + '✖ 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.resolve('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.`); }); diff --git a/source/test/deprecated.ts b/source/test/deprecated.ts index 24d2a1ad..a052f19b 100644 --- a/source/test/deprecated.ts +++ b/source/test/deprecated.ts @@ -1,26 +1,16 @@ -import path from 'node:path'; import test from 'ava'; -import tsd from '../index.js'; -import {verify} from './fixtures/utils.js'; +import {verifyTsd} from './_utils.js'; -test('deprecated', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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 af8b90a7..96367fca 100644 --- a/source/test/diff.ts +++ b/source/test/diff.ts @@ -1,39 +1,34 @@ import path from 'node:path'; import {execa, type ExecaError} from 'execa'; import test from 'ava'; -import tsd from '../index.js'; -import {verifyWithDiff} from './fixtures/utils.js'; +import {verifyTsdWithDiff, verifyCli} from './_utils.js'; -test('diff', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/diff')}); - - 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', 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.', + }], +]); test('diff cli', async t => { const file = path.resolve('fixtures/diff'); @@ -41,8 +36,7 @@ test('diff cli', async t => { const {exitCode, stderr} = await t.throwsAsync(execa('tsx ../cli.js', [file, '--show-diff'])); t.is(exitCode, 1); - - const expectedLines = [ + verifyCli(t, stderr, [ '✖ 8:0 Parameter type { life?: number | undefined; } is declared too wide for argument type { life: number; }.', '', '- { life?: number | undefined; }', @@ -69,13 +63,5 @@ test('diff cli', async t => { '+ This is a comment.', '', '6 errors', - ]; - - // NOTE: If lines are added to the output in the future startLine and endLine should be adjusted. - const startLine = 2; // Skip tsd error message and file location. - const endLine = startLine + expectedLines.length; // Grab diff output only and skip stack trace. - - const receivedLines = stderr.trim().split('\n').slice(startLine, endLine).map(line => line.trim()); - - t.deepEqual(receivedLines, expectedLines); + ]); }); diff --git a/source/test/expect-error.ts b/source/test/expect-error.ts index 758ef302..3e14ee21 100644 --- a/source/test/expect-error.ts +++ b/source/test/expect-error.ts @@ -1,63 +1,29 @@ -import path from 'node:path'; import test from 'ava'; -import tsd from '../index.js'; -import {verify} from './fixtures/utils.js'; +import {verifyTsd, noDiagnostics} from './_utils.js'; -test('expectError for classes', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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.resolve('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.resolve('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 values', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/expect-error/values')}); - - 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.resolve('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.resolve('fixtures/expect-error/enabled-exact-optional-property-types')}); - - verify(t, diagnostics, []); -}); - -test('expectError should report missing diagnostic codes', async t => { - const diagnostics = await tsd({cwd: path.resolve('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/utils.ts b/source/test/fixtures/utils.ts deleted file mode 100644 index e1a3c536..00000000 --- a/source/test/fixtures/utils.ts +++ /dev/null @@ -1,119 +0,0 @@ -import path from 'path'; -import {ExecutionContext} from 'ava'; -import type {Diagnostic} from '../../lib/interfaces.js'; - -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!'); -}; diff --git a/source/test/fixtures/warnings/only-warnings/index.d.ts b/source/test/fixtures/warnings/only-warnings/index.d.ts new file mode 100644 index 00000000..0616ebaa --- /dev/null +++ b/source/test/fixtures/warnings/only-warnings/index.d.ts @@ -0,0 +1,6 @@ +declare const one: { + (foo: string, bar: string): string; + (foo: number, bar: number): number; +}; + +export default one; diff --git a/source/test/fixtures/warnings/only-warnings/index.js b/source/test/fixtures/warnings/only-warnings/index.js new file mode 100644 index 00000000..f17717f5 --- /dev/null +++ b/source/test/fixtures/warnings/only-warnings/index.js @@ -0,0 +1,3 @@ +module.exports.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 new file mode 100644 index 00000000..51347575 --- /dev/null +++ b/source/test/fixtures/warnings/only-warnings/index.test-d.ts @@ -0,0 +1,4 @@ +import {printType} from '../../../..'; +import one from '.'; + +printType(one(1, 1)); diff --git a/source/test/fixtures/warnings/only-warnings/package.json b/source/test/fixtures/warnings/only-warnings/package.json new file mode 100644 index 00000000..de6dc1db --- /dev/null +++ b/source/test/fixtures/warnings/only-warnings/package.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} diff --git a/source/test/fixtures/warnings/with-errors/index.d.ts b/source/test/fixtures/warnings/with-errors/index.d.ts new file mode 100644 index 00000000..0616ebaa --- /dev/null +++ b/source/test/fixtures/warnings/with-errors/index.d.ts @@ -0,0 +1,6 @@ +declare const one: { + (foo: string, bar: string): string; + (foo: number, bar: number): number; +}; + +export default one; diff --git a/source/test/fixtures/warnings/with-errors/index.js b/source/test/fixtures/warnings/with-errors/index.js new file mode 100644 index 00000000..f17717f5 --- /dev/null +++ b/source/test/fixtures/warnings/with-errors/index.js @@ -0,0 +1,3 @@ +module.exports.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 new file mode 100644 index 00000000..65ccce61 --- /dev/null +++ b/source/test/fixtures/warnings/with-errors/index.test-d.ts @@ -0,0 +1,5 @@ +import {printType, expectType} from '../../../..'; +import one from '.'; + +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 new file mode 100644 index 00000000..de6dc1db --- /dev/null +++ b/source/test/fixtures/warnings/with-errors/package.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} diff --git a/source/test/identicality.ts b/source/test/identicality.ts index afde12cc..ad7d262d 100644 --- a/source/test/identicality.ts +++ b/source/test/identicality.ts @@ -1,27 +1,17 @@ -import path from 'node:path'; import test from 'ava'; -import tsd from '../index.js'; -import {verify} from './fixtures/utils.js'; +import {verifyTsd} from './_utils.js'; -test('identical', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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 dbffeaae..23a1bc52 100644 --- a/source/test/informational.ts +++ b/source/test/informational.ts @@ -1,30 +1,20 @@ -import path from 'node:path'; import test from 'ava'; -import tsd from '../index.js'; -import {verify} from './fixtures/utils.js'; +import {verifyTsd} from './_utils.js'; -test('print type', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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 3ae4ed26..f3d1cb4a 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -1,313 +1,148 @@ import path from 'node:path'; import test from 'ava'; import tsd from '../index.js'; -import type {Diagnostic} from '../lib/interfaces.js'; -import {verify, verifyWithFileName} from './fixtures/utils.js'; +import {type Diagnostic, TsdError} from '../lib/interfaces.js'; +import { + verify, + verifyTsd, + verifyTsdWithFileNames, + noDiagnostics, +} from './_utils.js'; test('throw if no type definition was found', async t => { const cwd = path.resolve('fixtures/no-tsd'); const index = path.join(cwd, 'index.d.ts'); - 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.`}); + 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.resolve('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.resolve('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.resolve('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.resolve('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.resolve('fixtures/files-folder')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying negative gitignore-style patterns in `files` list', async t => { - const diagnostics = await tsd({cwd: path.resolve('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.resolve('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.resolve('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.resolve('fixtures/files-glob')}); - - verify(t, diagnostics, []); -}); - -test('fail if `typings` property is used instead of `types`', async t => { - const cwd = path.resolve('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('fail if tests don\'t pass in strict mode', async t => { - const cwd = path.resolve('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('overridden config defaults to `strict` if `strict` is not explicitly overridden', async t => { - const cwd = path.resolve('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('fail if types are used from a lib that was not explicitly specified', async t => { - const cwd = path.resolve('fixtures/lib-config/failure-missing-lib'); - const diagnostics = await tsd({cwd}); - - 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('allow specifying a lib as a triple-slash-reference', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-as-triple-slash-reference')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying a lib in package.json\'s `tsd` field', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-from-package-json')}); - - verify(t, diagnostics, []); -}); - -test('allow specifying a lib in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-from-tsconfig-json')}); - - verify(t, diagnostics, []); -}); - -test('use moduleResolution `nodenext` when module is `nodenext` in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/nodenext-from-tsconfig-json')}); - - verify(t, diagnostics, []); -}); - -test('use moduleResolution `nodenext` when module is `nodenext` in package.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/nodenext-from-package-json')}); - - verify(t, diagnostics, []); -}); - -test('use moduleResolution `node16` when module is `node16` in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/node16-from-tsconfig-json')}); - - verify(t, diagnostics, []); -}); - -test('use moduleResolution `node16` when module is `node16` in package.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/module-resolution/node16-from-package-json')}); - - verify(t, diagnostics, []); + 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('add support for esm with esModuleInterop', async t => { - const diagnostics = await tsd({ - cwd: path.resolve('fixtures/esm'), - }); +test('return diagnostics', verifyTsd, 'failure', [ + [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], +]); - verify(t, diagnostics, []); -}); +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('add DOM support by default', async t => { - const diagnostics = await tsd({ - cwd: path.resolve('fixtures/dom'), - }); +test('fail if typings file is not part of `files` list', verifyTsdWithFileNames, 'no-files', [ + [3, 1, 'error', 'TypeScript type definition `index.d.ts` is not part of the `files` list.', 'package.json'], +]); - verify(t, diagnostics, []); -}); +test('allow specifying folders containing typings file in `files` list', noDiagnostics, 'files-folder'); -test('a lib option in package.json overrdides a lib option in tsconfig.json', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/lib-config/lib-from-package-json-overrides-tsconfig-json')}); +test('allow specifying negative gitignore-style patterns in `files` list', verifyTsd, 'files-gitignore-patterns/negative-pattern', [ + [3, 1, 'error', 'TypeScript type definition `index.d.ts` is not part of the `files` list.'], +]); - verify(t, diagnostics, []); -}); +test('allow specifying negated negative (positive) gitignore-style patterns in `files` list', noDiagnostics, 'files-gitignore-patterns/negative-pattern-negated'); -test('pass in loose mode when strict mode is disabled in settings', async t => { - const diagnostics = await tsd({ - cwd: path.resolve('fixtures/non-strict-check-with-config'), - }); +test('allow specifying root marker (/) gitignore-style patterns in `files` list', noDiagnostics, 'files-gitignore-patterns/root-marker-pattern'); - verify(t, diagnostics, []); -}); +test('allow specifying glob patterns containing typings file in `files` list', noDiagnostics, 'files-glob'); -test('return no diagnostics', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/success')}); +test('fail if `typings` property is used instead of `types`', verifyTsdWithFileNames, 'types-property/typings', [ + [3, 1, 'error', 'Use property `types` instead of `typings`.', 'package.json'], +]); - verify(t, diagnostics, []); -}); +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'], +]); -test('support non-barrel main', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/test-non-barrel-main')}); +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'], +]); - verify(t, diagnostics, []); -}); +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'], +]); -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.resolve('fixtures/no-explicit-types-property/without-main')}); +test('allow specifying a lib as a triple-slash-reference', noDiagnostics, 'lib-config/lib-as-triple-slash-reference'); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'], - ]); -}); +test('allow specifying a lib in package.json\'s `tsd` field', noDiagnostics, 'lib-config/lib-from-package-json'); -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.resolve('fixtures/no-explicit-types-property/with-main-barrel')}); +test('allow specifying a lib in tsconfig.json', noDiagnostics, 'lib-config/lib-from-tsconfig-json'); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'], - ]); -}); +test('use moduleResolution `nodenext` when module is `nodenext` in tsconfig.json', noDiagnostics, 'module-resolution/nodenext-from-tsconfig-json'); -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.resolve('fixtures/no-explicit-types-property/with-main-other')}); +test('use moduleResolution `nodenext` when module is `nodenext` in package.json', noDiagnostics, 'module-resolution/nodenext-from-package-json'); - verify(t, diagnostics, [ - [6, 0, 'error', 'Expected an error, but found none.'], - ]); -}); +test('use moduleResolution `node16` when module is `node16` in tsconfig.json', noDiagnostics, 'module-resolution/node16-from-tsconfig-json'); -test('support testing in sub-directories', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/test-in-subdir')}); +test('use moduleResolution `node16` when module is `node16` in package.json', noDiagnostics, 'module-resolution/node16-from-package-json'); - verify(t, diagnostics, []); -}); +test('add support for esm with esModuleInterop', noDiagnostics, 'esm'); -test('support top-level await', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/top-level-await')}); +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('support default test directory', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/test-directory/default')}); +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('support tsx in subdirectory', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/test-directory/tsx')}); +test('support non-barrel main', noDiagnostics, 'test-non-barrel-main'); - verify(t, diagnostics, []); -}); +test('allow omitting `types` property when `main` property is missing but main is a barrel (`index.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/without-main', [ + [6, 0, 'error', 'Expected an error, but found none.'], +]); -test('support setting a custom test directory', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/test-directory/custom')}); +test('allow omitting `types` property when `main` property is set to a barrel (`index.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/with-main-barrel', [ + [6, 0, 'error', 'Expected an error, but found none.'], +]); - verify(t, diagnostics, [ - [4, 0, 'error', 'Expected an error, but found none.'], - ]); -}); +test('allow omitting `types` property when `main` property is set to non-barrel (`foo.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/with-main-other', [ + [6, 0, 'error', 'Expected an error, but found none.'], +]); -test('missing import', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/missing-import')}); +test('support testing in sub-directories', noDiagnostics, 'test-in-subdir'); - verify(t, diagnostics, [ - [3, 18, 'error', 'Cannot find name \'Primitive\'.'], - ]); -}); +test('support top-level await', noDiagnostics, 'top-level-await'); -test('tsx component', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/tsx/component')}); +test('support default test directory', noDiagnostics, 'test-directory/default'); - verify(t, diagnostics, []); -}); +test('support tsx in subdirectory', noDiagnostics, 'test-directory/tsx'); -test('tsx component type', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/tsx/component-type')}); +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('loose types', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/strict-types/loose')}); +test('tsx component', noDiagnostics, 'tsx/component'); - 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('tsx component type', noDiagnostics, 'tsc/component-type'); -test('strict types', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/strict-types/strict')}); +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`.'], +]); - verify(t, diagnostics, []); -}); +test('strict types', noDiagnostics, 'strict-types/strict'); test('typings in custom directory', async t => { const diagnostics = await tsd({ @@ -337,19 +172,15 @@ test('specify test files manually', async t => { test('fails if typings file is not found in the specified path', async t => { const cwd = path.resolve('fixtures/typings-custom-dir'); - await t.throwsAsync(tsd({ - cwd, - typingsFile: 'unknown.d.ts', - }), {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.`}); + await t.throwsAsync( + tsd({cwd, typingsFile: 'unknown.d.ts'}), + {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.resolve('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.resolve('fixtures/exclude-node-modules')}); @@ -397,32 +228,23 @@ test('errors in libs from node_modules are not reported', async t => { ]); }); -test('allow specifying `rootDir` option in `tsconfig.json`', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/root-dir')}); +test('allow specifying `rootDir` option in `tsconfig.json`', noDiagnostics, 'root-dir'); - verify(t, diagnostics, []); -}); +test('assertions should be identified if imported as an aliased module', noDiagnostics, 'aliased/aliased-module'); -test('assertions should be identified if imported as an aliased module', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-module')}); +test('assertions should be identified if imported as an alias', noDiagnostics, 'aliased/aliased-assertion'); - verify(t, diagnostics, []); -}); - -test('assertions should be identified if imported as an alias', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-assertion')}); - - verify(t, diagnostics, []); -}); +test('assertions should be identified if aliased', noDiagnostics, 'aliased/aliased-const'); -test('assertions should be identified if aliased', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/aliased/aliased-const')}); +test('parsing undefined symbol should not fail', noDiagnostics, 'undefined-symbol'); - verify(t, diagnostics, []); -}); - -test('parsing undefined symbol should not fail', async t => { - const diagnostics = await tsd({cwd: path.resolve('fixtures/undefined-symbol')}); +test('custom tsd errors are created correctly', t => { + const tsdError = t.throws(() => { + throw new TsdError('foo'); + }); - verify(t, diagnostics, []); + t.true(tsdError instanceof Error); + t.true(tsdError instanceof TsdError); + t.is(tsdError?.name, 'TsdError'); + t.is(tsdError?.message, 'foo'); }); diff --git a/tsconfig.tsd.json b/tsconfig.tsd.json index a230cea9..e42a74e0 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -1,12 +1,14 @@ { "compilerOptions": { "outDir": "dist", - "target": "ES2020", // Node.js 14 + "target": "ES2021", // Node.js 16 "lib": [ - "ES2020" + "ES2021" ], - "module": "node16", - "moduleResolution": "node16", + // "module": "node16", + // "moduleResolution": "node16", + "module": "ES2020", + "moduleResolution": "node", "declaration": true, "pretty": true, "newLine": "lf", From 8d4559baf58f5e4636dfd776dd191dec583fb8f0 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 4 Apr 2023 19:26:49 -0500 Subject: [PATCH 07/18] tests(`cli`): add macros --- source/test/_utils.ts | 37 +++++--- source/test/cli.ts | 205 +++++++++++++++--------------------------- source/test/diff.ts | 67 ++++++-------- 3 files changed, 127 insertions(+), 182 deletions(-) diff --git a/source/test/_utils.ts b/source/test/_utils.ts index afb92b54..9c85ba8c 100644 --- a/source/test/_utils.ts +++ b/source/test/_utils.ts @@ -1,8 +1,11 @@ import path from 'node:path'; import test, {type ExecutionContext} from 'ava'; +import {type ExecaError, execa} from 'execa'; import tsd from '../index.js'; import type {Diagnostic} from '../lib/interfaces.js'; +export const binPath = path.resolve('../cli.js'); + type Expectation = [ line: number, column: number, @@ -119,6 +122,10 @@ export const verifyWithDiff = ( t.deepEqual(diagnosticObjs, expectationObjs, 'Received diagnostics that are different from expectations!'); }; +type VerifyCliOptions = { + startLine: number; +}; + /** * Verify a list of diagnostics reported from the CLI. * @@ -132,28 +139,28 @@ export const verifyCli = ( diagnostics: string, expectedLines: string[], // eslint-disable-next-line unicorn/no-object-as-default-parameter - {startLine}: {startLine: number} = {startLine: 1}, // Skip file location. + {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!'); }; -type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff' | 'verifyCli'; +export const getFixture = (fixtureName: string) => path.resolve('fixtures', fixtureName); + +type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff'; type ExpectationType = ( Type extends 'verify' ? Expectation[] : Type extends 'verifyWithFileName' ? ExpectationWithFileName[] - : Type extends 'verifyWithDiff' - ? ExpectationWithDiff[] - : string[] + : ExpectationWithDiff[] ); const _verifyTsd = (verifyType: Type) => ( test.macro(async (t, fixtureName: string, expectations: ExpectationType) => { - const cwd = path.resolve('fixtures', fixtureName); + const cwd = getFixture(fixtureName); const diagnostics = await tsd({cwd}); switch (verifyType) { @@ -172,10 +179,6 @@ const _verifyTsd = (verifyType: Type) => ( break; } - // Case 'verifyCli': { - // verifyCli(t, diagnostics, expectations as ExpectationType<'verifyCli'>); - // break; - // } default: { break; } @@ -186,7 +189,6 @@ const _verifyTsd = (verifyType: Type) => ( export const verifyTsd = _verifyTsd('verify'); export const verifyTsdWithFileNames = _verifyTsd('verifyWithFileName'); export const verifyTsdWithDiff = _verifyTsd('verifyWithDiff'); -// Export const verifyCli = _verifyTsd('verifyCli'); export const noDiagnostics = test.macro(async (t, fixtureName: string) => { const cwd = path.resolve('fixtures', fixtureName); @@ -194,3 +196,16 @@ export const noDiagnostics = test.macro(async (t, fixtureName: string) => { verify(t, diagnostics, []); }); + +const _verifyCli = (shouldPass: boolean) => test.macro(async (t, fixtureName: string, args: string[], expectedLines: string[], options?: VerifyCliOptions) => { + const cwd = getFixture(fixtureName); + const result = shouldPass + ? await execa(binPath, args, {cwd}) + : await t.throwsAsync(execa(binPath, args, {cwd})); + + verifyCli(t, result?.stdout ?? result?.stderr ?? '', expectedLines, options); + t.is(result?.exitCode, shouldPass ? 0 : 1, 'CLI exited with the wrong exit code!'); +}); + +export const verifyCliPasses = _verifyCli(true); +export const verifyCliFails = _verifyCli(false); diff --git a/source/test/cli.ts b/source/test/cli.ts index 1d4119c2..f01a631e 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -1,41 +1,27 @@ import path from 'node:path'; import test from 'ava'; -import {execa, $} from 'execa'; +import {execa, type ExecaError} from 'execa'; import {readPackageUp} from 'read-pkg-up'; import resolveFrom from 'resolve-from'; import tsd, {formatter} from '../index.js'; -import {verifyCli} from './_utils.js'; - -type ExecaError = { - readonly exitCode: number; - readonly stderr: string; -} & Error; - -test('fail if errors are found', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', { - cwd: path.resolve('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.resolve('fixtures/success'), - }); - - t.is(exitCode, 0); -}); +import { + binPath, + getFixture, + verifyCli, + verifyCliPasses, + verifyCliFails, +} from './_utils.js'; + +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', async t => { - const file = path.resolve('fixtures/failure'); - - const {exitCode, stderr} = await t.throwsAsync(execa('dist/cli.js', [file])); + const {exitCode, stderr} = await t.throwsAsync(execa(binPath, [getFixture('failure')])); t.is(exitCode, 1); verifyCli(t, stderr, [ @@ -45,88 +31,58 @@ test('provide a path', async t => { ]); }); -test('cli help flag', async t => { - const {exitCode} = await execa('dist/cli.js', ['--help']); +test('cli help flag: --help', async t => { + const {exitCode} = await execa(binPath, ['--help']); t.is(exitCode, 0); }); -test('cli version flag', async t => { +test('cli version flag: --version', async t => { const {packageJson: pkg} = await readPackageUp() ?? {packageJson: {}}; - - const {exitCode, stdout} = await execa('dist/cli.js', ['--version']); + const {exitCode, stdout} = await execa(binPath, ['--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.resolve('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.resolve('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.resolve('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} = await t.throwsAsync($`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('cli typings flag: --typings', verifyCliFails, 'typings-custom-dir', ['--typings', 'utils/index.d.ts'], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +test('cli typings flag: -t', verifyCliFails, 'typings-custom-dir', ['-t', 'utils/index.d.ts'], [ + '✖ 5:19 Argument of type number is not assignable to parameter of type string.', + '', + '1 error', +]); + +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('cli typings and files flags', verifyCliFails, 'typings-custom-dir', ['-t', 'utils/index.d.ts', '-f', 'index.test-d.ts'], [ + '✖ 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.resolve('fixtures/empty-package-json'), - })); + const {exitCode, stderr} = await t.throwsAsync(execa(binPath, {cwd: getFixture('empty-package-json')})); const nodeModulesPath = path.resolve('node_modules'); const parseJsonPath = resolveFrom.silent(`${nodeModulesPath}/read-pkg`, 'parse-json') ?? `${nodeModulesPath}/index.js`; @@ -142,11 +98,8 @@ test('tsd logs stacktrace on failure', async t => { }); test('exported formatter matches cli results', async t => { - const options = { - cwd: path.resolve('fixtures/failure'), - }; - - const {stderr: cliResults} = await t.throwsAsync(execa('../../../cli.js', options)); + const options = {cwd: getFixture('failure')}; + const {stderr: cliResults} = await t.throwsAsync(execa(binPath, options)); verifyCli(t, cliResults, [ '✖ 5:19 Argument of type number is not assignable to parameter of type string.', @@ -164,38 +117,24 @@ test('exported formatter matches cli results', async t => { ]); }); -test('warnings are reported correctly and do not fail', async t => { - const {exitCode, stdout} = await execa('../../../../cli.js', { - cwd: path.resolve('fixtures/warnings/only-warnings'), - }); +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', +]); - 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.resolve('fixtures/warnings/with-errors'), - })); - - t.is(exitCode, 1); - verifyCli(t, stderr, [ - '✖ 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('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', async t => { const cwd = path.resolve('fixtures/no-tsd'); - const {exitCode, stderr} = await t.throwsAsync(execa('../../../cli.js', {cwd})); + const {exitCode, stderr} = await t.throwsAsync(execa(binPath, {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.`); diff --git a/source/test/diff.ts b/source/test/diff.ts index 96367fca..b3dab628 100644 --- a/source/test/diff.ts +++ b/source/test/diff.ts @@ -1,7 +1,5 @@ -import path from 'node:path'; -import {execa, type ExecaError} from 'execa'; import test from 'ava'; -import {verifyTsdWithDiff, verifyCli} from './_utils.js'; +import {verifyTsdWithDiff, verifyCliFails} from './_utils.js'; test('diff', verifyTsdWithDiff, 'diff', [ [8, 0, 'error', 'Parameter type `{ life?: number | undefined; }` is declared too wide for argument type `{ life: number; }`.', { @@ -30,38 +28,31 @@ test('diff', verifyTsdWithDiff, 'diff', [ }], ]); -test('diff cli', async t => { - const file = path.resolve('fixtures/diff'); - - const {exitCode, stderr} = await t.throwsAsync(execa('tsx ../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', +]); From 59105638adc606f40b974f0fd8048245ba442b3f Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 4 Apr 2023 20:43:41 -0500 Subject: [PATCH 08/18] refactor: update `@tsd/typescript` imports for ESM --- package.json | 6 ++- .../lib/assertions/handlers/identicality.ts | 4 +- .../lib/assertions/handlers/informational.ts | 8 ++-- source/lib/compiler.ts | 10 ++--- source/lib/config.ts | 41 +++++++------------ source/lib/interfaces.ts | 4 +- source/lib/parser.ts | 18 +++----- source/lib/rules/files-property.ts | 2 +- source/lib/utils/make-diagnostic-with-diff.ts | 24 +++++------ source/lib/utils/make-diagnostic.ts | 4 +- source/lib/utils/typescript.ts | 4 +- tsconfig.tsd.json | 6 +-- 12 files changed, 55 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index 52ca26cf..a8a3ab2e 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "react": "^16.9.0", "resolve-from": "^5.0.0", "rxjs": "^6.5.3", - "ts-node": "^10.9.1", "tsx": "^3.12.6", "typescript": "~5.0.3", "xo": "^0.53.1" @@ -72,7 +71,10 @@ }, "nodeArguments": [ "--loader=tsx" - ] + ], + "environmentVariables": { + "ESBK_TSCONFIG_PATH": "tsconfig.tsd.json" + } }, "xo": { "ignores": [ diff --git a/source/lib/assertions/handlers/identicality.ts b/source/lib/assertions/handlers/identicality.ts index 804f6b11..4fb07118 100644 --- a/source/lib/assertions/handlers/identicality.ts +++ b/source/lib/assertions/handlers/identicality.ts @@ -1,4 +1,4 @@ -import {type CallExpression, type TypeChecker, TypeFlags} from '@tsd/typescript'; +import ts, {type CallExpression, type TypeChecker} from '@tsd/typescript'; import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnostic, makeDiagnosticWithDiff} from '../../utils/index.js'; @@ -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/informational.ts b/source/lib/assertions/handlers/informational.ts index e8ed0698..72485d8f 100644 --- a/source/lib/assertions/handlers/informational.ts +++ b/source/lib/assertions/handlers/informational.ts @@ -1,4 +1,4 @@ -import {type CallExpression, type TypeChecker, TypeFormatFlags} from '@tsd/typescript'; +import ts, {type CallExpression, type TypeChecker} from '@tsd/typescript'; import type {Diagnostic} from '../../interfaces.js'; import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils/index.js'; @@ -8,9 +8,9 @@ import {makeDiagnostic, makeDiagnosticWithDiff, tsutils} from '../../utils/index * @see {@link https://github.dev/microsoft/TypeScript/blob/b975dfa1027d1f3073fa7cbe6f7045bf4c882785/src/compiler/checker.ts#L4717 TypeChecker.typeToString} */ const typeToStringFormatFlags - = TypeFormatFlags.AllowUniqueESSymbolType - | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope - | TypeFormatFlags.NoTruncation; + = 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/compiler.ts b/source/lib/compiler.ts index 497949f3..79f88a54 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,8 +1,4 @@ -import { - flattenDiagnosticMessageText, - createProgram, - type Diagnostic as TSDiagnostic, -} from '@tsd/typescript'; +import ts, {type Diagnostic as TSDiagnostic} from '@tsd/typescript'; import {type ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; import {type Diagnostic, DiagnosticCode, type Context, type Location} from './interfaces.js'; import {handle} from './assertions/index.js'; @@ -100,7 +96,7 @@ 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(), @@ -136,7 +132,7 @@ export const getDiagnostics = (context: Context): Diagnostic[] => { 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, diff --git a/source/lib/config.ts b/source/lib/config.ts index 155823ea..2f549769 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -1,15 +1,4 @@ -import { - type CompilerOptions, - JsxEmit, - ScriptTarget, - ModuleResolutionKind, - parseJsonConfigFileContent, - findConfigFile, - sys, - readJsonConfigFile, - parseJsonSourceFileConfigFileContent, - ModuleKind, -} from '@tsd/typescript'; +import ts, {type CompilerOptions} from '@tsd/typescript'; import type {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; /** @@ -32,25 +21,25 @@ const loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { ...packageJsonCompilerOptions, }; - const module = combinedCompilerOptions.module ?? ModuleKind.CommonJS; + const module = combinedCompilerOptions.module ?? ts.ModuleKind.CommonJS; return { directory: 'test-d', ...pkgConfig, compilerOptions: { strict: true, - jsx: JsxEmit.React, + jsx: ts.JsxEmit.React, lib: parseRawLibs(['es2020', '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), + moduleResolution: module === ts.ModuleKind.NodeNext + ? ts.ModuleResolutionKind.NodeNext + : (module === ts.ModuleKind.Node16 + ? ts.ModuleResolutionKind.Node16 + : ts.ModuleResolutionKind.Node10), skipLibCheck: false, }, }; @@ -59,15 +48,15 @@ const loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { 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, @@ -75,9 +64,9 @@ function getOptionsFromTsConfig(cwd: string): CompilerOptions { } function parseCompilerConfigObject(compilerOptions: RawCompilerOptions, cwd: string): CompilerOptions { - return parseJsonConfigFileContent( + return ts.parseJsonConfigFileContent( {compilerOptions: compilerOptions || {}}, - sys, + ts.sys, cwd, ).options; } diff --git a/source/lib/interfaces.ts b/source/lib/interfaces.ts index 6a5de867..54b64625 100644 --- a/source/lib/interfaces.ts +++ b/source/lib/interfaces.ts @@ -1,5 +1,5 @@ -import {type CompilerOptions} from '@tsd/typescript'; -import {type NormalizedPackageJson} from 'read-pkg-up'; +import type {CompilerOptions} from '@tsd/typescript'; +import type {NormalizedPackageJson} from 'read-pkg-up'; export type RawCompilerOptions = Record; diff --git a/source/lib/parser.ts b/source/lib/parser.ts index 19b85293..3bca5464 100644 --- a/source/lib/parser.ts +++ b/source/lib/parser.ts @@ -1,12 +1,4 @@ -import { - type Program, - type Node, - type CallExpression, - forEachChild, - isCallExpression, - isPropertyAccessExpression, - SymbolFlags, -} from '@tsd/typescript'; +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'; @@ -25,7 +17,7 @@ export const extractAssertions = (program: Program): Map(resolve: R) => { type ConditionalResolveReturn = (R extends 'JSDoc' ? Map : string) | undefined; diff --git a/tsconfig.tsd.json b/tsconfig.tsd.json index e42a74e0..2be3eb85 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -5,10 +5,8 @@ "lib": [ "ES2021" ], - // "module": "node16", - // "moduleResolution": "node16", - "module": "ES2020", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "declaration": true, "pretty": true, "newLine": "lf", From 3d54b5702305fde4bed78cd0b961a6f60633ad06 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Tue, 4 Apr 2023 21:38:29 -0500 Subject: [PATCH 09/18] tests: add more macros --- source/test/_utils.ts | 61 +++++++++++++++++++++++++++++++---------- source/test/cli.ts | 63 +++++++++++++++--------------------------- source/test/test.ts | 64 +++++++++++++------------------------------ 3 files changed, 88 insertions(+), 100 deletions(-) diff --git a/source/test/_utils.ts b/source/test/_utils.ts index 9c85ba8c..3731372b 100644 --- a/source/test/_utils.ts +++ b/source/test/_utils.ts @@ -1,7 +1,8 @@ +import process from 'node:process'; import path from 'node:path'; import test, {type ExecutionContext} from 'ava'; import {type ExecaError, execa} from 'execa'; -import tsd from '../index.js'; +import tsd, {type Options} from '../lib/index.js'; import type {Diagnostic} from '../lib/interfaces.js'; export const binPath = path.resolve('../cli.js'); @@ -146,7 +147,9 @@ export const verifyCli = ( t.deepEqual(receivedLines, expectedLines, 'Received diagnostics that are different from expectations!'); }; -export const getFixture = (fixtureName: string) => path.resolve('fixtures', fixtureName); +export const getFixture = (fixtureName: string) => fixtureName.length > 0 + ? path.resolve('fixtures', fixtureName) + : process.cwd(); type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff'; @@ -158,10 +161,27 @@ type ExpectationType = ( : 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, fixtureName: string, expectations: ExpectationType) => { - const cwd = getFixture(fixtureName); - const diagnostics = await tsd({cwd}); + test.macro(async (t, options: FixtureName | VerifyTsdOptions, expectations: ExpectationType) => { + const {cwd, tsdOptions} = parseOptions(options); + const diagnostics = await tsd({cwd, ...tsdOptions}); switch (verifyType) { case 'verify': { @@ -191,21 +211,34 @@ export const verifyTsdWithFileNames = _verifyTsd('verifyWithFileName'); export const verifyTsdWithDiff = _verifyTsd('verifyWithDiff'); export const noDiagnostics = test.macro(async (t, fixtureName: string) => { - const cwd = path.resolve('fixtures', fixtureName); + const cwd = getFixture(fixtureName); const diagnostics = await tsd({cwd}); verify(t, diagnostics, []); }); -const _verifyCli = (shouldPass: boolean) => test.macro(async (t, fixtureName: string, args: string[], expectedLines: string[], options?: VerifyCliOptions) => { - const cwd = getFixture(fixtureName); - const result = shouldPass - ? await execa(binPath, args, {cwd}) - : await t.throwsAsync(execa(binPath, args, {cwd})); - - verifyCli(t, result?.stdout ?? result?.stderr ?? '', expectedLines, options); - t.is(result?.exitCode, shouldPass ? 0 : 1, 'CLI exited with the wrong exit code!'); +// 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, args: string[], expectations: string[] | ((cwd: string) => string[]), options?: VerifyCliOptions) => { + const cwd = getFixture(fixtureName); + + const result = shouldPass + ? await execa(binPath, args, {cwd}) + : await t.throwsAsync(execa(binPath, args, {cwd})); + + const expectedLines = typeof expectations === 'function' + ? expectations(cwd) + : expectations; + + verifyCli(t, result?.stdout ?? result?.stderr ?? '', expectedLines, options); + t.is(result?.exitCode, shouldPass ? 0 : 1, 'CLI exited with the wrong exit code!'); + }) +); + export const verifyCliPasses = _verifyCli(true); export const verifyCliFails = _verifyCli(false); diff --git a/source/test/cli.ts b/source/test/cli.ts index f01a631e..d5a91ce0 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -12,6 +12,9 @@ import { verifyCliFails, } from './_utils.js'; +// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain, unicorn/no-await-expression-member +const pkg = (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.', '', @@ -20,30 +23,17 @@ test('fail if errors are found', verifyCliFails, 'failure', [], [ test('succeed if no errors are found', verifyCliPasses, 'success', [], []); -test('provide a path', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa(binPath, [getFixture('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('cli help flag: --help', async t => { - const {exitCode} = await execa(binPath, ['--help']); - - t.is(exitCode, 0); -}); +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 version flag: --version', async t => { - const {packageJson: pkg} = await readPackageUp() ?? {packageJson: {}}; - const {exitCode, stdout} = await execa(binPath, ['--version']); +test('cli help flag: --help', verifyCliPasses, '', ['--help'], [ + 'Usage', +]); - t.is(exitCode, 0); - t.is(stdout, pkg.version); -}); +test('cli version flag: --version', verifyCliPasses, '', ['--version'], [pkg.version]); test('cli typings flag: --typings', verifyCliFails, 'typings-custom-dir', ['--typings', 'utils/index.d.ts'], [ '✖ 5:19 Argument of type number is not assignable to parameter of type string.', @@ -81,25 +71,24 @@ test('cli typings and files flags', verifyCliFails, 'typings-custom-dir', ['-t', '1 error', ]); -test('tsd logs stacktrace on failure', async t => { - const {exitCode, stderr} = await t.throwsAsync(execa(binPath, {cwd: getFixture('empty-package-json')})); - +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}); -}); + ]; +}, {startLine: 0}); test('exported formatter matches cli results', async t => { const options = {cwd: getFixture('failure')}; + 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.', @@ -107,10 +96,7 @@ test('exported formatter matches cli results', async t => { '1 error', ]); - const tsdResults = await tsd(options); - const formattedResults = formatter(tsdResults); - - verifyCli(t, formattedResults, [ + verifyCli(t, formattedTsdResults, [ '✖ 5:19 Argument of type number is not assignable to parameter of type string.', '', '1 error', @@ -131,11 +117,6 @@ test('warnings are reported with errors', verifyCliFails, 'warnings/with-errors' '1 error', ]); -test('tsd failures (not crashes) report only the message', async t => { - const cwd = path.resolve('fixtures/no-tsd'); - - const {exitCode, stderr} = await t.throwsAsync(execa(binPath, {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('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/test.ts b/source/test/test.ts index f3d1cb4a..fb695dc4 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -5,27 +5,18 @@ 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.resolve('fixtures/no-tsd'); - const index = path.join(cwd, 'index.d.ts'); +test('throw if no type definition was found', verifyTsdFails, 'no-tsd', cwd => ( + `The type definition \`index.d.ts\` does not exist at \`${path.join(cwd, 'index.d.ts')}\`. Is the path correct? Create one and try again.` +)); - 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.resolve('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('throw if no test is found', verifyTsdFails, 'no-test', cwd => ( + `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', verifyTsd, 'failure', [ [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], @@ -144,39 +135,22 @@ test('loose types', verifyTsd, 'strict-types/loose', [ test('strict types', noDiagnostics, 'strict-types/strict'); -test('typings in custom directory', async t => { - const diagnostics = await tsd({ - cwd: path.resolve('fixtures/typings-custom-dir'), - typingsFile: 'utils/index.d.ts', - }); - - verify(t, diagnostics, [ +test('typings in custom directory', verifyTsd, + {fixtureName: 'typings-custom-dir', tsdOptions: {typingsFile: 'utils/index.d.ts'}}, [ [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.resolve('fixtures/specify-test-files'), - testFiles: [ - 'unknown.test.ts', - 'second.test.ts', - ], - }); + ], +); - verify(t, diagnostics, [ +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\'.'], - ]); -}); - -test('fails if typings file is not found in the specified path', async t => { - const cwd = path.resolve('fixtures/typings-custom-dir'); + ], +); - await t.throwsAsync( - tsd({cwd, typingsFile: 'unknown.d.ts'}), - {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('fails if typings file is not found in the specified path', verifyTsdFails, + {fixtureName: 'typings-custom-dir', tsdOptions: {testFiles: ['unknown.test.ts']}}, + cwd => `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', verifyTsd, 'ts-config-extends', [ [6, 64, 'error', 'Not all code paths return a value.'], From 47de976b8096215b4782689652fd00dc6db6c66e Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Wed, 5 Apr 2023 01:52:52 -0500 Subject: [PATCH 10/18] tests: start converting fixtures to ESM --- source/test/fixtures/aliased/aliased-assertion/index.js | 2 +- .../test/fixtures/aliased/aliased-assertion/index.test-d.ts | 4 ++-- source/test/fixtures/aliased/aliased-assertion/package.json | 3 ++- source/test/fixtures/aliased/aliased-const/index.js | 2 +- source/test/fixtures/aliased/aliased-const/index.test-d.ts | 4 ++-- source/test/fixtures/aliased/aliased-const/package.json | 3 ++- source/test/fixtures/aliased/aliased-module/index.js | 2 +- source/test/fixtures/aliased/aliased-module/index.test-d.ts | 6 +++--- source/test/fixtures/aliased/aliased-module/package.json | 3 ++- source/test/fixtures/assignability/assignable/index.js | 2 +- .../test/fixtures/assignability/assignable/index.test-d.ts | 4 ++-- source/test/fixtures/assignability/assignable/package.json | 3 ++- source/test/fixtures/assignability/not-assignable/index.js | 2 +- .../fixtures/assignability/not-assignable/index.test-d.ts | 4 ++-- .../test/fixtures/assignability/not-assignable/package.json | 3 ++- source/test/fixtures/deprecated/expect-deprecated/index.js | 2 +- .../fixtures/deprecated/expect-deprecated/index.test-d.ts | 4 ++-- .../test/fixtures/deprecated/expect-deprecated/package.json | 3 ++- .../test/fixtures/deprecated/expect-not-deprecated/index.js | 2 +- .../deprecated/expect-not-deprecated/index.test-d.ts | 4 ++-- .../fixtures/deprecated/expect-not-deprecated/package.json | 3 ++- source/test/fixtures/diff/index.js | 2 +- source/test/fixtures/diff/index.test-d.ts | 4 ++-- source/test/fixtures/diff/package.json | 1 + source/test/fixtures/dom/index.js | 2 +- source/test/fixtures/dom/index.test-d.ts | 4 ++-- source/test/fixtures/dom/package.json | 3 ++- source/test/fixtures/eslint-compatibility/index.test-d.ts | 4 ++-- source/test/fixtures/esm/index.test-d.ts | 2 +- source/test/fixtures/exclude-node-modules/index.js | 2 +- source/test/fixtures/exclude-node-modules/index.test-d.ts | 4 ++-- source/test/fixtures/exclude-node-modules/package.json | 1 + source/test/fixtures/expect-error/classes/index.js | 4 +--- source/test/fixtures/expect-error/classes/index.test-d.ts | 4 ++-- source/test/fixtures/expect-error/classes/package.json | 1 + .../enabled-exact-optional-property-types/index.js | 2 +- .../enabled-exact-optional-property-types/index.test-d.ts | 4 ++-- .../enabled-exact-optional-property-types/package.json | 1 + source/test/fixtures/expect-error/functions/index.js | 6 +++--- source/test/fixtures/expect-error/functions/index.test-d.ts | 4 ++-- source/test/fixtures/expect-error/functions/package.json | 3 ++- source/test/fixtures/expect-error/generics/index.js | 4 ++-- source/test/fixtures/expect-error/generics/index.test-d.ts | 4 ++-- source/test/fixtures/expect-error/generics/package.json | 3 ++- .../fixtures/expect-error/missing-diagnostic-code/index.js | 2 +- .../expect-error/missing-diagnostic-code/index.test-d.ts | 4 ++-- .../expect-error/missing-diagnostic-code/package.json | 3 ++- source/test/fixtures/expect-error/syntax/index.js | 2 +- source/test/fixtures/expect-error/syntax/index.test-d.ts | 4 ++-- source/test/fixtures/expect-error/syntax/package.json | 3 ++- .../expect-error/values-disabled-no-implicit-any/index.js | 2 +- .../values-disabled-no-implicit-any/index.test-d.ts | 4 ++-- .../values-disabled-no-implicit-any/package.json | 1 + source/test/fixtures/expect-error/values/index.js | 2 +- source/test/fixtures/expect-error/values/index.test-d.ts | 4 ++-- source/test/fixtures/expect-error/values/package.json | 3 ++- source/test/fixtures/failure-nested/child.test-d.ts | 4 ++-- source/test/fixtures/failure-nested/index.js | 2 +- source/test/fixtures/failure-nested/index.test-d.ts | 4 ++-- source/test/fixtures/failure-nested/package.json | 3 ++- source/test/fixtures/failure-strict-null-checks/index.js | 2 +- .../fixtures/failure-strict-null-checks/index.test-d.ts | 4 ++-- .../test/fixtures/failure-strict-null-checks/package.json | 3 ++- source/test/fixtures/failure/index.js | 2 +- source/test/fixtures/failure/index.test-d.ts | 4 ++-- source/test/fixtures/failure/package.json | 3 ++- source/test/fixtures/files-folder/out/index.js | 2 +- source/test/fixtures/files-folder/out/index.test-d.ts | 4 ++-- source/test/fixtures/files-folder/package.json | 1 + .../negative-pattern-negated/index.js | 2 +- .../negative-pattern-negated/package.json | 1 + .../files-gitignore-patterns/negative-pattern/index.js | 2 +- .../negative-pattern/index.test-d.ts | 4 ++-- .../files-gitignore-patterns/negative-pattern/package.json | 1 + .../files-gitignore-patterns/root-marker-pattern/index.js | 2 +- .../root-marker-pattern/package.json | 1 + source/test/fixtures/files-glob/out/index.js | 2 +- source/test/fixtures/files-glob/out/index.test-d.ts | 4 ++-- source/test/fixtures/files-glob/package.json | 1 + source/test/fixtures/identicality/identical/index.js | 4 ++-- source/test/fixtures/identicality/identical/index.test-d.ts | 4 ++-- source/test/fixtures/identicality/identical/package.json | 3 ++- source/test/fixtures/identicality/not-identical/index.js | 2 +- .../fixtures/identicality/not-identical/index.test-d.ts | 4 ++-- .../test/fixtures/identicality/not-identical/package.json | 3 ++- .../test/fixtures/informational/expect-doc-comment/index.js | 2 +- .../informational/expect-doc-comment/index.test-d.ts | 2 +- .../fixtures/informational/expect-doc-comment/package.json | 3 ++- source/test/fixtures/informational/print-type/index.js | 2 +- .../test/fixtures/informational/print-type/index.test-d.ts | 4 ++-- source/test/fixtures/informational/print-type/package.json | 3 ++- .../test/fixtures/lib-config/failure-missing-lib/index.js | 2 +- .../fixtures/lib-config/failure-missing-lib/index.test-d.ts | 4 ++-- .../fixtures/lib-config/failure-missing-lib/package.json | 1 + .../lib-config/lib-as-triple-slash-reference/index.js | 2 +- .../lib-as-triple-slash-reference/index.test-d.ts | 4 ++-- .../lib-config/lib-as-triple-slash-reference/package.json | 3 ++- .../lib-from-package-json-overrides-tsconfig-json/index.js | 2 +- .../index.test-d.ts | 4 ++-- .../package.json | 1 + .../test/fixtures/lib-config/lib-from-package-json/index.js | 2 +- .../lib-config/lib-from-package-json/index.test-d.ts | 4 ++-- .../fixtures/lib-config/lib-from-package-json/package.json | 1 + .../fixtures/lib-config/lib-from-tsconfig-json/index.js | 2 +- .../lib-config/lib-from-tsconfig-json/index.test-d.ts | 4 ++-- .../fixtures/lib-config/lib-from-tsconfig-json/package.json | 3 ++- source/test/fixtures/missing-import/index.test-d.ts | 4 ++-- source/test/fixtures/missing-import/package.json | 3 ++- .../module-resolution/node16-from-package-json/index.js | 2 +- .../module-resolution/node16-from-tsconfig-json/index.js | 2 +- .../module-resolution/nodenext-from-package-json/index.js | 2 +- .../module-resolution/nodenext-from-tsconfig-json/index.js | 2 +- .../no-explicit-types-property/with-main-barrel/index.js | 2 +- .../with-main-barrel/index.test-d.ts | 2 +- .../with-main-barrel/package.json | 1 + .../no-explicit-types-property/with-main-other/foo.js | 2 +- .../with-main-other/foo.test-d.ts | 2 +- .../no-explicit-types-property/with-main-other/package.json | 1 + .../no-explicit-types-property/without-main/index.js | 2 +- .../no-explicit-types-property/without-main/index.test-d.ts | 2 +- .../no-explicit-types-property/without-main/package.json | 1 + source/test/fixtures/no-files/index.js | 2 +- source/test/fixtures/no-files/index.test-d.ts | 4 ++-- source/test/fixtures/no-files/package.json | 1 + source/test/fixtures/no-test/index.js | 2 +- source/test/fixtures/no-test/package.json | 3 ++- source/test/fixtures/non-strict-check-with-config/index.js | 2 +- .../fixtures/non-strict-check-with-config/index.test-d.ts | 4 ++-- .../test/fixtures/non-strict-check-with-config/package.json | 1 + source/test/fixtures/root-dir/test-d/index.test-d.ts | 2 +- source/test/fixtures/specify-test-files/index.js | 2 +- source/test/fixtures/specify-test-files/package.json | 3 ++- source/test/fixtures/specify-test-files/second.test.ts | 4 ++-- source/test/fixtures/specify-test-files/unknown.test.ts | 4 ++-- .../strict-null-checks-as-default-config-value/index.js | 2 +- .../index.test-d.ts | 4 ++-- .../strict-null-checks-as-default-config-value/package.json | 1 + source/test/fixtures/strict-types/loose/index.js | 2 +- source/test/fixtures/strict-types/loose/index.test-d.ts | 4 ++-- source/test/fixtures/strict-types/loose/package.json | 1 + source/test/fixtures/strict-types/strict/index.js | 2 +- source/test/fixtures/strict-types/strict/index.test-d.ts | 4 ++-- source/test/fixtures/strict-types/strict/package.json | 1 + source/test/fixtures/success/index.js | 2 +- source/test/fixtures/success/index.test-d.ts | 4 ++-- source/test/fixtures/success/package.json | 1 + source/test/fixtures/test-directory/custom/index.js | 2 +- source/test/fixtures/test-directory/custom/package.json | 1 + source/test/fixtures/test-directory/default/index.js | 2 +- source/test/fixtures/test-directory/default/package.json | 1 + source/test/fixtures/test-directory/tsx/package.json | 1 + source/test/fixtures/test-in-subdir/package.json | 3 ++- source/test/fixtures/test-in-subdir/src/index.js | 2 +- source/test/fixtures/test-in-subdir/src/index.test-d.ts | 4 ++-- source/test/fixtures/test-non-barrel-main/foo.js | 2 +- source/test/fixtures/test-non-barrel-main/foo.test-d.ts | 2 +- source/test/fixtures/test-non-barrel-main/package.json | 1 + source/test/fixtures/top-level-await/index.js | 2 +- source/test/fixtures/top-level-await/index.test-d.ts | 4 ++-- source/test/fixtures/top-level-await/package.json | 1 + source/test/fixtures/ts-config-extends/index.js | 2 +- source/test/fixtures/ts-config-extends/index.test-d.ts | 4 ++-- source/test/fixtures/ts-config-extends/package.json | 3 ++- source/test/fixtures/tsx/component-type/index.js | 2 +- source/test/fixtures/tsx/component-type/index.test-d.tsx | 2 +- source/test/fixtures/tsx/component-type/package.json | 1 + source/test/fixtures/tsx/component/index.js | 3 +-- source/test/fixtures/tsx/component/index.test-d.tsx | 2 +- source/test/fixtures/tsx/component/package.json | 1 + .../test/fixtures/types-property/no-property/package.json | 3 ++- source/test/fixtures/types-property/typings/package.json | 1 + source/test/fixtures/typings-custom-dir/index.js | 2 +- source/test/fixtures/typings-custom-dir/index.test-d.ts | 2 +- source/test/fixtures/typings-custom-dir/package.json | 3 ++- source/test/fixtures/undefined-symbol/index.test-d.ts | 2 +- source/test/fixtures/undefined-symbol/package.json | 3 ++- source/test/fixtures/warnings/only-warnings/index.js | 2 +- source/test/fixtures/warnings/only-warnings/index.test-d.ts | 4 ++-- source/test/fixtures/warnings/only-warnings/package.json | 3 ++- source/test/fixtures/warnings/with-errors/index.js | 2 +- source/test/fixtures/warnings/with-errors/index.test-d.ts | 4 ++-- source/test/fixtures/warnings/with-errors/package.json | 3 ++- 182 files changed, 267 insertions(+), 208 deletions(-) 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..2b635375 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/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/esm/index.test-d.ts b/source/test/fixtures/esm/index.test-d.ts index 67eb5ed0..21881cac 100644 --- a/source/test/fixtures/esm/index.test-d.ts +++ b/source/test/fixtures/esm/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../..'; +import {expectType} from '../../../../index.js'; import one from './index.js'; expectType(one('foo', 'bar')); 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/test-d/index.test-d.ts b/source/test/fixtures/root-dir/test-d/index.test-d.ts index bf1dd794..2685e51e 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 {expectType} from '../../../../index.js'; import {a} from '../src'; expectType<2>(a); 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/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/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-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..01b6801e 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,4 +1,4 @@ -import {expectType} from '../../..'; +import {expectType} from '../../../index.js'; import one from './foo'; expectType(one('foo', 'bar')); 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/tsx/component-type/index.js b/source/test/fixtures/tsx/component-type/index.js index 6db2eca6..155aa37d 100644 --- a/source/test/fixtures/tsx/component-type/index.js +++ b/source/test/fixtures/tsx/component-type/index.js @@ -1,5 +1,5 @@ 'use strict'; -const React = require('react'); +import React from 'react'; export class Unicorn extends React.Component { constructor(props) { diff --git a/source/test/fixtures/tsx/component-type/index.test-d.tsx b/source/test/fixtures/tsx/component-type/index.test-d.tsx index 9a566007..8537ecf7 100644 --- a/source/test/fixtures/tsx/component-type/index.test-d.tsx +++ b/source/test/fixtures/tsx/component-type/index.test-d.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import {expectType, expectError} from '../../../..'; +import {expectType, expectError} from '../../../../index.js'; import {Unicorn} from '.'; expectType(); diff --git a/source/test/fixtures/tsx/component-type/package.json b/source/test/fixtures/tsx/component-type/package.json index 09392033..4b4ec164 100644 --- a/source/test/fixtures/tsx/component-type/package.json +++ b/source/test/fixtures/tsx/component-type/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" diff --git a/source/test/fixtures/tsx/component/index.js b/source/test/fixtures/tsx/component/index.js index 6db2eca6..5a3a2d9e 100644 --- a/source/test/fixtures/tsx/component/index.js +++ b/source/test/fixtures/tsx/component/index.js @@ -1,5 +1,4 @@ -'use strict'; -const React = require('react'); +import React from 'react'; export class Unicorn extends React.Component { constructor(props) { diff --git a/source/test/fixtures/tsx/component/index.test-d.tsx b/source/test/fixtures/tsx/component/index.test-d.tsx index 9a566007..8537ecf7 100644 --- a/source/test/fixtures/tsx/component/index.test-d.tsx +++ b/source/test/fixtures/tsx/component/index.test-d.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import {expectType, expectError} from '../../../..'; +import {expectType, expectError} from '../../../../index.js'; import {Unicorn} from '.'; expectType(); diff --git a/source/test/fixtures/tsx/component/package.json b/source/test/fixtures/tsx/component/package.json index 09392033..4b4ec164 100644 --- a/source/test/fixtures/tsx/component/package.json +++ b/source/test/fixtures/tsx/component/package.json @@ -1,5 +1,6 @@ { "name": "foo", + "type": "module", "files": [ "index.js", "index.d.ts" 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..0aea555f 100644 --- a/source/test/fixtures/typings-custom-dir/index.test-d.ts +++ b/source/test/fixtures/typings-custom-dir/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../..'; +import {expectType} from '../../../index.js'; import one from './utils'; expectType(one('foo', 'bar')); 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..f5a02960 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/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" } From 22a816dce2ec907f77b3a46b687b4a0ff185772b Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Nov 2023 00:35:25 +0700 Subject: [PATCH 11/18] Update config.ts --- source/lib/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/config.ts b/source/lib/config.ts index 2f549769..9d9f6b4b 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -29,7 +29,7 @@ const loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { compilerOptions: { strict: true, jsx: ts.JsxEmit.React, - lib: parseRawLibs(['es2020', 'dom', 'dom.iterable'], cwd), + lib: parseRawLibs(['es2022', 'dom', 'dom.iterable'], cwd), module, target: ts.ScriptTarget.ES2020, esModuleInterop: true, From c91e9abfa6088a1fd4d3245c30931fb62c6b3d9e Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Nov 2023 00:35:42 +0700 Subject: [PATCH 12/18] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8a3ab2e..91caad59 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "types": "./dist/index.d.ts", "bin": "./dist/cli.js", "engines": { - "node": ">=16" + "node": ">=18" }, "scripts": { "prepublishOnly": "npm run build", From 7f92ab44fc17ec534707e4dfc2e6ce58e1a607e6 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Nov 2023 00:36:08 +0700 Subject: [PATCH 13/18] Update tsconfig.tsd.json --- tsconfig.tsd.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.tsd.json b/tsconfig.tsd.json index 2be3eb85..beab5ac4 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -1,9 +1,9 @@ { "compilerOptions": { "outDir": "dist", - "target": "ES2021", // Node.js 16 + "target": "ES2022", // Node.js 18 "lib": [ - "ES2021" + "ES2022" ], "module": "node16", "moduleResolution": "node16", From 69aff05c1113700cb6877d8e853d8674c4298fec Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Nov 2023 00:36:50 +0700 Subject: [PATCH 14/18] Update main.yaml --- .github/workflows/main.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index d50ada65..346585cf 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -10,12 +10,11 @@ jobs: fail-fast: false matrix: node-version: + - 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 From 13e610cf442a751d94a8dcddc2c8d8516bafa26b Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Thu, 22 Feb 2024 20:15:11 -0600 Subject: [PATCH 15/18] update deps, remove `index.d.ts` rule, style updates, bundle types --- .gitignore | 1 + package.json | 56 +++++++------ source/cli.ts | 25 +++--- source/lib/assertions/assert.ts | 51 +++--------- source/lib/compiler.ts | 7 +- source/lib/config.ts | 10 ++- source/lib/formatter.ts | 1 + source/lib/index.ts | 78 ++++++------------ source/lib/interfaces.ts | 10 +-- source/lib/parser.ts | 4 +- source/lib/rules/files-property.ts | 68 ---------------- source/lib/rules/index.ts | 9 +-- source/lib/rules/types-property.ts | 32 -------- .../lib/utils/get-json-property-position.ts | 2 +- source/lib/utils/typescript.ts | 20 +++-- source/test/_utils.ts | 81 ++++++++++++------- source/test/cli.ts | 26 +----- source/test/eslint-compatibility.ts | 14 ++-- source/test/expect-error.ts | 12 +-- source/test/fixtures/dom/index.test-d.ts | 2 +- .../fixtures/eslint-compatibility/.eslintrc | 3 +- .../fixtures/eslint-compatibility/index.js | 1 - source/test/fixtures/esm/index.d.ts | 7 -- source/test/fixtures/esm/index.js | 3 - source/test/fixtures/esm/index.test-d.ts | 4 - source/test/fixtures/esm/package.json | 5 -- source/test/fixtures/root-dir/package.json | 1 + .../fixtures/root-dir/test-d/index.test-d.ts | 4 +- .../root-dir/ts-dist/{index.js => index.cjs} | 0 source/test/fixtures/root-dir/tsconfig.json | 1 + .../test-directory/custom/test/unknown.ts | 4 +- .../test-directory/default/test-d/numbers.ts | 4 +- .../test-directory/default/test-d/strings.ts | 4 +- .../test-directory/default/test-d/unknown.ts | 4 +- .../test-directory/tsx/test-d/unicorn.tsx | 4 +- .../test-non-barrel-main/foo.test-d.ts | 2 +- .../fixtures/ts-config-extends/tsconfig.json | 2 +- source/test/fixtures/tsconfig.json | 9 +++ .../fixtures/tsx/component-type/index.d.ts | 8 -- .../test/fixtures/tsx/component-type/index.js | 12 --- .../tsx/component-type/index.test-d.tsx | 9 --- .../fixtures/tsx/component-type/package.json | 11 --- source/test/fixtures/tsx/component/index.d.ts | 8 -- source/test/fixtures/tsx/component/index.js | 11 --- .../tsx/{component => }/index.test-d.tsx | 6 +- source/test/fixtures/tsx/index.tsx | 10 +++ .../fixtures/tsx/{component => }/package.json | 5 +- .../typings-custom-dir/index.test-d.ts | 2 +- .../fixtures/undefined-symbol/index.test-d.ts | 2 +- source/test/test.ts | 56 +++---------- tsconfig.build.json | 10 +++ tsconfig.tsd.json | 22 +---- tsup.config.ts | 13 +++ 53 files changed, 258 insertions(+), 498 deletions(-) mode change 100644 => 100755 source/cli.ts delete mode 100644 source/lib/rules/files-property.ts delete mode 100644 source/lib/rules/types-property.ts delete mode 100644 source/test/fixtures/esm/index.d.ts delete mode 100644 source/test/fixtures/esm/index.js delete mode 100644 source/test/fixtures/esm/index.test-d.ts delete mode 100644 source/test/fixtures/esm/package.json rename source/test/fixtures/root-dir/ts-dist/{index.js => index.cjs} (100%) create mode 100644 source/test/fixtures/tsconfig.json delete mode 100644 source/test/fixtures/tsx/component-type/index.d.ts delete mode 100644 source/test/fixtures/tsx/component-type/index.js delete mode 100644 source/test/fixtures/tsx/component-type/index.test-d.tsx delete mode 100644 source/test/fixtures/tsx/component-type/package.json delete mode 100644 source/test/fixtures/tsx/component/index.d.ts delete mode 100644 source/test/fixtures/tsx/component/index.js rename source/test/fixtures/tsx/{component => }/index.test-d.tsx (59%) create mode 100644 source/test/fixtures/tsx/index.tsx rename source/test/fixtures/tsx/{component => }/package.json (62%) create mode 100644 tsconfig.build.json create mode 100644 tsup.config.ts 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 ae8434b9..3ddd02b6 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "url": "https://github.com/SamVerschueren" }, "type": "module", - "exports": "./dist/index.js", - "types": "./dist/index.d.ts", + "exports": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, "bin": "./dist/cli.js", "engines": { "node": ">=18" @@ -19,7 +21,7 @@ "scripts": { "prepublishOnly": "npm run build", "test": "xo && tsc --project tsconfig.tsd.json --noEmit && ava", - "build": "del-cli dist && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js" + "build": "tsc --project tsconfig.build.json && chmod +x dist/cli.js && tsup" }, "files": [ "dist/**/*.js", @@ -37,40 +39,38 @@ ], "dependencies": { "@tsd/typescript": "~5.3.3", - "eslint-formatter-pretty": "^5.0.0", - "globby": "^13.1.3", - "jest-diff": "^29.5.0", - "meow": "^11.0.0", - "p-map": "^5.5.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-pkg-up": "^9.1.0" + "read-package-up": "^11.0.0" }, "devDependencies": { - "@types/common-tags": "^1.8.1", - "@types/node": "^16", - "@types/react": "^16.9.2", - "ava": "^5.2.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", - "del-cli": "^3.0.0", - "execa": "^7.1.1", + "eslint": "^8.56.0", + "execa": "^8.0.1", "react": "^16.9.0", "resolve-from": "^5.0.0", "rxjs": "^6.5.3", - "tsx": "^3.12.6", - "typescript": "~5.0.3", - "xo": "^0.53.1" + "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": [ - "--loader=tsx" + "--import=tsimp" ], "environmentVariables": { "ESBK_TSCONFIG_PATH": "tsconfig.tsd.json" @@ -81,7 +81,15 @@ "source/test/fixtures" ], "rules": { - "no-bitwise": "off" + "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 4a737bf4..12ee036e --- a/source/cli.ts +++ b/source/cli.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env node +#!/usr/bin/env tsimp import process from 'node:process'; import meow from 'meow'; import {TsdError} from './lib/interfaces.js'; @@ -9,21 +9,20 @@ 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 @@ -32,13 +31,9 @@ const cli = meow(` `, { importMeta: import.meta, flags: { - typings: { - type: 'string', - alias: 't', - }, files: { type: 'string', - alias: 'f', + shortFlag: 'f', isMultiple: true, }, showDiff: { @@ -65,9 +60,9 @@ const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => { try { const cwd = cli.input.at(0) ?? process.cwd(); - const {typings: typingsFile, files: testFiles, showDiff} = cli.flags; + 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'); @@ -75,7 +70,7 @@ try { exit(formattedDiagnostics, {isError: hasErrors}); } -} catch (error: unknown) { +} catch (error) { const potentialError = error as Error | undefined; if (potentialError instanceof TsdError) { diff --git a/source/lib/assertions/assert.ts b/source/lib/assertions/assert.ts index 2fcebec5..b8fce95e 100644 --- a/source/lib/assertions/assert.ts +++ b/source/lib/assertions/assert.ts @@ -3,72 +3,51 @@ * * @param expression - Expression that should be identical to type `T`. */ -// @ts-expect-error: "expression is never read" -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: "expression is never read" -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: "expression is never read" -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: "expression is never read" -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: "expression is never read" -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: "expression is never read" -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: "expression is never read" -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`. @@ -84,17 +63,11 @@ export const expectNever = (expression: never): never => expression; * * @param expression - Expression whose type should be printed as a warning. */ -// @ts-expect-error: "expression is never read" -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: "expression is never read" -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/compiler.ts b/source/lib/compiler.ts index 7d07519c..9bceaa64 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,6 +1,11 @@ import ts, {type Diagnostic as TSDiagnostic} from '@tsd/typescript'; import {type ExpectedError, extractAssertions, parseErrorAssertionToLocation} from './parser.js'; -import {type Diagnostic, DiagnosticCode, type Context, type Location} from './interfaces.js'; +import { + 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 diff --git a/source/lib/config.ts b/source/lib/config.ts index 9d9f6b4b..0df6a678 100644 --- a/source/lib/config.ts +++ b/source/lib/config.ts @@ -1,18 +1,20 @@ import ts, {type CompilerOptions} from '@tsd/typescript'; import type {Config, PackageJsonWithTsdConfig, RawCompilerOptions} from './interfaces.js'; +// TODO: update this + /** * Load the configuration settings. * * @param pkg - The package.json object. * @returns The config object. */ -const loadConfig = (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 ?? {}, + packageConfig.compilerOptions ?? {}, cwd, ); @@ -25,7 +27,7 @@ const loadConfig = (pkg: PackageJsonWithTsdConfig, cwd: string): Config => { return { directory: 'test-d', - ...pkgConfig, + ...packageConfig, compilerOptions: { strict: true, jsx: ts.JsxEmit.React, diff --git a/source/lib/formatter.ts b/source/lib/formatter.ts index 3985b857..1b18c90a 100644 --- a/source/lib/formatter.ts +++ b/source/lib/formatter.ts @@ -59,6 +59,7 @@ const formatter = (diagnostics: Diagnostic[], showDiff = false): string => { entry.messages.push(diagnostic); } + // @ts-expect-error return String(prettyFormatter([...fileMap.values()])); }; diff --git a/source/lib/index.ts b/source/lib/index.ts index 3868ce55..3696d7bc 100644 --- a/source/lib/index.ts +++ b/source/lib/index.ts @@ -1,77 +1,55 @@ import path from 'node:path'; import process from 'node:process'; -import {readPackageUp} from 'read-pkg-up'; +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 {type Context, type Config, type Diagnostic, type PackageJsonWithTsdConfig, TsdError} from './interfaces.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 => { - /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ - const typings = options.typingsFile - || pkg.types - || pkg.typings - || (pkg.main && path.parse(pkg.main).name + '.d.ts') - || 'index.d.ts'; - /* eslint-enable @typescript-eslint/prefer-nullish-coalescing */ - - 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 cwdGlobs = TS_EXTENSIONS.map(extension => `**/*.test-d.${extension}`); + const testDirectory = options.config.directory; - const testFile = typingsFile.replace(/\.d\.ts$/, '.test-d.ts'); - const tsxTestFile = typingsFile.replace(/\.d\.ts$/, '.test-d.tsx'); - const testDir = options.config.directory; + let testFiles = await globby(cwdGlobs, {cwd: options.cwd}); + const testDirectoryExists = await pathExists(path.join(options.cwd, testDirectory)); - let testFiles = await globby([testFile, tsxTestFile], {cwd: options.cwd}); - const testDirExists = await pathExists(path.join(options.cwd, testDir)); - - 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)); @@ -84,27 +62,23 @@ const findTestFiles = async (typingsFilePath: string, options: Options & {config */ // eslint-disable-next-line unicorn/no-object-as-default-parameter const tsd = async (options: Options = {cwd: process.cwd()}): Promise => { - const pkgResult = await readPackageUp({cwd: options.cwd}); + 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); - - // 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 package_ = packageResult.packageJson as PackageJsonWithTsdConfig; + const config = loadConfig(package_, options.cwd); - const testFiles = await findTestFiles(typingsFile, { + const testFiles = await findTestFiles({ ...options, config, }); const context: Context = { cwd: options.cwd, - pkg, - typingsFile, + pkg: package_, testFiles, config, }; diff --git a/source/lib/interfaces.ts b/source/lib/interfaces.ts index a874e382..4d1b1950 100644 --- a/source/lib/interfaces.ts +++ b/source/lib/interfaces.ts @@ -1,5 +1,5 @@ import type {CompilerOptions} from '@tsd/typescript'; -import type {NormalizedPackageJson} from 'read-pkg-up'; +import type {NormalizedPackageJson} from 'read-package-up'; export type RawCompilerOptions = Record; @@ -17,7 +17,6 @@ export type PackageJsonWithTsdConfig = NormalizedPackageJson & { export type Context = { cwd: string; pkg: PackageJsonWithTsdConfig; - typingsFile: string; testFiles: string[]; config: Config; }; @@ -91,10 +90,3 @@ export class TsdError extends Error { this.name = this.constructor.name; } } - -export class TsdError extends Error { - constructor(message: string) { - super(message); - this.name = this.constructor.name; - } -} diff --git a/source/lib/parser.ts b/source/lib/parser.ts index 3bca5464..40b9bb94 100644 --- a/source/lib/parser.ts +++ b/source/lib/parser.ts @@ -2,7 +2,7 @@ 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. @@ -38,7 +38,7 @@ export const extractAssertions = (program: Program): Map(); diff --git a/source/lib/rules/files-property.ts b/source/lib/rules/files-property.ts deleted file mode 100644 index 6eaf8c9e..00000000 --- a/source/lib/rules/files-property.ts +++ /dev/null @@ -1,68 +0,0 @@ -import path from 'node:path'; -import fs from 'node:fs'; -import pMap from 'p-map'; -import {globby} from 'globby'; -import type {Context, Diagnostic} from '../interfaces.js'; -import {getJsonPropertyPosition} from '../utils/index.js'; - -/** - * 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. - */ -const filesProperty = async (context: Context): Promise => { - const {pkg, typingsFile} = context; - - const packageFiles = pkg.files; - if (!Array.isArray(packageFiles)) { - return []; - } - - const normalizedTypingsFile = path.normalize(typingsFile); - - const patternProcessedPackageFiles = processGitIgnoreStylePatterns(packageFiles); - const normalizedFiles = await pMap( - await globby(patternProcessedPackageFiles, {cwd: context.cwd}), - glob => path.normalize(glob), - ); - - 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'), - }, - ]; -}; - -export default filesProperty; - -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 aed2bd16..b0579937 100644 --- a/source/lib/rules/index.ts +++ b/source/lib/rules/index.ts @@ -1,14 +1,9 @@ import type {Diagnostic, Context} from '../interfaces.js'; -import filesProperty from './files-property.js'; -import typesProperty from './types-property.js'; type RuleFunction = (context: Context) => Promise; // List of custom rules -const rules: RuleFunction[] = [ - filesProperty, - typesProperty, -]; +const rules: RuleFunction[] = []; /** * Get a list of custom diagnostics within the current context. @@ -22,3 +17,5 @@ const getCustomDiagnostics = async (context: Context): Promise => }; export default getCustomDiagnostics; + +// 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 25db7bb3..00000000 --- a/source/lib/rules/types-property.ts +++ /dev/null @@ -1,32 +0,0 @@ -import path from 'node:path'; -import fs from 'node:fs/promises'; -import type {Context, Diagnostic} from '../interfaces.js'; -import {getJsonPropertyPosition} from '../utils/index.js'; - -/** - * Rule which enforces the use of a `types` property over a `typings` property. - * - * @param context - The context object. - * @returns A list of custom diagnostics. - */ -const typesProperty = async (context: Context): Promise => { - const {pkg} = context; - - if (!pkg.types && pkg.typings) { - const packageJsonFullPath = path.join(context.cwd, 'package.json'); - const content = await fs.readFile(packageJsonFullPath, 'utf8'); - - return [ - { - fileName: packageJsonFullPath, - message: 'Use property `types` instead of `typings`.', - severity: 'error', - ...getJsonPropertyPosition(content, 'typings'), - }, - ]; - } - - return []; -}; - -export default typesProperty; diff --git a/source/lib/utils/get-json-property-position.ts b/source/lib/utils/get-json-property-position.ts index ae649201..714e13dd 100644 --- a/source/lib/utils/get-json-property-position.ts +++ b/source/lib/utils/get-json-property-position.ts @@ -13,7 +13,7 @@ const getJsonPropertyPosition = (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, diff --git a/source/lib/utils/typescript.ts b/source/lib/utils/typescript.ts index 40f5acec..a24e7b90 100644 --- a/source/lib/utils/typescript.ts +++ b/source/lib/utils/typescript.ts @@ -1,26 +1,24 @@ -import type {TypeChecker, Expression, JSDocTagInfo} from '@tsd/typescript'; - -const {isCallLikeExpression, displayPartsToString} = await import('@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) + 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; + return new Map(reference.getJsDocTags().map(tag => [tag.name, tag])) as ConditionalResolveReturn; } case 'DocComment': { - return displayPartsToString(ref.getDocumentationComment(checker)) as ConditionalResolveReturn; + return ts.displayPartsToString(reference.getDocumentationComment(checker)) as ConditionalResolveReturn; } default: { @@ -57,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 index 3731372b..d4afc699 100644 --- a/source/test/_utils.ts +++ b/source/test/_utils.ts @@ -1,11 +1,15 @@ 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} from 'execa'; +import { + type ExecaError, execa, execaNode, execaCommand, +} from 'execa'; import tsd, {type Options} from '../lib/index.js'; import type {Diagnostic} from '../lib/interfaces.js'; -export const binPath = path.resolve('../cli.js'); +// TODO: switch to URL when execa is updated +export const binPath = fileURLToPath(new URL('../cli.ts', import.meta.url)); type Expectation = [ line: number, @@ -148,7 +152,7 @@ export const verifyCli = ( }; export const getFixture = (fixtureName: string) => fixtureName.length > 0 - ? path.resolve('fixtures', fixtureName) + ? fileURLToPath(new URL(`fixtures/${fixtureName}`, import.meta.url)) : process.cwd(); type VerifyType = 'verify' | 'verifyWithFileName' | 'verifyWithDiff'; @@ -183,26 +187,32 @@ const _verifyTsd = (verifyType: Type) => ( const {cwd, tsdOptions} = parseOptions(options); const diagnostics = await tsd({cwd, ...tsdOptions}); - switch (verifyType) { - case 'verify': { - verify(t, diagnostics, expectations as ExpectationType<'verify'>); - break; - } + const assertions = await t.try(tt => { + tt.log('cwd:', cwd); - case 'verifyWithFileName': { - verifyWithFileName(t, cwd, diagnostics, expectations as ExpectationType<'verifyWithFileName'>); - break; - } + switch (verifyType) { + case 'verify': { + verify(tt, diagnostics, expectations as ExpectationType<'verify'>); + break; + } - case 'verifyWithDiff': { - verifyWithDiff(t, diagnostics, expectations as ExpectationType<'verifyWithDiff'>); - break; - } + case 'verifyWithFileName': { + verifyWithFileName(tt, cwd, diagnostics, expectations as ExpectationType<'verifyWithFileName'>); + break; + } - default: { - break; + case 'verifyWithDiff': { + verifyWithDiff(tt, diagnostics, expectations as ExpectationType<'verifyWithDiff'>); + break; + } + + default: { + break; + } } - } + }); + + assertions.commit({retainLogs: !assertions.passed}); }) ); @@ -214,7 +224,12 @@ export const noDiagnostics = test.macro(async (t, fixtureName: string) => { const cwd = getFixture(fixtureName); const diagnostics = await tsd({cwd}); - verify(t, diagnostics, []); + const assertions = await t.try(tt => { + tt.log('cwd:', cwd); + verify(tt, diagnostics, []); + }); + + assertions.commit({retainLogs: !assertions.passed}); }); // TODO: maybe use TsdError in generic @@ -224,19 +239,27 @@ export const verifyTsdFails = test.macro(async (t, options: FixtureName | Verify }); const _verifyCli = (shouldPass: boolean) => ( - test.macro(async (t, fixtureName: string, args: string[], expectations: string[] | ((cwd: string) => string[]), options?: VerifyCliOptions) => { + test.macro(async (t, fixtureName: string, arguments_: string[], expectations: string[] | ((cwd: string) => string[]), options?: VerifyCliOptions) => { const cwd = getFixture(fixtureName); - const result = shouldPass - ? await execa(binPath, args, {cwd}) - : await t.throwsAsync(execa(binPath, args, {cwd})); + 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; - 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!'); + }); - verifyCli(t, result?.stdout ?? result?.stderr ?? '', expectedLines, options); - t.is(result?.exitCode, shouldPass ? 0 : 1, 'CLI exited with the wrong exit code!'); + assertions.commit({retainLogs: !assertions.passed}); }) ); diff --git a/source/test/cli.ts b/source/test/cli.ts index d5a91ce0..11b6a3a4 100644 --- a/source/test/cli.ts +++ b/source/test/cli.ts @@ -1,7 +1,7 @@ import path from 'node:path'; import test from 'ava'; import {execa, type ExecaError} from 'execa'; -import {readPackageUp} from 'read-pkg-up'; +import {readPackageUp} from 'read-package-up'; import resolveFrom from 'resolve-from'; import tsd, {formatter} from '../index.js'; import { @@ -13,7 +13,7 @@ import { } from './_utils.js'; // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain, unicorn/no-await-expression-member -const pkg = (await readPackageUp())?.packageJson!; +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.', @@ -33,19 +33,7 @@ test('cli help flag: --help', verifyCliPasses, '', ['--help'], [ 'Usage', ]); -test('cli version flag: --version', verifyCliPasses, '', ['--version'], [pkg.version]); - -test('cli typings flag: --typings', verifyCliFails, 'typings-custom-dir', ['--typings', 'utils/index.d.ts'], [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', -]); - -test('cli typings flag: -t', verifyCliFails, 'typings-custom-dir', ['-t', 'utils/index.d.ts'], [ - '✖ 5:19 Argument of type number is not assignable to parameter of type string.', - '', - '1 error', -]); +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.', @@ -65,12 +53,6 @@ test('cli files flag: array', verifyCliFails, 'specify-test-files', ['--files', '1 error', ]); -test('cli typings and files flags', verifyCliFails, 'typings-custom-dir', ['-t', 'utils/index.d.ts', '-f', 'index.test-d.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`; @@ -80,7 +62,7 @@ test('tsd logs stacktrace on failure', verifyCliFails, 'empty-package-json', [], '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)`, + `at async module.exports (${nodeModulesPath}/read-package-up/index.js:14:16)`, ]; }, {startLine: 0}); diff --git a/source/test/eslint-compatibility.ts b/source/test/eslint-compatibility.ts index 9e31bf07..80158d53 100644 --- a/source/test/eslint-compatibility.ts +++ b/source/test/eslint-compatibility.ts @@ -5,13 +5,15 @@ import {stripIndent} from 'common-tags'; test('`expectType` is compatible with eslint @typescript-eslint/no-unsafe-call rule', async t => { await t.throwsAsync( - execa('eslint', ['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 + 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 - ✖ 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 a73c74ef..7821091b 100644 --- a/source/test/expect-error.ts +++ b/source/test/expect-error.ts @@ -22,17 +22,9 @@ test('expectError for values (noImplicitAny disabled)', noDiagnostics, 'expect-e test('expectError for values (exactOptionalPropertyTypes enabled)', noDiagnostics, 'expect-error/enabled-exact-optional-property-types'); -test('expectError for decorators', async t => { - const diagnostics = await tsd({cwd: path.join(__dirname, 'fixtures/expect-error/decorators')}); +test('expectError for decorators', noDiagnostics, '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 for experimental decorators', noDiagnostics, 'expect-error/experimental-decorators'); test('expectError should report missing diagnostic codes', verifyTsd, 'expect-error/missing-diagnostic-code', [ [8, 12, 'error', 'Cannot find name \'undeclared\'.'], diff --git a/source/test/fixtures/dom/index.test-d.ts b/source/test/fixtures/dom/index.test-d.ts index 2b635375..e7b56307 100644 --- a/source/test/fixtures/dom/index.test-d.ts +++ b/source/test/fixtures/dom/index.test-d.ts @@ -1,4 +1,4 @@ -import {expectType} from '../../../../index.js'; +import {expectType} from '../../../index.js'; import append from './index.js'; const parent = document.createElement('div'); 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 7721e422..095da138 100644 --- a/source/test/fixtures/eslint-compatibility/index.js +++ b/source/test/fixtures/eslint-compatibility/index.js @@ -1,4 +1,3 @@ export default (foo, bar) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/restrict-plus-operands return foo + bar; }; 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 21881cac..00000000 --- a/source/test/fixtures/esm/index.test-d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import {expectType} from '../../../../index.js'; -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/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 2685e51e..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 '../../../../index.js'; -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/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/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/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-non-barrel-main/foo.test-d.ts b/source/test/fixtures/test-non-barrel-main/foo.test-d.ts index 01b6801e..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 '../../../index.js'; -import one from './foo'; +import one from './foo.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); 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 155aa37d..00000000 --- a/source/test/fixtures/tsx/component-type/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; -import React from '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 8537ecf7..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 '../../../../index.js'; -import {Unicorn} from '.'; - -expectType(); - -expectError(); -expectError(); -expectError(); diff --git a/source/test/fixtures/tsx/component-type/package.json b/source/test/fixtures/tsx/component-type/package.json deleted file mode 100644 index 4b4ec164..00000000 --- a/source/test/fixtures/tsx/component-type/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "foo", - "type": "module", - "files": [ - "index.js", - "index.d.ts" - ], - "dependencies": { - "react": "*" - } -} 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 5a3a2d9e..00000000 --- a/source/test/fixtures/tsx/component/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -export class Unicorn extends React.Component { - constructor(props) { - super(props); - } - - render() { - return

{this.props.rainbow}

; - } -} diff --git a/source/test/fixtures/tsx/component/index.test-d.tsx b/source/test/fixtures/tsx/index.test-d.tsx similarity index 59% rename from source/test/fixtures/tsx/component/index.test-d.tsx rename to source/test/fixtures/tsx/index.test-d.tsx index 8537ecf7..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 '../../../../index.js'; -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/package.json b/source/test/fixtures/tsx/package.json similarity index 62% rename from source/test/fixtures/tsx/component/package.json rename to source/test/fixtures/tsx/package.json index 4b4ec164..4e76501a 100644 --- a/source/test/fixtures/tsx/component/package.json +++ b/source/test/fixtures/tsx/package.json @@ -6,6 +6,9 @@ "index.d.ts" ], "dependencies": { - "react": "*" + "react": "18" + }, + "imports": { + "#tsd": "../../../index.js" } } 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 0aea555f..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 '../../../index.js'; -import one from './utils'; +import one from './utils/index.js'; expectType(one('foo', 'bar')); expectType(one(1, 2)); diff --git a/source/test/fixtures/undefined-symbol/index.test-d.ts b/source/test/fixtures/undefined-symbol/index.test-d.ts index f5a02960..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 '../../../../index.js'; +import {expectType} from '../../../index.js'; // Identifier `bar` has no Symbol const anyCall = (foo: any) => foo.bar(); diff --git a/source/test/test.ts b/source/test/test.ts index fb695dc4..1356c68e 100644 --- a/source/test/test.ts +++ b/source/test/test.ts @@ -10,12 +10,10 @@ import { noDiagnostics, } from './_utils.js'; -test('throw if no type definition was found', verifyTsdFails, 'no-tsd', cwd => ( - `The type definition \`index.d.ts\` does not exist at \`${path.join(cwd, 'index.d.ts')}\`. Is the path correct? Create one and try again.` -)); +// TODO: remove unused fixtures test('throw if no test is found', verifyTsdFails, 'no-test', cwd => ( - `The test file \`index.test-d.ts\` or \`index.test-d.tsx\` does not exist in \`${cwd}\`. Create one and try again.` + `No test files were found in \`${cwd}\` or in any of its subdirectories.` )); test('return diagnostics', verifyTsd, 'failure', [ @@ -27,26 +25,6 @@ test('return diagnostics from imported files as well', verifyTsdWithFileNames, ' [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', verifyTsdWithFileNames, 'no-files', [ - [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', noDiagnostics, 'files-folder'); - -test('allow specifying negative gitignore-style patterns in `files` list', verifyTsd, 'files-gitignore-patterns/negative-pattern', [ - [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', noDiagnostics, 'files-gitignore-patterns/negative-pattern-negated'); - -test('allow specifying root marker (/) gitignore-style patterns in `files` list', noDiagnostics, 'files-gitignore-patterns/root-marker-pattern'); - -test('allow specifying glob patterns containing typings file in `files` list', noDiagnostics, 'files-glob'); - -test('fail if `typings` property is used instead of `types`', verifyTsdWithFileNames, 'types-property/typings', [ - [3, 1, 'error', 'Use property `types` instead of `typings`.', 'package.json'], -]); - 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'], ]); @@ -74,8 +52,6 @@ test('use moduleResolution `node16` when module is `node16` in tsconfig.json', n test('use moduleResolution `node16` when module is `node16` in package.json', noDiagnostics, 'module-resolution/node16-from-package-json'); -test('add support for esm with esModuleInterop', noDiagnostics, 'esm'); - test('add DOM support by default', noDiagnostics, 'dom'); test('a lib option in package.json overrdides a lib option in tsconfig.json', noDiagnostics, 'lib-config/lib-from-package-json-overrides-tsconfig-json'); @@ -86,18 +62,6 @@ test('return no diagnostics', noDiagnostics, 'success'); test('support non-barrel main', noDiagnostics, 'test-non-barrel-main'); -test('allow omitting `types` property when `main` property is missing but main is a barrel (`index.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/without-main', [ - [6, 0, 'error', 'Expected an error, but found none.'], -]); - -test('allow omitting `types` property when `main` property is set to a barrel (`index.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/with-main-barrel', [ - [6, 0, 'error', 'Expected an error, but found none.'], -]); - -test('allow omitting `types` property when `main` property is set to non-barrel (`foo.js`) and .d.ts file matches main', verifyTsd, 'no-explicit-types-property/with-main-other', [ - [6, 0, 'error', 'Expected an error, but found none.'], -]); - test('support testing in sub-directories', noDiagnostics, 'test-in-subdir'); test('support top-level await', noDiagnostics, 'top-level-await'); @@ -114,9 +78,7 @@ test('missing import', verifyTsd, 'missing-import', [ [3, 18, 'error', 'Cannot find name \'Primitive\'.'], ]); -test('tsx component', noDiagnostics, 'tsx/component'); - -test('tsx component type', noDiagnostics, 'tsc/component-type'); +test('tsx component', noDiagnostics, 'tsx'); test('loose types', verifyTsd, 'strict-types/loose', [ [5, 0, 'error', 'Parameter type `string` is declared too wide for argument type `"cat"`.'], @@ -135,11 +97,9 @@ test('loose types', verifyTsd, 'strict-types/loose', [ test('strict types', noDiagnostics, 'strict-types/strict'); -test('typings in custom directory', verifyTsd, - {fixtureName: 'typings-custom-dir', tsdOptions: {typingsFile: 'utils/index.d.ts'}}, [ - [5, 19, 'error', 'Argument of type \'number\' is not assignable to parameter of type \'string\'.'], - ], -); +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('specify test files manually', verifyTsd, {fixtureName: 'specify-test-files', tsdOptions: {testFiles: ['unknown.test.ts', 'second.test.ts']}}, [ @@ -149,7 +109,7 @@ test('specify test files manually', verifyTsd, test('fails if typings file is not found in the specified path', verifyTsdFails, {fixtureName: 'typings-custom-dir', tsdOptions: {testFiles: ['unknown.test.ts']}}, - cwd => `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.`, + () => 'Could not find any test files with the given pattern(s).', ); test('includes extended config files along with found ones', verifyTsd, 'ts-config-extends', [ @@ -222,3 +182,5 @@ test('custom tsd errors are created correctly', t => { 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 beab5ac4..a49bd0bc 100644 --- a/tsconfig.tsd.json +++ b/tsconfig.tsd.json @@ -1,24 +1,8 @@ { + "extends": "@sindresorhus/tsconfig", "compilerOptions": { - "outDir": "dist", - "target": "ES2022", // Node.js 18 - "lib": [ - "ES2022" - ], - "module": "node16", - "moduleResolution": "node16", - "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; From 1e9861172abf1887975c174b773778a76570668c Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Thu, 22 Feb 2024 20:25:31 -0600 Subject: [PATCH 16/18] rename workflow to `.yml` to match editorconfig --- .github/workflows/{main.yaml => main.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{main.yaml => main.yml} (100%) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yml similarity index 100% rename from .github/workflows/main.yaml rename to .github/workflows/main.yml From cc776508113575611c26c13463dfac10d3cb934a Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Thu, 22 Feb 2024 20:25:49 -0600 Subject: [PATCH 17/18] add Node.js 21 to test matrix --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 346585cf..a768beba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,7 @@ jobs: fail-fast: false matrix: node-version: + - 21 - 20 - 18 steps: From ca4f46e61328aac7e4677f96acc1ab1ad947a0cc Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Thu, 22 Feb 2024 20:28:20 -0600 Subject: [PATCH 18/18] provide `tsconfig.tsd.json` path to `xo` --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 3ddd02b6..90aa5258 100644 --- a/package.json +++ b/package.json @@ -80,16 +80,16 @@ "ignores": [ "source/test/fixtures" ], + "parserOptions": { + "project": "./tsconfig.tsd.json" + }, "rules": { "no-bitwise": "off", - "unicorn/prevent-abbreviations": [ - "error", - { - "replacements": { - "doc": false - } + "unicorn/prevent-abbreviations": ["error", { + "replacements": { + "doc": false } - ] + }] } } }