joist-test-utils 1.32.2 → 1.33.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.
@@ -0,0 +1,4 @@
1
+ import { EntityManager } from "joist-orm";
2
+ export declare type Context = {
3
+ em: EntityManager;
4
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":""}
package/build/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="jest" />
2
2
  import { MatchedEntity } from "./toMatchEntity";
3
+ export { run, runEach } from "./run";
3
4
  export { toMatchEntity } from "./toMatchEntity";
4
5
  declare global {
5
6
  namespace jest {
package/build/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toMatchEntity = void 0;
3
+ exports.toMatchEntity = exports.runEach = exports.run = void 0;
4
+ var run_1 = require("./run");
5
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
6
+ Object.defineProperty(exports, "runEach", { enumerable: true, get: function () { return run_1.runEach; } });
4
7
  var toMatchEntity_1 = require("./toMatchEntity");
5
8
  Object.defineProperty(exports, "toMatchEntity", { enumerable: true, get: function () { return toMatchEntity_1.toMatchEntity; } });
6
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,6BAAqC;AAA5B,0FAAA,GAAG,OAAA;AAAE,8FAAA,OAAO,OAAA;AACrB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
package/build/run.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Context } from "./context";
2
+ declare type MaybePromise<T> = T | Promise<T>;
3
+ /** Runs the `fn` in a dedicated / non-test Unit of Work . */
4
+ export declare function run<C extends Context, T>(ctx: C, fn: (ctx: C) => MaybePromise<T>): Promise<T>;
5
+ /** Runs the `fn` in a dedicated / non-test Unit of Work for each value in `values */
6
+ export declare function runEach<C extends Context, T, U>(ctx: C, valuesFn: () => U[], fn: (ctx: C, value: U) => MaybePromise<T>): Promise<T[]>;
7
+ export {};
package/build/run.js ADDED
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runEach = exports.run = void 0;
4
+ const joist_orm_1 = require("joist-orm");
5
+ /** Runs the `fn` in a dedicated / non-test Unit of Work . */
6
+ async function run(ctx, fn) {
7
+ const { em } = ctx;
8
+ // Ensure any test data we've setup is flushed
9
+ await em.flush();
10
+ const result = await runWithNewCtx(ctx, fn);
11
+ // We expect `fn` (i.e. a resolver) to do its own UoW management, so don't flush.
12
+ await em.refresh({ deepLoad: true });
13
+ return mapResultToOriginalEm(em, result);
14
+ }
15
+ exports.run = run;
16
+ /** Runs the `fn` in a dedicated / non-test Unit of Work for each value in `values */
17
+ async function runEach(ctx, valuesFn, fn) {
18
+ const { em } = ctx;
19
+ // Ensure any test data we've setup is flushed
20
+ await em.flush();
21
+ const results = await Promise.all(valuesFn().map((value) => runWithNewCtx(ctx, (ctx) => fn(ctx, value))));
22
+ // We expect `fn` (i.e. a resolver) to do its own UoW management, so don't flush.
23
+ await em.refresh({ deepLoad: true });
24
+ return mapResultToOriginalEm(em, results);
25
+ }
26
+ exports.runEach = runEach;
27
+ /** Runs the `fn` in a dedicated / non-test Unit of Work. */
28
+ async function runWithNewCtx(ctx, fn) {
29
+ const { em } = ctx;
30
+ const newCtx = { ...ctx };
31
+ const newEm = new joist_orm_1.EntityManager(newCtx, em.driver);
32
+ return fn(newCtx);
33
+ }
34
+ function gatherEntities(result) {
35
+ if ((0, joist_orm_1.isEntity)(result)) {
36
+ return [result];
37
+ }
38
+ else if (Array.isArray(result)) {
39
+ return result.flatMap(gatherEntities);
40
+ }
41
+ else if (result !== null && typeof result === "object") {
42
+ return Object.values(result).flatMap(gatherEntities);
43
+ }
44
+ else {
45
+ return [];
46
+ }
47
+ }
48
+ async function mapResultToOriginalEm(em, result) {
49
+ const newEmEntities = gatherEntities(result);
50
+ // load any entities that don't exist in the original em
51
+ await Promise.all(newEmEntities.filter((e) => !em.findExistingInstance(e.idOrFail)).map((e) => em.load(e.idOrFail)));
52
+ // generate a cache of id -> entity in original em
53
+ const cache = Object.fromEntries(newEmEntities.map((e) => [e.idOrFail, em.findExistingInstance(e.idOrFail)]));
54
+ function doMap(value) {
55
+ if ((0, joist_orm_1.isEntity)(value)) {
56
+ return cache[value.idOrFail];
57
+ }
58
+ else if (Array.isArray(value)) {
59
+ return value.map(doMap);
60
+ }
61
+ else if (typeof value === "object" && value?.constructor === Object) {
62
+ return Object.fromEntries(Object.entries(value).map(([key, value]) => [key, doMap(value)]));
63
+ }
64
+ else {
65
+ return value;
66
+ }
67
+ }
68
+ return doMap(result);
69
+ }
70
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,10 @@ export declare function toMatchEntity<T>(actual: Entity, expected: MatchedEntity
7
7
  *
8
8
  * I.e. so that you can `toMatchEntity({ otherEntity: { name: "foo" } })` even though
9
9
  * `otherEntity` is technically a joist `Reference` or `Collection`.
10
+ *
11
+ * We allow `| null` so that `toMatchEntity` can work against optional fields
12
+ * that are returned from GraphQL object resolvers.
10
13
  */
11
14
  export declare type MatchedEntity<T> = {
12
- [K in keyof T]?: T[K] extends Reference<any, infer U, any> ? MatchedEntity<U> | U : T[K] extends Collection<any, infer U> ? Array<MatchedEntity<U> | U> : T[K] extends AsyncProperty<any, infer V> ? V : T[K];
15
+ [K in keyof T]?: T[K] extends Reference<any, infer U, any> ? MatchedEntity<U> | U : T[K] extends Collection<any, infer U> ? Array<MatchedEntity<U> | U> : T[K] extends AsyncProperty<any, infer V> ? V : T[K] | null;
13
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joist-test-utils",
3
- "version": "1.32.2",
3
+ "version": "1.33.0",
4
4
  "license": "MIT",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",