-
Notifications
You must be signed in to change notification settings - Fork 440
Refactor test script for improved readability and modularity #1956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
465e347
74fe737
34e146c
d04d009
c899c09
414add9
23e40c5
81e4c8f
4399d1e
9e2aba4
eaddc8b
1291a7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,162 +10,139 @@ const tscPath = new URL( | |
import.meta.url, | ||
); | ||
|
||
function normalizeLineEndings(text: string): string { | ||
return text.replace(/\r\n?/g, "\n"); | ||
} | ||
const normalizeLineEndings = (text: string) => text.replace(/\r\n?/g, "\n"); | ||
|
||
function compareToBaselines(baselineFolder: URL, outputFolder: URL) { | ||
let baselineFiles: string[] = []; | ||
const getFiles = (folder: URL) => { | ||
try { | ||
baselineFiles = fs.readdirSync(baselineFolder); | ||
return fs.readdirSync(folder); | ||
} catch { | ||
// do nothing | ||
return []; | ||
} | ||
}; | ||
|
||
let outputFiles: string[] = []; | ||
const readFileContent = (filePath: URL) => { | ||
try { | ||
outputFiles = fs.readdirSync(outputFolder); | ||
return normalizeLineEndings(fs.readFileSync(filePath, "utf-8")); | ||
} catch { | ||
// do nothing | ||
return null; | ||
} | ||
}; | ||
|
||
for (const file of new Set([...baselineFiles, ...outputFiles])) { | ||
if (file.startsWith(".")) { | ||
continue; | ||
} | ||
const compareToBaselines = (baselineFolder: URL, outputFolder: URL) => { | ||
const files = new Set([ | ||
...getFiles(baselineFolder), | ||
...getFiles(outputFolder), | ||
]); | ||
|
||
let baselineStats: fs.Stats | undefined; | ||
try { | ||
baselineStats = fs.statSync(new URL(file, baselineFolder)); | ||
} catch { | ||
// do nothing | ||
} | ||
for (const file of files) { | ||
if (file.startsWith(".")) continue; | ||
|
||
let outputStats: fs.Stats | undefined; | ||
try { | ||
outputStats = fs.statSync(new URL(file, outputFolder)); | ||
} catch { | ||
// do nothing | ||
} | ||
const baselinePath = new URL(file, baselineFolder); | ||
const outputPath = new URL(file, outputFolder); | ||
|
||
const baseline = baselineStats?.isFile() | ||
? normalizeLineEndings( | ||
fs.readFileSync(new URL(file, baselineFolder)).toString(), | ||
) | ||
: null; | ||
const isBaselineFile = | ||
fs.existsSync(baselinePath) && fs.statSync(baselinePath).isFile(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's actually advised to not call https://nodejs.org/docs/latest/api/fs.html#fsexistspath-callback
|
||
const isOutputFile = | ||
fs.existsSync(outputPath) && fs.statSync(outputPath).isFile(); | ||
|
||
const generated = outputStats?.isFile() | ||
? normalizeLineEndings( | ||
fs.readFileSync(new URL(file, outputFolder)).toString(), | ||
) | ||
: null; | ||
const baseline = isBaselineFile ? readFileContent(baselinePath) : null; | ||
const generated = isOutputFile ? readFileContent(outputPath) : null; | ||
|
||
if (baseline !== null || generated !== null) { | ||
if (baseline !== generated) { | ||
console.error( | ||
`Test failed: '${file}' is different from baseline file.`, | ||
); | ||
console.error(`Test failed: '${file}' is different from baseline.`); | ||
printUnifiedDiff(baseline ?? "", generated ?? ""); | ||
return false; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
if (baselineStats?.isDirectory() || outputStats?.isDirectory()) { | ||
const childBaselineFolder = new URL(`${file}/`, baselineFolder); | ||
const childOutputFolder = new URL(`${file}/`, outputFolder); | ||
if (!compareToBaselines(childBaselineFolder, childOutputFolder)) { | ||
if (fs.existsSync(baselinePath) || fs.existsSync(outputPath)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not same as detecting directory? |
||
if ( | ||
!compareToBaselines( | ||
new URL(`${file}/`, baselineFolder), | ||
new URL(`${file}/`, outputFolder), | ||
) | ||
) { | ||
return false; | ||
} | ||
|
||
continue; | ||
} | ||
} | ||
return true; | ||
} | ||
}; | ||
|
||
function compileGeneratedFiles(lib: string, ...files: string[]) { | ||
const compileGeneratedFiles = (lib: string[] | string, ...files: string[]) => { | ||
try { | ||
const fileArgs = files | ||
.map((file) => fileURLToPath(new URL(file, outputFolder))) | ||
.join(" "); | ||
child_process.execSync( | ||
`node ${fileURLToPath( | ||
tscPath, | ||
)} --strict --lib ${lib} --types --noEmit ${files | ||
.map((file) => fileURLToPath(new URL(file, outputFolder))) | ||
.join(" ")}`, | ||
`node ${fileURLToPath(tscPath)} --strict --lib ${lib} --types --noEmit ${fileArgs}`, | ||
); | ||
} catch (e: any) { | ||
console.error(`Test failed: could not compile '${files.join(",")}':`); | ||
console.error(e.stdout.toString()); | ||
console.error(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Skipping this would hide the actual error which would make debugging harder. |
||
} catch { | ||
console.error(`Test failed: could not compile '${files.join(", ")}'.`); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
function test() { | ||
if ( | ||
compareToBaselines(baselineFolder, outputFolder) && | ||
compileGeneratedFiles("es5", "dom.generated.d.ts") && | ||
compileGeneratedFiles( | ||
"es6", | ||
"dom.generated.d.ts", | ||
"dom.iterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles( | ||
}; | ||
|
||
const test = () => { | ||
const compileSets = [ | ||
["es5", ["dom.generated.d.ts"]], | ||
["es6", ["dom.generated.d.ts", "dom.iterable.generated.d.ts"]], | ||
["es2018", ["dom.generated.d.ts", "dom.asynciterable.generated.d.ts"]], | ||
["es5", ["webworker.generated.d.ts"]], | ||
["es6", ["webworker.generated.d.ts", "webworker.iterable.generated.d.ts"]], | ||
[ | ||
"es2018", | ||
"dom.generated.d.ts", | ||
"dom.asynciterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles("es5", "webworker.generated.d.ts") && | ||
compileGeneratedFiles( | ||
["webworker.generated.d.ts", "webworker.asynciterable.generated.d.ts"], | ||
], | ||
["es5", ["sharedworker.generated.d.ts"]], | ||
[ | ||
"es6", | ||
"webworker.generated.d.ts", | ||
"webworker.iterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles( | ||
["sharedworker.generated.d.ts", "sharedworker.iterable.generated.d.ts"], | ||
], | ||
[ | ||
"es2018", | ||
"webworker.generated.d.ts", | ||
"webworker.asynciterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles("es5", "sharedworker.generated.d.ts") && | ||
compileGeneratedFiles( | ||
[ | ||
"sharedworker.generated.d.ts", | ||
"sharedworker.asynciterable.generated.d.ts", | ||
], | ||
], | ||
["es5", ["serviceworker.generated.d.ts"]], | ||
[ | ||
"es6", | ||
"sharedworker.generated.d.ts", | ||
"sharedworker.iterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles( | ||
["serviceworker.generated.d.ts", "serviceworker.iterable.generated.d.ts"], | ||
], | ||
[ | ||
"es2018", | ||
"sharedworker.generated.d.ts", | ||
"sharedworker.asynciterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles("es5", "serviceworker.generated.d.ts") && | ||
compileGeneratedFiles( | ||
[ | ||
"serviceworker.generated.d.ts", | ||
"serviceworker.asynciterable.generated.d.ts", | ||
], | ||
], | ||
["es5", ["audioworklet.generated.d.ts"]], | ||
[ | ||
"es6", | ||
"serviceworker.generated.d.ts", | ||
"serviceworker.iterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles( | ||
["audioworklet.generated.d.ts", "audioworklet.iterable.generated.d.ts"], | ||
], | ||
[ | ||
"es2018", | ||
"serviceworker.generated.d.ts", | ||
"serviceworker.asynciterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles("es5", "audioworklet.generated.d.ts") && | ||
compileGeneratedFiles( | ||
"es6", | ||
"audioworklet.generated.d.ts", | ||
"audioworklet.iterable.generated.d.ts", | ||
) && | ||
compileGeneratedFiles( | ||
"es2018", | ||
"audioworklet.generated.d.ts", | ||
"audioworklet.asynciterable.generated.d.ts", | ||
) | ||
[ | ||
"audioworklet.generated.d.ts", | ||
"audioworklet.asynciterable.generated.d.ts", | ||
], | ||
], | ||
]; | ||
|
||
if ( | ||
compareToBaselines(baselineFolder, outputFolder) && | ||
compileSets.every(([lib, files]) => compileGeneratedFiles(lib, ...files)) | ||
) { | ||
console.log("All tests passed."); | ||
process.exit(0); | ||
} | ||
process.exit(1); | ||
} | ||
}; | ||
|
||
test(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already stat the file before calling this and thus doesn't expect any error here. Thus we should skip try-catch here to see actual failures if happens.