Skip to content

Commit e6cdf9d

Browse files
authored
Merge pull request #2920 from Particular/john/stack_tests
Refactor stack trace formatter and add unit tests
2 parents 99f8a2c + 019f5dd commit e6cdf9d

3 files changed

Lines changed: 385 additions & 91 deletions

File tree

src/Frontend/src/components/messages/StacktraceFormatter.vue

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts" setup>
22
import { ref, watch } from "vue";
3+
import { type Language, type StackTraceElement, languages, detectLanguagesInOrder, formatStackTrace } from "./StacktraceFormatter/stacktraceFormatter";
34
45
// Define TypeScript interfaces for settings and supported languages
56
interface NetStackOptions {
@@ -13,26 +14,6 @@ interface NetStackOptions {
1314
line?: string;
1415
}
1516
16-
interface Language {
17-
name: string;
18-
at: string;
19-
in: string;
20-
line: string;
21-
}
22-
23-
type Text = string;
24-
25-
interface Node {
26-
params: Array<{ name: string; type: string }>;
27-
type: string;
28-
lineNumber?: number;
29-
file?: string;
30-
method: string;
31-
spaces: string;
32-
}
33-
34-
type Element = Text | Node;
35-
3617
// Props
3718
const props = withDefaults(defineProps<{ stackTrace: string; options?: NetStackOptions }>(), {
3819
options: () => ({
@@ -47,80 +28,10 @@ const props = withDefaults(defineProps<{ stackTrace: string; options?: NetStackO
4728
}),
4829
});
4930
50-
// Supported languages and their keywords
51-
const languages: Language[] = [
52-
{ name: "english", at: "at", in: "in", line: "line" },
53-
{ name: "danish", at: "ved", in: "i", line: "linje" },
54-
{ name: "german", at: "bei", in: "in", line: "Zeile" },
55-
{ name: "spanish", at: "en", in: "en", line: "línea" },
56-
{ name: "russian", at: "в", in: "в", line: "строка" },
57-
{ name: "chinese", at: "", in: "位置", line: "行号" },
58-
];
59-
6031
// Reactive variables and setup state
61-
const formattedStack = ref<Element[]>([]);
32+
const formattedStack = ref<StackTraceElement[]>([]);
6233
const selectedLanguage = ref<Language>(languages[0]);
6334
64-
// Helper function to detect languages in the stack trace
65-
const detectLanguagesInOrder = (text: string): Language[] => {
66-
const languageRegexes = {
67-
english: /\s+at .*?\)/g,
68-
danish: /\s+ved .*?\)/g,
69-
german: /\s+bei .*?\)/g,
70-
spanish: /\s+en .*?\)/g,
71-
russian: /\s+в .*?\)/g,
72-
chinese: /\s+.*?\)/g,
73-
};
74-
75-
const detectedLanguages: Language[] = [];
76-
for (const lang in languageRegexes) {
77-
if (languageRegexes[lang as keyof typeof languageRegexes].test(text)) {
78-
const foundLang = languages.find((l) => l.name === lang);
79-
if (foundLang) {
80-
detectedLanguages.push(foundLang);
81-
}
82-
}
83-
}
84-
85-
return detectedLanguages;
86-
};
87-
88-
// Core formatting logic
89-
const formatStackTrace = (stackTrace: string, selectedLang: Language): Element[] => {
90-
const lines = stackTrace.split("\n");
91-
const fileAndLineNumberRegEx = new RegExp(`${selectedLang.in} (.+):${selectedLang.line} (\\d+)`);
92-
const atRegex = new RegExp(`^(\\s+)(${selectedLang.at}) (.+?)\\((.*?)\\)`);
93-
94-
return lines.map((line) => {
95-
const match = line.match(atRegex);
96-
if (match) {
97-
const [, spaces, , methodWithType, paramsWithFile] = match;
98-
99-
const [type, method] = (() => {
100-
const parts = methodWithType.split(".");
101-
const method = parts.pop() ?? "";
102-
const type = parts.join(".");
103-
return [type, method];
104-
})();
105-
106-
const params = paramsWithFile.split(", ").map((param) => {
107-
const [paramType, paramName] = param.split(" ");
108-
return { name: paramName, type: paramType };
109-
});
110-
111-
const matchFile = line.match(fileAndLineNumberRegEx);
112-
let file, lineNumber;
113-
if (matchFile) {
114-
[, file, lineNumber] = matchFile;
115-
}
116-
117-
return <Node>{ method, type, params, file, lineNumber, spaces };
118-
} else {
119-
return line;
120-
}
121-
});
122-
};
123-
12435
// Process the provided stack trace
12536
const processStackTrace = (): void => {
12637
const rawContent = props.stackTrace;

0 commit comments

Comments
 (0)