@starci/jest-preset 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +17 -2
- package/dist/entity-manager.d.ts +1 -1
- package/dist/index.d.ts +21 -19
- package/dist/index.js +7 -3
- package/dist/query-builder.d.ts +56 -0
- package/dist/query-builder.js +51 -0
- package/dist/world-runner.js +2 -2
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.5.0 - 2026-10-29
|
|
4
|
+
|
|
5
|
+
- Added: `fakeQueryBuilder(answers)` and `queueQueryBuilders(em, answers)` (also at `@starci/jest-preset/query-builder`), the double of `createQueryBuilder(Entity, "alias")` beside `mockEntityManager`: every chained call is recorded and returned to the chain, the terminals resolve the spec's answers. Lite persistence reads through entities and that builder (ruling `lite-persistence-typeorm-entities`), so the double moves here from the apps.
|
|
6
|
+
|
|
7
|
+
## 2.4.1 - 2026-10-28
|
|
8
|
+
|
|
9
|
+
- Changed: `@starci/ai-router` joins the ESM-only dependencies jest compiles to CommonJS, so a spec that builds an AppModule registering the AI pool loads it.
|
|
10
|
+
- Fixed: the built declarations name `.js` (`dist/index.d.ts` and `dist/entity-manager.d.ts` named `.ts` files a consumer tsc cannot read).
|
|
11
|
+
- Fixed: the pair-mismatch message names state protocol 2 as test-world 1.1 and later write it, not "test-world 1.1.x"; release C pins this preset beside `@starci/test-world` 1.2.3, which speaks protocol 2.
|
|
12
|
+
|
|
3
13
|
## 2.4.0 - 2026-10-28
|
|
4
14
|
|
|
5
15
|
- Changed: the source is TypeScript in `src/`, built to CommonJS JavaScript in `dist/` (`npm run build`; `prepack` builds), and the declarations are emitted from it instead of hand-written; `main`, `types` and every export (`.`, `./mock`, `./clock`, `./entity-manager`, `./ids`, `./matchers`, `./cache`, `./lock`, `./event-bus`, `./queue`, `./inbox`, `./builders`, `./merge`) point into `dist/`. No rule or behaviour changed; the specifiers are unchanged. The files jest loads by path are now `dist/world-runner.js`, `dist/unit-metadata.js`, `dist/unit-metadata.generated.js` (the coverage anchor, copied byte for byte from `assets/`) and `dist/lcov.js`; `@starci/jest-preset/merge` now has types.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @starci/jest-preset
|
|
2
2
|
|
|
3
|
-
The jest config of a Nest repository and the one shared unit-test double kit (`mock<T>()`, `mockEntityManager`, `fakeTransaction`, `fakeCache`, `fakeLock`, `recordingEventBus`, `recordingQueueOutbox`, `fakeInbox`, `builder`, `FakeClock`, `fakeIds` and the Outcome matchers). Install it from the npm registry at the exact version in the StarCi runtime's `knowledge/stack/pins.yaml` (see [`packages/README.md`](../README.md)).
|
|
3
|
+
The jest config of a Nest repository and the one shared unit-test double kit (`mock<T>()`, `mockEntityManager`, `fakeTransaction`, `fakeQueryBuilder`, `queueQueryBuilders`, `fakeCache`, `fakeLock`, `recordingEventBus`, `recordingQueueOutbox`, `fakeInbox`, `builder`, `FakeClock`, `fakeIds` and the Outcome matchers). Install it from the npm registry at the exact version in the StarCi runtime's `knowledge/stack/pins.yaml` (see [`packages/README.md`](../README.md)).
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
6
|
// jest.config.js (a managed file: `starci app sync` renders it, `starci app check` compares it; do not edit)
|
|
@@ -72,7 +72,7 @@ const service = moduleRef.get(CommissionService)
|
|
|
72
72
|
No `new` of the service, no `imports`, no `overrideProvider`, no `jest.mock`, no casts, no `Date.now()` and no `process.env`. The
|
|
73
73
|
full rules and the dependency-to-double-to-cases table are `contexts/code/be/test.md` (the BE-TEST rules). Every
|
|
74
74
|
export below is on the package root (`@starci/jest-preset`); the sub-paths `./mock`, `./clock`, `./entity-manager`, `./ids`,
|
|
75
|
-
`./matchers`, `./cache`, `./lock`, `./event-bus`, `./queue`, `./inbox` and `./builders` exist as well.
|
|
75
|
+
`./query-builder`, `./matchers`, `./cache`, `./lock`, `./event-bus`, `./queue`, `./inbox` and `./builders` exist as well.
|
|
76
76
|
|
|
77
77
|
## `mockEntityManager` and `fakeTransaction`
|
|
78
78
|
|
|
@@ -105,6 +105,21 @@ The stubbable methods are `findOne`, `findOneBy`, `findOneOrFail`, `findOneByOrF
|
|
|
105
105
|
`delete`, `softDelete`, `restore`, `increment`, `decrement` and `query`. `fakeTransaction(em)` returns `{ em, outcomes, commits,
|
|
106
106
|
rollbacks, committedWrites, rolledBackWrites }`.
|
|
107
107
|
|
|
108
|
+
## `fakeQueryBuilder` and `queueQueryBuilders`
|
|
109
|
+
|
|
110
|
+
The double of `createQueryBuilder(Entity, "alias")`, the builder a lite service reads with. Every chained method records
|
|
111
|
+
`{ method, args }` and returns the builder; a terminal (`execute`, `getMany`, `getOne`, `getRawMany`, `getRawOne`, `getCount`,
|
|
112
|
+
`getManyAndCount`) resolves the answer the spec gave it, and a function answer is called when the terminal runs.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { mockEntityManager, queueQueryBuilders } from "@starci/jest-preset"
|
|
116
|
+
|
|
117
|
+
const em = mockEntityManager()
|
|
118
|
+
const [open] = queueQueryBuilders(em, [{ getMany: [order] }]) // one fake per createQueryBuilder call, in order
|
|
119
|
+
await service.listOpen(owner)
|
|
120
|
+
expect(open.callsOf("where")).toEqual([["o.ownerId = :owner", { owner }]])
|
|
121
|
+
```
|
|
122
|
+
|
|
108
123
|
## `fakeCache(clock)`, `fakeLock(clock)`, `recordingEventBus()` and `recordingQueueOutbox()`
|
|
109
124
|
|
|
110
125
|
```ts
|
package/dist/entity-manager.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* rethrown) and which writes it made, so a spec can assert that a rolled-back transaction committed nothing.
|
|
18
18
|
*/
|
|
19
19
|
import type { DeleteResult, EntityManager, InsertResult, UpdateResult } from "typeorm";
|
|
20
|
-
import type { MockOf } from "./mock.
|
|
20
|
+
import type { MockOf } from "./mock.js";
|
|
21
21
|
/** A typed double of `EntityManager`: assignable wherever an `EntityManager` is required, every method a jest mock. */
|
|
22
22
|
export type MockEntityManager = MockOf<EntityManager>;
|
|
23
23
|
/** An entity class. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import type { Config } from "jest";
|
|
2
|
-
import { mock, createMock } from "./mock.
|
|
3
|
-
import { mockEntityManager, fakeTransaction } from "./entity-manager.
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
export type {
|
|
14
|
-
export type {
|
|
15
|
-
export type {
|
|
16
|
-
export type {
|
|
17
|
-
export type {
|
|
18
|
-
export type {
|
|
19
|
-
export type {
|
|
2
|
+
import { mock, createMock } from "./mock.js";
|
|
3
|
+
import { mockEntityManager, fakeTransaction } from "./entity-manager.js";
|
|
4
|
+
import { fakeQueryBuilder, queueQueryBuilders } from "./query-builder.js";
|
|
5
|
+
import { FakeClock } from "./clock.js";
|
|
6
|
+
import { fakeCache } from "./cache.js";
|
|
7
|
+
import { fakeLock } from "./lock.js";
|
|
8
|
+
import { recordingEventBus } from "./event-bus.js";
|
|
9
|
+
import { recordingQueueOutbox } from "./queue.js";
|
|
10
|
+
import { fakeInbox } from "./inbox.js";
|
|
11
|
+
import { builder } from "./builders.js";
|
|
12
|
+
import { fakeIds, FakeIds } from "./ids.js";
|
|
13
|
+
export type { MockOf } from "./mock.js";
|
|
14
|
+
export type { MockEntityManager, FakeTransaction, EntityClass } from "./entity-manager.js";
|
|
15
|
+
export type { FakeQueryBuilder, QueryBuilderAnswers, QueryBuilderCall, QueryBuilderHost } from "./query-builder.js";
|
|
16
|
+
export type { FakeCache } from "./cache.js";
|
|
17
|
+
export type { FakeLock } from "./lock.js";
|
|
18
|
+
export type { RecordingEventBus } from "./event-bus.js";
|
|
19
|
+
export type { RecordingQueueOutbox } from "./queue.js";
|
|
20
|
+
export type { FakeInbox } from "./inbox.js";
|
|
21
|
+
export type { RefusalReason } from "./matchers.js";
|
|
20
22
|
/** The coverage scope `starci app sync` renders from the slot manifest: the measured roots (a directory pattern per measured slot, a placeholder folder written as a star), the logic roles measured in them and the directories inside a root that are never measured (each ending in a double star). */
|
|
21
23
|
export interface StarciCoverageScope {
|
|
22
24
|
readonly roots: readonly string[];
|
|
@@ -111,4 +113,4 @@ declare const WORLD_RUNNER: string;
|
|
|
111
113
|
declare function hasCoverageSubjects(root: string, glob: string): boolean;
|
|
112
114
|
/** The whole jest config: projects `unit`, `integration`, `e2e` and `contract`. It takes the coverage scope the managed repository config renders; without it it refuses. */
|
|
113
115
|
declare function starciJestConfig(options: StarciJestOptions): StarciJestConfig;
|
|
114
|
-
export { starciJestConfig, TEST_KIND_FOLDERS, MODULE_NAME_MAPPER, mock, createMock, mockEntityManager, fakeTransaction, FakeClock, fakeCache, fakeLock, recordingEventBus, recordingQueueOutbox, fakeInbox, builder, fakeIds, FakeIds, collectCoverageFrom, rootGlob, sonarExclusions, hasCoverageSubjects, COVERAGE_EXCLUDES, COVERAGE_THRESHOLD, UNIT_COMPILER_OPTIONS, WORLD_RUNNER, };
|
|
116
|
+
export { starciJestConfig, TEST_KIND_FOLDERS, MODULE_NAME_MAPPER, mock, createMock, mockEntityManager, fakeTransaction, fakeQueryBuilder, queueQueryBuilders, FakeClock, fakeCache, fakeLock, recordingEventBus, recordingQueueOutbox, fakeInbox, builder, fakeIds, FakeIds, collectCoverageFrom, rootGlob, sonarExclusions, hasCoverageSubjects, COVERAGE_EXCLUDES, COVERAGE_THRESHOLD, UNIT_COMPILER_OPTIONS, WORLD_RUNNER, };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WORLD_RUNNER = exports.UNIT_COMPILER_OPTIONS = exports.COVERAGE_THRESHOLD = exports.COVERAGE_EXCLUDES = exports.FakeIds = exports.fakeIds = exports.builder = exports.fakeInbox = exports.recordingQueueOutbox = exports.recordingEventBus = exports.fakeLock = exports.fakeCache = exports.FakeClock = exports.fakeTransaction = exports.mockEntityManager = exports.createMock = exports.mock = exports.MODULE_NAME_MAPPER = exports.TEST_KIND_FOLDERS = void 0;
|
|
3
|
+
exports.WORLD_RUNNER = exports.UNIT_COMPILER_OPTIONS = exports.COVERAGE_THRESHOLD = exports.COVERAGE_EXCLUDES = exports.FakeIds = exports.fakeIds = exports.builder = exports.fakeInbox = exports.recordingQueueOutbox = exports.recordingEventBus = exports.fakeLock = exports.fakeCache = exports.FakeClock = exports.queueQueryBuilders = exports.fakeQueryBuilder = exports.fakeTransaction = exports.mockEntityManager = exports.createMock = exports.mock = exports.MODULE_NAME_MAPPER = exports.TEST_KIND_FOLDERS = void 0;
|
|
4
4
|
exports.starciJestConfig = starciJestConfig;
|
|
5
5
|
exports.collectCoverageFrom = collectCoverageFrom;
|
|
6
6
|
exports.rootGlob = rootGlob;
|
|
@@ -14,6 +14,9 @@ Object.defineProperty(exports, "createMock", { enumerable: true, get: function (
|
|
|
14
14
|
const entity_manager_ts_1 = require("./entity-manager.js");
|
|
15
15
|
Object.defineProperty(exports, "mockEntityManager", { enumerable: true, get: function () { return entity_manager_ts_1.mockEntityManager; } });
|
|
16
16
|
Object.defineProperty(exports, "fakeTransaction", { enumerable: true, get: function () { return entity_manager_ts_1.fakeTransaction; } });
|
|
17
|
+
const query_builder_ts_1 = require("./query-builder.js");
|
|
18
|
+
Object.defineProperty(exports, "fakeQueryBuilder", { enumerable: true, get: function () { return query_builder_ts_1.fakeQueryBuilder; } });
|
|
19
|
+
Object.defineProperty(exports, "queueQueryBuilders", { enumerable: true, get: function () { return query_builder_ts_1.queueQueryBuilders; } });
|
|
17
20
|
const clock_ts_1 = require("./clock.js");
|
|
18
21
|
Object.defineProperty(exports, "FakeClock", { enumerable: true, get: function () { return clock_ts_1.FakeClock; } });
|
|
19
22
|
const cache_ts_1 = require("./cache.js");
|
|
@@ -87,9 +90,10 @@ function transform(tsconfig) {
|
|
|
87
90
|
* The runtime dependencies of a back end that ship ECMAScript modules only: jest's CommonJS runtime cannot load them, so their
|
|
88
91
|
* files are compiled to CommonJS like the repository's own (ts-jest with `allowJs`) instead of being skipped as node_modules.
|
|
89
92
|
* `jose` is the Supabase access-token verifier of every lite back end (be.integrations.supabase); a lite app keeps full's unit
|
|
90
|
-
* run (ruling:R212/case-1, amended by ruling:R212/case-4), so a spec that imports its guard must load it.
|
|
93
|
+
* run (ruling:R212/case-1, amended by ruling:R212/case-4), so a spec that imports its guard must load it. `@starci/ai-router`
|
|
94
|
+
* is the AI pool module a back end registers in its AppModule, so a spec that builds the AppModule must load it.
|
|
91
95
|
*/
|
|
92
|
-
const ESM_ONLY_DEPENDENCIES = Object.freeze(["jose"]);
|
|
96
|
+
const ESM_ONLY_DEPENDENCIES = Object.freeze(["jose", String.raw `@starci[\\/]ai-router`]);
|
|
93
97
|
const ESM_DEPENDENCY_TRANSFORM = String.raw `^.+[\\/]node_modules[\\/](?:${ESM_ONLY_DEPENDENCIES.join("|")})[\\/].+\.js$`;
|
|
94
98
|
function esmDependencyTransform() {
|
|
95
99
|
return { [ESM_DEPENDENCY_TRANSFORM]: ["ts-jest", { tsconfig: { allowJs: true, module: "commonjs", target: "es2022", esModuleInterop: true }, diagnostics: false }] };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fakeQueryBuilder()` and `queueQueryBuilders()` -- the double of a typeorm `SelectQueryBuilder` (and its insert, update
|
|
3
|
+
* and delete siblings) that `mockEntityManager` hands out from `createQueryBuilder(Entity, "alias")`.
|
|
4
|
+
*
|
|
5
|
+
* A lite service reads with `createQueryBuilder(Entity, "alias")` and named parameters (persistence.md BE-PERSISTENCE-4).
|
|
6
|
+
* The fake is a Proxy: every chained method (`where`, `andWhere`, `innerJoin`, `orderBy`, `take`, `setLock`, `returning`,
|
|
7
|
+
* ...) records `{ method, args }` and returns the builder; a terminal method (`execute`, `getMany`, `getOne`,
|
|
8
|
+
* `getRawMany`, `getRawOne`, `getCount`, `getManyAndCount`) records too and resolves the answer the spec gave it (a function
|
|
9
|
+
* answer is called when the terminal runs). A spec asserts the statement it expects through `calls` or `callsOf(method)`.
|
|
10
|
+
*
|
|
11
|
+
* `queueQueryBuilders(em, answers)` queues one fake per answer on `em.createQueryBuilder` of a `mockEntityManager()`, in
|
|
12
|
+
* call order, and returns the fakes so the spec can read each one's calls.
|
|
13
|
+
*/
|
|
14
|
+
/** One chained call recorded on a fake query builder. */
|
|
15
|
+
export interface QueryBuilderCall {
|
|
16
|
+
/** The builder method that was called. */
|
|
17
|
+
readonly method: string;
|
|
18
|
+
/** The arguments it was called with. */
|
|
19
|
+
readonly args: ReadonlyArray<unknown>;
|
|
20
|
+
}
|
|
21
|
+
/** What the terminal methods of a fake query builder answer; a function is called when the terminal runs and its result returned. */
|
|
22
|
+
export interface QueryBuilderAnswers {
|
|
23
|
+
/** The answer of `execute()`. */
|
|
24
|
+
readonly execute?: unknown;
|
|
25
|
+
/** The answer of `getMany()`. */
|
|
26
|
+
readonly getMany?: ReadonlyArray<unknown> | (() => unknown);
|
|
27
|
+
/** The answer of `getOne()`. */
|
|
28
|
+
readonly getOne?: unknown;
|
|
29
|
+
/** The answer of `getRawMany()`. */
|
|
30
|
+
readonly getRawMany?: ReadonlyArray<unknown> | (() => unknown);
|
|
31
|
+
/** The answer of `getRawOne()`. */
|
|
32
|
+
readonly getRawOne?: unknown;
|
|
33
|
+
/** The answer of `getCount()`. */
|
|
34
|
+
readonly getCount?: number | (() => unknown);
|
|
35
|
+
/** The answer of `getManyAndCount()`. */
|
|
36
|
+
readonly getManyAndCount?: readonly [ReadonlyArray<unknown>, number] | (() => unknown);
|
|
37
|
+
}
|
|
38
|
+
/** A chainable stand-in for a typeorm query builder that records every chained call. */
|
|
39
|
+
export interface FakeQueryBuilder {
|
|
40
|
+
/** The builder to hand back from `entityManager.createQueryBuilder`. */
|
|
41
|
+
readonly builder: object;
|
|
42
|
+
/** Every chained call, in order. */
|
|
43
|
+
readonly calls: ReadonlyArray<QueryBuilderCall>;
|
|
44
|
+
/** The argument lists of every call of one builder method, in order. */
|
|
45
|
+
callsOf(method: string): ReadonlyArray<ReadonlyArray<unknown>>;
|
|
46
|
+
}
|
|
47
|
+
/** Builds a chainable query-builder double: every method returns the builder, the terminal methods resolve `answers`. */
|
|
48
|
+
export declare const fakeQueryBuilder: (answers?: QueryBuilderAnswers) => FakeQueryBuilder;
|
|
49
|
+
/** The part of a `mockEntityManager()` this helper queues on: its `createQueryBuilder` jest mock. */
|
|
50
|
+
export interface QueryBuilderHost {
|
|
51
|
+
readonly createQueryBuilder: {
|
|
52
|
+
mockReturnValueOnce(value: never): unknown;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Queues one fake query builder per answer on `manager.createQueryBuilder`, handed out in call order, and returns them. */
|
|
56
|
+
export declare const queueQueryBuilders: (manager: QueryBuilderHost, answers: ReadonlyArray<QueryBuilderAnswers>) => ReadonlyArray<FakeQueryBuilder>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `fakeQueryBuilder()` and `queueQueryBuilders()` -- the double of a typeorm `SelectQueryBuilder` (and its insert, update
|
|
4
|
+
* and delete siblings) that `mockEntityManager` hands out from `createQueryBuilder(Entity, "alias")`.
|
|
5
|
+
*
|
|
6
|
+
* A lite service reads with `createQueryBuilder(Entity, "alias")` and named parameters (persistence.md BE-PERSISTENCE-4).
|
|
7
|
+
* The fake is a Proxy: every chained method (`where`, `andWhere`, `innerJoin`, `orderBy`, `take`, `setLock`, `returning`,
|
|
8
|
+
* ...) records `{ method, args }` and returns the builder; a terminal method (`execute`, `getMany`, `getOne`,
|
|
9
|
+
* `getRawMany`, `getRawOne`, `getCount`, `getManyAndCount`) records too and resolves the answer the spec gave it (a function
|
|
10
|
+
* answer is called when the terminal runs). A spec asserts the statement it expects through `calls` or `callsOf(method)`.
|
|
11
|
+
*
|
|
12
|
+
* `queueQueryBuilders(em, answers)` queues one fake per answer on `em.createQueryBuilder` of a `mockEntityManager()`, in
|
|
13
|
+
* call order, and returns the fakes so the spec can read each one's calls.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.queueQueryBuilders = exports.fakeQueryBuilder = void 0;
|
|
17
|
+
/** The methods that end a chain and resolve the spec's answer. */
|
|
18
|
+
const TERMINALS = ["execute", "getMany", "getOne", "getRawMany", "getRawOne", "getCount", "getManyAndCount"];
|
|
19
|
+
const isTerminal = (method) => TERMINALS.some((name) => name === method);
|
|
20
|
+
/** Builds a chainable query-builder double: every method returns the builder, the terminal methods resolve `answers`. */
|
|
21
|
+
const fakeQueryBuilder = (answers = {}) => {
|
|
22
|
+
const calls = [];
|
|
23
|
+
const builder = new Proxy({}, {
|
|
24
|
+
get: (_target, property) => {
|
|
25
|
+
// `then` stays undefined so an awaited builder is not mistaken for a promise.
|
|
26
|
+
if (typeof property !== "string" || property === "then")
|
|
27
|
+
return undefined;
|
|
28
|
+
return (...args) => {
|
|
29
|
+
calls.push({ method: property, args });
|
|
30
|
+
if (!isTerminal(property))
|
|
31
|
+
return builder;
|
|
32
|
+
const answer = answers[property];
|
|
33
|
+
return Promise.resolve(typeof answer === "function" ? answer() : answer);
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
builder,
|
|
39
|
+
calls,
|
|
40
|
+
callsOf: (method) => calls.filter((call) => call.method === method).map((call) => call.args),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
exports.fakeQueryBuilder = fakeQueryBuilder;
|
|
44
|
+
/** Queues one fake query builder per answer on `manager.createQueryBuilder`, handed out in call order, and returns them. */
|
|
45
|
+
const queueQueryBuilders = (manager, answers) => {
|
|
46
|
+
const fakes = answers.map((answer) => (0, exports.fakeQueryBuilder)(answer));
|
|
47
|
+
for (const fake of fakes)
|
|
48
|
+
manager.createQueryBuilder.mockReturnValueOnce(fake.builder);
|
|
49
|
+
return fakes;
|
|
50
|
+
};
|
|
51
|
+
exports.queueQueryBuilders = queueQueryBuilders;
|
package/dist/world-runner.js
CHANGED
|
@@ -30,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
30
30
|
const node_module_1 = require("node:module");
|
|
31
31
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
32
32
|
const node_path_1 = __importDefault(require("node:path"));
|
|
33
|
-
/** The state-file protocol of `@starci/test-world` this runner speaks (test-world 1.1
|
|
33
|
+
/** The state-file protocol of `@starci/test-world` this runner speaks (test-world 1.1 and later). */
|
|
34
34
|
const WORLD_STATE_VERSION = 2;
|
|
35
35
|
/** The variable that carries the path of the world's state file (set by its globalSetup in this process). */
|
|
36
36
|
const STATE_FILE_ENV = "STARCI_TEST_WORLD_STATE";
|
|
@@ -53,7 +53,7 @@ const fieldOf = (value, name) => (typeof value === "object" && value !== null &&
|
|
|
53
53
|
/** The slot count the world published; a missing or foreign state file is a pair mismatch. */
|
|
54
54
|
function worldSlots(env = process.env) {
|
|
55
55
|
const file = env[STATE_FILE_ENV];
|
|
56
|
-
const fix = `pin @starci/test-world and @starci/jest-preset together as knowledge/hfs/canon-pins.yaml pairs them (${PRESET} speaks state protocol ${WORLD_STATE_VERSION}, @starci/test-world 1.1
|
|
56
|
+
const fix = `pin @starci/test-world and @starci/jest-preset together as knowledge/hfs/canon-pins.yaml pairs them (${PRESET} speaks state protocol ${WORLD_STATE_VERSION}, as @starci/test-world 1.1 and later write it)`;
|
|
57
57
|
if (file === undefined || file === "") {
|
|
58
58
|
throw runnerError(WORLD_PAIR_MISMATCH, `${STATE_FILE_ENV} is not set: the world's globalSetup published no state file for ${PRESET}; ${fix}`);
|
|
59
59
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starci/jest-preset",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "The StarCi jest config for Nest repositories (unit, integration, e2e and contract projects, ts-jest with diagnostics off, per-file 100 coverage of *.service.ts only) and the one shared unit-test double kit: typed mock<T>(), mockEntityManager(), fakeTransaction(), fakeCache(), fakeLock(), recordingEventBus(), recordingQueueOutbox(), fakeInbox(), FakeClock, fakeIds(), builder() and the Outcome matchers toBeRefused/toSucceedWith.",
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"description": "The StarCi jest config for Nest repositories (unit, integration, e2e and contract projects, ts-jest with diagnostics off, per-file 100 coverage of *.service.ts only) and the one shared unit-test double kit: typed mock<T>(), mockEntityManager(), fakeTransaction(), fakeQueryBuilder(), queueQueryBuilders(), fakeCache(), fakeLock(), recordingEventBus(), recordingQueueOutbox(), fakeInbox(), FakeClock, fakeIds(), builder() and the Outcome matchers toBeRefused/toSucceedWith.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "starci183",
|
|
7
7
|
"homepage": "https://github.com/starci183/starci-harness/tree/main/packages/jest-preset#readme",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"types": "./dist/entity-manager.d.ts",
|
|
35
35
|
"default": "./dist/entity-manager.js"
|
|
36
36
|
},
|
|
37
|
+
"./query-builder": {
|
|
38
|
+
"types": "./dist/query-builder.d.ts",
|
|
39
|
+
"default": "./dist/query-builder.js"
|
|
40
|
+
},
|
|
37
41
|
"./ids": {
|
|
38
42
|
"types": "./dist/ids.d.ts",
|
|
39
43
|
"default": "./dist/ids.js"
|
|
@@ -88,7 +92,7 @@
|
|
|
88
92
|
"typeorm": ">=0.3"
|
|
89
93
|
},
|
|
90
94
|
"scripts": {
|
|
91
|
-
"build": "node -e \"require('node:fs').rmSync('dist', {recursive: true, force: true})\" && tsc -p tsconfig.build.json && node -e \"require('node:fs').copyFileSync('assets/unit-metadata.generated.js', 'dist/unit-metadata.generated.js')\"",
|
|
95
|
+
"build": "node -e \"require('node:fs').rmSync('dist', {recursive: true, force: true})\" && tsc -p tsconfig.build.json && node -e \"const fs = require('node:fs'); for (const f of fs.readdirSync('dist', {recursive: true}).filter((n) => n.endsWith('.d.ts'))) fs.writeFileSync('dist/' + f, fs.readFileSync('dist/' + f, 'utf8').replace(/((?:from |import\\()['\\x22]\\.\\.?\\/[^'\\x22]+)\\.ts(['\\x22])/g, (all, head, quote) => head + '.js' + quote))\" && node -e \"require('node:fs').copyFileSync('assets/unit-metadata.generated.js', 'dist/unit-metadata.generated.js')\"",
|
|
92
96
|
"typecheck": "tsc -p tsconfig.json",
|
|
93
97
|
"prepack": "npm run build",
|
|
94
98
|
"test": "npm run build && npm run typecheck && node --test \"test/**/*.spec.ts\""
|