82 lines
3.2 KiB
TypeScript
82 lines
3.2 KiB
TypeScript
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!);
|
|
});
|
|
});
|