Skip to content
Merged

V3 #30

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@imqueue/rpc",
"version": "3.1.0",
"version": "3.2.0",
"description": "RPC-like client-service implementation over messaging queue",
"keywords": [
"redis",
Expand All @@ -20,9 +20,9 @@
"lint": "oxlint",
"format": "oxfmt \"index.ts\" \"debug.ts\" \"src/**/*.ts\" \"test/**/*.ts\"",
"format:check": "oxfmt --check \"index.ts\" \"debug.ts\" \"src/**/*.ts\" \"test/**/*.ts\"",
"test": "npm run build && node --experimental-test-module-mocks --test --test-timeout=15000 $(find test -name '*.spec.js')",
"test-coverage": "npm run build && node --experimental-test-module-mocks --enable-source-maps --test --experimental-test-coverage --test-timeout=15000 $(find test -name '*.spec.js')",
"test-lcov": "npm run build && mkdir -p coverage && node --experimental-test-module-mocks --enable-source-maps --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info --test-timeout=15000 $(find test -name '*.spec.js'); node scripts/strip-comment-coverage.mjs coverage/lcov.info",
"test": "npm run build && node --experimental-test-module-mocks --import ./test/warmup.mjs --test --test-timeout=15000 $(find test -name '*.spec.js')",
"test-coverage": "npm run build && node --experimental-test-module-mocks --enable-source-maps --import ./test/warmup.mjs --test --experimental-test-coverage --test-timeout=15000 $(find test -name '*.spec.js')",
"test-lcov": "npm run build && mkdir -p coverage && node --experimental-test-module-mocks --enable-source-maps --import ./test/warmup.mjs --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info --test-timeout=15000 $(find test -name '*.spec.js'); node scripts/strip-comment-coverage.mjs coverage/lcov.info",
"test-coverage-html": "npm run test-lcov; genhtml coverage/lcov.info --output-directory coverage/html --ignore-errors inconsistent,corrupt,format,mismatch && echo \"Coverage report: file://$(pwd)/coverage/html/index.html\"",
"test-dev": "npm run test && npm run clean-js && npm run clean-typedefs && npm run clean-maps",
"clean-typedefs": "find . -name '*.d.ts' -not -wholename '*node_modules*' -not -wholename '*generator*' -type f -delete",
Expand All @@ -43,7 +43,7 @@
"author": "imqueue.com <support@imqueue.com> (https://imqueue.com)",
"license": "GPL-3.0-only",
"dependencies": {
"@imqueue/core": "^3.1.0",
"@imqueue/core": "^3.2.0",
"acorn": "^8.17.0",
"typescript": "^7.0.2"
},
Expand Down
15 changes: 6 additions & 9 deletions test/mocks/moduleMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import { mock, MockModuleOptions } from 'node:test';
* Node 22 only understands the earlier pair, so the same exports shape is
* translated there.
*
* `cache: true` keeps mock-require's semantics: every `require()` of the
* mocked specifier returns the same module instance, so a test may patch a
* property in place and the code under test observes the change.
* `cache: false` is required: as of the Node 24.17/24.18 module-loader
* changes, `cache: true` mock modules expose their export names with the
* values never bound. Instance caching is not load-bearing here — shared
* state lives on the exported references themselves (mock class statics),
* so each re-evaluation serves the same objects.
*
* @param {Record<string, unknown>} exports - mock exports, `default` key being
* the default export
Expand All @@ -42,13 +44,8 @@ import { mock, MockModuleOptions } from 'node:test';
export function moduleMockOptions(
exports: Record<string, unknown>,
): MockModuleOptions {
if (+process.versions.node.split('.')[0] >= 24) {
// typings (@types/node 24.x) lag the runtime's `exports` option
return { cache: true, exports } as MockModuleOptions;
}

const { default: defaultExport, ...namedExports } = exports;
const options: MockModuleOptions = { cache: true };
const options: MockModuleOptions = { cache: false };

if (defaultExport !== undefined) {
options.defaultExport = defaultExport;
Expand Down
11 changes: 9 additions & 2 deletions test/mocks/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
* purchase a proprietary commercial license. Please contact us at
* <support@imqueue.com> to get commercial licensing options.
*/
import { mockModule } from './moduleMock';
import { mock } from 'node:test';
import { moduleMockOptions } from './moduleMock';
import { EventEmitter } from 'node:events';
import * as crypto from 'node:crypto';

Expand Down Expand Up @@ -322,7 +323,13 @@ const Redis = RedisClientMock;
// exports onto a class default, so the whole ESM-shaped namespace object is
// registered as the module's export (for CJS consumers it IS what
// `require('ioredis')` returns).
mockModule('ioredis', { __esModule: true, Redis, default: Redis });
mock.module(
'ioredis',
moduleMockOptions({
default: { __esModule: true, Redis, default: Redis },
Redis,
}),
);

// @ts-ignore
export * from 'ioredis';
Expand Down
15 changes: 15 additions & 0 deletions test/warmup.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*!
* Test preload (wired via `node --import ./test/warmup.mjs`).
*
* Registers all module mocks (side effect of the mocks index) and then
* fully loads the ES module graph of @imqueue/core BEFORE any spec file
* runs. CommonJS specs may then require('@imqueue/core') synchronously:
* require(esm) of an already-evaluated module returns its bound namespace,
* whereas evaluating a graph that contains node:test module mocks through
* the synchronous require(esm) path leaves the mock exports unbound (the
* mocks evaluate asynchronously), which manifests as
* "TypeError: core_1.Redis is not a constructor".
*/
import './mocks/index.js';

await import('@imqueue/core');
Loading