add more integration test for hooks

This commit is contained in:
DennisYu07 2026-03-02 23:32:10 -08:00
parent 423cc85265
commit 4a44eb7a17
23 changed files with 924 additions and 171 deletions

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Parallel hooks executed with mixed results - one succeeded, one failed.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The first hook blocked the request. Second hook was not executed.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Output from first hook was passed to second hook successfully.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Stop hook is not active.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Stop hook is active and processing.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I have received the final context from the stop hook and included it in my response.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Goodbye! Have a great day.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1,2 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I understand you'd like me to continue. Let me do more work.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I've completed the additional work you requested.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":150,"totalTokenCount":180}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The stop hook had an error but I completed my response.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Task completed with custom stop reason from hook.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The stop hook timed out but I completed my response.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Final system message from stop hook has been processed.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I have received additional context from the hook and will use it in my response.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"Hello! I can help you. What would you like me to do?","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I apologize, but I'm unable to process this request as it was blocked by a security policy.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I received an empty prompt. How can I help you?","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The hook had a blocking error and your request was blocked.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The hook had a non-blocking error but I continued processing your request.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The hook command was not found but I continued processing your request.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"I received your modified prompt and will process it accordingly.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -1 +0,0 @@
{"method":"generateContentStream","response":[{"candidates":[{"content":{"parts":[{"text":"The hook timed out but I continued processing your request.","thought":true}],"role":"model"},"index":0}],"usageMetadata":{"promptTokenCount":100,"totalTokenCount":120}}]}

View file

@ -145,7 +145,6 @@ export class TestRig {
testName?: string;
_lastRunStdout?: string;
_interactiveOutput = '';
_fakeResponsesPath?: string;
constructor() {
this.bundlePath = join(__dirname, '..', 'dist/cli.js');
@ -161,21 +160,13 @@ export class TestRig {
setup(
testName: string,
options: {
settings?: Record<string, unknown>;
fakeResponsesPath?: string;
} = {},
options: { settings?: Record<string, unknown> } = {},
) {
this.testName = testName;
const sanitizedName = sanitizeTestName(testName);
this.testDir = join(env['INTEGRATION_TEST_FILE_DIR']!, sanitizedName);
mkdirSync(this.testDir, { recursive: true });
// Store fake responses path for use in run()
if (options.fakeResponsesPath) {
this._fakeResponsesPath = options.fakeResponsesPath;
}
// Create a settings file to point the CLI to the local collector
const qwenDir = join(this.testDir, '.qwen');
mkdirSync(qwenDir, { recursive: true });
@ -199,16 +190,6 @@ export class TestRig {
);
}
/**
* Creates a script file in the test directory and returns its path.
* Useful for creating hook scripts that need to be executed.
*/
createScript(fileName: string, content: string): string {
const filePath = join(this.testDir!, fileName);
writeFileSync(filePath, content, { mode: 0o755 });
return filePath;
}
createFile(fileName: string, content: string) {
const filePath = join(this.testDir!, fileName);
writeFileSync(filePath, content);
@ -275,16 +256,10 @@ export class TestRig {
commandArgs.push(...args);
// Set up environment with fake responses path if configured
const childEnv = { ...process.env };
if (this._fakeResponsesPath) {
childEnv['QWEN_FAKE_RESPONSES_PATH'] = this._fakeResponsesPath;
}
const child = spawn(command, commandArgs, {
cwd: this.testDir!,
stdio: 'pipe',
env: childEnv,
env: process.env,
});
let stdout = '';