maestro/src/bridge/a2a/reconciler-wiring.test.ts
oss-sync b1292e34b2
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (edc775f2)
2026-07-06 01:04:12 +00:00

101 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* reconciler-wiring.test.ts
*
* A2aTaskReconciler のライフサイクルstart/stopを fake timers で検証。
* server.ts への結線は Task 6 の e2e テストで確認するため、ここは reconciler
* 単体に留める。
*/
import { describe, it, expect, vi, afterEach } from 'vitest';
import { A2aTaskReconciler } from './reconciler.js';
afterEach(() => {
vi.useRealTimers();
});
describe('A2aTaskReconciler lifecycle', () => {
it('start() triggers an immediate reconcile tick', async () => {
vi.useFakeTimers();
let callCount = 0;
const fakeRepo = {
listNonTerminalA2aTasks: () => { callCount++; return []; },
} as any;
const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
reconciler.start();
// Drain the microtask queue so the immediate async tick completes.
await Promise.resolve();
expect(callCount).toBeGreaterThanOrEqual(1);
});
it('periodic interval fires after intervalMs', async () => {
vi.useFakeTimers();
let callCount = 0;
const fakeRepo = {
listNonTerminalA2aTasks: () => { callCount++; return []; },
} as any;
const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
reconciler.start();
// Drain immediate tick.
await Promise.resolve();
const afterStart = callCount;
// Advance one full interval.
await vi.advanceTimersByTimeAsync(1000);
expect(callCount).toBeGreaterThan(afterStart);
});
it('stop() prevents further ticks after interval advances', async () => {
vi.useFakeTimers();
let callCount = 0;
const fakeRepo = {
listNonTerminalA2aTasks: () => { callCount++; return []; },
} as any;
const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
reconciler.start();
// Drain immediate tick.
await Promise.resolve();
reconciler.stop();
const countAfterStop = callCount;
// Advance several intervals — the cleared timer must not fire.
await vi.advanceTimersByTimeAsync(5000);
expect(callCount).toBe(countAfterStop);
});
it('double start() does not leak a second interval', async () => {
vi.useFakeTimers();
let callCount = 0;
const fakeRepo = {
listNonTerminalA2aTasks: () => { callCount++; return []; },
} as any;
const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
reconciler.start();
reconciler.start(); // should replace, not add
await Promise.resolve();
const afterDoubleStart = callCount;
await vi.advanceTimersByTimeAsync(1000);
// Only one interval should fire; if two leaked, callCount would jump by 2.
expect(callCount).toBe(afterDoubleStart + 1);
reconciler.stop();
});
});