Skip to content

Commit 2f6e71a

Browse files
authored
feat: support brief mode to generate json datas (#1285)
1 parent 599e977 commit 2f6e71a

File tree

26 files changed

+1081
-226
lines changed

26 files changed

+1081
-226
lines changed

e2e/cases/doctor-rspack/linter-rule-render.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,11 @@ async function rspackCompile(
6565
{ name: 'Foo', stage: 99999 },
6666
async () => {
6767
const sdk = getSDK();
68+
if (!sdk) {
69+
throw new Error('SDK is undefined');
70+
}
6871
setSDK(
69-
new Proxy(sdk, {
72+
new Proxy(sdk as object, {
7073
get(target, key, receiver) {
7174
switch (key) {
7275
case 'reportLoader':
@@ -85,7 +88,7 @@ async function rspackCompile(
8588
defineProperty(target, p, attrs) {
8689
return Reflect.defineProperty(target, p, attrs);
8790
},
88-
}),
91+
}) as any,
8992
);
9093
},
9194
);
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import { expect, test } from '@playwright/test';
2+
import { getSDK } from '@rsdoctor/core/plugins';
3+
import { compileByWebpack5 } from '@scripts/test-helper';
4+
import { File } from '@rsdoctor/utils/build';
5+
import fs from 'node:fs/promises';
6+
import path from 'path';
7+
import { tmpdir } from 'os';
8+
import { createRsdoctorMultiPlugin } from '../test-utils';
9+
10+
async function compileWithBriefHtmlMode(htmlOptions?: any) {
11+
const file = path.resolve(__dirname, '../fixtures/a.js');
12+
const loader = path.resolve(__dirname, '../fixtures/loaders/comment.js');
13+
14+
const outputDir = path.resolve(
15+
tmpdir(),
16+
`./rsdoctor_html_test_${Date.now()}`,
17+
);
18+
19+
const plugin = createRsdoctorMultiPlugin({
20+
mode: 'brief',
21+
output: {
22+
mode: 'brief',
23+
reportDir: outputDir,
24+
options: {
25+
type: ['html'],
26+
htmlOptions: htmlOptions || {
27+
reportHtmlName: 'rsdoctor-report.html',
28+
writeDataJson: false,
29+
},
30+
},
31+
},
32+
});
33+
34+
// Set the output directory immediately
35+
plugin.sdk.setOutputDir(outputDir);
36+
37+
// Ensure the output directory exists
38+
await File.fse.ensureDir(outputDir);
39+
40+
const res = await compileByWebpack5(file, {
41+
module: {
42+
rules: [
43+
{
44+
test: /\.js/,
45+
use: loader,
46+
},
47+
],
48+
},
49+
plugins: [plugin],
50+
});
51+
52+
return { res, outputDir, plugin };
53+
}
54+
55+
test('brief mode with HTML type should generate HTML report file', async () => {
56+
const { outputDir } = await compileWithBriefHtmlMode();
57+
58+
const sdk = getSDK();
59+
expect(sdk?.type).toBe(0);
60+
expect(sdk?.extraConfig?.mode).toBe('brief');
61+
expect(sdk?.extraConfig?.brief).toMatchObject({
62+
type: ['html'],
63+
htmlOptions: {
64+
reportHtmlName: 'rsdoctor-report.html',
65+
writeDataJson: false,
66+
},
67+
});
68+
69+
// Wait for files to be written
70+
await new Promise((resolve) => setTimeout(resolve, 1000));
71+
72+
// Check if HTML report file is generated
73+
const htmlReportPath = path.join(outputDir, 'rsdoctor-report.html');
74+
const htmlExists = await File.fse.pathExists(htmlReportPath);
75+
expect(htmlExists).toBeTruthy();
76+
77+
if (htmlExists) {
78+
const htmlContent = await fs.readFile(htmlReportPath, 'utf-8');
79+
// Should contain HTML structure (the inlined version may not have DOCTYPE)
80+
expect(htmlContent).toContain('<html');
81+
expect(htmlContent).toContain('</html>');
82+
// Should contain the Rsdoctor app content
83+
expect(htmlContent.length).toBeGreaterThan(1000);
84+
}
85+
86+
// Cleanup
87+
try {
88+
await File.fse.remove(outputDir);
89+
} catch (e) {
90+
console.warn('Failed to cleanup test directory:', e);
91+
}
92+
});
93+
94+
test('brief mode with HTML type and custom report name should generate file with custom name', async () => {
95+
const customHtmlOptions = {
96+
reportHtmlName: 'custom-analysis-report.html',
97+
writeDataJson: true,
98+
};
99+
100+
const { outputDir, plugin } =
101+
await compileWithBriefHtmlMode(customHtmlOptions);
102+
103+
const sdk = getSDK();
104+
expect(sdk?.extraConfig?.brief).toMatchObject({
105+
type: ['html'],
106+
htmlOptions: customHtmlOptions,
107+
});
108+
109+
// Wait for files to be written
110+
await new Promise((resolve) => setTimeout(resolve, 1000));
111+
112+
// Check if HTML report file is generated with custom name
113+
const htmlReportPath = path.join(outputDir, 'custom-analysis-report.html');
114+
const htmlExists = await File.fse.pathExists(htmlReportPath);
115+
expect(htmlExists).toBeTruthy();
116+
117+
if (htmlExists) {
118+
const htmlContent = await fs.readFile(htmlReportPath, 'utf-8');
119+
// Should contain HTML structure (the inlined version may not have DOCTYPE)
120+
expect(htmlContent).toContain('<html');
121+
expect(htmlContent).toContain('</html>');
122+
}
123+
124+
// Since writeDataJson is true, should also check for data files
125+
// Note: In brief mode, .rsdoctor directory is only created when type includes 'json'
126+
// writeDataJson in HTML mode doesn't create .rsdoctor directory
127+
// This is the expected behavior for brief mode
128+
129+
// Cleanup
130+
try {
131+
await File.fse.remove(outputDir);
132+
} catch (e) {
133+
console.warn('Failed to cleanup test directory:', e);
134+
}
135+
});
136+
137+
test('brief mode with HTML type and writeDataJson should generate both HTML and data files', async () => {
138+
const htmlOptionsWithData = {
139+
reportHtmlName: 'report-with-data.html',
140+
writeDataJson: true,
141+
};
142+
143+
const { outputDir, plugin } =
144+
await compileWithBriefHtmlMode(htmlOptionsWithData);
145+
146+
const sdk = getSDK();
147+
expect(sdk?.extraConfig?.brief?.htmlOptions?.writeDataJson).toBe(true);
148+
149+
// Wait for files to be written
150+
await new Promise((resolve) => setTimeout(resolve, 1000));
151+
152+
// Check if HTML report is generated
153+
const htmlReportPath = path.join(outputDir, 'report-with-data.html');
154+
const htmlExists = await File.fse.pathExists(htmlReportPath);
155+
156+
expect(htmlExists).toBeTruthy();
157+
158+
// Note: In brief mode, writeDataJson in HTML options doesn't create .rsdoctor directory
159+
// The .rsdoctor directory is only created when type includes 'json'
160+
// This test focuses on HTML generation with writeDataJson flag
161+
162+
// Cleanup
163+
try {
164+
await File.fse.remove(outputDir);
165+
} catch (e) {
166+
console.warn('Failed to cleanup test directory:', e);
167+
}
168+
});
169+
170+
test('brief mode with default HTML configuration should use default values', async () => {
171+
const file = path.resolve(__dirname, '../fixtures/a.js');
172+
const loader = path.resolve(__dirname, '../fixtures/loaders/comment.js');
173+
174+
const outputDir = path.resolve(
175+
tmpdir(),
176+
`./rsdoctor_default_html_test_${Date.now()}`,
177+
);
178+
179+
const plugin = createRsdoctorMultiPlugin({
180+
mode: 'brief',
181+
output: {
182+
mode: 'brief',
183+
reportDir: outputDir,
184+
// No options specified, should use defaults
185+
},
186+
});
187+
188+
// Set the output directory immediately
189+
plugin.sdk.setOutputDir(outputDir);
190+
191+
// Ensure the output directory exists
192+
await File.fse.ensureDir(outputDir);
193+
194+
await compileByWebpack5(file, {
195+
module: {
196+
rules: [
197+
{
198+
test: /\.js/,
199+
use: loader,
200+
},
201+
],
202+
},
203+
plugins: [plugin],
204+
});
205+
206+
const sdk = getSDK();
207+
expect(sdk?.extraConfig?.brief).toMatchObject({
208+
type: ['html'], // Should default to HTML
209+
htmlOptions: {
210+
reportHtmlName: undefined, // Should be undefined by default
211+
writeDataJson: false, // Should be false by default
212+
},
213+
});
214+
215+
// Wait for files to be written
216+
await new Promise((resolve) => setTimeout(resolve, 1000));
217+
218+
// Check if default HTML file is generated (should be in the output directory)
219+
// Default file name should be 'rsdoctor-report.html'
220+
const defaultHtmlPath = path.join(outputDir, 'rsdoctor-report.html');
221+
const htmlExists = await File.fse.pathExists(defaultHtmlPath);
222+
expect(htmlExists).toBeTruthy();
223+
224+
// Cleanup
225+
try {
226+
await File.fse.remove(outputDir);
227+
} catch (e) {
228+
console.warn('Failed to cleanup test directory:', e);
229+
}
230+
});

0 commit comments

Comments
 (0)