Files
ever-gauzy/jest.interop.js
Ruslan KonviserandClaude Opus 5.5 e39e9323c6 test: finish the Angular stub specs; interop for callable CJS, d3 transforms
Local runs after this commit: ui-core 45/45 suites, ui-auth 4/4, gauzy
29/29, desktop-ui-lib 41/41, gauzy-server 2/2, and every plugin UI project
that was red (integration-ai/github/hubstaff/upwork-ui, job-employee/
matching/proposal/search-ui, jobs-ui) green.

- jest.interop.js now patches every callable CommonJS package the code
  imports both ways (moment, randomcolor) with `default` + `__esModule`, so
  both import styles resolve to the function under either esModuleInterop.
  apps/gauzy's spec tsconfig turns esModuleInterop on (as ui-core, docs-ui
  and videos-ui do): ui-core's line chart default-imports
  chartjs-plugin-annotation and Chart.register received undefined.
- jest.preset.js transforms d3-* / internmap (ESM-only, reached through
  @swimlane/ngx-charts).
- desktop-ui-lib specs: section forms get the FormGroup their parent passes,
  cell renderers their rowData, dialogs their data; Settings/Setup/
  ScreenCapture get the library's GAUZY_ENV and the time tracker the
  AuthStrategy/AuthService the desktop apps bootstrap; the task table a
  signed-in session. Two test-side overrides are documented in place:
  LanguageSelectorComponent binds [(ngModel)] without FormsModule (a dead
  binding in the app too), and the plugin source forms use <nb-hint> as a
  plain styled element (Nebular has no such component).
- apps/gauzy: page specs get the date-picker config their route sets,
  the timesheet layout / job pages their route data, the task dialog a
  selected organization (its unguarded async read crashed the Jest worker)
  and a stand-in for docs-ui's links panel (docs-ui's entry point loads a
  PDF viewer that uses import.meta, which CommonJS Jest cannot parse).
- integration-upwork-ui: two hand-written specs used jasmine spies (jest
  has none) and partial Router/TranslateService mocks the template could
  not render with; they use jest.fn() and the real services now.
- gauzy-server's AppComponent spec was the 2021 CLI scaffold (title
  'desktop-web-ui', a "Welcome" h1) and declared a standalone component; it
  now imports it and asserts what the shell does (router outlet, language
  bridge started on init), with the library entry mocked to its one token.
- jobs-ui: the layout spec has asserted a main landmark since it was
  written; the layout now renders <main role="main"> around its outlet (the
  app shell defines no other main landmark).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:25:57 +02:00

46 lines
2.3 KiB
JavaScript

/**
* Jest `setupFiles` entry for the whole workspace (wired in `jest.preset.js`): make the callable
* CommonJS packages that this codebase imports BOTH ways load under either import style, the way the
* app bundlers already treat them.
*
* `moment` is a CommonJS function (`module.exports = moment`, no `default`, no `__esModule`), and the
* code imports it two ways:
* - `import moment from 'moment'` — ui-core (43 files), public-layout-ui, the React UI plugins;
* - `import * as moment from 'moment'` — core, desktop-lib, desktop-ui-lib, apps/gauzy and others.
* Webpack / esbuild accept both. The TypeScript CommonJS emit Jest runs cannot accept both under one
* `esModuleInterop` setting:
* - `esModuleInterop: false` (the root tsconfig) compiles the default import to `moment_1.default`,
* which is undefined — "(0, moment_1.default) is not a function" failed ~50 Angular suites at load
* time, in every project that reaches ui-core's date-range-picker service;
* - `esModuleInterop: true` fixes that, but compiles the namespace import through `__importStar`,
* which copies the module's properties into a plain object — so `moment()` stops being callable.
* `randomcolor` has the same shape and is namespace-imported and called (ui-core's tags colour input,
* apps/gauzy's weekly report), which breaks in exactly the projects that set `esModuleInterop: true`.
*
* Giving each loaded module `default` (itself) and `__esModule` makes every combination resolve to the
* function itself, exactly as the bundlers do. `moment-timezone` returns the same object as `moment`.
*
* Scope: this file runs in each test file's module registry before the spec loads, so the specs see
* the patched instances. A spec that calls `jest.resetModules()` and then re-requires one of these
* gets a fresh, unpatched copy — repeat the patch there if one ever needs it.
*/
const CALLABLE_COMMONJS_PACKAGES = ['moment', 'randomcolor'];
for (const name of CALLABLE_COMMONJS_PACKAGES) {
let mod;
try {
mod = require(name);
} catch {
continue; // not installed in this checkout: nothing can import it either
}
if (typeof mod !== 'function') {
continue;
}
if (mod.default === undefined) {
mod.default = mod;
}
if (!mod.__esModule) {
Object.defineProperty(mod, '__esModule', { value: true });
}
}