107 lines
2.9 KiB
JavaScript
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);
|
|
});
|