Files
zeekayandHanzo Dev e85f851ca8 jest: ts-jest cannot start on typescript 7, so the transform is babel-jest
Moving to typescript 7.0.2 — the native Go compiler — took the ENTIRE test suite
with it, and silently, because a runner that cannot construct its transformer
reports no test results at all:

  ● Test suite failed to run
    TypeError: Cannot read properties of undefined (reading 'readFile')
      at ConfigSet._resolveTsConfig (ts-jest/dist/legacy/config/config-set.js:519)

ts-jest drives the TypeScript compiler's JavaScript API — `ts.sys.readFile` here
— and typescript 7's shipped JS shim does not expose `ts.sys`. Its peer range
says so plainly (`>=4.3 <7`), and there is no way to hand it a private
TypeScript: it takes typescript as a PEER, so pnpm resolves it from this
package, and neither an override nor a packageExtension changes that. 465 of 465
suites died before running.

babel-jest has no TypeScript at all. babel.config.js already carries a `test`
env with preset-typescript + preset-react targeting node, so one transform now
covers ts, tsx, js, jsx and mjs, and ts-jest leaves devDependencies. Type
checking was never the runner's job — `tsc --noEmit` does it, with the compiler
this repo actually builds with.

Two allowlist entries came out of the switch, and both name a real fact about
this stack: @hanzo/* and @hanzogui/* publish ESM only (dist/esm/index.mjs), and
so does react-native-svg-web / react-native-web, which @hanzo/gui's web build
imports by name. They are the design system — on the import path of most of this
app — so leaving them untransformed cost 202 suites on the word `export`.

  jest -> 342 suites and 4286 tests PASS, from 0 and 0.
          122 suites still fail; 106 of those fail to run, and 92 of THOSE are
          one cause: babel-plugin-jest-hoist rejects a jest.mock() factory that
          closes over an out-of-scope binding (38× `ROUTES`, 10×
          `successNotification`, then a long tail). ts-jest never enforced it.
          The rule is right — an uninitialised mock variable is a real bug — and
          the fix is per-file and mechanical: require the value inside the
          factory, or name it mock*. It is a test-file change, not a toolchain
          one, and it is not this commit's.
  pnpm build -> EXIT=0, built in 43.40s
  tsc --noEmit -> 22 errors, all pre-existing and all in test files

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 01:43:11 -07:00

69 lines
3.2 KiB
TypeScript

import type { Config } from '@jest/types';
const USE_SAFE_NAVIGATE_MOCK_PATH = '<rootDir>/__mocks__/useSafeNavigate.ts';
const config: Config.InitialOptions = {
silent: true,
clearMocks: true,
coverageDirectory: 'coverage',
coverageReporters: ['text', 'cobertura', 'html', 'json-summary'],
collectCoverageFrom: ['src/**/*.{ts,tsx}'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'mjs', 'json'],
modulePathIgnorePatterns: ['dist'],
moduleNameMapper: {
'\\.(png|jpg|jpeg|gif|svg|webp|avif|ico|bmp|tiff)$':
'<rootDir>/__mocks__/fileMock.ts',
'^@/(.*)$': '<rootDir>/src/$1',
'\\.(css|less|scss)$': '<rootDir>/__mocks__/cssMock.ts',
'\\.module\\.mjs$': '<rootDir>/__mocks__/cssMock.ts',
'\\.md$': '<rootDir>/__mocks__/cssMock.ts',
'^uplot$': '<rootDir>/__mocks__/uplotMock.ts',
'^components/ui/resizable$': '<rootDir>/__mocks__/resizableMock.tsx',
'^hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
'^src/hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
'^.*/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
'^constants/env$': '<rootDir>/__mocks__/env.ts',
'^src/constants/env$': '<rootDir>/__mocks__/env.ts',
'^@o11yhq/icons$':
'<rootDir>/node_modules/@o11yhq/icons/dist/index.esm.js',
'^react-syntax-highlighter/dist/esm/(.*)$':
'<rootDir>/node_modules/react-syntax-highlighter/dist/cjs/$1',
'^@o11yhq/([^/]+)$': '<rootDir>/node_modules/@o11yhq/$1/dist/$1.js',
},
testMatch: ['<rootDir>/src/**/*?(*.)(test).(ts|js)?(x)'],
// ONE transform for every source extension. babel-jest reads babel.config.js,
// whose `test` env already compiles TS + JSX to CommonJS for node. ts-jest is
// gone because it drives the TypeScript compiler's JS API — and typescript 7,
// the native Go compiler this repo builds with, does not expose it: every
// suite died in ts-jest's config-set with
// TypeError: Cannot read properties of undefined (reading 'readFile')
// before a single test ran. Type checking is `tsc --noEmit`'s job, not the
// test runner's; jest's job is to execute.
transform: {
'^.+\\.(ts|tsx|js|jsx|mjs)$': 'babel-jest',
},
transformIgnorePatterns: [
// pnpm's real path is node_modules/.pnpm/<pkg>@<ver>/node_modules/<pkg>/…,
// so skip the .pnpm indirection segment and let the allowlist below judge
// the inner node_modules/<pkg>/, which is identical in either layout.
// @hanzo/* and @hanzogui/* ship ESM only (dist/esm/index.mjs). They are the
// design system, so they are on the import path of most of this app — leave
// them untransformed and 202 suites die on `export` before a test runs.
'node_modules/(?!\\.pnpm/|(@hanzo/[a-z0-9-]+|@hanzogui/[a-z0-9-]+|react-native-svg-web|react-native-web|lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@o11yhq/design-tokens|@o11yhq/table|@o11yhq/calendar|@o11yhq/input|@o11yhq/popover|@o11yhq/button|@o11yhq/sonner|@o11yhq/*|date-fns|d3-interpolate|d3-color|api|@codemirror|@lezer|@marijn|@grafana|nuqs)/)',
],
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
testPathIgnorePatterns: ['/node_modules/', '/public/'],
moduleDirectories: ['node_modules', 'src'],
testEnvironment: 'jest-environment-jsdom',
coverageThreshold: {
global: {
statements: 80,
branches: 65,
functions: 80,
lines: 80,
},
},
};
export default config;