@fragno-dev/test 1.0.2 → 2.0.2
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/.turbo/turbo-build.log +41 -15
- package/CHANGELOG.md +112 -0
- package/dist/adapters.d.ts +20 -5
- package/dist/adapters.d.ts.map +1 -1
- package/dist/adapters.js +20 -210
- package/dist/adapters.js.map +1 -1
- package/dist/db-test.d.ts +120 -18
- package/dist/db-test.d.ts.map +1 -1
- package/dist/db-test.js +236 -57
- package/dist/db-test.js.map +1 -1
- package/dist/durable-hooks.d.ts +11 -0
- package/dist/durable-hooks.d.ts.map +1 -0
- package/dist/durable-hooks.js +17 -0
- package/dist/durable-hooks.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/model-checker-actors.d.ts +41 -0
- package/dist/model-checker-actors.d.ts.map +1 -0
- package/dist/model-checker-actors.js +406 -0
- package/dist/model-checker-actors.js.map +1 -0
- package/dist/model-checker-adapter.d.ts +32 -0
- package/dist/model-checker-adapter.d.ts.map +1 -0
- package/dist/model-checker-adapter.js +109 -0
- package/dist/model-checker-adapter.js.map +1 -0
- package/dist/model-checker.d.ts +128 -0
- package/dist/model-checker.d.ts.map +1 -0
- package/dist/model-checker.js +443 -0
- package/dist/model-checker.js.map +1 -0
- package/dist/test-adapters/drizzle-pglite.js +116 -0
- package/dist/test-adapters/drizzle-pglite.js.map +1 -0
- package/dist/test-adapters/in-memory.js +39 -0
- package/dist/test-adapters/in-memory.js.map +1 -0
- package/dist/test-adapters/kysely-pglite.js +105 -0
- package/dist/test-adapters/kysely-pglite.js.map +1 -0
- package/dist/test-adapters/kysely-sqlite.js +87 -0
- package/dist/test-adapters/kysely-sqlite.js.map +1 -0
- package/dist/test-adapters/model-checker.js +41 -0
- package/dist/test-adapters/model-checker.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +34 -34
- package/src/adapter-conformance.test.ts +324 -0
- package/src/adapters.ts +52 -320
- package/src/db-roundtrip-guard.test.ts +206 -0
- package/src/db-test.test.ts +133 -79
- package/src/db-test.ts +583 -99
- package/src/durable-hooks.test.ts +58 -0
- package/src/durable-hooks.ts +28 -0
- package/src/index.test.ts +250 -89
- package/src/index.ts +45 -6
- package/src/model-checker-actors.test.ts +81 -0
- package/src/model-checker-actors.ts +643 -0
- package/src/model-checker-adapter.ts +201 -0
- package/src/model-checker.test.ts +402 -0
- package/src/model-checker.ts +800 -0
- package/src/test-adapters/drizzle-pglite.ts +162 -0
- package/src/test-adapters/in-memory.ts +56 -0
- package/src/test-adapters/kysely-pglite.ts +151 -0
- package/src/test-adapters/kysely-sqlite.ts +119 -0
- package/src/test-adapters/model-checker.ts +58 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +1 -0
package/dist/db-test.d.ts
CHANGED
|
@@ -1,24 +1,102 @@
|
|
|
1
1
|
import { AdapterContext, SupportedAdapter } from "./adapters.js";
|
|
2
2
|
import { BaseTestContext } from "./index.js";
|
|
3
|
-
import { DatabaseAdapter } from "@fragno-dev/db";
|
|
3
|
+
import { DatabaseAdapter, FragnoPublicConfigWithDatabase } from "@fragno-dev/db";
|
|
4
4
|
import { AnySchema } from "@fragno-dev/db/schema";
|
|
5
5
|
import { SimpleQueryInterface } from "@fragno-dev/db/query";
|
|
6
|
-
import { FragmentInstantiationBuilder, FragnoInstantiatedFragment, FragnoPublicConfig, RequestThisContext } from "@fragno-dev/core";
|
|
7
6
|
import { AnyRouteOrFactory, FlattenRouteFactories } from "@fragno-dev/core/route";
|
|
7
|
+
import { FragmentDefinition, FragmentInstantiationBuilder, FragnoInstantiatedFragment, FragnoPublicConfig, RequestThisContext } from "@fragno-dev/core";
|
|
8
8
|
|
|
9
9
|
//#region src/db-test.d.ts
|
|
10
10
|
type BoundServices<T> = { [K in keyof T]: T[K] extends ((this: any, ...args: infer A) => infer R) ? (...args: A) => R : T[K] extends Record<string, unknown> ? BoundServices<T[K]> : T[K] };
|
|
11
|
-
type
|
|
11
|
+
type FragmentFactoryContext = {
|
|
12
|
+
adapter: DatabaseAdapter<any>;
|
|
13
|
+
test: BaseTestContext & AdapterContext<SupportedAdapter>;
|
|
14
|
+
};
|
|
15
|
+
type FragmentFactoryResult = FragmentInstantiationBuilder<any,
|
|
16
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
17
|
+
any,
|
|
18
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
19
|
+
any,
|
|
20
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
21
|
+
any,
|
|
22
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
23
|
+
any,
|
|
24
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
25
|
+
any,
|
|
26
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
27
|
+
any,
|
|
28
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
29
|
+
any,
|
|
30
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
31
|
+
any,
|
|
32
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
33
|
+
any,
|
|
34
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
35
|
+
any,
|
|
36
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
37
|
+
any> | FragnoInstantiatedFragment<any,
|
|
38
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
39
|
+
any,
|
|
40
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
41
|
+
any,
|
|
42
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
43
|
+
any,
|
|
44
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
45
|
+
any,
|
|
46
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
47
|
+
any,
|
|
48
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
49
|
+
any>;
|
|
50
|
+
type HandlerThisContextFromFactoryResult<T> = T extends FragmentInstantiationBuilder<any,
|
|
51
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
52
|
+
any,
|
|
53
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
54
|
+
any,
|
|
55
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
56
|
+
any,
|
|
57
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
58
|
+
any,
|
|
59
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
60
|
+
any,
|
|
61
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
62
|
+
any,
|
|
63
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
64
|
+
any,
|
|
65
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
66
|
+
infer THandlerThisContext, any,
|
|
67
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
68
|
+
any,
|
|
69
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
70
|
+
any> ? THandlerThisContext : T extends FragnoInstantiatedFragment<any,
|
|
71
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
72
|
+
any,
|
|
73
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
74
|
+
any,
|
|
75
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
76
|
+
any,
|
|
77
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
78
|
+
infer THandlerThisContext, any,
|
|
79
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
80
|
+
any> ? THandlerThisContext : RequestThisContext;
|
|
81
|
+
type FragmentResultFromFactoryResult<T> = T extends FragmentInstantiationBuilder<any,
|
|
82
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
83
|
+
any,
|
|
84
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
85
|
+
infer TDeps, infer TBaseServices, infer TServices, any,
|
|
86
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
87
|
+
any,
|
|
88
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
89
|
+
infer TServiceThisContext, infer THandlerThisContext, infer TRequestStorage, infer TRoutesOrFactories, any> ? FragmentResult<TDeps, BoundServices<TBaseServices & TServices>, TServiceThisContext, THandlerThisContext, TRequestStorage, FlattenRouteFactories<TRoutesOrFactories>, ExtractSchemaFromDeps<TDeps>> : T extends FragnoInstantiatedFragment<infer TRoutes, infer TDeps, infer TServices, infer TServiceThisContext, infer THandlerThisContext, infer TRequestStorage, any> ? FragmentResult<TDeps, BoundServices<TServices>, TServiceThisContext, THandlerThisContext, TRequestStorage, TRoutes, ExtractSchemaFromDeps<TDeps>> : never;
|
|
90
|
+
type ExtractSchemaFromDeps<TDeps$1> = TDeps$1 extends {
|
|
12
91
|
schema: infer TSchema extends AnySchema;
|
|
13
92
|
} ? TSchema : AnySchema;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
callRoute: FragnoInstantiatedFragment<TRoutes, TDeps, TServices, TServiceThisContext, THandlerThisContext, TRequestStorage, FragnoPublicConfig, TLinkedFragments>["callRoute"];
|
|
93
|
+
interface FragmentResult<TDeps$1, TServices$1 extends Record<string, unknown>, TServiceThisContext$1 extends RequestThisContext, THandlerThisContext$1 extends RequestThisContext, TRequestStorage$1, TRoutes$1 extends readonly any[],
|
|
94
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
95
|
+
TSchema$1 extends AnySchema> {
|
|
96
|
+
fragment: FragnoInstantiatedFragment<TRoutes$1, TDeps$1, TServices$1, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, FragnoPublicConfig>;
|
|
97
|
+
services: TServices$1;
|
|
98
|
+
deps: TDeps$1;
|
|
99
|
+
callRoute: FragnoInstantiatedFragment<TRoutes$1, TDeps$1, TServices$1, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, FragnoPublicConfig>["callRoute"];
|
|
22
100
|
db: SimpleQueryInterface<TSchema$1>;
|
|
23
101
|
}
|
|
24
102
|
type AnyFragmentResult = FragmentResult<any,
|
|
@@ -33,8 +111,6 @@ any,
|
|
|
33
111
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
34
112
|
any,
|
|
35
113
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
36
|
-
any,
|
|
37
|
-
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
38
114
|
any>;
|
|
39
115
|
/**
|
|
40
116
|
* Test context combining base and adapter-specific functionality
|
|
@@ -64,6 +140,11 @@ declare class DatabaseFragmentsTestBuilder<TFragments extends Record<string, Any
|
|
|
64
140
|
* Set the test adapter configuration
|
|
65
141
|
*/
|
|
66
142
|
withTestAdapter<TNewAdapter extends SupportedAdapter>(adapter: TNewAdapter): DatabaseFragmentsTestBuilder<TFragments, TNewAdapter, TFirstFragmentThisContext>;
|
|
143
|
+
/**
|
|
144
|
+
* Opt out of the default roundtrip guard (enabled by default), or override its configuration.
|
|
145
|
+
* Useful for allowing multi-roundtrip routes in tests.
|
|
146
|
+
*/
|
|
147
|
+
withDbRoundtripGuard(guard?: FragnoPublicConfigWithDatabase["dbRoundtripGuard"]): DatabaseFragmentsTestBuilder<TFragments, TAdapter, TFirstFragmentThisContext>;
|
|
67
148
|
/**
|
|
68
149
|
* Add a fragment to the test setup
|
|
69
150
|
*
|
|
@@ -71,11 +152,32 @@ declare class DatabaseFragmentsTestBuilder<TFragments extends Record<string, Any
|
|
|
71
152
|
* @param builder - Pre-configured instantiation builder
|
|
72
153
|
* @param options - Additional options (optional)
|
|
73
154
|
*/
|
|
74
|
-
withFragment<TName extends string, TConfig, TOptions extends FragnoPublicConfig, TDeps, TBaseServices extends Record<string, unknown>, TServices extends Record<string, unknown>, TServiceDependencies, TPrivateServices extends Record<string, unknown>, TServiceThisContext extends RequestThisContext, THandlerThisContext extends RequestThisContext, TRequestStorage, TRoutesOrFactories extends readonly AnyRouteOrFactory[],
|
|
155
|
+
withFragment<TName extends string, TConfig, TOptions extends FragnoPublicConfig, TDeps$1, TBaseServices$1 extends Record<string, unknown>, TServices$1 extends Record<string, unknown>, TServiceDependencies, TPrivateServices extends Record<string, unknown>, TServiceThisContext$1 extends RequestThisContext, THandlerThisContext$1 extends RequestThisContext, TRequestStorage$1, TRoutesOrFactories$1 extends readonly AnyRouteOrFactory[], TInternalRoutes extends readonly AnyRouteOrFactory[]>(name: TName, builder: FragmentInstantiationBuilder<TConfig, TOptions, TDeps$1, TBaseServices$1, TServices$1, TServiceDependencies, TPrivateServices, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, TRoutesOrFactories$1, TInternalRoutes>, options?: {
|
|
156
|
+
migrateToVersion?: number;
|
|
157
|
+
}): DatabaseFragmentsTestBuilder<TFragments & { [K in TName]: FragmentResult<TDeps$1, BoundServices<TBaseServices$1 & TServices$1>, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, FlattenRouteFactories<TRoutesOrFactories$1>, ExtractSchemaFromDeps<TDeps$1>> }, TAdapter, keyof TFragments extends never ? THandlerThisContext$1 : TFirstFragmentThisContext>;
|
|
158
|
+
/**
|
|
159
|
+
* Add a pre-built fragment instance to the test setup
|
|
160
|
+
*
|
|
161
|
+
* @param name - Unique name for the fragment
|
|
162
|
+
* @param fragment - Already-built fragment instance
|
|
163
|
+
*/
|
|
164
|
+
withFragmentInstance<TName extends string, TRoutes$1 extends readonly any[],
|
|
165
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
166
|
+
TDeps$1, TServices$1 extends Record<string, unknown>, TServiceThisContext$1 extends RequestThisContext, THandlerThisContext$1 extends RequestThisContext, TRequestStorage$1>(name: TName, fragment: FragnoInstantiatedFragment<TRoutes$1, TDeps$1, TServices$1, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, FragnoPublicConfig>, options?: {
|
|
167
|
+
migrateToVersion?: number;
|
|
168
|
+
}): DatabaseFragmentsTestBuilder<TFragments & { [K in TName]: FragmentResult<TDeps$1, BoundServices<TServices$1>, TServiceThisContext$1, THandlerThisContext$1, TRequestStorage$1, TRoutes$1, ExtractSchemaFromDeps<TDeps$1>> }, TAdapter, keyof TFragments extends never ? THandlerThisContext$1 : TFirstFragmentThisContext>;
|
|
169
|
+
/**
|
|
170
|
+
* Add a fragment factory to the test setup.
|
|
171
|
+
* The factory runs after the adapter is created.
|
|
172
|
+
*
|
|
173
|
+
* @param name - Unique name for the fragment
|
|
174
|
+
* @param definition - Fragment definition (used to extract schema/namespace)
|
|
175
|
+
* @param factory - Factory that returns a builder or a pre-built fragment
|
|
176
|
+
*/
|
|
177
|
+
withFragmentFactory<TName extends string, TFactoryResult extends FragmentFactoryResult>(name: TName, definition: FragmentDefinition<any, any, any, any, any, any, any, any, any, any, any>, factory: (context: FragmentFactoryContext) => TFactoryResult, options?: {
|
|
75
178
|
migrateToVersion?: number;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
TLinkedFragments> }, TAdapter, keyof TFragments extends never ? THandlerThisContext : TFirstFragmentThisContext>;
|
|
179
|
+
config?: any;
|
|
180
|
+
}): DatabaseFragmentsTestBuilder<TFragments & { [K in TName]: FragmentResultFromFactoryResult<TFactoryResult> }, TAdapter, keyof TFragments extends never ? HandlerThisContextFromFactoryResult<TFactoryResult> : TFirstFragmentThisContext>;
|
|
79
181
|
/**
|
|
80
182
|
* Build the test setup and return fragments and test context
|
|
81
183
|
*/
|
|
@@ -125,5 +227,5 @@ declare class DatabaseFragmentsTestBuilder<TFragments extends Record<string, Any
|
|
|
125
227
|
*/
|
|
126
228
|
declare function buildDatabaseFragmentsTest(): DatabaseFragmentsTestBuilder<{}, undefined, RequestThisContext>;
|
|
127
229
|
//#endregion
|
|
128
|
-
export { DatabaseFragmentsTestBuilder, buildDatabaseFragmentsTest };
|
|
230
|
+
export { AnyFragmentResult, DatabaseFragmentsTestBuilder, buildDatabaseFragmentsTest };
|
|
129
231
|
//# sourceMappingURL=db-test.d.ts.map
|
package/dist/db-test.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-test.d.ts","names":[],"sources":["../src/db-test.ts"],"sourcesContent":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"db-test.d.ts","names":[],"sources":["../src/db-test.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/db-test.js
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { createAdapter } from "./adapters.js";
|
|
2
|
+
import { drainDurableHooks } from "./durable-hooks.js";
|
|
2
3
|
|
|
3
4
|
//#region src/db-test.ts
|
|
5
|
+
const disableAutoSchedule = (options) => {
|
|
6
|
+
const durableHooks = options.durableHooks ?? {};
|
|
7
|
+
return {
|
|
8
|
+
...options,
|
|
9
|
+
durableHooks: {
|
|
10
|
+
...durableHooks,
|
|
11
|
+
autoSchedule: false
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
};
|
|
4
15
|
/**
|
|
5
16
|
* Builder for creating multiple database fragments for testing
|
|
6
17
|
*/
|
|
7
18
|
var DatabaseFragmentsTestBuilder = class {
|
|
8
19
|
#adapter;
|
|
9
20
|
#fragments = /* @__PURE__ */ new Map();
|
|
21
|
+
#dbRoundtripGuard = true;
|
|
10
22
|
/**
|
|
11
23
|
* Set the test adapter configuration
|
|
12
24
|
*/
|
|
@@ -15,6 +27,14 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
15
27
|
return this;
|
|
16
28
|
}
|
|
17
29
|
/**
|
|
30
|
+
* Opt out of the default roundtrip guard (enabled by default), or override its configuration.
|
|
31
|
+
* Useful for allowing multi-roundtrip routes in tests.
|
|
32
|
+
*/
|
|
33
|
+
withDbRoundtripGuard(guard = false) {
|
|
34
|
+
this.#dbRoundtripGuard = guard;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
18
38
|
* Add a fragment to the test setup
|
|
19
39
|
*
|
|
20
40
|
* @param name - Unique name for the fragment
|
|
@@ -23,6 +43,7 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
23
43
|
*/
|
|
24
44
|
withFragment(name, builder, options) {
|
|
25
45
|
this.#fragments.set(name, {
|
|
46
|
+
kind: "builder",
|
|
26
47
|
definition: builder.definition,
|
|
27
48
|
builder,
|
|
28
49
|
migrateToVersion: options?.migrateToVersion
|
|
@@ -30,30 +51,73 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
30
51
|
return this;
|
|
31
52
|
}
|
|
32
53
|
/**
|
|
54
|
+
* Add a pre-built fragment instance to the test setup
|
|
55
|
+
*
|
|
56
|
+
* @param name - Unique name for the fragment
|
|
57
|
+
* @param fragment - Already-built fragment instance
|
|
58
|
+
*/
|
|
59
|
+
withFragmentInstance(name, fragment, options) {
|
|
60
|
+
this.#fragments.set(name, {
|
|
61
|
+
kind: "instance",
|
|
62
|
+
fragment,
|
|
63
|
+
migrateToVersion: options?.migrateToVersion
|
|
64
|
+
});
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Add a fragment factory to the test setup.
|
|
69
|
+
* The factory runs after the adapter is created.
|
|
70
|
+
*
|
|
71
|
+
* @param name - Unique name for the fragment
|
|
72
|
+
* @param definition - Fragment definition (used to extract schema/namespace)
|
|
73
|
+
* @param factory - Factory that returns a builder or a pre-built fragment
|
|
74
|
+
*/
|
|
75
|
+
withFragmentFactory(name, definition, factory, options) {
|
|
76
|
+
this.#fragments.set(name, {
|
|
77
|
+
kind: "factory",
|
|
78
|
+
definition,
|
|
79
|
+
factory,
|
|
80
|
+
config: options?.config,
|
|
81
|
+
migrateToVersion: options?.migrateToVersion
|
|
82
|
+
});
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
33
86
|
* Build the test setup and return fragments and test context
|
|
34
87
|
*/
|
|
35
88
|
async build() {
|
|
36
89
|
if (!this.#adapter) throw new Error("Test adapter must be set using withTestAdapter()");
|
|
37
|
-
if (this.#fragments.size === 0) throw new Error("At least one fragment must be added using withFragment()");
|
|
90
|
+
if (this.#fragments.size === 0) throw new Error("At least one fragment must be added using withFragment(), withFragmentFactory(), or withFragmentInstance().");
|
|
38
91
|
const adapterConfig = this.#adapter;
|
|
39
|
-
const
|
|
40
|
-
const
|
|
92
|
+
const fragmentEntries = Array.from(this.#fragments.entries());
|
|
93
|
+
const fragmentNames = fragmentEntries.map(([name]) => name);
|
|
41
94
|
const schemaConfigs = [];
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const builder = fragmentConfig.builder;
|
|
45
|
-
const definition = builder.definition;
|
|
95
|
+
const fragmentPlans = [];
|
|
96
|
+
const extractSchemaFromDefinition = (definition, actualConfig, actualOptions) => {
|
|
46
97
|
let schema;
|
|
47
98
|
let namespace;
|
|
48
99
|
if (definition.dependencies) try {
|
|
49
100
|
const mockAdapter = {
|
|
50
101
|
createQueryEngine: () => ({ schema: null }),
|
|
51
|
-
|
|
102
|
+
getSchemaVersion: async () => void 0,
|
|
103
|
+
namingStrategy: {
|
|
104
|
+
namespaceScope: "suffix",
|
|
105
|
+
namespaceToSchema: (value) => value,
|
|
106
|
+
tableName: (logicalTable, ns) => ns ? `${logicalTable}_${ns}` : logicalTable,
|
|
107
|
+
columnName: (logicalColumn) => logicalColumn,
|
|
108
|
+
indexName: (logicalIndex) => logicalIndex,
|
|
109
|
+
uniqueIndexName: (logicalIndex) => logicalIndex,
|
|
110
|
+
foreignKeyName: ({ referenceName }) => referenceName
|
|
111
|
+
},
|
|
112
|
+
contextStorage: { run: (_data, fn) => fn() },
|
|
113
|
+
close: async () => {}
|
|
52
114
|
};
|
|
53
|
-
const actualConfig = builder.config ?? {};
|
|
54
115
|
const deps = definition.dependencies({
|
|
55
|
-
config: actualConfig,
|
|
56
|
-
options: {
|
|
116
|
+
config: actualConfig ?? {},
|
|
117
|
+
options: {
|
|
118
|
+
...actualOptions,
|
|
119
|
+
databaseAdapter: mockAdapter
|
|
120
|
+
}
|
|
57
121
|
});
|
|
58
122
|
if (deps && typeof deps === "object" && "schema" in deps) {
|
|
59
123
|
schema = deps.schema;
|
|
@@ -64,69 +128,165 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
64
128
|
throw new Error(`Failed to extract schema from fragment '${definition.name}'.\nOriginal error: ${errorMessage}\n\nMake sure the fragment is a database fragment using defineFragment().extend(withDatabase(schema)).`);
|
|
65
129
|
}
|
|
66
130
|
if (!schema) throw new Error(`Fragment '${definition.name}' does not have a database schema. Make sure you're using defineFragment().extend(withDatabase(schema)).`);
|
|
67
|
-
if (
|
|
68
|
-
|
|
131
|
+
if (namespace === void 0) throw new Error(`Fragment '${definition.name}' does not have a namespace in dependencies. This should be automatically provided by withDatabase().`);
|
|
132
|
+
return {
|
|
69
133
|
schema,
|
|
70
|
-
namespace
|
|
134
|
+
namespace
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
for (const [name, fragmentConfig] of fragmentEntries) {
|
|
138
|
+
if (fragmentConfig.kind === "builder") {
|
|
139
|
+
const builder = fragmentConfig.builder;
|
|
140
|
+
const definition = builder.definition;
|
|
141
|
+
const { schema, namespace } = extractSchemaFromDefinition(definition, builder.config ?? {}, builder.options ?? {});
|
|
142
|
+
schemaConfigs.push({
|
|
143
|
+
schema,
|
|
144
|
+
namespace,
|
|
145
|
+
migrateToVersion: fragmentConfig.migrateToVersion
|
|
146
|
+
});
|
|
147
|
+
fragmentPlans.push({
|
|
148
|
+
name,
|
|
149
|
+
kind: "builder",
|
|
150
|
+
schema,
|
|
151
|
+
namespace,
|
|
152
|
+
migrateToVersion: fragmentConfig.migrateToVersion,
|
|
153
|
+
builderConfig: {
|
|
154
|
+
builder: fragmentConfig.builder,
|
|
155
|
+
definition: fragmentConfig.definition,
|
|
156
|
+
config: builder.config ?? {},
|
|
157
|
+
routes: builder.routes ?? [],
|
|
158
|
+
options: builder.options ?? {}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (fragmentConfig.kind === "factory") {
|
|
164
|
+
const definition = fragmentConfig.definition;
|
|
165
|
+
const { schema, namespace } = extractSchemaFromDefinition(definition, fragmentConfig.config ?? {});
|
|
166
|
+
schemaConfigs.push({
|
|
167
|
+
schema,
|
|
168
|
+
namespace,
|
|
169
|
+
migrateToVersion: fragmentConfig.migrateToVersion
|
|
170
|
+
});
|
|
171
|
+
fragmentPlans.push({
|
|
172
|
+
name,
|
|
173
|
+
kind: "factory",
|
|
174
|
+
schema,
|
|
175
|
+
namespace,
|
|
176
|
+
migrateToVersion: fragmentConfig.migrateToVersion,
|
|
177
|
+
factory: fragmentConfig.factory
|
|
178
|
+
});
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const fragment = fragmentConfig.fragment;
|
|
182
|
+
const deps = fragment.$internal?.deps;
|
|
183
|
+
if (!deps?.schema) throw new Error(`Fragment '${name}' does not have a database schema in deps. Make sure you're using defineFragment().extend(withDatabase(schema)).`);
|
|
184
|
+
schemaConfigs.push({
|
|
185
|
+
schema: deps.schema,
|
|
186
|
+
namespace: deps.namespace ?? null,
|
|
71
187
|
migrateToVersion: fragmentConfig.migrateToVersion
|
|
72
188
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
189
|
+
fragmentPlans.push({
|
|
190
|
+
name,
|
|
191
|
+
kind: "instance",
|
|
192
|
+
schema: deps.schema,
|
|
193
|
+
namespace: deps.namespace ?? null,
|
|
194
|
+
migrateToVersion: fragmentConfig.migrateToVersion,
|
|
195
|
+
fragment
|
|
77
196
|
});
|
|
78
197
|
}
|
|
79
198
|
const { testContext, adapter } = await createAdapter(adapterConfig, schemaConfigs);
|
|
199
|
+
const resolveDbRoundtripGuardOption = (options) => {
|
|
200
|
+
if (options && typeof options === "object") {
|
|
201
|
+
if (Object.prototype.hasOwnProperty.call(options, "dbRoundtripGuard")) return options.dbRoundtripGuard;
|
|
202
|
+
}
|
|
203
|
+
return this.#dbRoundtripGuard;
|
|
204
|
+
};
|
|
205
|
+
const mergeBuilderOptions = (options) => {
|
|
206
|
+
const resolvedOptions = disableAutoSchedule(options ?? {});
|
|
207
|
+
const merged = {
|
|
208
|
+
...resolvedOptions,
|
|
209
|
+
databaseAdapter: adapter
|
|
210
|
+
};
|
|
211
|
+
const guardOption = resolveDbRoundtripGuardOption(resolvedOptions);
|
|
212
|
+
if (guardOption !== void 0) merged["dbRoundtripGuard"] = guardOption;
|
|
213
|
+
return merged;
|
|
214
|
+
};
|
|
80
215
|
const createFragments = () => {
|
|
216
|
+
const resolveBuilderConfig = (builder) => ({
|
|
217
|
+
builder,
|
|
218
|
+
definition: builder.definition,
|
|
219
|
+
config: builder.config ?? {},
|
|
220
|
+
routes: builder.routes ?? [],
|
|
221
|
+
options: builder.options ?? {}
|
|
222
|
+
});
|
|
223
|
+
const isBuilder = (value) => Boolean(value) && typeof value === "object" && "build" in value && "definition" in value;
|
|
81
224
|
const providedServicesByName = {};
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
225
|
+
const instanceResults = /* @__PURE__ */ new Map();
|
|
226
|
+
const builderConfigs = /* @__PURE__ */ new Map();
|
|
227
|
+
for (const plan of fragmentPlans) {
|
|
228
|
+
const orm = testContext.getOrm(plan.namespace);
|
|
229
|
+
let fragment;
|
|
230
|
+
let builderConfig = plan.builderConfig;
|
|
231
|
+
if (plan.kind === "factory") {
|
|
232
|
+
const result = plan.cachedFactoryResult ?? plan.factory({
|
|
233
|
+
adapter,
|
|
234
|
+
test: testContext
|
|
235
|
+
});
|
|
236
|
+
if (!plan.cachedFactoryResult) plan.cachedFactoryResult = result;
|
|
237
|
+
if (isBuilder(result)) builderConfig = resolveBuilderConfig(result);
|
|
238
|
+
else fragment = result;
|
|
239
|
+
}
|
|
240
|
+
const usesBuilder = plan.kind === "builder" || !!builderConfig;
|
|
241
|
+
if (usesBuilder) {
|
|
242
|
+
const resolvedBuilderConfig = builderConfig ?? plan.builderConfig;
|
|
243
|
+
const mergedOptions = mergeBuilderOptions(resolvedBuilderConfig.options);
|
|
244
|
+
fragment = resolvedBuilderConfig.builder.withOptions(mergedOptions).build();
|
|
245
|
+
builderConfigs.set(plan.name, resolvedBuilderConfig);
|
|
246
|
+
} else {
|
|
247
|
+
fragment = fragment ?? plan.fragment;
|
|
248
|
+
const deps = fragment.$internal?.deps;
|
|
249
|
+
if (deps?.databaseAdapter && deps.databaseAdapter !== adapter) throw new Error(`Fragment '${plan.name}' was built with a different database adapter instance. Use withFragment() or ensure the fragment uses the same adapter instance as the test builder.`);
|
|
250
|
+
}
|
|
251
|
+
if (!fragment) throw new Error(`Fragment '${plan.name}' did not return a valid fragment instance from its factory.`);
|
|
94
252
|
for (const [serviceName, serviceImpl] of Object.entries(fragment.services)) providedServicesByName[serviceName] = {
|
|
95
253
|
service: serviceImpl,
|
|
96
254
|
orm
|
|
97
255
|
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
256
|
+
if (!usesBuilder) {
|
|
257
|
+
const deps = fragment.$internal?.deps;
|
|
258
|
+
instanceResults.set(plan.name, {
|
|
259
|
+
fragment,
|
|
260
|
+
services: fragment.services,
|
|
261
|
+
deps: deps || {},
|
|
262
|
+
callRoute: fragment.callRoute.bind(fragment),
|
|
263
|
+
get db() {
|
|
264
|
+
return orm;
|
|
265
|
+
},
|
|
266
|
+
_orm: orm,
|
|
267
|
+
_schema: plan.schema
|
|
268
|
+
});
|
|
269
|
+
}
|
|
110
270
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
271
|
+
const fragmentResults$1 = [];
|
|
272
|
+
for (const plan of fragmentPlans) {
|
|
273
|
+
const orm = testContext.getOrm(plan.namespace);
|
|
274
|
+
if (instanceResults.has(plan.name)) {
|
|
275
|
+
fragmentResults$1.push(instanceResults.get(plan.name));
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const builderConfig = builderConfigs.get(plan.name);
|
|
279
|
+
if (!builderConfig) throw new Error(`Fragment '${plan.name}' was expected to produce a builder for service wiring.`);
|
|
280
|
+
const definition = builderConfig.definition;
|
|
118
281
|
const serviceImplementations = {};
|
|
119
282
|
const serviceDependencies = definition.serviceDependencies;
|
|
120
283
|
if (serviceDependencies) {
|
|
121
284
|
for (const serviceName of Object.keys(serviceDependencies)) if (providedServicesByName[serviceName]) serviceImplementations[serviceName] = providedServicesByName[serviceName].service;
|
|
122
285
|
}
|
|
123
|
-
const mergedOptions =
|
|
124
|
-
|
|
125
|
-
databaseAdapter: adapter
|
|
126
|
-
};
|
|
127
|
-
const fragment = fragmentConfig.builder.withOptions(mergedOptions).withServices(serviceImplementations).build();
|
|
286
|
+
const mergedOptions = mergeBuilderOptions(builderConfig.options);
|
|
287
|
+
const fragment = builderConfig.builder.withOptions(mergedOptions).withServices(serviceImplementations).build();
|
|
128
288
|
const deps = fragment.$internal?.deps;
|
|
129
|
-
fragmentResults$1
|
|
289
|
+
fragmentResults$1.push({
|
|
130
290
|
fragment,
|
|
131
291
|
services: fragment.services,
|
|
132
292
|
deps: deps || {},
|
|
@@ -135,8 +295,8 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
135
295
|
return orm;
|
|
136
296
|
},
|
|
137
297
|
_orm: orm,
|
|
138
|
-
_schema: schema
|
|
139
|
-
};
|
|
298
|
+
_schema: plan.schema
|
|
299
|
+
});
|
|
140
300
|
}
|
|
141
301
|
return fragmentResults$1;
|
|
142
302
|
};
|
|
@@ -155,9 +315,28 @@ var DatabaseFragmentsTestBuilder = class {
|
|
|
155
315
|
};
|
|
156
316
|
const firstFragment = fragmentResults[0]?.fragment;
|
|
157
317
|
if (!firstFragment) throw new Error("At least one fragment must be added");
|
|
318
|
+
const originalCleanup = testContext.cleanup;
|
|
319
|
+
const cleanup = async () => {
|
|
320
|
+
let drainError;
|
|
321
|
+
let cleanupError;
|
|
322
|
+
for (const result of fragmentResults) try {
|
|
323
|
+
await drainDurableHooks(result.fragment);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (!drainError) drainError = error;
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
await originalCleanup();
|
|
329
|
+
} catch (error) {
|
|
330
|
+
cleanupError = error;
|
|
331
|
+
}
|
|
332
|
+
if (drainError && cleanupError) throw new AggregateError([drainError, cleanupError], "Failed to drain durable hooks and clean up test context");
|
|
333
|
+
if (drainError) throw drainError;
|
|
334
|
+
if (cleanupError) throw cleanupError;
|
|
335
|
+
};
|
|
158
336
|
const finalTestContext = {
|
|
159
337
|
...testContext,
|
|
160
338
|
resetDatabase,
|
|
339
|
+
cleanup,
|
|
161
340
|
adapter,
|
|
162
341
|
inContext: firstFragment.inContext.bind(firstFragment)
|
|
163
342
|
};
|