UNPKG

types-testing

Version:

Test TypeScript types at test runner runtime - Works seamlessly with Jest, Vitest, and Bun.

135 lines (134 loc) 4.54 kB
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 };