Skip to content

Commit b69bbce

Browse files
committed
feat: Update html generation method in generateHtml
1 parent 6bf9a54 commit b69bbce

File tree

1 file changed

+131
-60
lines changed

1 file changed

+131
-60
lines changed

packages/test-case-component/src/generateHtml.ts

Lines changed: 131 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,10 @@ const myTheme = createCssVariablesTheme({
2828
* @param {DataFixture} data - The state object containing the necessary data for HTML generation.
2929
* @returns {Promise<string>} A promise that resolves to the generated HTML content.
3030
*/
31-
export async function generateHtml({
32-
stateName,
33-
state,
34-
languageId: lang,
35-
command,
36-
ide,
37-
raw
38-
}: {
39-
stateName: string;
40-
state: TestCaseSnapshot;
41-
languageId: BundledLanguage;
42-
command?: any; // Replace `any` with the appropriate type if with
43-
ide?: any; // Replace `any` with the appropriate type if known
44-
raw: any;
45-
}) {
46-
return new HTMLGenerator({ state, lang, command, ide, raw }).generate();
31+
export async function generateHtml(data: DataFixture) {
32+
const HTMLOBject = await new HTMLGenerator(data)
33+
const returnObject = HTMLOBject.generateAll()
34+
return returnObject;
4735
}
4836

4937
const highlighter = createHighlighter({
@@ -61,63 +49,146 @@ type ExtendedTestCaseSnapshot = TestCaseSnapshot &
6149
};
6250

6351
class HTMLGenerator {
64-
private state: TestCaseSnapshot;
52+
private testCaseStates: {
53+
before: ExtendedTestCaseSnapshot | undefined;
54+
during: ExtendedTestCaseSnapshot | undefined;
55+
after: ExtendedTestCaseSnapshot | undefined;
56+
}
6557
private lang: Lang;
66-
private command?: any;
67-
private ide?: any;
68-
private raw: any;
69-
70-
constructor({
71-
state,
72-
lang,
73-
command,
74-
ide,
75-
raw
76-
}: {
77-
state: TestCaseSnapshot,
78-
lang: Lang,
79-
command?: any,
80-
ide?: any,
81-
raw?: any
82-
}) {
83-
this.state = state;
84-
this.lang = lang;
58+
private command?: CommandLatest | Command;
59+
private raw: TestCaseFixture;
60+
private rendered: {
61+
before: string;
62+
during: string;
63+
after: string;
64+
}
65+
66+
constructor(data: DataFixture) {
67+
const { languageId, command } = data;
68+
this.lang = languageId as BundledLanguage;
8569
this.command = command; // Optional command parameter
86-
this.ide = ide; // Optional ide parameter
87-
this.raw = raw
70+
this.raw = data
71+
this.rendered = {
72+
before: "",
73+
during: "",
74+
after: "",
75+
}
76+
this.testCaseStates = {
77+
before: data.initialState,
78+
during: {
79+
...(
80+
/**
81+
* Spread the document state with more lines (finalState vs initialState),
82+
* so Shiki decorations stay in bounds and don't go out of range.
83+
*/
84+
data.finalState &&
85+
(data.finalState.documentContents?.split("\n").length > data.initialState.documentContents?.split("\n").length)
86+
? data.finalState
87+
: data.initialState
88+
),
89+
...data.ide,
90+
finalStateMarkHelpers: {
91+
thatMark: data?.finalState?.thatMark,
92+
sourceMark: data?.finalState?.sourceMark
93+
}
94+
},
95+
after: data.finalState
96+
}
8897
}
8998

99+
async generate(stepName: StepNameType) {
100+
const state = this.testCaseStates[stepName]
101+
102+
if (!state) {
103+
console.error(`Error in ${stepName} ${this.raw.command.spokenForm}`)
104+
return "Error"
105+
}
106+
107+
const decorations = await this.getDecorations(state);
108+
109+
const { documentContents } = state
110+
111+
const htmlArray: string[] = []
112+
let codeBody;
113+
114+
const errorLevels = [
115+
"excludes thatMarks sourceMarks selectionRanges ideFlashes",
116+
"excludes thatMarks sourceMarks selectionRanges",
117+
"excludes thatMarks sourceMarks",
118+
"excludes thatMarks",
119+
"success",
120+
]
121+
122+
let errorLevel = errorLevels.length - 1
90123

91-
async generate() {
92-
const decorations = await this.getDecorations();
93-
const options = {
94-
theme: "css-variables",
95-
lang: this.lang,
96-
decorations
97-
};
124+
for (let i = decorations.length - 1; i >= 0; i--) {
125+
const fallbackDecoration = decorations.slice(0, i).flat();
126+
errorLevel = i
127+
try {
128+
const marker = await highlighter;
129+
const options = {
130+
theme: "css-variables",
131+
lang: this.lang,
132+
decorations: fallbackDecoration
133+
};
134+
codeBody = marker.codeToHtml(documentContents, options);
135+
htmlArray.push(codeBody)
136+
break; // Exit loop if successful
137+
} catch (error) {
138+
console.warn("Failed with decorations level:", fallbackDecoration, error);
139+
// Continue to the next fallback level
140+
}
141+
}
142+
143+
if (!codeBody) {
144+
console.error("All fallback levels failed. Unable to generate code body.");
145+
codeBody = ""; // Provide a default empty string or handle as needed
146+
}
147+
148+
let clipboardRendered = ""
149+
if (state.clipboard) {
150+
clipboardRendered = `<pre><code>clipboard: ${state.clipboard}</pre></code>`
151+
if (clipboardRendered !== "") {
152+
htmlArray.push(clipboardRendered)
153+
}
154+
}
155+
156+
let error = ""
157+
if (errorLevel !== errorLevels.length - 1) {
158+
error = errorLevels[errorLevel]
159+
const errorRendered = `<pre><code>Omitted due to errors: ${error}</pre></code>`
160+
htmlArray.push(errorRendered)
161+
}
162+
return htmlArray.join("")
163+
}
164+
165+
async generateAll() {
98166

99-
const marker = await highlighter
100-
const codeBody = marker.codeToHtml(this.state.documentContents, options)
101-
let clipboard = ""
102-
if (this.state.clipboard) {
103-
clipboard = `<pre><code>clipboard: ${this.state.clipboard}</pre></code>`
167+
const output = {
168+
before: await this.generate("before"),
169+
during: await this.generate("during"),
170+
after: await this.generate("after"),
104171
}
105-
const output = clipboard !== "" ? codeBody + clipboard : codeBody
106172
return output
107173
}
108174

109-
async getDecorations() {
110-
const potentialMarks = this.state.marks || {}
111-
const lines = this.state.documentContents.split("\n")
112-
console.log("💎", this.state.thatMark)
113-
const decorations = createDecorations({
175+
async getDecorations(testCaseState: ExtendedTestCaseSnapshot) {
176+
const { messages, flashes, highlights, finalStateMarkHelpers } = testCaseState
177+
178+
const potentialMarks = testCaseState.marks || {}
179+
const lines = testCaseState.documentContents.split("\n")
180+
const obj = {
114181
marks: potentialMarks,
115-
ide: this.ide,
182+
ide: { messages, flashes, highlights },
116183
command: this.command,
117184
lines,
118-
selections: this.state.selections,
119-
thatMark: this.state.thatMark
120-
})
185+
selections: testCaseState.selections,
186+
thatMark: testCaseState.thatMark,
187+
sourceMark: testCaseState.sourceMark,
188+
finalStateMarkHelpers
189+
}
190+
191+
const decorations = createDecorations(obj)
121192
return decorations
122193
}
123194
}

0 commit comments

Comments
 (0)