Files
CASAN/packages/casan-devkit/tests/vscode-extension-tests.js

107 lines
2.9 KiB
JavaScript

'use strict';
// Dependency-free contract test for the packaged VS Code @casan participant.
// It mocks only the stable VS Code host surface and runs the real project
// bootstrap + global harness adapters in a child process.
const assert = require('assert');
const Module = require('module');
const path = require('path');
const project = path.resolve(process.argv[2]);
const extensionPath = path.resolve(process.argv[3]);
let registeredHandler;
const streamed = [];
class CancellationError extends Error {}
class CancellationTokenSource {
constructor() {
this.token = {
isCancellationRequested: false,
onCancellationRequested: () => ({ dispose() {} })
};
}
dispose() {}
}
const vscodeMock = {
version: '1.98.0-test',
workspace: {
workspaceFolders: [{ uri: { fsPath: project } }],
isTrusted: true,
getConfiguration() {
return {
get(key, fallback) {
if (key === 'pythonPath') return process.env.PYTHON || 'python3';
if (key === 'hookTimeoutMs') return 30000;
return fallback;
}
};
}
},
chat: {
createChatParticipant(_id, handler) {
registeredHandler = handler;
return { dispose() {} };
}
},
LanguageModelChatMessage: {
User(value) { return { role: 'user', value }; }
},
CancellationError,
CancellationTokenSource
};
const originalLoad = Module._load;
Module._load = function load(request, parent, isMain) {
if (request === 'vscode') return vscodeMock;
return originalLoad.call(this, request, parent, isMain);
};
async function main() {
try {
const extension = require(extensionPath);
const subscriptions = [];
extension.activate({ subscriptions });
assert.strictEqual(typeof registeredHandler, 'function');
assert.strictEqual(subscriptions.length, 1);
const token = {
isCancellationRequested: false,
onCancellationRequested: () => ({ dispose() {} })
};
const request = {
prompt: 'Explain the CASAN integration without changing files.',
model: {
id: 'copilot-test-model',
async sendRequest(messages) {
assert.strictEqual(messages.length, 2);
return {
text: (async function* responseText() {
yield 'Governed ';
yield 'response';
})()
};
}
}
};
const stream = {
progress(value) { streamed.push(`progress:${value}`); },
markdown(value) { streamed.push(value); }
};
const result = await registeredHandler(request, {}, stream, token);
assert.strictEqual(streamed.filter(value => !value.startsWith('progress:')).join(''),
'Governed response');
assert.strictEqual(result.metadata.certified, true);
assert.strictEqual(result.metadata.certificationStrength, 'casan_owned');
assert.ok(result.metadata.traceId);
} finally {
Module._load = originalLoad;
}
}
main().catch(error => {
console.error(error.stack || error);
process.exit(1);
});