refactor - Extract the stacktrace parsing to util (#1704)

This commit is contained in:
Sheng Chen 2024-06-27 14:17:34 +08:00 коммит произвёл GitHub
Родитель f343d8984a
Коммит afe9114e39
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 59 добавлений и 42 удалений

Просмотреть файл

@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import * as path from 'path';
import { Location, MarkdownString, Range, TestItem } from 'vscode';
import { Location, MarkdownString, TestItem } from 'vscode';
import { IRunTestContext } from '../../types';
import { processStackTraceLine } from '../utils';
export abstract class RunnerResultAnalyzer {
constructor(protected testContext: IRunTestContext) { }
@ -21,46 +21,14 @@ export abstract class RunnerResultAnalyzer {
}
protected processStackTrace(data: string, traces: MarkdownString, currentItem: TestItem | undefined, projectName: string): void {
const traceRegExp: RegExp = /(\s?at\s+)([\w$\\.]+\/)?((?:[\w$]+\.)+[<\w$>]+)\((.*)\)/;
const traceResults: RegExpExecArray | null = traceRegExp.exec(data);
if (traceResults) {
const fullyQualifiedName: string = traceResults[3];
if (this.isExcluded(fullyQualifiedName)) {
return;
}
const location: string = traceResults[4];
let sourceName: string | undefined;
let lineNumLiteral: string | undefined;
const locationResult: RegExpExecArray | null = /([\w-$]+\.java):(\d+)/.exec(location);
if (locationResult) {
sourceName = locationResult[1];
lineNumLiteral = locationResult[2];
}
if (!sourceName || !lineNumLiteral) {
traces.appendText(data);
} else {
const atLiteral: string = traceResults[1];
const optionalModuleName: string = traceResults[2] || '';
traces.appendText(atLiteral);
traces.appendMarkdown(`${optionalModuleName + fullyQualifiedName}([${sourceName}:${lineNumLiteral}](command:_java.test.openStackTrace?${encodeURIComponent(JSON.stringify([data, projectName]))}))`);
if (currentItem && path.basename(currentItem.uri?.fsPath || '') === sourceName) {
const lineNum: number = parseInt(lineNumLiteral, 10);
if (currentItem.uri) {
if (!currentItem.range || (currentItem.range.start.line + 1 < lineNum && currentItem.range.end.line + 1 > lineNum)) {
this.testMessageLocation = new Location(currentItem.uri, new Range(lineNum - 1, 0, lineNum, 0));
} else {
this.testMessageLocation = new Location(currentItem.uri, new Range(currentItem.range.start.line, 0, currentItem.range.start.line, 0));
}
}
}
}
} else {
// '<' & '>' will be escaped when displaying the test message, so replacing them to '[' & ']'.
traces.appendText(data.replace(/</g, '[').replace(/>/g, ']'));
if (this.isExcluded(data)) {
return;
}
const location: Location | undefined = processStackTraceLine(data, traces, currentItem, projectName);
if (location) {
this.testMessageLocation = location;
}
traces.appendMarkdown('<br/>');
}
private isExcluded(stacktrace: string): boolean {

Просмотреть файл

@ -1,10 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import { Location, TestItem, TestMessage, TestRun, Uri } from 'vscode';
import { Location, MarkdownString, Range, TestItem, TestMessage, TestRun, Uri } from 'vscode';
import { JavaTestRunnerCommands } from '../constants';
import { asRange } from '../controller/utils';
import { executeJavaLanguageServerCommand } from '../utils/commandUtils';
import * as path from 'path';
export async function findTestLocation(fullName: string): Promise<Location | undefined> {
const location: any | undefined = await executeJavaLanguageServerCommand<any>(
@ -52,3 +53,51 @@ export enum TestResultState {
// Test run failed for some other reason (compilation error, timeout, etc)
Errored = 6,
}
/**
* Append the line of stack trace to the traces.
* @param lineOfMessage line of stack trace.
* @param traces stack trace in markdown string.
* @param currentItem current test item.
* @param projectName project name.
*/
export function processStackTraceLine(lineOfMessage: string, traces: MarkdownString, currentItem: TestItem | undefined, projectName: string): Location | undefined {
let testMessageLocation: Location | undefined;
const traceResults: RegExpExecArray | null = /(\s?at\s+)([\w$\\.]+\/)?((?:[\w$]+\.)+[<\w$>]+)\((.*)\)/.exec(lineOfMessage);
if (traceResults) {
const fullyQualifiedName: string = traceResults[3];
const location: string = traceResults[4];
let sourceName: string | undefined;
let lineNumLiteral: string | undefined;
const locationResult: RegExpExecArray | null = /([\w-$]+\.java):(\d+)/.exec(location);
if (locationResult) {
sourceName = locationResult[1];
lineNumLiteral = locationResult[2];
}
if (!sourceName || !lineNumLiteral) {
traces.appendText(lineOfMessage);
} else {
const atLiteral: string = traceResults[1];
const optionalModuleName: string = traceResults[2] || '';
traces.appendText(atLiteral);
traces.appendMarkdown(`${optionalModuleName + fullyQualifiedName}([${sourceName}:${lineNumLiteral}](command:_java.test.openStackTrace?${encodeURIComponent(JSON.stringify([lineOfMessage, projectName]))}))`);
if (currentItem && path.basename(currentItem.uri?.fsPath || '') === sourceName) {
const lineNum: number = parseInt(lineNumLiteral, 10);
if (currentItem.uri) {
if (!currentItem.range || (currentItem.range.start.line + 1 < lineNum && currentItem.range.end.line + 1 > lineNum)) {
testMessageLocation = new Location(currentItem.uri, new Range(lineNum - 1, 0, lineNum, 0));
} else {
testMessageLocation = new Location(currentItem.uri, new Range(currentItem.range.start.line, 0, currentItem.range.start.line, 0));
}
}
}
}
} else {
// '<' & '>' will be escaped when displaying the test message, so replacing them to '[' & ']'.
traces.appendText(lineOfMessage.replace(/</g, '[').replace(/>/g, ']'));
}
traces.appendMarkdown('<br/>');
return testMessageLocation
}