ts-snippet
Version:
A TypeScript snippet testing library for any test framework
115 lines (114 loc) • 4.52 kB
JavaScript
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;
;