eng: identify ternary expressions in selfhost runner (#227848)

Fixes #227222
pull/227857/head
Connor Peet 2024-09-06 17:19:05 -07:00 committed by GitHub
parent f8785f8021
commit 976e68e620
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 37 additions and 17 deletions

View File

@ -8,6 +8,7 @@ import * as vscode from 'vscode';
import { TestCase, TestConstruct, TestSuite, VSCodeTest } from './testTree';
const suiteNames = new Set(['suite', 'flakySuite']);
const testNames = new Set(['test']);
export const enum Action {
Skip,
@ -19,22 +20,19 @@ export const extractTestFromNode = (src: ts.SourceFile, node: ts.Node, parent: V
return Action.Recurse;
}
let lhs = node.expression;
if (isSkipCall(lhs)) {
const asSuite = identifyCall(node.expression, suiteNames);
const asTest = identifyCall(node.expression, testNames);
const either = asSuite || asTest;
if (either === IdentifiedCall.Skipped) {
return Action.Skip;
}
if (isPropertyCall(lhs) && lhs.name.text === 'only') {
lhs = lhs.expression;
if (either === IdentifiedCall.Nothing) {
return Action.Recurse;
}
const name = node.arguments[0];
const func = node.arguments[1];
if (!name || !ts.isIdentifier(lhs) || !ts.isStringLiteralLike(name)) {
return Action.Recurse;
}
if (!func) {
if (!name || !ts.isStringLiteralLike(name) || !func) {
return Action.Recurse;
}
@ -46,23 +44,45 @@ export const extractTestFromNode = (src: ts.SourceFile, node: ts.Node, parent: V
);
const cparent = parent instanceof TestConstruct ? parent : undefined;
if (lhs.escapedText === 'test') {
// we know this is either a suite or a test because we checked for skipped/nothing above
if (asTest) {
return new TestCase(name.text, range, cparent);
}
if (suiteNames.has(lhs.escapedText.toString())) {
if (asSuite) {
return new TestSuite(name.text, range, cparent);
}
return Action.Recurse;
throw new Error('unreachable');
};
const enum IdentifiedCall {
Nothing,
Skipped,
IsThing,
}
const identifyCall = (lhs: ts.Node, needles: ReadonlySet<string>): IdentifiedCall => {
if (ts.isIdentifier(lhs)) {
return needles.has(lhs.escapedText || lhs.text) ? IdentifiedCall.IsThing : IdentifiedCall.Nothing;
}
if (isPropertyCall(lhs) && lhs.name.text === 'skip') {
return needles.has(lhs.expression.text) ? IdentifiedCall.Skipped : IdentifiedCall.Nothing;
}
if (ts.isParenthesizedExpression(lhs) && ts.isConditionalExpression(lhs.expression)) {
return Math.max(identifyCall(lhs.expression.whenTrue, needles), identifyCall(lhs.expression.whenFalse, needles));
}
return IdentifiedCall.Nothing;
};
const isPropertyCall = (
lhs: ts.LeftHandSideExpression
lhs: ts.Node
): lhs is ts.PropertyAccessExpression & { expression: ts.Identifier; name: ts.Identifier } =>
ts.isPropertyAccessExpression(lhs) &&
ts.isIdentifier(lhs.expression) &&
ts.isIdentifier(lhs.name);
const isSkipCall = (lhs: ts.LeftHandSideExpression) =>
isPropertyCall(lhs) && suiteNames.has(lhs.expression.text) && lhs.name.text === 'skip';