@stratal/testing 0.0.6 → 0.0.8
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/dist/core/testing-module-builder.d.ts +0 -42
- package/dist/core/testing-module-builder.d.ts.map +1 -1
- package/dist/core/testing-module-builder.js +6 -55
- package/dist/core/testing-module-builder.js.map +1 -1
- package/dist/core/testing-module.d.ts +8 -6
- package/dist/core/testing-module.d.ts.map +1 -1
- package/dist/core/testing-module.js +42 -55
- package/dist/core/testing-module.js.map +1 -1
- package/package.json +7 -7
|
@@ -24,37 +24,6 @@ export interface TestingModuleConfig extends ModuleOptions {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Builder for creating test modules with provider overrides
|
|
27
|
-
*
|
|
28
|
-
* Provides a NestJS-style fluent API for configuring test modules.
|
|
29
|
-
* Supports all ModuleOptions properties (imports, providers, controllers, consumers, jobs).
|
|
30
|
-
*
|
|
31
|
-
* @example Basic usage
|
|
32
|
-
* ```typescript
|
|
33
|
-
* const module = await Test.createTestingModule({
|
|
34
|
-
* imports: [RegistrationModule],
|
|
35
|
-
* }).compile()
|
|
36
|
-
* ```
|
|
37
|
-
*
|
|
38
|
-
* @example Provider override
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const module = await Test.createTestingModule({
|
|
41
|
-
* imports: [RegistrationModule, GeoModule],
|
|
42
|
-
* })
|
|
43
|
-
* .overrideProvider(EMAIL_TOKENS.EmailService)
|
|
44
|
-
* .useValue(mockEmailService)
|
|
45
|
-
* .compile()
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @example Full ModuleOptions
|
|
49
|
-
* ```typescript
|
|
50
|
-
* const module = await Test.createTestingModule({
|
|
51
|
-
* imports: [RegistrationModule],
|
|
52
|
-
* providers: [{ provide: MOCK_TOKEN, useValue: mockValue }],
|
|
53
|
-
* controllers: [TestController],
|
|
54
|
-
* consumers: [TestConsumer],
|
|
55
|
-
* jobs: [TestJob],
|
|
56
|
-
* }).compile()
|
|
57
|
-
* ```
|
|
58
27
|
*/
|
|
59
28
|
export declare class TestingModuleBuilder {
|
|
60
29
|
private config;
|
|
@@ -62,11 +31,6 @@ export declare class TestingModuleBuilder {
|
|
|
62
31
|
constructor(config: TestingModuleConfig);
|
|
63
32
|
/**
|
|
64
33
|
* Override a provider with a custom implementation
|
|
65
|
-
*
|
|
66
|
-
* Returns a ProviderOverrideBuilder for specifying the override type.
|
|
67
|
-
*
|
|
68
|
-
* @param token - The injection token to override
|
|
69
|
-
* @returns ProviderOverrideBuilder for chaining useValue/useClass/useFactory
|
|
70
34
|
*/
|
|
71
35
|
overrideProvider<T>(token: InjectionToken<T>): ProviderOverrideBuilder<T>;
|
|
72
36
|
/**
|
|
@@ -77,18 +41,12 @@ export declare class TestingModuleBuilder {
|
|
|
77
41
|
addProviderOverride<T>(override: ProviderOverrideConfig<T>): this;
|
|
78
42
|
/**
|
|
79
43
|
* Merge additional environment bindings
|
|
80
|
-
*
|
|
81
|
-
* @param env - Partial environment to merge
|
|
82
|
-
* @returns This builder for chaining
|
|
83
44
|
*/
|
|
84
45
|
withEnv(env: Partial<StratalEnv>): this;
|
|
85
46
|
/**
|
|
86
47
|
* Compile the testing module
|
|
87
48
|
*
|
|
88
49
|
* Creates the Application, applies overrides, initializes, and returns TestingModule.
|
|
89
|
-
* The ModuleRegistry handles all module registrations automatically.
|
|
90
|
-
*
|
|
91
|
-
* @returns Promise<TestingModule> - The compiled testing module
|
|
92
50
|
*/
|
|
93
51
|
compile(): Promise<TestingModule>;
|
|
94
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-module-builder.d.ts","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,EAEjB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAuB,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAInF,OAAO,EAAE,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IACzB,qEAAqE;IACrE,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAA;CACvC;AAED
|
|
1
|
+
{"version":3,"file":"testing-module-builder.d.ts","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,EAEjB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAuB,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAInF,OAAO,EAAE,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IACzB,qEAAqE;IACrE,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAA;CACvC;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAGnB,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,SAAS,CAAuC;gBAEpC,MAAM,EAAE,mBAAmB;IAE/C;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC;IAIzE;;;;OAIG;IACH,mBAAmB,CAAC,CAAC,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,IAAI;IAKjE;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI;IAKvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IA6DvC;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAK7B"}
|
|
@@ -16,37 +16,6 @@ import { Test } from './test';
|
|
|
16
16
|
import { TestingModule } from './testing-module';
|
|
17
17
|
/**
|
|
18
18
|
* Builder for creating test modules with provider overrides
|
|
19
|
-
*
|
|
20
|
-
* Provides a NestJS-style fluent API for configuring test modules.
|
|
21
|
-
* Supports all ModuleOptions properties (imports, providers, controllers, consumers, jobs).
|
|
22
|
-
*
|
|
23
|
-
* @example Basic usage
|
|
24
|
-
* ```typescript
|
|
25
|
-
* const module = await Test.createTestingModule({
|
|
26
|
-
* imports: [RegistrationModule],
|
|
27
|
-
* }).compile()
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @example Provider override
|
|
31
|
-
* ```typescript
|
|
32
|
-
* const module = await Test.createTestingModule({
|
|
33
|
-
* imports: [RegistrationModule, GeoModule],
|
|
34
|
-
* })
|
|
35
|
-
* .overrideProvider(EMAIL_TOKENS.EmailService)
|
|
36
|
-
* .useValue(mockEmailService)
|
|
37
|
-
* .compile()
|
|
38
|
-
* ```
|
|
39
|
-
*
|
|
40
|
-
* @example Full ModuleOptions
|
|
41
|
-
* ```typescript
|
|
42
|
-
* const module = await Test.createTestingModule({
|
|
43
|
-
* imports: [RegistrationModule],
|
|
44
|
-
* providers: [{ provide: MOCK_TOKEN, useValue: mockValue }],
|
|
45
|
-
* controllers: [TestController],
|
|
46
|
-
* consumers: [TestConsumer],
|
|
47
|
-
* jobs: [TestJob],
|
|
48
|
-
* }).compile()
|
|
49
|
-
* ```
|
|
50
19
|
*/
|
|
51
20
|
export class TestingModuleBuilder {
|
|
52
21
|
config;
|
|
@@ -56,11 +25,6 @@ export class TestingModuleBuilder {
|
|
|
56
25
|
}
|
|
57
26
|
/**
|
|
58
27
|
* Override a provider with a custom implementation
|
|
59
|
-
*
|
|
60
|
-
* Returns a ProviderOverrideBuilder for specifying the override type.
|
|
61
|
-
*
|
|
62
|
-
* @param token - The injection token to override
|
|
63
|
-
* @returns ProviderOverrideBuilder for chaining useValue/useClass/useFactory
|
|
64
28
|
*/
|
|
65
29
|
overrideProvider(token) {
|
|
66
30
|
return new ProviderOverrideBuilder(this, token);
|
|
@@ -76,9 +40,6 @@ export class TestingModuleBuilder {
|
|
|
76
40
|
}
|
|
77
41
|
/**
|
|
78
42
|
* Merge additional environment bindings
|
|
79
|
-
*
|
|
80
|
-
* @param env - Partial environment to merge
|
|
81
|
-
* @returns This builder for chaining
|
|
82
43
|
*/
|
|
83
44
|
withEnv(env) {
|
|
84
45
|
this.config.env = { ...this.config.env, ...env };
|
|
@@ -88,20 +49,13 @@ export class TestingModuleBuilder {
|
|
|
88
49
|
* Compile the testing module
|
|
89
50
|
*
|
|
90
51
|
* Creates the Application, applies overrides, initializes, and returns TestingModule.
|
|
91
|
-
* The ModuleRegistry handles all module registrations automatically.
|
|
92
|
-
*
|
|
93
|
-
* @returns Promise<TestingModule> - The compiled testing module
|
|
94
52
|
*/
|
|
95
53
|
async compile() {
|
|
96
|
-
// 1. Create environment (cloudflare:test base + overrides)
|
|
97
54
|
const env = getTestEnv(this.config.env);
|
|
98
|
-
// 2. Create ExecutionContext
|
|
99
55
|
const ctx = createExecutionContext();
|
|
100
|
-
//
|
|
56
|
+
// Build root module from config
|
|
101
57
|
const baseModules = Test.getBaseModules();
|
|
102
|
-
const
|
|
103
|
-
const allImports = [...baseModules, ...configImports];
|
|
104
|
-
// Create root module with all config properties
|
|
58
|
+
const allImports = [...baseModules, ...(this.config.imports ?? [])];
|
|
105
59
|
const rootModule = this.createTestRootModule({
|
|
106
60
|
imports: allImports,
|
|
107
61
|
providers: this.config.providers,
|
|
@@ -109,7 +63,6 @@ export class TestingModuleBuilder {
|
|
|
109
63
|
consumers: this.config.consumers,
|
|
110
64
|
jobs: this.config.jobs,
|
|
111
65
|
});
|
|
112
|
-
// 4. Create Application
|
|
113
66
|
const app = new Application({
|
|
114
67
|
module: rootModule,
|
|
115
68
|
logging: {
|
|
@@ -119,12 +72,9 @@ export class TestingModuleBuilder {
|
|
|
119
72
|
env,
|
|
120
73
|
ctx,
|
|
121
74
|
});
|
|
122
|
-
//
|
|
123
|
-
await app.initialize();
|
|
124
|
-
// 5. Auto-register FakeStorageService as singleton (can be overridden by user)
|
|
125
|
-
// Must be singleton so files uploaded in setup are available when consumers run
|
|
75
|
+
// Auto-register FakeStorageService (can be overridden by user)
|
|
126
76
|
app.container.registerSingleton(STORAGE_TOKENS.StorageService, FakeStorageService);
|
|
127
|
-
//
|
|
77
|
+
// Apply user overrides BEFORE initialize
|
|
128
78
|
for (const override of this.overrides) {
|
|
129
79
|
switch (override.type) {
|
|
130
80
|
case 'value':
|
|
@@ -141,7 +91,8 @@ export class TestingModuleBuilder {
|
|
|
141
91
|
break;
|
|
142
92
|
}
|
|
143
93
|
}
|
|
144
|
-
|
|
94
|
+
await app.initialize();
|
|
95
|
+
return new TestingModule(app, env, ctx);
|
|
145
96
|
}
|
|
146
97
|
/**
|
|
147
98
|
* Create a test root module with the given options
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-module-builder.js","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EACL,WAAW,GAIZ,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAkB,MAAM,EAA8B,MAAM,gBAAgB,CAAA;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,EAAE,uBAAuB,EAA+B,MAAM,YAAY,CAAA;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAuBhD
|
|
1
|
+
{"version":3,"file":"testing-module-builder.js","sourceRoot":"","sources":["../../src/core/testing-module-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,8 +37,10 @@ import { TestHttpClient } from './http/test-http-client';
|
|
|
37
37
|
export declare class TestingModule {
|
|
38
38
|
private readonly app;
|
|
39
39
|
private readonly env;
|
|
40
|
+
private readonly ctx;
|
|
40
41
|
private _http;
|
|
41
|
-
|
|
42
|
+
private readonly _requestContainer;
|
|
43
|
+
constructor(app: Application, env: StratalEnv, ctx: ExecutionContext);
|
|
42
44
|
/**
|
|
43
45
|
* Resolve a service from the container
|
|
44
46
|
*/
|
|
@@ -56,22 +58,22 @@ export declare class TestingModule {
|
|
|
56
58
|
*/
|
|
57
59
|
get application(): Application;
|
|
58
60
|
/**
|
|
59
|
-
* Get DI Container
|
|
61
|
+
* Get DI Container (request-scoped)
|
|
60
62
|
*/
|
|
61
63
|
get container(): Container;
|
|
62
64
|
/**
|
|
63
|
-
* Execute an HTTP request through
|
|
65
|
+
* Execute an HTTP request through HonoApp
|
|
64
66
|
*/
|
|
65
67
|
fetch(request: Request): Promise<Response>;
|
|
66
68
|
/**
|
|
67
69
|
* Run callback in request scope (for DB operations, service access)
|
|
68
70
|
*/
|
|
69
|
-
runInRequestScope<T>(callback: () => T | Promise<T>): Promise<T>;
|
|
71
|
+
runInRequestScope<T>(callback: (container: Container) => T | Promise<T>): Promise<T>;
|
|
70
72
|
/**
|
|
71
73
|
* Get database service instance (resolved in request scope)
|
|
72
74
|
*/
|
|
73
|
-
getDb():
|
|
74
|
-
getDb<K extends ConnectionName>(name: K):
|
|
75
|
+
getDb(): DatabaseService;
|
|
76
|
+
getDb<K extends ConnectionName>(name: K): DatabaseService<K>;
|
|
75
77
|
/**
|
|
76
78
|
* Truncate all non-prisma tables in the database
|
|
77
79
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-module.d.ts","sourceRoot":"","sources":["../../src/core/testing-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAElF,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"testing-module.d.ts","sourceRoot":"","sources":["../../src/core/testing-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAElF,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,aAAa;IAKtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAW;gBAG1B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,gBAAgB;IAMxC;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAInC;;OAEG;IACH,IAAI,IAAI,IAAI,cAAc,CAGzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,kBAAkB,CAEhC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD;;OAEG;IACG,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAK1F;;OAEG;IACH,KAAK,IAAI,eAAe;IACxB,KAAK,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAM5D;;OAEG;IACG,UAAU,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtD;;OAEG;IACG,IAAI,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBrE;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3G;;OAEG;IACG,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/G;;OAEG;IACG,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhG;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { connectionSymbol } from '@stratal/framework/database';
|
|
2
2
|
import { DI_TOKENS } from 'stratal/di';
|
|
3
|
-
import { ROUTER_TOKENS } from 'stratal/router';
|
|
4
3
|
import { STORAGE_TOKENS } from 'stratal/storage';
|
|
5
4
|
import { TestHttpClient } from './http/test-http-client';
|
|
6
5
|
/**
|
|
@@ -35,16 +34,21 @@ import { TestHttpClient } from './http/test-http-client';
|
|
|
35
34
|
export class TestingModule {
|
|
36
35
|
app;
|
|
37
36
|
env;
|
|
37
|
+
ctx;
|
|
38
38
|
_http = null;
|
|
39
|
-
|
|
39
|
+
_requestContainer;
|
|
40
|
+
constructor(app, env, ctx) {
|
|
40
41
|
this.app = app;
|
|
41
42
|
this.env = env;
|
|
43
|
+
this.ctx = ctx;
|
|
44
|
+
const mockContext = this.app.createMockRouterContext();
|
|
45
|
+
this._requestContainer = this.app.container.createRequestScope(mockContext);
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
44
48
|
* Resolve a service from the container
|
|
45
49
|
*/
|
|
46
50
|
get(token) {
|
|
47
|
-
return this.
|
|
51
|
+
return this._requestContainer.resolve(token);
|
|
48
52
|
}
|
|
49
53
|
/**
|
|
50
54
|
* Get HTTP test client for making requests
|
|
@@ -66,17 +70,16 @@ export class TestingModule {
|
|
|
66
70
|
return this.app;
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
69
|
-
* Get DI Container
|
|
73
|
+
* Get DI Container (request-scoped)
|
|
70
74
|
*/
|
|
71
75
|
get container() {
|
|
72
|
-
return this.
|
|
76
|
+
return this._requestContainer;
|
|
73
77
|
}
|
|
74
78
|
/**
|
|
75
|
-
* Execute an HTTP request through
|
|
79
|
+
* Execute an HTTP request through HonoApp
|
|
76
80
|
*/
|
|
77
81
|
async fetch(request) {
|
|
78
|
-
|
|
79
|
-
return router.fetch(request, this.env, this.app.ctx);
|
|
82
|
+
return this.app.hono.fetch(request, this.env, this.ctx);
|
|
80
83
|
}
|
|
81
84
|
/**
|
|
82
85
|
* Run callback in request scope (for DB operations, service access)
|
|
@@ -85,29 +88,24 @@ export class TestingModule {
|
|
|
85
88
|
const mockContext = this.app.createMockRouterContext();
|
|
86
89
|
return this.app.container.runInRequestScope(mockContext, callback);
|
|
87
90
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return this.get(token);
|
|
92
|
-
});
|
|
91
|
+
getDb(name) {
|
|
92
|
+
const token = name ? connectionSymbol(name) : DI_TOKENS.Database;
|
|
93
|
+
return this._requestContainer.resolve(token);
|
|
93
94
|
}
|
|
94
95
|
/**
|
|
95
96
|
* Truncate all non-prisma tables in the database
|
|
96
97
|
*/
|
|
97
98
|
async truncateDb(name) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const tableList = tables.map((t) => `"${t.tablename}"`).join(', ');
|
|
109
|
-
await db.$executeRawUnsafe(`TRUNCATE ${tableList} RESTART IDENTITY CASCADE`);
|
|
110
|
-
});
|
|
99
|
+
const db = this.getDb(name);
|
|
100
|
+
const tables = await db.$queryRaw `
|
|
101
|
+
SELECT tablename::text as tablename FROM pg_tables
|
|
102
|
+
WHERE schemaname = current_schema()
|
|
103
|
+
AND tablename NOT LIKE '_prisma%'
|
|
104
|
+
`;
|
|
105
|
+
if (tables.length === 0)
|
|
106
|
+
return;
|
|
107
|
+
const tableList = tables.map((t) => `"${t.tablename}"`).join(', ');
|
|
108
|
+
await db.$executeRawUnsafe(`TRUNCATE ${tableList} RESTART IDENTITY CASCADE`);
|
|
111
109
|
}
|
|
112
110
|
async seed(...args) {
|
|
113
111
|
let name;
|
|
@@ -119,14 +117,11 @@ export class TestingModule {
|
|
|
119
117
|
else {
|
|
120
118
|
seeders = args;
|
|
121
119
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
await seeder.run(tx);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
120
|
+
const db = this.getDb(name);
|
|
121
|
+
await db.$transaction(async (tx) => {
|
|
122
|
+
for (const seeder of seeders) {
|
|
123
|
+
await seeder.run(tx);
|
|
124
|
+
}
|
|
130
125
|
});
|
|
131
126
|
}
|
|
132
127
|
/**
|
|
@@ -134,44 +129,36 @@ export class TestingModule {
|
|
|
134
129
|
*/
|
|
135
130
|
async assertDatabaseHas(table, data, name) {
|
|
136
131
|
const { expect } = await import('vitest');
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const result = await model.findFirst({ where: data });
|
|
142
|
-
expect(result, `Expected ${table} with ${JSON.stringify(data)}`).not.toBeNull();
|
|
143
|
-
});
|
|
132
|
+
const db = this.getDb(name);
|
|
133
|
+
const model = db[table];
|
|
134
|
+
const result = await model.findFirst({ where: data });
|
|
135
|
+
expect(result, `Expected ${table} with ${JSON.stringify(data)}`).not.toBeNull();
|
|
144
136
|
}
|
|
145
137
|
/**
|
|
146
138
|
* Assert that a record does not exist in the database
|
|
147
139
|
*/
|
|
148
140
|
async assertDatabaseMissing(table, data, name) {
|
|
149
141
|
const { expect } = await import('vitest');
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const result = await model.findFirst({ where: data });
|
|
155
|
-
expect(result, `Expected ${table} NOT to have ${JSON.stringify(data)}`).toBeNull();
|
|
156
|
-
});
|
|
142
|
+
const db = this.getDb(name);
|
|
143
|
+
const model = db[table];
|
|
144
|
+
const result = await model.findFirst({ where: data });
|
|
145
|
+
expect(result, `Expected ${table} NOT to have ${JSON.stringify(data)}`).toBeNull();
|
|
157
146
|
}
|
|
158
147
|
/**
|
|
159
148
|
* Assert the number of records in a table
|
|
160
149
|
*/
|
|
161
150
|
async assertDatabaseCount(table, expected, name) {
|
|
162
151
|
const { expect } = await import('vitest');
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const actual = await model.count();
|
|
168
|
-
expect(actual, `Expected ${table} count ${expected}, got ${actual}`).toBe(expected);
|
|
169
|
-
});
|
|
152
|
+
const db = this.getDb(name);
|
|
153
|
+
const model = db[table];
|
|
154
|
+
const actual = await model.count();
|
|
155
|
+
expect(actual, `Expected ${table} count ${expected}, got ${actual}`).toBe(expected);
|
|
170
156
|
}
|
|
171
157
|
/**
|
|
172
158
|
* Cleanup - call in afterAll
|
|
173
159
|
*/
|
|
174
160
|
async close() {
|
|
161
|
+
await this._requestContainer.dispose();
|
|
175
162
|
await this.app.shutdown();
|
|
176
163
|
}
|
|
177
164
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing-module.js","sourceRoot":"","sources":["../../src/core/testing-module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAE9D,OAAO,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAA;AAEtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"testing-module.js","sourceRoot":"","sources":["../../src/core/testing-module.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratal/testing",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Testing utilities and mocks for Stratal framework applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"@golevelup/ts-vitest": "^2.2.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@stratal/framework": "^0.0.
|
|
63
|
+
"@stratal/framework": "^0.0.8",
|
|
64
64
|
"better-auth": "^1.4.9",
|
|
65
|
-
"stratal": "^0.0.
|
|
65
|
+
"stratal": "^0.0.8",
|
|
66
66
|
"vitest": "^3.2.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@cloudflare/vitest-pool-workers": "^0.12.
|
|
78
|
-
"@cloudflare/workers-types": "4.
|
|
77
|
+
"@cloudflare/vitest-pool-workers": "^0.12.20",
|
|
78
|
+
"@cloudflare/workers-types": "4.20260307.1",
|
|
79
79
|
"@stratal/framework": "workspace:*",
|
|
80
|
-
"@types/node": "^25.3.
|
|
81
|
-
"better-auth": "^1.5.
|
|
80
|
+
"@types/node": "^25.3.5",
|
|
81
|
+
"better-auth": "^1.5.4",
|
|
82
82
|
"stratal": "workspace:*",
|
|
83
83
|
"typescript": "^5.9.3",
|
|
84
84
|
"vitest": "~3.2.0"
|