@fragno-dev/test 0.1.11 → 0.1.13
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 +15 -11
- package/CHANGELOG.md +35 -0
- package/dist/adapters.d.ts +3 -11
- package/dist/adapters.d.ts.map +1 -1
- package/dist/adapters.js +65 -50
- package/dist/adapters.js.map +1 -1
- package/dist/db-test.d.ts +129 -0
- package/dist/db-test.d.ts.map +1 -0
- package/dist/db-test.js +214 -0
- package/dist/db-test.js.map +1 -0
- package/dist/index.d.ts +23 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -91
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
- package/src/adapters.ts +137 -118
- package/src/db-test.test.ts +352 -0
- package/src/db-test.ts +574 -0
- package/src/index.test.ts +287 -546
- package/src/index.ts +39 -241
package/src/index.ts
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
import type { AnySchema } from "@fragno-dev/db/schema";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import type { FragmentDefinition } from "@fragno-dev/core/api/fragment-builder";
|
|
9
|
-
import type { AnyRouteOrFactory, FlattenRouteFactories } from "@fragno-dev/core/api/route";
|
|
10
|
-
import {
|
|
11
|
-
createAdapter,
|
|
12
|
-
type SupportedAdapter,
|
|
13
|
-
type TestContext,
|
|
14
|
-
type KyselySqliteAdapter,
|
|
15
|
-
type KyselyPgliteAdapter,
|
|
16
|
-
type DrizzlePgliteAdapter,
|
|
2
|
+
import type {
|
|
3
|
+
SupportedAdapter,
|
|
4
|
+
AdapterContext,
|
|
5
|
+
KyselySqliteAdapter,
|
|
6
|
+
KyselyPgliteAdapter,
|
|
7
|
+
DrizzlePgliteAdapter,
|
|
17
8
|
} from "./adapters";
|
|
18
|
-
import type {
|
|
19
|
-
import type {
|
|
20
|
-
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
9
|
+
import type { DatabaseAdapter } from "@fragno-dev/db";
|
|
10
|
+
import type { AbstractQuery } from "@fragno-dev/db/query";
|
|
21
11
|
|
|
22
12
|
// Re-export utilities from @fragno-dev/core/test
|
|
23
13
|
export {
|
|
24
14
|
createFragmentForTest,
|
|
25
15
|
type CreateFragmentForTestOptions,
|
|
26
16
|
type RouteHandlerInputOptions,
|
|
27
|
-
type FragmentForTest,
|
|
28
17
|
} from "@fragno-dev/core/test";
|
|
29
18
|
|
|
30
19
|
// Re-export adapter types
|
|
@@ -33,240 +22,49 @@ export type {
|
|
|
33
22
|
KyselySqliteAdapter,
|
|
34
23
|
KyselyPgliteAdapter,
|
|
35
24
|
DrizzlePgliteAdapter,
|
|
36
|
-
|
|
25
|
+
AdapterContext,
|
|
37
26
|
} from "./adapters";
|
|
38
27
|
|
|
28
|
+
// Re-export new builder-based database test utilities
|
|
29
|
+
export { buildDatabaseFragmentsTest, DatabaseFragmentsTestBuilder } from "./db-test";
|
|
30
|
+
|
|
39
31
|
/**
|
|
40
|
-
*
|
|
32
|
+
* Base test context with common functionality across all adapters
|
|
41
33
|
*/
|
|
42
|
-
export interface
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
TOptions extends FragnoPublicConfig,
|
|
48
|
-
TAdapter extends SupportedAdapter,
|
|
49
|
-
> extends Omit<
|
|
50
|
-
CreateFragmentForTestOptions<TConfig, TDeps, TServices, TAdditionalContext, TOptions>,
|
|
51
|
-
"config"
|
|
52
|
-
> {
|
|
53
|
-
adapter: TAdapter;
|
|
54
|
-
migrateToVersion?: number;
|
|
55
|
-
config?: TConfig;
|
|
34
|
+
export interface BaseTestContext {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
readonly adapter: DatabaseAdapter<any>;
|
|
37
|
+
resetDatabase: () => Promise<void>;
|
|
38
|
+
cleanup: () => Promise<void>;
|
|
56
39
|
}
|
|
57
40
|
|
|
58
41
|
/**
|
|
59
|
-
*
|
|
60
|
-
* All properties are getters that return the current fragment instance
|
|
42
|
+
* Internal interface with getOrm for adapter implementations
|
|
61
43
|
*/
|
|
62
|
-
export interface
|
|
63
|
-
|
|
64
|
-
TDeps,
|
|
65
|
-
TServices,
|
|
66
|
-
TAdditionalContext extends Record<string, unknown>,
|
|
67
|
-
TOptions extends FragnoPublicConfig,
|
|
68
|
-
TAdapter extends SupportedAdapter,
|
|
69
|
-
TRoutes extends readonly FragnoRouteConfig<
|
|
70
|
-
HTTPMethod,
|
|
71
|
-
string,
|
|
72
|
-
StandardSchemaV1 | undefined,
|
|
73
|
-
StandardSchemaV1 | undefined,
|
|
74
|
-
string,
|
|
75
|
-
string
|
|
76
|
-
>[],
|
|
77
|
-
> {
|
|
78
|
-
readonly fragment: FragmentForTest<
|
|
79
|
-
TConfig,
|
|
80
|
-
TDeps,
|
|
81
|
-
TServices,
|
|
82
|
-
TAdditionalContext,
|
|
83
|
-
TOptions,
|
|
84
|
-
TRoutes
|
|
85
|
-
>;
|
|
86
|
-
readonly services: TServices;
|
|
87
|
-
readonly callRoute: FragmentForTest<
|
|
88
|
-
TConfig,
|
|
89
|
-
TDeps,
|
|
90
|
-
TServices,
|
|
91
|
-
TAdditionalContext,
|
|
92
|
-
TOptions,
|
|
93
|
-
TRoutes
|
|
94
|
-
>["callRoute"];
|
|
95
|
-
readonly config: TConfig;
|
|
96
|
-
readonly deps: TDeps;
|
|
97
|
-
readonly additionalContext: TAdditionalContext;
|
|
98
|
-
test: TestContext<TAdapter>;
|
|
44
|
+
export interface InternalTestContextMethods {
|
|
45
|
+
getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;
|
|
99
46
|
}
|
|
100
47
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const TOptions extends FragnoPublicConfig,
|
|
107
|
-
const TSchema extends AnySchema,
|
|
108
|
-
const TAdapter extends SupportedAdapter,
|
|
109
|
-
const TRoutesOrFactories extends readonly AnyRouteOrFactory[],
|
|
110
|
-
>(
|
|
111
|
-
fragmentBuilder: {
|
|
112
|
-
definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;
|
|
113
|
-
$requiredOptions: TOptions;
|
|
114
|
-
},
|
|
115
|
-
routesOrFactories: TRoutesOrFactories,
|
|
116
|
-
options: CreateDatabaseFragmentForTestOptions<
|
|
117
|
-
TConfig,
|
|
118
|
-
TDeps,
|
|
119
|
-
TServices,
|
|
120
|
-
TAdditionalContext,
|
|
121
|
-
TOptions,
|
|
122
|
-
TAdapter
|
|
123
|
-
>,
|
|
124
|
-
): Promise<
|
|
125
|
-
DatabaseFragmentTestResult<
|
|
126
|
-
TConfig,
|
|
127
|
-
TDeps,
|
|
128
|
-
TServices,
|
|
129
|
-
TAdditionalContext,
|
|
130
|
-
TOptions,
|
|
131
|
-
TAdapter,
|
|
132
|
-
FlattenRouteFactories<TRoutesOrFactories>
|
|
133
|
-
>
|
|
134
|
-
> {
|
|
135
|
-
const {
|
|
136
|
-
adapter: adapterConfig,
|
|
137
|
-
migrateToVersion,
|
|
138
|
-
config,
|
|
139
|
-
options: fragmentOptions,
|
|
140
|
-
deps,
|
|
141
|
-
services,
|
|
142
|
-
additionalContext,
|
|
143
|
-
} = options;
|
|
144
|
-
|
|
145
|
-
// Get schema and namespace from fragment definition's additionalContext
|
|
146
|
-
// Safe cast: DatabaseFragmentBuilder adds databaseSchema and databaseNamespace to additionalContext
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
148
|
-
const fragmentAdditionalContext = fragmentBuilder.definition.additionalContext as any;
|
|
149
|
-
const schema = fragmentAdditionalContext?.databaseSchema as TSchema | undefined;
|
|
150
|
-
const namespace = (fragmentAdditionalContext?.databaseNamespace as string | undefined) ?? "";
|
|
151
|
-
|
|
152
|
-
if (!schema) {
|
|
153
|
-
throw new Error(
|
|
154
|
-
`Fragment '${fragmentBuilder.definition.name}' does not have a database schema. ` +
|
|
155
|
-
`Make sure you're using defineFragmentWithDatabase().withDatabase(schema).`,
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Create adapter using the factory
|
|
160
|
-
const { testContext: originalTestContext, adapter } = await createAdapter(
|
|
161
|
-
adapterConfig,
|
|
162
|
-
schema,
|
|
163
|
-
namespace,
|
|
164
|
-
migrateToVersion,
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
// Create fragment with database adapter in options
|
|
168
|
-
// Safe cast: We're merging the user's options with the databaseAdapter, which is required by TOptions
|
|
169
|
-
// The user's TOptions is constrained to FragnoPublicConfig (or a subtype), which we extend with databaseAdapter
|
|
170
|
-
let mergedOptions = {
|
|
171
|
-
...fragmentOptions,
|
|
172
|
-
databaseAdapter: adapter,
|
|
173
|
-
} as unknown as TOptions;
|
|
174
|
-
|
|
175
|
-
let fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {
|
|
176
|
-
// Safe cast: If config is not provided, we pass undefined as TConfig.
|
|
177
|
-
// The base createFragmentForTest expects config: TConfig, but if TConfig allows undefined
|
|
178
|
-
// or if the fragment doesn't use config in its dependencies function, this will work correctly.
|
|
179
|
-
config: config as TConfig,
|
|
180
|
-
options: mergedOptions,
|
|
181
|
-
deps,
|
|
182
|
-
services,
|
|
183
|
-
additionalContext,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Wrap resetDatabase to also recreate the fragment with the new adapter
|
|
187
|
-
const originalResetDatabase = originalTestContext.resetDatabase;
|
|
188
|
-
|
|
189
|
-
// Create test context with getters that always return current values
|
|
190
|
-
// We need to cast to any to avoid TypeScript errors when accessing kysely/drizzle properties
|
|
191
|
-
// that may not exist depending on the adapter type
|
|
48
|
+
/**
|
|
49
|
+
* Helper to create common test context methods from an ORM map
|
|
50
|
+
* This is used internally by adapter implementations to avoid code duplication
|
|
51
|
+
*/
|
|
52
|
+
export function createCommonTestContextMethods(
|
|
192
53
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
get() {
|
|
196
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
197
|
-
return (originalTestContext as any).db;
|
|
198
|
-
},
|
|
199
|
-
enumerable: true,
|
|
200
|
-
},
|
|
201
|
-
kysely: {
|
|
202
|
-
get() {
|
|
203
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
204
|
-
return (originalTestContext as any).kysely;
|
|
205
|
-
},
|
|
206
|
-
enumerable: true,
|
|
207
|
-
},
|
|
208
|
-
drizzle: {
|
|
209
|
-
get() {
|
|
210
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
211
|
-
return (originalTestContext as any).drizzle;
|
|
212
|
-
},
|
|
213
|
-
enumerable: true,
|
|
214
|
-
},
|
|
215
|
-
adapter: {
|
|
216
|
-
get() {
|
|
217
|
-
return originalTestContext.adapter;
|
|
218
|
-
},
|
|
219
|
-
enumerable: true,
|
|
220
|
-
},
|
|
221
|
-
resetDatabase: {
|
|
222
|
-
value: async () => {
|
|
223
|
-
// Call the original reset database function
|
|
224
|
-
await originalResetDatabase();
|
|
225
|
-
|
|
226
|
-
// Recreate the fragment with the new adapter (which has been updated by the factory's resetDatabase)
|
|
227
|
-
mergedOptions = {
|
|
228
|
-
...fragmentOptions,
|
|
229
|
-
databaseAdapter: originalTestContext.adapter,
|
|
230
|
-
} as unknown as TOptions;
|
|
231
|
-
|
|
232
|
-
fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {
|
|
233
|
-
config: config as TConfig,
|
|
234
|
-
options: mergedOptions,
|
|
235
|
-
deps,
|
|
236
|
-
services,
|
|
237
|
-
additionalContext,
|
|
238
|
-
});
|
|
239
|
-
},
|
|
240
|
-
enumerable: true,
|
|
241
|
-
},
|
|
242
|
-
cleanup: {
|
|
243
|
-
value: async () => {
|
|
244
|
-
await originalTestContext.cleanup();
|
|
245
|
-
},
|
|
246
|
-
enumerable: true,
|
|
247
|
-
},
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
// Return an object with getters for fragment properties so they always reference the current fragment
|
|
54
|
+
ormMap: Map<string, AbstractQuery<any>>,
|
|
55
|
+
): InternalTestContextMethods {
|
|
251
56
|
return {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
get callRoute() {
|
|
259
|
-
return fragment.callRoute;
|
|
260
|
-
},
|
|
261
|
-
get config() {
|
|
262
|
-
return fragment.config;
|
|
263
|
-
},
|
|
264
|
-
get deps() {
|
|
265
|
-
return fragment.deps;
|
|
57
|
+
getOrm: <TSchema extends AnySchema>(namespace: string) => {
|
|
58
|
+
const orm = ormMap.get(namespace);
|
|
59
|
+
if (!orm) {
|
|
60
|
+
throw new Error(`No ORM found for namespace: ${namespace}`);
|
|
61
|
+
}
|
|
62
|
+
return orm as AbstractQuery<TSchema>;
|
|
266
63
|
},
|
|
267
|
-
get additionalContext() {
|
|
268
|
-
return fragment.additionalContext;
|
|
269
|
-
},
|
|
270
|
-
test: testContext,
|
|
271
64
|
};
|
|
272
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Complete test context combining base and adapter-specific functionality
|
|
69
|
+
*/
|
|
70
|
+
export type TestContext<T extends SupportedAdapter> = BaseTestContext & AdapterContext<T>;
|