@peerigon/typescript-exercises-tools
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -6,2 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.assertProgramToOnlyHaveExpectedErrors = void 0; | ||
const typescript_1 = __importDefault(require("./typescript")); | ||
@@ -24,5 +25,4 @@ const diagnostics_1 = require("./diagnostics"); | ||
}; | ||
exports.assertProgramToOnlyHaveExpectedErrors = (programPath, compilerOptions = findCompilerOptionsFor(programPath)) => { | ||
const assertProgramToOnlyHaveExpectedErrors = (programPath, compilerOptions = findCompilerOptionsFor(programPath)) => { | ||
const program = typescript_1.default.createProgram([programPath], compilerOptions); | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const sourceFile = program.getSourceFile(programPath); | ||
@@ -40,2 +40,3 @@ const actualDiagnostics = Array.from(typescript_1.default.getPreEmitDiagnostics(program, sourceFile)); | ||
}; | ||
exports.assertProgramToOnlyHaveExpectedErrors = assertProgramToOnlyHaveExpectedErrors; | ||
//# sourceMappingURL=assertions.js.map |
@@ -6,2 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.pluginName = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
@@ -8,0 +9,0 @@ const fs_1 = __importDefault(require("fs")); |
@@ -12,4 +12,4 @@ import ts from "./typescript"; | ||
export declare const matchesDiagnostic: (diagnosticA: ts.Diagnostic) => (diagnosticB: ts.Diagnostic) => boolean; | ||
export declare const getUnexpectedDiagnostics: (actualDiagnostics: ts.Diagnostic[], expectedDiagnostics: ts.Diagnostic[]) => ts.Diagnostic[]; | ||
export declare const getMissingExpectedDiagnostics: (actualDiagnostics: ts.Diagnostic[], expectedDiagnostics: ts.Diagnostic[]) => ts.Diagnostic[]; | ||
export declare const lowerSeverityOfExpectedDiagnostics: (actualDiagnostics: ts.Diagnostic[], expectedDiagnostics: ts.Diagnostic[]) => ts.Diagnostic[]; | ||
export declare const getUnexpectedDiagnostics: (actualDiagnostics: Array<ts.Diagnostic>, expectedDiagnostics: Array<ts.Diagnostic>) => ts.Diagnostic[]; | ||
export declare const getMissingExpectedDiagnostics: (actualDiagnostics: Array<ts.Diagnostic>, expectedDiagnostics: Array<ts.Diagnostic>) => ts.Diagnostic[]; | ||
export declare const lowerSeverityOfExpectedDiagnostics: (actualDiagnostics: Array<ts.Diagnostic>, expectedDiagnostics: Array<ts.Diagnostic>) => ts.Diagnostic[]; |
@@ -6,17 +6,30 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.lowerSeverityOfExpectedDiagnostics = exports.getMissingExpectedDiagnostics = exports.getUnexpectedDiagnostics = exports.matchesDiagnostic = exports.getExpectedDiagnostics = void 0; | ||
const typescript_1 = __importDefault(require("./typescript")); | ||
const const_1 = require("./const"); | ||
exports.getExpectedDiagnostics = (sourceFile) => { | ||
const parseAnnotations = (sourceFile) => { | ||
const sourceCode = sourceFile.getFullText(); | ||
const annotations = sourceCode.matchAll(/(.*?\/\/ 💥? ?Expect error (\d+):? ?(.*?)\r?\n\s*)([^\n\r]*)/g); | ||
const regex = /([\t ]*?\/\/ 💥? ?Expect error (\d+):? ?(.*?)\n)(?:\n|\s|.*?\/\/ 💥? ?Expect error \d+.*?\n)*([^\n\r]*)/g; | ||
let match = regex.exec(sourceCode); | ||
const results = []; | ||
while (match !== null) { | ||
const [, comment, code, message, nextLine] = match; | ||
const nextLineStart = regex.lastIndex - nextLine.length; | ||
results.push({ comment, code, message, nextLine, nextLineStart }); | ||
// Rewind index to end of last comment to be able to parse multiple comments | ||
regex.lastIndex = match.index + comment.length; | ||
match = regex.exec(sourceCode); | ||
} | ||
return results; | ||
}; | ||
const getExpectedDiagnostics = (sourceFile) => { | ||
const annotations = parseAnnotations(sourceFile); | ||
return Array.from(annotations, (annotation) => { | ||
const [, comment, code, expectedErrorMessage, nextLine] = annotation; | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const start = annotation.index + comment.length; | ||
const { code, message, nextLine, nextLineStart } = annotation; | ||
const messageText = `Missing error ${code}` + | ||
(expectedErrorMessage === "" ? "" : ` "${expectedErrorMessage}"`); | ||
(message === "" ? "" : ` "${message}"`); | ||
return { | ||
file: sourceFile, | ||
category: typescript_1.default.DiagnosticCategory.Error, | ||
start, | ||
start: nextLineStart, | ||
length: nextLine.length, | ||
@@ -29,2 +42,3 @@ code: parseInt(code), | ||
}; | ||
exports.getExpectedDiagnostics = getExpectedDiagnostics; | ||
const isInSameRange = (diagnosticA, diagnosticB) => { | ||
@@ -45,3 +59,3 @@ const startA = diagnosticA.start; | ||
}; | ||
exports.matchesDiagnostic = (diagnosticA) => { | ||
const matchesDiagnostic = (diagnosticA) => { | ||
return (diagnosticB) => { | ||
@@ -55,11 +69,14 @@ return (diagnosticA.file !== undefined && | ||
}; | ||
exports.getUnexpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
exports.matchesDiagnostic = matchesDiagnostic; | ||
const getUnexpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
const unexpectedDiagnostics = actualDiagnostics.filter((actualDiagnostic) => expectedDiagnostics.some(exports.matchesDiagnostic(actualDiagnostic)) === false); | ||
return unexpectedDiagnostics; | ||
}; | ||
exports.getMissingExpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
exports.getUnexpectedDiagnostics = getUnexpectedDiagnostics; | ||
const getMissingExpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
const missingExpectedDiagnostics = expectedDiagnostics.filter((expectedDiagnostic) => actualDiagnostics.some(exports.matchesDiagnostic(expectedDiagnostic)) === false); | ||
return missingExpectedDiagnostics; | ||
}; | ||
exports.lowerSeverityOfExpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
exports.getMissingExpectedDiagnostics = getMissingExpectedDiagnostics; | ||
const lowerSeverityOfExpectedDiagnostics = (actualDiagnostics, expectedDiagnostics) => { | ||
return expectedDiagnostics.map((expectedDiagnostic) => { | ||
@@ -75,2 +92,3 @@ const actualDiagnostic = actualDiagnostics.find(exports.matchesDiagnostic(expectedDiagnostic)); | ||
}; | ||
exports.lowerSeverityOfExpectedDiagnostics = lowerSeverityOfExpectedDiagnostics; | ||
//# sourceMappingURL=diagnostics.js.map |
declare const init: () => { | ||
create: (info: import("typescript/lib/tsserverlibrary").server.PluginCreateInfo) => import("typescript/lib/tsserverlibrary").LanguageService; | ||
create: (info: ts.server.PluginCreateInfo) => import("typescript/lib/tsserverlibrary").LanguageService; | ||
}; | ||
export default init; |
@@ -7,2 +7,3 @@ "use strict"; | ||
create: (info) => { | ||
info.project.projectService.logger.info("Started typescript-exercise-tools plugin!"); | ||
const proxy = Object.create(null); | ||
@@ -13,3 +14,2 @@ Object.entries(info.languageService) | ||
}); | ||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
proxy.getSemanticDiagnostics = (...paths) => { | ||
@@ -16,0 +16,0 @@ const actualDiagnostics = info.languageService.getSemanticDiagnostics(...paths); |
@@ -9,2 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.tsserverlibrary = void 0; | ||
const typescript_1 = __importDefault(require("typescript")); | ||
@@ -11,0 +12,0 @@ const tsserverlibrary_js_1 = __importDefault(require("typescript/lib/tsserverlibrary.js")); |
{ | ||
"name": "@peerigon/typescript-exercises-tools", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Tools for writing and validating TypeScript exercises", | ||
"keywords": ["typescript", "language", "service", "server", "validate", "validation", "test", "types", "exercise"], | ||
"main": "dist/main.js", | ||
"repository": "https://github.com/peerigon/typescript-exercises-tools", | ||
"author": "Peerigon GmbH", | ||
"license": "Unlicense", | ||
"main": "plugin.js", | ||
"keywords": [ | ||
"typescript", | ||
"language", | ||
"service", | ||
"server", | ||
"validate", | ||
"validation", | ||
"test", | ||
"types", | ||
"exercise" | ||
], | ||
"files": [ | ||
"dist", | ||
"plugin.js", | ||
"plugin.d.ts", | ||
"tests.js", | ||
"tests.d.ts" | ||
], | ||
"scripts": { | ||
@@ -11,44 +31,33 @@ "build": "run-s build:clean build:tsc", | ||
"build:tsc": "tsc -p ./tsconfig.build.json", | ||
"test": "jest", | ||
"posttest": "run-p lint", | ||
"lint": "eslint --ext ts --ignore-path ./.eslintignore src", | ||
"prepare": "run-p build", | ||
"watch:build:tsc": "npm run build:tsc -- -w", | ||
"prepublishOnly": "pubcop", | ||
"release": "standard-version" | ||
"build:tsc:watch": "npm run build:tsc -- -w", | ||
"test": "run-s test:unit test:lint", | ||
"test:unit": "jest", | ||
"test:lint": "eslint --ext ts --ignore-path ./.eslintignore src", | ||
"prepublishOnly": "run-p build" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/peerigon/typescript-exercises-tools.git" | ||
}, | ||
"author": "peerigon <developers@peerigon.com>", | ||
"license": "Unlicense", | ||
"peerDependencies": { | ||
"typescript": "^3.6.4" | ||
"typescript": "^4.2.4" | ||
}, | ||
"devDependencies": { | ||
"@peerigon/typescript-exercises-tools": "file:/.", | ||
"@types/jest": "^24.0.18", | ||
"@types/node": "^12.7.12", | ||
"@typescript-eslint/eslint-plugin": "^2.12.0", | ||
"@typescript-eslint/parser": "^2.12.0", | ||
"eslint": "^5.16.0", | ||
"eslint-config-peerigon": "^25.0.1", | ||
"eslint-import-resolver-typescript": "^2.0.0", | ||
"eslint-plugin-prefer-arrow": "^1.1.7", | ||
"jest": "^24.9.0", | ||
"nodemon": "^2.0.2", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@types/jest": "^26.0.22", | ||
"@types/node": "^14.14.41", | ||
"@typescript-eslint/eslint-plugin": "^4.22.0", | ||
"@typescript-eslint/parser": "^4.22.0", | ||
"eslint": "^7.24.0", | ||
"eslint-config-peerigon": "^30.0.2", | ||
"eslint-import-resolver-typescript": "^2.4.0", | ||
"eslint-plugin-prefer-arrow": "^1.2.3", | ||
"jest": "^26.6.3", | ||
"nodemon": "^2.0.7", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^1.19.1", | ||
"pubcop": "^1.0.2", | ||
"rimraf": "^3.0.0", | ||
"standard-version": "^7.0.1", | ||
"ts-jest": "^24.1.0", | ||
"ts-node": "^8.4.1", | ||
"typescript": "^3.6.4" | ||
}, | ||
"files": [ | ||
"dist", | ||
"plugin.js" | ||
] | ||
"prettier": "^2.2.1", | ||
"rimraf": "^3.0.2", | ||
"standard-version": "^9.2.0", | ||
"ts-jest": "^26.5.5", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.4" | ||
} | ||
} |
@@ -23,3 +23,3 @@ @peerigon/typescript-exercises-tools | ||
With the TypeScript language server plugin provided by this module, these expected type errors will show up as a suggestion instead of an error: | ||
With the TypeScript language service plugin provided by this module, these expected type errors will show up as a suggestion instead of an error: | ||
@@ -36,3 +36,3 @@ ![Screenshot of an editor that shows a type error as a suggestion](./docs/editor-screenshot-1.jpg) | ||
```ts | ||
import {assertProgramToOnlyHaveExpectedErrors} from "@peerigon/typescript-exercises-tools"; | ||
import {assertProgramToOnlyHaveExpectedErrors} from "@peerigon/typescript-exercises-tools/tests"; | ||
@@ -61,3 +61,3 @@ test("The program has only expected errors", () => { | ||
"plugins": [{ | ||
"name": "@peerigon/typescript-exercises-tools/plugin" | ||
"name": "@peerigon/typescript-exercises-tools" | ||
}] | ||
@@ -76,2 +76,19 @@ } | ||
## Support for multiple errors | ||
If you expect more than one error, you can add multiple comments, like this: | ||
```ts | ||
type Person = { | ||
readonly name: string; | ||
}; | ||
const person: Person = { | ||
name: "Bob", | ||
}; | ||
// 💥 Expect error 2704: … cannot be a read-only property. | ||
// 💥 Expect error 2790: … must be optional. | ||
delete person.name; | ||
``` | ||
## API | ||
@@ -84,3 +101,3 @@ | ||
```ts | ||
import {assertProgramToOnlyHaveExpectedErrors} from "@peerigon/typescript-exercises-tools"; | ||
import {assertProgramToOnlyHaveExpectedErrors} from "@peerigon/typescript-exercises-tools/tests"; | ||
@@ -87,0 +104,0 @@ assertProgramToOnlyHaveExpectedErrors("/path/to/module.ts"); // may throw |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
27684
26
227
116
20
2
1