upulse-engine/templates/workflow.test.ts.tmpl

84 lines
2.3 KiB
Cheetah

/**
* {{WORKFLOW_NAME}} workflow tests
*
* 小橘 🍊 (NEKO Team)
*/
import { afterEach, describe, expect, it } from 'bun:test';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { createStore, createWorkflowRule } from '@uncaged/pulse';
import { {{WORKFLOW_EXPORT}} } from './{{WORKFLOW_FILE}}.js';
describe('{{WORKFLOW_NAME}} workflow', () => {
let tmpDir: string;
let store: ReturnType<typeof createStore>;
const setup = () => {
tmpDir = mkdtempSync(join(tmpdir(), 'engine-test-'));
store = createStore({
eventsDbPath: join(tmpDir, 'test.db'),
objectsDir: join(tmpDir, 'objects'),
});
};
afterEach(() => {
store?.close();
if (tmpDir) rmSync(tmpDir, { recursive: true, force: true });
});
it('runs full lifecycle: START → ... → END', async () => {
setup();
const rule = createWorkflowRule({{WORKFLOW_EXPORT}}, store);
// Trigger workflow
const hash = await store.putObject('test input');
await store.appendEvent({
occurredAt: Date.now(),
kind: '{{WORKFLOW_NAME}}.__start__',
key: 'test-1',
hash,
});
// Tick until quiescent
const executed: string[] = [];
for (let i = 0; i < 20; i++) {
const r = await rule.tick();
if (r.executed.length === 0) break;
for (const ex of r.executed) executed.push(ex.role);
}
// Verify all roles executed in order
expect(executed).toEqual(['step1', 'step2']);
// Verify __end__ event was written
const events = await store.getAfter(0);
const endEvent = events.find((e) => e.kind === '{{WORKFLOW_NAME}}.__end__');
expect(endEvent).toBeTruthy();
});
it('produces expected output', async () => {
setup();
const rule = createWorkflowRule({{WORKFLOW_EXPORT}}, store);
const hash = await store.putObject('hello');
await store.appendEvent({
occurredAt: Date.now(),
kind: '{{WORKFLOW_NAME}}.__start__',
key: 'test-2',
hash,
});
const r1 = await rule.tick();
expect(r1.executed.length).toBe(1);
expect(r1.executed[0].role).toBe('step1');
// TODO: assert on content/meta
const r2 = await rule.tick();
expect(r2.executed.length).toBe(1);
expect(r2.executed[0].role).toBe('step2');
// TODO: assert on content/meta
});
});