takt/src/__tests__/abort-signal.test.ts
nrs a82d6d9d8a
github-issue-244 (#250)
* dist-tag 検証をリトライ付きに変更(npm レジストリの結果整合性対策)

* takt run 実行時に蓋閉じスリープを抑制

* takt: github-issue-244

* takt: #244/implement-parallel-subtasks
2026-02-12 11:51:34 +09:00

69 lines
2.0 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { buildAbortSignal } from '../core/piece/engine/abort-signal.js';
describe('buildAbortSignal', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
it('タイムアウトでabortされる', () => {
const { signal, dispose } = buildAbortSignal(100, undefined);
expect(signal.aborted).toBe(false);
vi.advanceTimersByTime(100);
expect(signal.aborted).toBe(true);
expect(signal.reason).toBeInstanceOf(Error);
expect((signal.reason as Error).message).toBe('Part timeout after 100ms');
dispose();
});
it('親シグナルがabortされると子シグナルへ伝搬する', () => {
const parent = new AbortController();
const { signal, dispose } = buildAbortSignal(1000, parent.signal);
const reason = new Error('parent aborted');
parent.abort(reason);
expect(signal.aborted).toBe(true);
expect(signal.reason).toBe(reason);
dispose();
});
it('disposeでタイマーと親リスナーを解放する', () => {
const parent = new AbortController();
const addSpy = vi.spyOn(parent.signal, 'addEventListener');
const removeSpy = vi.spyOn(parent.signal, 'removeEventListener');
const { signal, dispose } = buildAbortSignal(100, parent.signal);
expect(addSpy).toHaveBeenCalledTimes(1);
dispose();
vi.advanceTimersByTime(200);
expect(signal.aborted).toBe(false);
expect(removeSpy).toHaveBeenCalledTimes(1);
});
it('親シグナルが既にabort済みなら即時伝搬する', () => {
const parent = new AbortController();
const reason = new Error('already aborted');
const addSpy = vi.spyOn(parent.signal, 'addEventListener');
parent.abort(reason);
const { signal, dispose } = buildAbortSignal(1000, parent.signal);
expect(signal.aborted).toBe(true);
expect(signal.reason).toBe(reason);
expect(addSpy).not.toHaveBeenCalled();
dispose();
});
});