types-testing
Version:
Test TypeScript types at test runner runtime - Works seamlessly with Jest, Vitest, and Bun.
135 lines (134 loc) • 4.54 kB
JavaScript
import { Assertion } from "../index.js";
import { AssertionState } from "../../src/definitions/__internal/assertions.js";
import ts from "typescript";
const getTypeChecker = (program) => {
const __cache = /* @__PURE__ */ new WeakMap();
const checker = program.getTypeChecker();
checker.__internal = {
identifyTestCall(node) {
var _a;
let result = null;
if (!ts.isCallExpression(node)) {
return result;
}
const props = checker.getTypeAtLocation(node).getProperties();
if (props.length === 0) {
return result;
}
if (__cache.has(props)) {
return __cache.get(props);
}
const getTypeStringFromType = (type) => {
if (!type) {
return null;
}
return checker.typeToString(
type,
void 0,
ts.TypeFormatFlags.InTypeAlias | ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType | ts.TypeFormatFlags.WriteTypeArgumentsOfSignature
);
};
const getProcessedType = (type) => {
const isNotProvided = type.getProperty("__typesTesting_notProvided") !== void 0;
if (isNotProvided) {
return;
}
return type;
};
for (const prop of props) {
const name = checker.symbolToString(prop);
if (name === "[__typesTesting_expectCall]") {
const receivedType = getProcessedType(checker.getTypeOfSymbol(prop));
result = {
type: "expect",
props: {
receivedType
}
};
break;
}
if (name === "[__typesTesting_assertionCall]") {
const propType = checker.getTypeOfSymbol(prop);
const getTypeFromProp = (key) => {
const innerProp = propType.getProperty(key);
if (!innerProp) {
return;
}
return checker.getTypeOfSymbol(innerProp);
};
const assertionName = getTypeFromProp("assertionName");
if ((assertionName == null ? void 0 : assertionName.value) === void 0) {
break;
}
const assertionFn = (_a = Assertion) == null ? void 0 : _a[assertionName.value];
if (assertionFn === void 0) {
break;
}
const assertionState = getTypeFromProp("assertionState");
if ((assertionState == null ? void 0 : assertionState.value) === void 0) {
break;
}
let receivedType = getTypeFromProp("receivedType");
if (receivedType === void 0) {
break;
}
let expectedType = getTypeFromProp("expectedType");
if (expectedType === void 0) {
break;
}
receivedType = getProcessedType(receivedType);
expectedType = getProcessedType(expectedType);
const receivedTypeString = getTypeStringFromType(receivedType);
const expectedTypeString = getTypeStringFromType(expectedType);
const needTypeArgument = assertionFn.needTypeArgument;
const isNegated = assertionState.value === AssertionState.Negated;
result = {
type: "assertion",
props: {
assertionFn,
isNegated,
receivedType,
expectedType,
receivedTypeString,
expectedTypeString,
needTypeArgument
}
};
}
}
__cache.set(props, result);
return result;
},
postIdentifyTestCall(node, forExpectCall) {
var _a;
if (forExpectCall) {
const callerNode2 = node;
const expectCallExpressionText = node.expression.getText();
return {
callerNode: callerNode2,
expectCallExpressionText
};
}
if (ts.isPropertyAccessExpression(node.expression)) {
const callerNode2 = node.expression.name;
const assertionCallExpressionText2 = node.expression.name.getText();
const expectCallExpressionText = (_a = node.getFirstToken()) == null ? void 0 : _a.getText();
return {
callerNode: callerNode2,
assertionCallExpressionText: assertionCallExpressionText2,
expectCallExpressionText
};
}
const callerNode = node;
const assertionCallExpressionText = node.expression.getText();
return {
callerNode,
assertionCallExpressionText
};
}
};
return checker;
};
export {
getTypeChecker
};