Skip to content

Commit b7d0bd9

Browse files
committed
test: validate .did.ts snapshots with allowJs disabled
Add a typecheck test that verifies .did.ts modules compile correctly when allowJs is false, ensuring they work in strict TypeScript projects. Also make the declarations_typescript field non-optional and rename declarationsTypescriptFile for consistency.
1 parent e310a29 commit b7d0bd9

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/core/generate/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export async function generate(options: GenerateOptions) {
160160
type Bindings = {
161161
declarations_js: string;
162162
declarations_ts: string;
163-
declarations_typescript?: string;
163+
declarations_typescript: string;
164164
interface_ts: string;
165165
service_ts: string;
166166
};
@@ -181,11 +181,11 @@ async function writeBindings({
181181
force,
182182
}: WriteBindingsOptions) {
183183
if (output.declarations?.typescript) {
184-
const declarationsTypescriptFile = resolve(outDir, 'declarations', `${outputFileName}.did.ts`);
184+
const declarationsTsModuleFile = resolve(outDir, 'declarations', `${outputFileName}.did.ts`);
185185
const declarationsTypescript = prepareTypescriptBinding(
186-
bindings.declarations_typescript as string,
186+
bindings.declarations_typescript,
187187
);
188-
await writeFileSafe(declarationsTypescriptFile, declarationsTypescript, force);
188+
await writeFileSafe(declarationsTsModuleFile, declarationsTypescript, force);
189189
} else {
190190
const declarationsTsFile = resolve(outDir, 'declarations', `${outputFileName}.did.d.ts`);
191191
const declarationsJsFile = resolve(outDir, 'declarations', `${outputFileName}.did.js`);

tests/typecheck.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,46 @@ afterAll(() => {
8484
if (tmpDir) rmSync(tmpDir, { recursive: true, force: true });
8585
});
8686

87+
describe('typecheck .did.ts with allowJs false', () => {
88+
const snapshotFiles = globSync('tests/snapshots/**/*.did.ts.snapshot');
89+
90+
it.each(snapshotFiles)('%s', (snapshotPath) => {
91+
const content = readFileSync(snapshotPath, 'utf-8');
92+
const tsFileName = basename(snapshotPath).replace('.snapshot', '');
93+
const tsFilePath = join(tmpDir, tsFileName);
94+
95+
writeFileSync(tsFilePath, content);
96+
97+
// A consumer file that imports the generated .did.ts module.
98+
const consumerPath = join(tmpDir, `consumer_${tsFileName}`);
99+
const importBase = tsFileName.replace(/\.ts$/, '');
100+
writeFileSync(
101+
consumerPath,
102+
`import { idlFactory } from './${importBase}';\nconsole.log(idlFactory);\n`,
103+
);
104+
105+
const configPath = join(tmpDir, 'tsconfig.json');
106+
const rawConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
107+
rawConfig.compilerOptions.allowJs = false;
108+
const { config } = ts.readConfigFile(configPath, () => JSON.stringify(rawConfig));
109+
const parsed = ts.parseJsonConfigFileContent(config, ts.sys, tmpDir);
110+
111+
const program = ts.createProgram([consumerPath], parsed.options);
112+
const diagnostics = ts
113+
.getPreEmitDiagnostics(program)
114+
.filter((d) => d.file?.fileName === consumerPath || d.file?.fileName === tsFilePath);
115+
116+
if (diagnostics.length > 0) {
117+
const formatted = ts.formatDiagnosticsWithColorAndContext(diagnostics, {
118+
getCanonicalFileName: (f) => f,
119+
getCurrentDirectory: () => tmpDir,
120+
getNewLine: () => '\n',
121+
});
122+
expect.fail(`TypeScript errors in ${snapshotPath}:\n${formatted}`);
123+
}
124+
});
125+
});
126+
87127
describe('typecheck .did.ts snapshots', () => {
88128
const snapshotFiles = globSync('tests/snapshots/**/*.did.ts.snapshot');
89129

0 commit comments

Comments
 (0)