|
1 | 1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
2 | 2 | // Licensed under the MIT license. |
3 | 3 |
|
4 | | -import { Location, TestItem, TestMessage, TestRun, Uri } from 'vscode'; |
| 4 | +import { Location, MarkdownString, Range, TestItem, TestMessage, TestRun, Uri } from 'vscode'; |
5 | 5 | import { JavaTestRunnerCommands } from '../constants'; |
6 | 6 | import { asRange } from '../controller/utils'; |
7 | 7 | import { executeJavaLanguageServerCommand } from '../utils/commandUtils'; |
| 8 | +import * as path from 'path'; |
8 | 9 |
|
9 | 10 | export async function findTestLocation(fullName: string): Promise<Location | undefined> { |
10 | 11 | const location: any | undefined = await executeJavaLanguageServerCommand<any>( |
@@ -52,3 +53,51 @@ export enum TestResultState { |
52 | 53 | // Test run failed for some other reason (compilation error, timeout, etc) |
53 | 54 | Errored = 6, |
54 | 55 | } |
| 56 | + |
| 57 | +/** |
| 58 | + * Append the line of stack trace to the traces. |
| 59 | + * @param lineOfMessage line of stack trace. |
| 60 | + * @param traces stack trace in markdown string. |
| 61 | + * @param currentItem current test item. |
| 62 | + * @param projectName project name. |
| 63 | + */ |
| 64 | +export function processStackTraceLine(lineOfMessage: string, traces: MarkdownString, currentItem: TestItem | undefined, projectName: string): Location | undefined { |
| 65 | + let testMessageLocation: Location | undefined; |
| 66 | + const traceResults: RegExpExecArray | null = /(\s?at\s+)([\w$\\.]+\/)?((?:[\w$]+\.)+[<\w$>]+)\((.*)\)/.exec(lineOfMessage); |
| 67 | + if (traceResults) { |
| 68 | + const fullyQualifiedName: string = traceResults[3]; |
| 69 | + const location: string = traceResults[4]; |
| 70 | + let sourceName: string | undefined; |
| 71 | + let lineNumLiteral: string | undefined; |
| 72 | + const locationResult: RegExpExecArray | null = /([\w-$]+\.java):(\d+)/.exec(location); |
| 73 | + if (locationResult) { |
| 74 | + sourceName = locationResult[1]; |
| 75 | + lineNumLiteral = locationResult[2]; |
| 76 | + } |
| 77 | + |
| 78 | + if (!sourceName || !lineNumLiteral) { |
| 79 | + traces.appendText(lineOfMessage); |
| 80 | + } else { |
| 81 | + const atLiteral: string = traceResults[1]; |
| 82 | + const optionalModuleName: string = traceResults[2] || ''; |
| 83 | + traces.appendText(atLiteral); |
| 84 | + traces.appendMarkdown(`${optionalModuleName + fullyQualifiedName}([${sourceName}:${lineNumLiteral}](command:_java.test.openStackTrace?${encodeURIComponent(JSON.stringify([lineOfMessage, projectName]))}))`); |
| 85 | + if (currentItem && path.basename(currentItem.uri?.fsPath || '') === sourceName) { |
| 86 | + const lineNum: number = parseInt(lineNumLiteral, 10); |
| 87 | + if (currentItem.uri) { |
| 88 | + if (!currentItem.range || (currentItem.range.start.line + 1 < lineNum && currentItem.range.end.line + 1 > lineNum)) { |
| 89 | + testMessageLocation = new Location(currentItem.uri, new Range(lineNum - 1, 0, lineNum, 0)); |
| 90 | + } else { |
| 91 | + testMessageLocation = new Location(currentItem.uri, new Range(currentItem.range.start.line, 0, currentItem.range.start.line, 0)); |
| 92 | + } |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + } else { |
| 97 | + // '<' & '>' will be escaped when displaying the test message, so replacing them to '[' & ']'. |
| 98 | + traces.appendText(lineOfMessage.replace(/</g, '[').replace(/>/g, ']')); |
| 99 | + } |
| 100 | + traces.appendMarkdown('<br/>'); |
| 101 | + |
| 102 | + return testMessageLocation |
| 103 | +} |
0 commit comments