Add test suite#3
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a first-class Node.js test suite (using node:test) for jarmuz, along with coverage/typecheck tooling and a handful of small refactors to make key runtime paths testable and typed (via JSDoc + TypeScript checkJs).
Changes:
- Added comprehensive tests (workers/fixtures/support helpers) for pipeline scheduling, worker lifecycle, job-types (basic/command/spawner/persist), and CLI watch/once behavior.
- Added tooling for typechecking and 100% coverage enforcement (TypeScript config, c8 config, Makefile targets, GitHub Actions workflows).
- Introduced dedicated error types and expanded JSDoc types across core libs/job-types/helpers.
Reviewed changes
Copilot reviewed 108 out of 111 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Enables TypeScript checkJs typechecking for src/**/*.mjs. |
| tests/support/wait-for-message.mjs | Promise helper for awaiting worker messages. |
| tests/support/wait-for-file-content.mjs | File-watching helper to await predicate-matching content. |
| tests/support/temp-directory.mjs | Temp directory helper with cleanup. |
| tests/support/run-worker-build.mjs | Helper to run a worker build and drain worker. |
| tests/support/run-persist-restart-scenario.mjs | Shared scenario helper for persist keepAlive restart tests. |
| tests/support/run-node-script.mjs | Spawns Node scripts for integration-style tests. |
| tests/support/kill-process.mjs | Utility for SIGKILLing a pid with ESRCH tolerance. |
| tests/support/exit-worker-on-drain.mjs | Ensures worker exits on drain and triggers V8 coverage flush. |
| tests/support/drain-worker.mjs | Sends drain message and waits for worker exit. |
| tests/support/create-worker.mjs | Worker constructor helper for fixtures. |
| tests/support/consumer-worker-sources.mjs | Inline worker sources for consumer-project integration tests. |
| tests/support/consumer-project.mjs | Creates a temp “consumer” project with jarmuz symlinked. |
| tests/spawner-sigkills-running-process-on-next-build.test.mjs | Verifies spawner abort kills still-running process between builds. |
| tests/spawner-runs-background-process-without-waiting.test.mjs | Verifies spawner background doesn’t block build completion. |
| tests/spawner-resolves-exec-with-command-stdout.test.mjs | Verifies new exec() resolves with stdout content. |
| tests/spawner-rejects-exec-when-command-fails.test.mjs | Verifies exec() rejects on command failure. |
| tests/scheduler-runs-callback-after-debounce-window.test.mjs | Covers scheduler debounce behavior. |
| tests/scheduler-reschedule-cancels-the-earlier-callback.test.mjs | Covers unique rescheduling cancellation behavior. |
| tests/persist-keepalive-starts-and-restarts-a-process.test.mjs | Covers persist keepAlive restart on natural exit. |
| tests/persist-keepalive-restarts-a-signal-killed-process.test.mjs | Covers persist keepAlive restart after signal termination. |
| tests/persist-keepalive-ignores-a-duplicate-exec-string.test.mjs | Covers persist deduplication of identical exec strings. |
| tests/manage-workers-stop-all-terminates-every-worker.test.mjs | Verifies manageWorkers stopAll empties registry. |
| tests/manage-workers-invokes-on-success-for-a-successful-build.test.mjs | Verifies onSuccess + pending cleared. |
| tests/manage-workers-invokes-on-failure-for-a-failed-build.test.mjs | Verifies onFailure + pending cleared. |
| tests/manage-pipeline-schedule-throws-for-an-unknown-job.test.mjs | Validates unknown job errors for scheduling. |
| tests/manage-pipeline-schedule-successor-runs-the-next-job.test.mjs | Validates successor scheduling to next pipeline job. |
| tests/manage-pipeline-schedule-successor-returns-false-at-pipeline-end.test.mjs | Validates end-of-pipeline behavior. |
| tests/manage-pipeline-schedule-skips-when-a-predecessor-is-pending.test.mjs | Validates predecessor-pending skip behavior. |
| tests/manage-pipeline-callback-throws-when-the-worker-is-not-registered.test.mjs | Validates WorkerNotRunning error path. |
| tests/manage-pipeline-callback-posts-the-build-message-to-the-worker.test.mjs | Validates posting build message to registered worker. |
| tests/manage-pipeline-callback-drops-job-when-a-predecessor-becomes-pending.test.mjs | Validates drop behavior when predecessor becomes pending during debounce. |
| tests/keep-worker-alive-stops-and-rejects-posting-after-terminate.test.mjs | Covers terminated worker handle behavior. |
| tests/keep-worker-alive-restarts-the-worker-after-an-unexpected-exit.test.mjs | Covers automatic restart after worker crash. |
| tests/keep-worker-alive-delivers-a-posted-message-to-the-worker.test.mjs | Covers message delivery through worker handle. |
| tests/jarmuz-watch-mode-skips-changes-matching-ignore-patterns.test.mjs | Integration coverage for ignore patterns. |
| tests/jarmuz-watch-mode-schedules-jobs-on-matching-changes.test.mjs | Integration coverage for pattern scheduling. |
| tests/jarmuz-uses-the-provided-base-directory.test.mjs | Integration coverage for baseDirectory override behavior. |
| tests/jarmuz-runs-the-decider-immediately-with-the-initial-flag.test.mjs | Covers decider initial execution contract. |
| tests/jarmuz-once-mode-runs-the-pipeline-after-the-watcher-is-ready.test.mjs | Integration coverage for once-mode scheduling timing. |
| tests/jarmuz-once-mode-exits-1-when-a-job-fails.test.mjs | Integration coverage for failure exit code in once mode. |
| tests/jarmuz-defaults-base-directory-to-the-working-directory.test.mjs | Integration coverage for baseDirectory defaulting. |
| tests/format-subtree-list-renders-sorted-tree-with-prefixes.test.mjs | Unit test for subtree formatting output. |
| tests/format-subtree-list-leaves-input-array-unmutated.test.mjs | Unit test asserting input immutability. |
| tests/fixtures/workers/worker-spawner-exec-success.mjs | Worker fixture for spawner exec success behavior. |
| tests/fixtures/workers/worker-spawner-exec-failure.mjs | Worker fixture for spawner exec failure behavior. |
| tests/fixtures/workers/worker-spawner-background.mjs | Worker fixture for spawner background behavior. |
| tests/fixtures/workers/worker-spawner-abort.mjs | Worker fixture for spawner abort-on-next-build behavior. |
| tests/fixtures/workers/worker-persist-keepalive-signal-kill.mjs | Worker fixture for persist + signal kill restarts. |
| tests/fixtures/workers/worker-persist-keepalive-restart.mjs | Worker fixture for persist + natural exit restarts. |
| tests/fixtures/workers/worker-persist-keepalive-dedup.mjs | Worker fixture for persist dedup behavior. |
| tests/fixtures/workers/worker-echo.mjs | Echo worker fixture used by pipeline/worker tests. |
| tests/fixtures/workers/worker-crashes-once.mjs | Crash-once worker fixture used to validate restart behavior. |
| tests/fixtures/workers/worker-command-success.mjs | Command job-type fixture for success. |
| tests/fixtures/workers/worker-command-failure.mjs | Command job-type fixture for failure. |
| tests/fixtures/workers/worker-basic-uses-context-helpers.mjs | Basic job-type fixture exercising context helpers. |
| tests/fixtures/workers/worker-basic-throws.mjs | Basic job-type fixture throwing error. |
| tests/fixtures/workers/worker-basic-returns-undefined.mjs | Basic job-type fixture returning non-false (success). |
| tests/fixtures/workers/worker-basic-returns-false.mjs | Basic job-type fixture returning false (failure). |
| tests/fixtures/scripts/write-pid-and-stay-alive.mjs | Helper script to simulate long-lived process for spawner abort tests. |
| tests/fixtures/scripts/touch-and-exit.mjs | Helper script to simulate background startup side effects. |
| tests/fixtures/scripts/create-lock-or-report.mjs | Helper script for persist dedup/lock conflict scenarios. |
| tests/fixtures/scripts/append-and-self-kill.mjs | Helper script to append then SIGKILL self (restart path). |
| tests/fixtures/scripts/append-and-exit.mjs | Helper script to append then exit (restart path). |
| tests/fixtures/jarmuz/worker-reports-success.mjs | Fixture worker reporting success to test manageWorkers. |
| tests/fixtures/jarmuz/worker-reports-failure.mjs | Fixture worker reporting failure to test manageWorkers. |
| tests/fixtures/entry-watch.mjs | Integration entrypoint for watch-mode tests + coverage flush on SIGTERM. |
| tests/fixtures/entry-once.mjs | Integration entrypoint for once-mode tests. |
| tests/fixtures/entry-once-records-context.mjs | Integration entrypoint that records decider context for assertions. |
| tests/command-reports-success-when-command-exits-zero.test.mjs | Unit/integration test for command job-type success. |
| tests/command-reports-failure-when-command-exits-nonzero.test.mjs | Unit/integration test for command job-type failure. |
| tests/basic-reports-success-when-build-returns-non-false.test.mjs | Unit test for basic job-type success semantics. |
| tests/basic-reports-failure-when-build-throws.test.mjs | Unit test for basic job-type failure on throw. |
| tests/basic-reports-failure-when-build-returns-false.test.mjs | Unit test for basic job-type failure on false. |
| tests/basic-passes-context-helpers-into-build-function.test.mjs | Unit test verifying helper injection into build context. |
| tests/autogenerated-comment-embeds-the-worker-name.test.mjs | Unit test for autogeneratedComment content. |
| src/libs/worker-not-running-error.mjs | Adds typed custom error for missing worker registration. |
| src/libs/unknown-job-error.mjs | Adds typed custom error for unknown pipeline job names. |
| src/libs/terminated-worker-error.mjs | Adds typed custom error for postMessage after termination. |
| src/libs/scheduler.mjs | Adds JSDoc types for scheduler API. |
| src/libs/manage-workers.mjs | Adds JSDoc types for worker management callbacks/outcomes. |
| src/libs/manage-pipeline.mjs | Uses new custom errors + adds JSDoc typing. |
| src/libs/keep-worker-alive.mjs | Refactors for clearer typing + typed termination error. |
| src/libs/jarmuz.mjs | Adds JSDoc for public API and aligns pipeline scheduling calls. |
| src/job-types/spawner.mjs | Adds exec() API + abort controller integration + JSDoc typing. |
| src/job-types/persist.mjs | Adds JSDoc typing and simplifies run() signature. |
| src/job-types/command.mjs | Removes unnecessary await on synchronous resetConsole. |
| src/job-types/basic.mjs | Adds assertion for worker context + JSDoc typing + injects sleep helper. |
| src/helpers/sleep.mjs | Adds sleep helper for job contexts/tests. |
| src/helpers/print-subtree-list.mjs | Delegates formatting to new pure helper for testability. |
| src/helpers/format-subtree-list.mjs | New pure formatter returning lines for printing/testing. |
| src/helpers/autogenerated-comment.mjs | Adds JSDoc typing for exported helper. |
| scripts/check-coverage.mjs | Adds a coverage runner using c8 + node test runner. |
| package.json | Adds test/coverage scripts, tooling deps, pins versions, and sets Node engine. |
| package-lock.json | Lockfile updates for new tooling and pinned versions. |
| Makefile | Adds standardized targets for test/coverage/typecheck/type-coverage/format. |
| CLAUDE.md | Adds project context guidance for contributors. |
| .prettierignore | Excludes generated/large files from formatting. |
| .nvmrc | Pins local Node version to 24 for consistency. |
| .gitignore | Ignores coverage output directory. |
| .github/workflows/typecheck.yml | Adds CI typecheck job using Makefile target. |
| .github/workflows/test.yml | Adds CI test job using Makefile target. |
| .claude/rules/testing.md | Adds testing/coverage expectations guidance. |
| .claude/rules/teamwork.md | Adds module ownership/organization guidance. |
| .claude/rules/nix-shell.md | Adds standards for any future Nix shell definitions. |
| .claude/rules/makefile.md | Adds Makefile organization/standards guidance. |
| .claude/rules/github-workflows.md | Adds workflow standards guidance. |
| .claude/rules/github-actions.md | Adds action standards guidance. |
| .claude/rules/commits.md | Adds commit-message guidance. |
| .claude/rules/code-style.md | Adds code style and architectural guidance. |
| .c8rc.json | Enforces 100% coverage thresholds for src/**. |
Comments suppressed due to low confidence (1)
src/job-types/spawner.mjs:38
abort()can hang indefinitely if a process exits (and emitsclose) between the start of thefor (const proc of running)loop and theproc.once("close", resolve)registration. In that caseproc.kill()will return false and thecloseevent will never fire again, so the awaited Promise never resolves and the next build stalls. Consider resolving immediately whenproc.exitCode/proc.signalCodeis already set, and/or using a timeout /once(proc, "close")with a pre-check to avoid missing the event.
for (const proc of running) {
await new Promise(function (resolve) {
console.debug(`jarmuz: Killing Process(${proc.pid})...`);
proc.once("close", resolve);
proc.kill("SIGKILL");
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.