Skip to content

@fedify/fixture's test() registers nothing on Node.js in 2.0-maintenance #1036

Description

@heeoneie

Summary

On 2.0-maintenance, tests registered through @fedify/fixture's test() never execute under Node.js. The registration call throws, the failure is swallowed by an empty catch, and node --test then reports each file as a single passing entry. The suite is counted green while the tests inside it have not run.

229 registrations across 7 packages go through this path. 228 of them do not execute on Node. (40 files import test from the fixture; 39 of them register at least one test.)

Package Files Registrations Run on Node
@fedify/fedify 28 149 none
@fedify/vocab 4 53 none
@fedify/testing 1 15 none
@fedify/redis 3 9 none
@fedify/postgres 1 1 none
@fedify/sqlite 1 1 none
@fedify/webfinger 1 1 yes (see below)

@fedify/fedify's Node run finishing in ~3s with # tests 28 / # pass 28 — one entry per file, no individual test names — is the visible symptom.

Cause

packages/fixture/src/test.ts calls require("node:test") in the Node branch. The file is ESM, where require is not defined, so the call throws and the empty catch discards it:

try {
  const { test: nodeTest } = require("node:test");
  nodeTest(def.name, { only: def.only, skip: def.ignore }, async (t) => {  });
} catch {
  // Fallback for environments without `node:test`
}

main does not have this problem: it uses createRequire(process.cwd() + "/")("node:test"), with no catch, behind a guard that checks process.release?.name === "node" and excludes Cloudflare Workers. The change landed in fab1c07, “Upgrade Deno to 2.9.5” (2026-08-24), whose message notes it is meant to “[e]nsure bundled Node tests register correctly”. It was never backported to 2.0-maintenance: that commit is not an ancestor of the branch, and 096becf is still the only commit touching this path there.

That commit does not cherry-pick onto 2.0-maintenance. It changes 23 files as part of the Deno upgrade, and git cherry-pick leaves 14 of them conflicted — deno.json, deno.lock, pnpm-lock.yaml, mise.toml, packages/lint/package.json, packages/vocab/src/actor.test.ts, the setup-deno action, and seven modify/delete conflicts against paths that do not exist on this branch (packages/uri-template/, test/smoke/, packages/fedify/src/federation/tasks/codec.ts, …). packages/fixture/src/test.ts itself is among the nine that apply cleanly, so the relevant change can be taken on its own, but not by cherry-picking the commit as it stands.

Why @fedify/webfinger is the exception

It builds both lookup.test.cjs and lookup.test.js into dist/, and node --test picks up both. require works in the CJS copy, so those tests register there; the ESM copy still fails silently and shows up as a bare file entry. @fedify/fedify and @fedify/vocab build .mjs only, and @fedify/redis, @fedify/postgres, @fedify/sqlite and @fedify/testing run ESM sources directly via --experimental-transform-types, so every one of them takes the failing path.

Reproduction

Add a test that must fail, registered through the fixture test(), and run each runtime:

deno: PROBE: this must fail ... FAILED
bun : (fail) PROBE: this must fail    0 pass
node: ok 1 - src/probe.test.ts        # pass 1, # fail 0

Node reports a pass for a test that cannot pass.

Note on fixing this

Restoring registration will make these 228 tests run on Node for the first time on this branch, and some may need work before they are green.

On main the same tests do run on Node, by name, and they pass. From the test-node job of the most recent main workflow run (34687149404, 2026-09-12):

Package Node tests on main on 2.0-maintenance
@fedify/fedify 934 passed, 0 failed, 1 skipped 28 bare file entries
@fedify/vocab 32492 passed, 0 failed, 1 skipped 4 bare file entries
@fedify/webfinger 72 passed, 0 failed 18 (1 real test + 16 steps, via the CJS copy)
@fedify/testing 60 passed, 0 failed 1 bare file entry
@fedify/postgres 33 passed, 0 failed 24, none of them the fixture-registered one
@fedify/sqlite 15 passed, 0 failed 14, none of them the fixture-registered one
@fedify/redis 13 passed, 0 failed 3 bare file entries

@fedify/redis on main lists RedisKvStore.get(), RedisKvStore.set(), RedisMessageQueue and the rest by name; the same three files on 2.0-maintenance report only src/kv.test.ts, src/codec.test.ts and src/mq.test.ts. So the exposure is bounded by what main already tolerates, though the two branches have diverged enough that this is an indication rather than a guarantee.

The unit to port is the file, not the commit, and the only option that disappears with it is unused on this branch: in source, the only two .only references anywhere in the tree are packages/fixture/src/test.ts's own Bun and Node branches, and no caller passes only to test(). main dropped the option from the TestDefinition type entirely, Bun branch included.

I'm happy to take this on if you'd like it backported; I'd rather check first, since the blast radius is larger than the diff.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

component/testingTesting utilities (@fedify/testing)runtime/nodeNode.js runtime related

Type

Fields

Priority

None yet

Effort

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions