feat: add automatic review loop (#1840)
This commit is contained in:
committed by
GitHub
parent
45df19c3b2
commit
1f549e4525
@@ -0,0 +1,81 @@
|
||||
import { beforeEach, describe, expect, test } from 'bun:test';
|
||||
import type { Message } from '@opencode-ai/sdk/v2/client';
|
||||
import { switchRuntimeEndpoint } from './runtime-switch';
|
||||
|
||||
import {
|
||||
assertAutoReviewRuntimeStillCurrent,
|
||||
claimAutoReviewForward,
|
||||
releaseAutoReviewForward,
|
||||
hasFinalReviewMarker,
|
||||
isAutoReviewRuntimeCurrent,
|
||||
isExpectedAutoReviewAssistantParent,
|
||||
stripFinalReviewMarker,
|
||||
} from './reviewFlow';
|
||||
import type { AutoReviewRun } from '@/stores/useAutoReviewStore';
|
||||
|
||||
describe('reviewFlow auto-review helpers', () => {
|
||||
beforeEach(() => {
|
||||
switchRuntimeEndpoint({ apiBaseUrl: 'http://runtime-a.test', runtimeKey: 'runtime-a' });
|
||||
});
|
||||
|
||||
test('detects and strips final review marker only from the final line', () => {
|
||||
const text = 'No remaining issues.\n\nFINAL_REVIEW_STATUS: no_remaining_findings\n';
|
||||
|
||||
expect(hasFinalReviewMarker(text)).toBe(true);
|
||||
expect(stripFinalReviewMarker(text)).toBe('No remaining issues.');
|
||||
});
|
||||
|
||||
test('detects and strips final review marker case-insensitively', () => {
|
||||
const text = 'No findings.\nFINAL_REVIEW_STATUS: no_remaining_findINGS\n';
|
||||
|
||||
expect(hasFinalReviewMarker(text)).toBe(true);
|
||||
expect(stripFinalReviewMarker(text)).toBe('No findings.');
|
||||
});
|
||||
|
||||
test('does not treat quoted or non-final marker text as completion', () => {
|
||||
const text = 'The marker is FINAL_REVIEW_STATUS: no_remaining_findings, but issues remain.';
|
||||
|
||||
expect(hasFinalReviewMarker(text)).toBe(false);
|
||||
expect(stripFinalReviewMarker(text)).toBe(text);
|
||||
});
|
||||
|
||||
test('requires assistant parent to match the auto-sent user message when provided', () => {
|
||||
const matching = { id: 'msg_assistant_1', parentID: 'msg_user_auto' } as Message;
|
||||
const unrelated = { id: 'msg_assistant_2', parentID: 'msg_user_manual' } as Message;
|
||||
|
||||
expect(isExpectedAutoReviewAssistantParent(matching, 'msg_user_auto')).toBe(true);
|
||||
expect(isExpectedAutoReviewAssistantParent(unrelated, 'msg_user_auto')).toBe(false);
|
||||
expect(isExpectedAutoReviewAssistantParent(unrelated)).toBe(true);
|
||||
});
|
||||
|
||||
test('runtime guard rejects runs from a stale runtime', () => {
|
||||
expect(isAutoReviewRuntimeCurrent('runtime-a')).toBe(true);
|
||||
switchRuntimeEndpoint({ apiBaseUrl: 'http://runtime-b.test', runtimeKey: 'runtime-b' });
|
||||
expect(isAutoReviewRuntimeCurrent('runtime-a')).toBe(false);
|
||||
expect(() => assertAutoReviewRuntimeStillCurrent('runtime-a')).toThrow('runtime changed');
|
||||
});
|
||||
|
||||
test('claims only one in-flight forward for the same auto-review message', () => {
|
||||
const run: AutoReviewRun = {
|
||||
originalSessionID: 'original-1',
|
||||
reviewSessionID: 'review-1',
|
||||
directory: '/workspace',
|
||||
runtimeKey: 'runtime-a',
|
||||
status: 'running',
|
||||
phase: 'waiting_for_reviewer',
|
||||
iteration: 0,
|
||||
maxIterations: 15,
|
||||
expectedAssistantParentID: 'msg_user_prompt',
|
||||
};
|
||||
|
||||
const key = claimAutoReviewForward(run, 'msg_assistant_review');
|
||||
|
||||
expect(typeof key).toBe('string');
|
||||
expect(claimAutoReviewForward(run, 'msg_assistant_review')).toBeNull();
|
||||
|
||||
releaseAutoReviewForward(key!);
|
||||
const nextKey = claimAutoReviewForward(run, 'msg_assistant_review');
|
||||
expect(nextKey).toBe(key);
|
||||
releaseAutoReviewForward(nextKey!);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user