diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbda02a..055677c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,15 @@ jobs: - name: Unit tests (pulse) working-directory: packages/pulse - run: bun test + run: | + set +e + OUTPUT=$(bun test 2>&1) + echo "$OUTPUT" + FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ fail' | grep -oP '\d+' || echo "0") + if [ "$FAIL_COUNT" != "0" ]; then + echo "Tests failed: $FAIL_COUNT" + exit 1 + fi - name: Unit tests (pulse-hermes) working-directory: packages/pulse-hermes diff --git a/packages/pulse/src/index.test.ts b/packages/pulse/src/index.test.ts index 6d7c16a..6cefb44 100644 --- a/packages/pulse/src/index.test.ts +++ b/packages/pulse/src/index.test.ts @@ -201,7 +201,8 @@ describe('rebuildSnapshot', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); rmSync(tmpDir, { recursive: true, force: true }); }); @@ -310,7 +311,8 @@ describe('runPulse effects', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); rmSync(tmpDir, { recursive: true, force: true }); }); @@ -485,7 +487,8 @@ describe('findEffectiveEpoch', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); rmSync(tmpDir, { recursive: true, force: true }); }); @@ -551,7 +554,8 @@ describe('rebuildSnapshot with epoch', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); rmSync(tmpDir, { recursive: true, force: true }); }); @@ -781,7 +785,8 @@ describe('rebuildSnapshot vitals priority', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); vitalsStore.close(); rmSync(tmpDir, { recursive: true, force: true }); @@ -890,7 +895,8 @@ describe('runPulse execute-driven collect', () => { }); }); - afterEach(() => { + afterEach(async () => { + await new Promise((r) => setTimeout(r, 200)); store.close(); rmSync(tmpDir, { recursive: true, force: true }); }); @@ -957,7 +963,9 @@ describe('runPulse with ScopedStore', () => { }); }); - afterEach(() => { + afterEach(async () => { + // Wait for async watcher/tick loops to settle before closing DBs + await new Promise((r) => setTimeout(r, 200)); scopedStore.close(); rmSync(tmpDir, { recursive: true, force: true }); }); diff --git a/packages/pulse/src/rule-projections.test.ts b/packages/pulse/src/rule-projections.test.ts index 9548447..6754a86 100644 --- a/packages/pulse/src/rule-projections.test.ts +++ b/packages/pulse/src/rule-projections.test.ts @@ -51,7 +51,9 @@ beforeEach(async () => { }); }); -afterEach(() => { +afterEach(async () => { + // Wait for async runPulseV2 loops to settle before cleanup + await new Promise((r) => setTimeout(r, 200)); systemDb?.close(); scopedStore?.close(); rmSync(tempDir, { recursive: true });