Skip to content

Commit a9d0b13

Browse files
Younes AYounes A
authored andcommitted
Add SANY tool temp-copy regression test
1 parent b6d45f1 commit a9d0b13

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

tests/suite/lm/sanyTool.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as assert from 'assert';
22
import * as path from 'path';
3+
import * as fs from 'fs';
4+
import * as os from 'os';
35
import * as vscode from 'vscode';
46
import { DCollection } from '../../../src/diagnostic';
57
import { SanyData } from '../../../src/parsers/sany';
@@ -65,4 +67,70 @@ suite('SANY Tool cancellation handling', () => {
6567
parseModuleMutable.parseSpec = originalParseSpec;
6668
}
6769
});
70+
71+
test('ParseModuleTool uses a temp copy and leaves the original file untouched', async () => {
72+
const parseModuleMutable = parseModule as unknown as {
73+
transpilePlusCal: typeof parseModule.transpilePlusCal;
74+
parseSpec: typeof parseModule.parseSpec;
75+
};
76+
const originalTranspile = parseModuleMutable.transpilePlusCal;
77+
const originalParseSpec = parseModuleMutable.parseSpec;
78+
79+
const originalDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'tlaplus-sany-orig-'));
80+
const originalPath = path.join(originalDir, 'Spec.tla');
81+
const originalContent = '---- MODULE Spec ----\n====\n';
82+
await fs.promises.writeFile(originalPath, originalContent, 'utf8');
83+
84+
let transpilePath: string | undefined;
85+
let transpileDiagPath: string | undefined;
86+
let parseSpecPath: string | undefined;
87+
88+
parseModuleMutable.transpilePlusCal = async (uri: vscode.Uri, _token?: vscode.CancellationToken, options?: { diagnosticFilePath?: string }) => {
89+
transpilePath = uri.fsPath;
90+
transpileDiagPath = options?.diagnosticFilePath;
91+
const dc = new DCollection();
92+
dc.addMessage(options?.diagnosticFilePath ?? uri.fsPath, new vscode.Range(0, 0, 0, 0), 'pluscal message');
93+
return dc;
94+
};
95+
96+
parseModuleMutable.parseSpec = async (uri: vscode.Uri) => {
97+
parseSpecPath = uri.fsPath;
98+
const sd = new SanyData();
99+
sd.dCollection.addMessage(uri.fsPath, new vscode.Range(1, 0, 1, 0), 'sany message');
100+
return sd;
101+
};
102+
103+
try {
104+
const tool = new ParseModuleTool();
105+
const options = {
106+
toolInvocationToken: undefined,
107+
input: { fileName: originalPath }
108+
} as unknown as vscode.LanguageModelToolInvocationOptions<FileParameter>;
109+
110+
const result = await tool.invoke(options, new vscode.CancellationTokenSource().token);
111+
112+
assert.ok(transpilePath, 'transpilePlusCal should have been called');
113+
assert.ok(parseSpecPath, 'parseSpec should have been called');
114+
assert.notStrictEqual(transpilePath, originalPath, 'transpilePlusCal must run on a temp copy');
115+
assert.notStrictEqual(parseSpecPath, originalPath, 'parseSpec must parse the temp copy');
116+
assert.strictEqual(transpileDiagPath, originalPath, 'diagnostics should be attributed to the original file');
117+
118+
// Returned messages should reference the original path, not the temp copy
119+
assert.strictEqual(result.content.length, 2, 'Should surface both PlusCal and SANY diagnostics');
120+
result.content.forEach(part => {
121+
assert.ok(part instanceof vscode.LanguageModelTextPart, 'Each result should be a text part');
122+
const val = (part as vscode.LanguageModelTextPart).value;
123+
assert.ok(val.includes(originalPath), 'Diagnostics should point to the original file path');
124+
assert.ok(!val.includes(transpilePath!), 'Diagnostics should not leak temp file paths');
125+
});
126+
127+
// Original file should remain unchanged on disk
128+
const after = await fs.promises.readFile(originalPath, 'utf8');
129+
assert.strictEqual(after, originalContent, 'Original file content must not be modified');
130+
} finally {
131+
parseModuleMutable.transpilePlusCal = originalTranspile;
132+
parseModuleMutable.parseSpec = originalParseSpec;
133+
await fs.promises.rm(originalDir, { recursive: true, force: true });
134+
}
135+
});
68136
});

0 commit comments

Comments
 (0)