UNPKG

dts-critic

Version:

Checks a new .d.ts against the Javascript source and tells you what problems it has

260 lines (248 loc) 9.4 kB
import { findDtsName, getNpmInfo, dtToNpmName, parseExportErrorKind, dtsCritic, checkSource, ErrorKind, ExportErrorKind } from "./index"; function suite(description: string, tests: { [s: string]: () => void; }) { describe(description, () => { for (const k in tests) { test(k, tests[k], 10 * 1000); } }); } suite("findDtsName", { absolutePath() { expect(findDtsName("~/dt/types/jquery/index.d.ts")).toBe("jquery"); }, relativePath() { expect(findDtsName("jquery/index.d.ts")).toBe("jquery"); }, currentDirectory() { expect(findDtsName("index.d.ts")).toBe("dts-critic"); }, relativeCurrentDirectory() { expect(findDtsName("./index.d.ts")).toBe("dts-critic"); }, emptyDirectory() { expect(findDtsName("")).toBe("dts-critic"); }, }); suite("getNpmInfo", { nonNpm() { expect(getNpmInfo("parseltongue")).toEqual({ isNpm: false }); }, npm() { expect(getNpmInfo("typescript")).toEqual({ isNpm: true, versions: expect.arrayContaining(["3.7.5"]), tags: expect.objectContaining({ latest: expect.stringContaining("") }), }); }, }); suite("dtToNpmName", { nonScoped() { expect(dtToNpmName("content-type")).toBe("content-type"); }, scoped() { expect(dtToNpmName("babel__core")).toBe("@babel/core"); }, }); suite("parseExportErrorKind", { existent() { expect(parseExportErrorKind("NoDefaultExport")).toBe(ErrorKind.NoDefaultExport); }, existentDifferentCase() { expect(parseExportErrorKind("JspropertyNotinDTS")).toBe(ErrorKind.JsPropertyNotInDts); }, nonexistent() { expect(parseExportErrorKind("FakeError")).toBe(undefined); } }); const allErrors: Map<ExportErrorKind, true> = new Map([ [ErrorKind.NeedsExportEquals, true], [ErrorKind.NoDefaultExport, true], [ErrorKind.JsSignatureNotInDts, true], [ErrorKind.DtsSignatureNotInJs, true], [ErrorKind.DtsPropertyNotInJs, true], [ErrorKind.JsPropertyNotInDts, true], ]); suite("checkSource", { noErrors() { expect(checkSource( "noErrors", "testsource/noErrors.d.ts", "testsource/noErrors.js", allErrors, false, )).toEqual([]); }, missingJsProperty() { expect(checkSource( "missingJsProperty", "testsource/missingJsProperty.d.ts", "testsource/missingJsProperty.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.JsPropertyNotInDts, message: `The declaration doesn't match the JavaScript module 'missingJsProperty'. Reason: The JavaScript module exports a property named 'foo', which is missing from the declaration module.` } ])); }, noMissingWebpackProperty() { expect(checkSource( "missingJsProperty", "testsource/webpackPropertyNames.d.ts", "testsource/webpackPropertyNames.js", allErrors, false, )).toHaveLength(0); }, missingDtsProperty() { expect(checkSource( "missingDtsProperty", "testsource/missingDtsProperty.d.ts", "testsource/missingDtsProperty.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.DtsPropertyNotInJs, message: `The declaration doesn't match the JavaScript module 'missingDtsProperty'. Reason: The declaration module exports a property named 'foo', which is missing from the JavaScript module.`, position: { start: 67, length: 11, }, } ])); }, missingDefaultExport() { expect(checkSource( "missingDefault", "testsource/missingDefault.d.ts", "testsource/missingDefault.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.NoDefaultExport, message: `The declaration doesn't match the JavaScript module 'missingDefault'. Reason: The declaration specifies 'export default' but the JavaScript source does not mention 'default' anywhere. The most common way to resolve this error is to use 'export =' syntax instead of 'export default'. To learn more about 'export =' syntax, see https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.`, position: { start: 0, length: 32, }, } ])); }, missingJsSignatureExportEquals() { expect(checkSource( "missingJsSignatureExportEquals", "testsource/missingJsSignatureExportEquals.d.ts", "testsource/missingJsSignatureExportEquals.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.JsSignatureNotInDts, message: `The declaration doesn't match the JavaScript module 'missingJsSignatureExportEquals'. Reason: The JavaScript module can be called or constructed, but the declaration module cannot.`, } ])); }, missingJsSignatureNoExportEquals() { expect(checkSource( "missingJsSignatureNoExportEquals", "testsource/missingJsSignatureNoExportEquals.d.ts", "testsource/missingJsSignatureNoExportEquals.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.JsSignatureNotInDts, message: `The declaration doesn't match the JavaScript module 'missingJsSignatureNoExportEquals'. Reason: The JavaScript module can be called or constructed, but the declaration module cannot. The most common way to resolve this error is to use 'export =' syntax. To learn more about 'export =' syntax, see https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.`, } ])); }, missingDtsSignature() { expect(checkSource( "missingDtsSignature", "testsource/missingDtsSignature.d.ts", "testsource/missingDtsSignature.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.DtsSignatureNotInJs, message: `The declaration doesn't match the JavaScript module 'missingDtsSignature'. Reason: The declaration module can be called or constructed, but the JavaScript module cannot.`, } ])); }, missingExportEquals() { expect(checkSource( "missingExportEquals", "testsource/missingExportEquals.d.ts", "testsource/missingExportEquals.js", allErrors, false, )).toEqual(expect.arrayContaining([ { kind: ErrorKind.NeedsExportEquals, message: `The declaration doesn't match the JavaScript module 'missingExportEquals'. Reason: The declaration should use 'export =' syntax because the JavaScript source uses 'module.exports =' syntax and 'module.exports' can be called or constructed. To learn more about 'export =' syntax, see https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.`, } ])); }, }); suite("dtsCritic", { noErrors() { expect(dtsCritic("testsource/dts-critic.d.ts", "testsource/dts-critic.js")).toEqual([]); }, noMatchingNpmPackage() { expect(dtsCritic("testsource/parseltongue.d.ts")).toEqual([ { kind: ErrorKind.NoMatchingNpmPackage, message: `Declaration file must have a matching npm package. To resolve this error, either: 1. Change the name to match an npm package. 2. Add a Definitely Typed header with the first line // Type definitions for non-npm package parseltongue-browser Add -browser to the end of your name to make sure it doesn't conflict with existing npm packages.`, }, ]); }, noMatchingNpmVersion() { expect(dtsCritic("testsource/typescript.d.ts")).toEqual([ { kind: ErrorKind.NoMatchingNpmVersion, message: expect.stringContaining(`The types for 'typescript' must match a version that exists on npm. You should copy the major and minor version from the package on npm.`), }, ]); }, nonNpmHasMatchingPackage() { expect(dtsCritic("testsource/tslib.d.ts")).toEqual([ { kind: ErrorKind.NonNpmHasMatchingPackage, message: `The non-npm package 'tslib' conflicts with the existing npm package 'tslib'. Try adding -browser to the end of the name to get tslib-browser `, }, ]); } });