UNPKG

ts-snippet

Version:

A TypeScript snippet testing library for any test framework

115 lines (114 loc) 4.52 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.snippet = exports.getVariables = exports.areEquivalentTypeStrings = exports.Snippet = void 0; var tsutils = require("tsutils"); var compiler_1 = require("./compiler"); var expect_1 = require("./expect"); var Snippet = (function () { function Snippet(_files, _compiler) { this._files = _files; this._compiler = _compiler; this.assertFail = function (message) { throw new Error(message); }; this.assertPass = function () { }; this._program = _compiler.compile(_files); } Snippet.prototype.expect = function (fileName) { return new expect_1.Expect(this.fail.bind(this, fileName), this.infer.bind(this, fileName), this.succeed.bind(this, fileName)); }; Snippet.prototype.fail = function (fileName, expectedMessage) { var diagnostics = this._getDiagnostics(fileName); var messages = diagnostics.map(this._compiler.formatDiagnostic); var matched = messages.some(function (message) { return expectedMessage ? expectedMessage.test(message) : true; }); if (!matched) { var receivedMessages = new Set(messages); this.assertFail(expectedMessage && receivedMessages.size > 0 ? "Expected an error matching:\n" + expectedMessage + "\nbut received:\n" + __spread(receivedMessages).join("\n") : "Expected an error"); } else { this.assertPass(); } }; Snippet.prototype.infer = function (fileName, variableName, expectedType) { this.succeed(fileName); var sourceFile = this._program.getSourceFile(fileName); var variables = getVariables(this._program, sourceFile); var actualType = variables[variableName]; if (!actualType) { this.assertFail("Variable '" + variableName + "' not found"); } else if (!areEquivalentTypeStrings(expectedType, actualType)) { this.assertFail("Expected '" + variableName + ": " + actualType + "' to be '" + expectedType + "'"); } else { this.assertPass(); } }; Snippet.prototype.succeed = function (fileName) { var diagnostics = this._getDiagnostics(fileName); if (diagnostics.length) { var _a = __read(diagnostics, 1), diagnostic = _a[0]; this.assertFail(this._compiler.formatDiagnostic(diagnostic)); } else { this.assertPass(); } }; Snippet.prototype._getDiagnostics = function (fileName) { return this._program .getSemanticDiagnostics() .concat(this._compiler.getDiagnostics(fileName)); }; return Snippet; }()); exports.Snippet = Snippet; function areEquivalentTypeStrings(a, b) { var spaces = /\s/g; return a.replace(spaces, "") === b.replace(spaces, ""); } exports.areEquivalentTypeStrings = areEquivalentTypeStrings; function getVariables(program, sourceFile) { var typeChecker = program.getTypeChecker(); var variables = {}; var visitNode = function (node) { if (tsutils.isVariableStatement(node)) { tsutils.forEachDeclaredVariable(node.declarationList, function (node) { variables[node.name.getText()] = typeChecker.typeToString(typeChecker.getTypeAtLocation(node)); }); } else { node.forEachChild(visitNode); } }; sourceFile.forEachChild(visitNode); return variables; } exports.getVariables = getVariables; function snippet(files, compiler) { return new Snippet(files, compiler || new compiler_1.Compiler()); } exports.snippet = snippet;