@grest-ts/testkit 0.0.5
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/LICENSE +21 -0
- package/README.md +413 -0
- package/dist/src/GGBundleTest.d.ts +8 -0
- package/dist/src/GGBundleTest.d.ts.map +1 -0
- package/dist/src/GGBundleTest.js +75 -0
- package/dist/src/GGBundleTest.js.map +1 -0
- package/dist/src/GGTest.d.ts +131 -0
- package/dist/src/GGTest.d.ts.map +1 -0
- package/dist/src/GGTest.js +245 -0
- package/dist/src/GGTest.js.map +1 -0
- package/dist/src/GGTestContext.d.ts +36 -0
- package/dist/src/GGTestContext.d.ts.map +1 -0
- package/dist/src/GGTestContext.js +63 -0
- package/dist/src/GGTestContext.js.map +1 -0
- package/dist/src/GGTestRunner.d.ts +108 -0
- package/dist/src/GGTestRunner.d.ts.map +1 -0
- package/dist/src/GGTestRunner.js +242 -0
- package/dist/src/GGTestRunner.js.map +1 -0
- package/dist/src/GGTestRuntime.d.ts +103 -0
- package/dist/src/GGTestRuntime.d.ts.map +1 -0
- package/dist/src/GGTestRuntime.js +219 -0
- package/dist/src/GGTestRuntime.js.map +1 -0
- package/dist/src/GGTestRuntimeWorker.d.ts +41 -0
- package/dist/src/GGTestRuntimeWorker.d.ts.map +1 -0
- package/dist/src/GGTestRuntimeWorker.js +136 -0
- package/dist/src/GGTestRuntimeWorker.js.map +1 -0
- package/dist/src/GGTestSharedRef.d.ts +35 -0
- package/dist/src/GGTestSharedRef.d.ts.map +1 -0
- package/dist/src/GGTestSharedRef.js +126 -0
- package/dist/src/GGTestSharedRef.js.map +1 -0
- package/dist/src/GGTestkitExtensionsDiscovery.d.ts +21 -0
- package/dist/src/GGTestkitExtensionsDiscovery.d.ts.map +1 -0
- package/dist/src/GGTestkitExtensionsDiscovery.js +24 -0
- package/dist/src/GGTestkitExtensionsDiscovery.js.map +1 -0
- package/dist/src/IGGLocalDiscoveryServer.d.ts +16 -0
- package/dist/src/IGGLocalDiscoveryServer.d.ts.map +1 -0
- package/dist/src/IGGLocalDiscoveryServer.js +2 -0
- package/dist/src/IGGLocalDiscoveryServer.js.map +1 -0
- package/dist/src/callOn/GGCallOnSelector.d.ts +42 -0
- package/dist/src/callOn/GGCallOnSelector.d.ts.map +1 -0
- package/dist/src/callOn/GGCallOnSelector.js +35 -0
- package/dist/src/callOn/GGCallOnSelector.js.map +1 -0
- package/dist/src/callOn/GGContractClass.implement.d.ts +8 -0
- package/dist/src/callOn/GGContractClass.implement.d.ts.map +1 -0
- package/dist/src/callOn/GGContractClass.implement.js +31 -0
- package/dist/src/callOn/GGContractClass.implement.js.map +1 -0
- package/dist/src/callOn/GGTestActionForLocatorOnCall.d.ts +28 -0
- package/dist/src/callOn/GGTestActionForLocatorOnCall.d.ts.map +1 -0
- package/dist/src/callOn/GGTestActionForLocatorOnCall.js +118 -0
- package/dist/src/callOn/GGTestActionForLocatorOnCall.js.map +1 -0
- package/dist/src/callOn/TestableIPC.d.ts +72 -0
- package/dist/src/callOn/TestableIPC.d.ts.map +1 -0
- package/dist/src/callOn/TestableIPC.js +34 -0
- package/dist/src/callOn/TestableIPC.js.map +1 -0
- package/dist/src/callOn/callOn.d.ts +113 -0
- package/dist/src/callOn/callOn.d.ts.map +1 -0
- package/dist/src/callOn/callOn.js +122 -0
- package/dist/src/callOn/callOn.js.map +1 -0
- package/dist/src/callOn/registerOnCallHandler.d.ts +13 -0
- package/dist/src/callOn/registerOnCallHandler.d.ts.map +1 -0
- package/dist/src/callOn/registerOnCallHandler.js +111 -0
- package/dist/src/callOn/registerOnCallHandler.js.map +1 -0
- package/dist/src/index-node.d.ts +35 -0
- package/dist/src/index-node.d.ts.map +1 -0
- package/dist/src/index-node.js +50 -0
- package/dist/src/index-node.js.map +1 -0
- package/dist/src/mockable/GGMockable.d.ts +19 -0
- package/dist/src/mockable/GGMockable.d.ts.map +1 -0
- package/dist/src/mockable/GGMockable.js +2 -0
- package/dist/src/mockable/GGMockable.js.map +1 -0
- package/dist/src/mockable/GGMockableCall.d.ts +2 -0
- package/dist/src/mockable/GGMockableCall.d.ts.map +1 -0
- package/dist/src/mockable/GGMockableCall.js +41 -0
- package/dist/src/mockable/GGMockableCall.js.map +1 -0
- package/dist/src/mockable/GGMockableIPC.d.ts +17 -0
- package/dist/src/mockable/GGMockableIPC.d.ts.map +1 -0
- package/dist/src/mockable/GGMockableIPC.js +8 -0
- package/dist/src/mockable/GGMockableIPC.js.map +1 -0
- package/dist/src/mockable/GGMockableInterceptor.d.ts +24 -0
- package/dist/src/mockable/GGMockableInterceptor.d.ts.map +1 -0
- package/dist/src/mockable/GGMockableInterceptor.js +32 -0
- package/dist/src/mockable/GGMockableInterceptor.js.map +1 -0
- package/dist/src/mockable/GGMockableInterceptorsServer.d.ts +12 -0
- package/dist/src/mockable/GGMockableInterceptorsServer.d.ts.map +1 -0
- package/dist/src/mockable/GGMockableInterceptorsServer.js +55 -0
- package/dist/src/mockable/GGMockableInterceptorsServer.js.map +1 -0
- package/dist/src/mockable/mockable.d.ts +46 -0
- package/dist/src/mockable/mockable.d.ts.map +1 -0
- package/dist/src/mockable/mockable.js +47 -0
- package/dist/src/mockable/mockable.js.map +1 -0
- package/dist/src/runner/InlineRunner.d.ts +12 -0
- package/dist/src/runner/InlineRunner.d.ts.map +1 -0
- package/dist/src/runner/InlineRunner.js +42 -0
- package/dist/src/runner/InlineRunner.js.map +1 -0
- package/dist/src/runner/IsolatedRunner.d.ts +17 -0
- package/dist/src/runner/IsolatedRunner.d.ts.map +1 -0
- package/dist/src/runner/IsolatedRunner.js +155 -0
- package/dist/src/runner/IsolatedRunner.js.map +1 -0
- package/dist/src/runner/RuntimeRunner.d.ts +14 -0
- package/dist/src/runner/RuntimeRunner.d.ts.map +1 -0
- package/dist/src/runner/RuntimeRunner.js +2 -0
- package/dist/src/runner/RuntimeRunner.js.map +1 -0
- package/dist/src/runner/WorkerRunner.d.ts +17 -0
- package/dist/src/runner/WorkerRunner.d.ts.map +1 -0
- package/dist/src/runner/WorkerRunner.js +155 -0
- package/dist/src/runner/WorkerRunner.js.map +1 -0
- package/dist/src/runner/isolated-loader.mjs +91 -0
- package/dist/src/runner/worker-loader.mjs +49 -0
- package/dist/src/testers/GGCallInterceptor.d.ts +71 -0
- package/dist/src/testers/GGCallInterceptor.d.ts.map +1 -0
- package/dist/src/testers/GGCallInterceptor.js +170 -0
- package/dist/src/testers/GGCallInterceptor.js.map +1 -0
- package/dist/src/testers/GGMockWith.d.ts +30 -0
- package/dist/src/testers/GGMockWith.d.ts.map +1 -0
- package/dist/src/testers/GGMockWith.js +70 -0
- package/dist/src/testers/GGMockWith.js.map +1 -0
- package/dist/src/testers/GGSpyWith.d.ts +40 -0
- package/dist/src/testers/GGSpyWith.d.ts.map +1 -0
- package/dist/src/testers/GGSpyWith.js +90 -0
- package/dist/src/testers/GGSpyWith.js.map +1 -0
- package/dist/src/testers/GGTestAction.d.ts +126 -0
- package/dist/src/testers/GGTestAction.d.ts.map +1 -0
- package/dist/src/testers/GGTestAction.js +245 -0
- package/dist/src/testers/GGTestAction.js.map +1 -0
- package/dist/src/testers/GGTestComponent.d.ts +15 -0
- package/dist/src/testers/GGTestComponent.d.ts.map +1 -0
- package/dist/src/testers/GGTestComponent.js +2 -0
- package/dist/src/testers/GGTestComponent.js.map +1 -0
- package/dist/src/testers/GGTestSelector.d.ts +54 -0
- package/dist/src/testers/GGTestSelector.d.ts.map +1 -0
- package/dist/src/testers/GGTestSelector.js +179 -0
- package/dist/src/testers/GGTestSelector.js.map +1 -0
- package/dist/src/testers/IGGTestInterceptor.d.ts +8 -0
- package/dist/src/testers/IGGTestInterceptor.d.ts.map +1 -0
- package/dist/src/testers/IGGTestInterceptor.js +2 -0
- package/dist/src/testers/IGGTestInterceptor.js.map +1 -0
- package/dist/src/testers/IGGTestWith.d.ts +13 -0
- package/dist/src/testers/IGGTestWith.d.ts.map +1 -0
- package/dist/src/testers/IGGTestWith.js +2 -0
- package/dist/src/testers/IGGTestWith.js.map +1 -0
- package/dist/src/testers/RuntimeSelector.d.ts +117 -0
- package/dist/src/testers/RuntimeSelector.d.ts.map +1 -0
- package/dist/src/testers/RuntimeSelector.js +2 -0
- package/dist/src/testers/RuntimeSelector.js.map +1 -0
- package/dist/src/tsconfig.json +17 -0
- package/dist/src/utils/GGExpectations.d.ts +18 -0
- package/dist/src/utils/GGExpectations.d.ts.map +1 -0
- package/dist/src/utils/GGExpectations.js +59 -0
- package/dist/src/utils/GGExpectations.js.map +1 -0
- package/dist/src/utils/GGTestError.d.ts +13 -0
- package/dist/src/utils/GGTestError.d.ts.map +1 -0
- package/dist/src/utils/GGTestError.js +26 -0
- package/dist/src/utils/GGTestError.js.map +1 -0
- package/dist/src/utils/captureStack.d.ts +9 -0
- package/dist/src/utils/captureStack.d.ts.map +1 -0
- package/dist/src/utils/captureStack.js +51 -0
- package/dist/src/utils/captureStack.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +66 -0
- package/src/GGBundleTest.ts +89 -0
- package/src/GGTest.ts +318 -0
- package/src/GGTestContext.ts +74 -0
- package/src/GGTestRunner.ts +308 -0
- package/src/GGTestRuntime.ts +265 -0
- package/src/GGTestRuntimeWorker.ts +159 -0
- package/src/GGTestSharedRef.ts +116 -0
- package/src/GGTestkitExtensionsDiscovery.ts +26 -0
- package/src/IGGLocalDiscoveryServer.ts +16 -0
- package/src/callOn/GGCallOnSelector.ts +61 -0
- package/src/callOn/GGContractClass.implement.ts +43 -0
- package/src/callOn/GGTestActionForLocatorOnCall.ts +134 -0
- package/src/callOn/TestableIPC.ts +81 -0
- package/src/callOn/callOn.ts +224 -0
- package/src/callOn/registerOnCallHandler.ts +123 -0
- package/src/index-node.ts +64 -0
- package/src/mockable/GGMockable.ts +22 -0
- package/src/mockable/GGMockableCall.ts +45 -0
- package/src/mockable/GGMockableIPC.ts +20 -0
- package/src/mockable/GGMockableInterceptor.ts +44 -0
- package/src/mockable/GGMockableInterceptorsServer.ts +69 -0
- package/src/mockable/mockable.ts +71 -0
- package/src/runner/InlineRunner.ts +47 -0
- package/src/runner/IsolatedRunner.ts +179 -0
- package/src/runner/RuntimeRunner.ts +15 -0
- package/src/runner/WorkerRunner.ts +179 -0
- package/src/runner/isolated-loader.mjs +91 -0
- package/src/runner/worker-loader.mjs +49 -0
- package/src/testers/GGCallInterceptor.ts +224 -0
- package/src/testers/GGMockWith.ts +92 -0
- package/src/testers/GGSpyWith.ts +115 -0
- package/src/testers/GGTestAction.ts +333 -0
- package/src/testers/GGTestComponent.ts +16 -0
- package/src/testers/GGTestSelector.ts +223 -0
- package/src/testers/IGGTestInterceptor.ts +11 -0
- package/src/testers/IGGTestWith.ts +15 -0
- package/src/testers/RuntimeSelector.ts +151 -0
- package/src/tsconfig.json +17 -0
- package/src/utils/GGExpectations.ts +78 -0
- package/src/utils/GGTestError.ts +37 -0
- package/src/utils/captureStack.ts +54 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { IPCClient } from "@grest-ts/ipc";
|
|
2
|
+
import { GGLog } from "@grest-ts/logger";
|
|
3
|
+
import { GGLoggerConsole } from "@grest-ts/logger-console";
|
|
4
|
+
import { GGLocatorKey, GGLocatorScope } from "@grest-ts/locator";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
import { GGExtensionDiscovery } from "@grest-ts/common";
|
|
7
|
+
import { runWithMockableContext } from "@grest-ts/testkit-runtime";
|
|
8
|
+
import { CALL_THROUGH } from "./mockable/GGMockableInterceptorsServer.js";
|
|
9
|
+
import { GGMockableIPC } from "./mockable/GGMockableIPC.js";
|
|
10
|
+
import { registerOnCallHandler } from "./callOn/registerOnCallHandler.js";
|
|
11
|
+
import { TestableIPC } from "./callOn/TestableIPC.js";
|
|
12
|
+
export const GG_TEST_RUNTIME_WORKER = new GGLocatorKey("GGTestRuntimeWorker");
|
|
13
|
+
export class GGTestRuntimeWorker {
|
|
14
|
+
static beforeRuntimeStartHandlers = [];
|
|
15
|
+
static beforeRuntimeStartExecuted = false;
|
|
16
|
+
ipcClient;
|
|
17
|
+
config;
|
|
18
|
+
runtime = undefined;
|
|
19
|
+
runtimeStopped = false;
|
|
20
|
+
scope;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.ipcClient = new IPCClient(config.testRouterPort);
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.scope = new GGLocatorScope("GGTestRuntimeWorker").enter();
|
|
25
|
+
this.scope.set(GG_TEST_RUNTIME_WORKER, this);
|
|
26
|
+
GGLog.init();
|
|
27
|
+
GGLog.add(new GGLoggerConsole({ showData: true }));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register a function to be called before the runtime starts.
|
|
31
|
+
* Safe to call at module load time - just adds to array.
|
|
32
|
+
* Handlers are executed during start() after extensions are loaded but before runtime creation.
|
|
33
|
+
*/
|
|
34
|
+
static onBeforeRuntimeStart(handler) {
|
|
35
|
+
if (this.beforeRuntimeStartExecuted) {
|
|
36
|
+
throw new Error("Cannot register beforeRuntimeStart handler after worker has started");
|
|
37
|
+
}
|
|
38
|
+
this.beforeRuntimeStartHandlers.push(handler);
|
|
39
|
+
}
|
|
40
|
+
async start(createRuntime) {
|
|
41
|
+
process.env.GG_LOCAL_ROUTER_PORT = String(this.config.testRouterPort);
|
|
42
|
+
await new GGExtensionDiscovery('testkit').load();
|
|
43
|
+
// Create mockable context that bridges to IPC
|
|
44
|
+
const mockableContext = {
|
|
45
|
+
CALL_THROUGH,
|
|
46
|
+
sendCall: async (className, methodName, callArgs) => {
|
|
47
|
+
return this.ipcClient.sendFrameworkRequest(GGMockableIPC.testServer.call, {
|
|
48
|
+
className,
|
|
49
|
+
methodName,
|
|
50
|
+
callArgs
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
sendSpyResult: async (className, methodName, callResult) => {
|
|
54
|
+
await this.ipcClient.sendFrameworkRequest(GGMockableIPC.testServer.spyResult, {
|
|
55
|
+
className,
|
|
56
|
+
methodName,
|
|
57
|
+
callResult
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
// Wrap in mockable context so @mockable decorators can intercept
|
|
62
|
+
await runWithMockableContext(mockableContext, async () => {
|
|
63
|
+
await this.ipcClient.connect(this.config.runtimeId);
|
|
64
|
+
GGLog.debug(this, 'Connected to test router');
|
|
65
|
+
// Register testable handler for direct service invocation from tests
|
|
66
|
+
registerOnCallHandler(this);
|
|
67
|
+
GGTestRuntimeWorker.beforeRuntimeStartExecuted = true;
|
|
68
|
+
GGTestRuntimeWorker.beforeRuntimeStartHandlers.forEach(handler => handler());
|
|
69
|
+
if (createRuntime) {
|
|
70
|
+
this.runtime = createRuntime();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Dynamic import of the runtime source file.
|
|
74
|
+
// Always use file:// URL — required by Node ESM on Windows.
|
|
75
|
+
const moduleUrl = this.config.executablePath.startsWith('file:')
|
|
76
|
+
? this.config.executablePath
|
|
77
|
+
: pathToFileURL(this.config.executablePath).href;
|
|
78
|
+
const module = await import(moduleUrl);
|
|
79
|
+
const RuntimeClass = module[this.config.className];
|
|
80
|
+
if (!RuntimeClass) {
|
|
81
|
+
throw new Error(`Runtime class '${this.config.className}' not found in module '${this.config.executablePath}'. ` +
|
|
82
|
+
`Make sure the class is exported.`);
|
|
83
|
+
}
|
|
84
|
+
this.runtime = new RuntimeClass();
|
|
85
|
+
}
|
|
86
|
+
await this.runtime.start();
|
|
87
|
+
// Send registered locator keys to test runner for callOn routing
|
|
88
|
+
const keys = this.runtime.scope.getKeys();
|
|
89
|
+
await this.ipcClient.sendFrameworkRequest(TestableIPC.server.registerKeys, {
|
|
90
|
+
runtimeId: this.config.runtimeId,
|
|
91
|
+
keys
|
|
92
|
+
});
|
|
93
|
+
GGLog.debug(this, `Sent ${keys.length} locator keys to test runner`);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stop the GGRuntime (teardown services) but keep IPC alive.
|
|
98
|
+
* The runtime reference is kept so IPC handlers can still access
|
|
99
|
+
* async contexts (logs, metrics, config) via runInContext().
|
|
100
|
+
*/
|
|
101
|
+
async stopRuntime() {
|
|
102
|
+
if (this.runtimeStopped)
|
|
103
|
+
return;
|
|
104
|
+
this.runtimeStopped = true;
|
|
105
|
+
if (this.runtime) {
|
|
106
|
+
await this.runtime.scope.run(() => this.runtime.teardown());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Register an IPC request handler that automatically runs within the runtime's context.
|
|
111
|
+
* Use this instead of ipcClient.onFrameworkRequest() for handlers that need access to
|
|
112
|
+
* runtime services (logs, metrics, config, etc.) even after runtime.stop().
|
|
113
|
+
*/
|
|
114
|
+
onIpcRequest(type, handler) {
|
|
115
|
+
this.ipcClient.onFrameworkRequest(type, async (payload) => {
|
|
116
|
+
if (this.runtime) {
|
|
117
|
+
return this.runtime.scope.run(() => handler(payload));
|
|
118
|
+
}
|
|
119
|
+
return handler(payload);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Fully shutdown the worker, including IPC disconnection.
|
|
124
|
+
* Calls stopRuntime() if not already stopped.
|
|
125
|
+
*/
|
|
126
|
+
async shutdown() {
|
|
127
|
+
if (!this.runtimeStopped) {
|
|
128
|
+
await this.stopRuntime();
|
|
129
|
+
}
|
|
130
|
+
this.ipcClient.disconnect();
|
|
131
|
+
}
|
|
132
|
+
getInitialCommandsFor(type) {
|
|
133
|
+
return this.config.initialCommands.filter(cmd => cmd.method === type);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=GGTestRuntimeWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestRuntimeWorker.js","sourceRoot":"","sources":["../../src/GGTestRuntimeWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference counting for shared test resources across workers.
|
|
3
|
+
*
|
|
4
|
+
* Used to coordinate shared resources (e.g. database schemas)
|
|
5
|
+
* that multiple workers use simultaneously. Handles file-system
|
|
6
|
+
* based locking so callers don't need their own locking mechanism.
|
|
7
|
+
*
|
|
8
|
+
* - acquire(key, onCreate): first caller runs onCreate, others wait and skip
|
|
9
|
+
* - release(key, onLast): last caller runs onLast (e.g. cleanup)
|
|
10
|
+
*/
|
|
11
|
+
export declare class GGTestSharedRef {
|
|
12
|
+
private static getRefDir;
|
|
13
|
+
private static getRefFile;
|
|
14
|
+
private static getLockPath;
|
|
15
|
+
private static acquireLock;
|
|
16
|
+
private static releaseLock;
|
|
17
|
+
/**
|
|
18
|
+
* Acquire a shared reference. If this is the first reference,
|
|
19
|
+
* the onCreate callback is called (e.g. to create a shared resource).
|
|
20
|
+
* Other callers wait for the lock and skip onCreate.
|
|
21
|
+
*/
|
|
22
|
+
static acquire(key: string, onCreate: () => Promise<void>): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Release a shared reference. If this is the last reference,
|
|
25
|
+
* the onLast callback is called (e.g. to drop a shared resource).
|
|
26
|
+
* Errors in onLast are caught and logged (cleanup is best-effort).
|
|
27
|
+
*/
|
|
28
|
+
static release(key: string, onLast: () => Promise<void>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove the ref counting temp directory for the current test run.
|
|
31
|
+
* Called by globalSetup teardown after all workers have finished.
|
|
32
|
+
*/
|
|
33
|
+
static cleanup(): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=GGTestSharedRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestSharedRef.d.ts","sourceRoot":"","sources":["../../src/GGTestSharedRef.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAExB,OAAO,CAAC,MAAM,CAAC,SAAS;IAUxB,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,WAAW;mBAIL,WAAW;IAiBhC,OAAO,CAAC,MAAM,CAAC,WAAW;IAI1B;;;;OAIG;WACU,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB/E;;;;OAIG;WACU,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB7E;;;OAGG;IACH,MAAM,CAAC,OAAO,IAAI,IAAI;CAMzB"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
/**
|
|
5
|
+
* Reference counting for shared test resources across workers.
|
|
6
|
+
*
|
|
7
|
+
* Used to coordinate shared resources (e.g. database schemas)
|
|
8
|
+
* that multiple workers use simultaneously. Handles file-system
|
|
9
|
+
* based locking so callers don't need their own locking mechanism.
|
|
10
|
+
*
|
|
11
|
+
* - acquire(key, onCreate): first caller runs onCreate, others wait and skip
|
|
12
|
+
* - release(key, onLast): last caller runs onLast (e.g. cleanup)
|
|
13
|
+
*/
|
|
14
|
+
export class GGTestSharedRef {
|
|
15
|
+
static getRefDir() {
|
|
16
|
+
const runId = process.env.GG_TEST_RUN_ID;
|
|
17
|
+
if (!runId) {
|
|
18
|
+
throw new Error("GG_TEST_RUN_ID not set. Add globalSetup '@grest-ts/testkit-vitest/globalSetup' to vitest.config.ts.");
|
|
19
|
+
}
|
|
20
|
+
const dir = path.join(os.tmpdir(), `gg-test-${runId}`);
|
|
21
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
static getRefFile(key) {
|
|
25
|
+
return path.join(this.getRefDir(), `${key}.ref`);
|
|
26
|
+
}
|
|
27
|
+
static getLockPath(key) {
|
|
28
|
+
return path.join(this.getRefDir(), `${key}.lock`);
|
|
29
|
+
}
|
|
30
|
+
static async acquireLock(key) {
|
|
31
|
+
const lockPath = this.getLockPath(key);
|
|
32
|
+
const timeout = 60000;
|
|
33
|
+
const start = Date.now();
|
|
34
|
+
while (true) {
|
|
35
|
+
try {
|
|
36
|
+
fs.mkdirSync(lockPath);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
if (Date.now() - start > timeout) {
|
|
41
|
+
throw new Error(`[GGTestSharedRef] Failed to acquire lock for '${key}' after ${timeout}ms`);
|
|
42
|
+
}
|
|
43
|
+
await new Promise(resolve => setTimeout(resolve, 50 + Math.random() * 50));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
static releaseLock(key) {
|
|
48
|
+
try {
|
|
49
|
+
fs.rmdirSync(this.getLockPath(key));
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Acquire a shared reference. If this is the first reference,
|
|
55
|
+
* the onCreate callback is called (e.g. to create a shared resource).
|
|
56
|
+
* Other callers wait for the lock and skip onCreate.
|
|
57
|
+
*/
|
|
58
|
+
static async acquire(key, onCreate) {
|
|
59
|
+
await this.acquireLock(key);
|
|
60
|
+
try {
|
|
61
|
+
const file = this.getRefFile(key);
|
|
62
|
+
let count = 0;
|
|
63
|
+
try {
|
|
64
|
+
count = parseInt(fs.readFileSync(file, 'utf-8'));
|
|
65
|
+
}
|
|
66
|
+
catch { }
|
|
67
|
+
if (count === 0) {
|
|
68
|
+
await onCreate();
|
|
69
|
+
}
|
|
70
|
+
fs.writeFileSync(file, (count + 1).toString());
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
this.releaseLock(key);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Release a shared reference. If this is the last reference,
|
|
78
|
+
* the onLast callback is called (e.g. to drop a shared resource).
|
|
79
|
+
* Errors in onLast are caught and logged (cleanup is best-effort).
|
|
80
|
+
*/
|
|
81
|
+
static async release(key, onLast) {
|
|
82
|
+
await this.acquireLock(key);
|
|
83
|
+
try {
|
|
84
|
+
const file = this.getRefFile(key);
|
|
85
|
+
let count = 0;
|
|
86
|
+
try {
|
|
87
|
+
count = parseInt(fs.readFileSync(file, 'utf-8'));
|
|
88
|
+
}
|
|
89
|
+
catch { }
|
|
90
|
+
count -= 1;
|
|
91
|
+
if (count <= 0) {
|
|
92
|
+
try {
|
|
93
|
+
fs.unlinkSync(file);
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
try {
|
|
97
|
+
await onLast();
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
console.error('[GGTestSharedRef] Cleanup failed:', err);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
fs.writeFileSync(file, count.toString());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
this.releaseLock(key);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Remove the ref counting temp directory for the current test run.
|
|
113
|
+
* Called by globalSetup teardown after all workers have finished.
|
|
114
|
+
*/
|
|
115
|
+
static cleanup() {
|
|
116
|
+
const runId = process.env.GG_TEST_RUN_ID;
|
|
117
|
+
if (!runId)
|
|
118
|
+
return;
|
|
119
|
+
const dir = path.join(os.tmpdir(), `gg-test-${runId}`);
|
|
120
|
+
try {
|
|
121
|
+
fs.rmSync(dir, { recursive: true });
|
|
122
|
+
}
|
|
123
|
+
catch { }
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=GGTestSharedRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestSharedRef.js","sourceRoot":"","sources":["../../src/GGTestSharedRef.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovers testkit extensions by scanning node_modules for packages
|
|
3
|
+
* that follow the convention of having a testkit/index-testkit.ts file.
|
|
4
|
+
*
|
|
5
|
+
* @deprecated Use GGExtensionDiscovery from @grest-ts/common directly:
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const discovery = new GGExtensionDiscovery('testkit');
|
|
8
|
+
* await discovery.load();
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare class GGTestkitExtensionsDiscovery {
|
|
12
|
+
private static discovery;
|
|
13
|
+
/**
|
|
14
|
+
* Discover and load all testkits.
|
|
15
|
+
* - Scans for testkit packages
|
|
16
|
+
* - Generates .d.ts file for IDE support
|
|
17
|
+
* - Dynamically imports testkits for runtime
|
|
18
|
+
*/
|
|
19
|
+
static load(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=GGTestkitExtensionsDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestkitExtensionsDiscovery.d.ts","sourceRoot":"","sources":["../../src/GGTestkitExtensionsDiscovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,qBAAa,4BAA4B;IAErC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAuC;IAE/D;;;;;OAKG;WACiB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GGExtensionDiscovery } from '@grest-ts/common';
|
|
2
|
+
/**
|
|
3
|
+
* Discovers testkit extensions by scanning node_modules for packages
|
|
4
|
+
* that follow the convention of having a testkit/index-testkit.ts file.
|
|
5
|
+
*
|
|
6
|
+
* @deprecated Use GGExtensionDiscovery from @grest-ts/common directly:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const discovery = new GGExtensionDiscovery('testkit');
|
|
9
|
+
* await discovery.load();
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export class GGTestkitExtensionsDiscovery {
|
|
13
|
+
static discovery = new GGExtensionDiscovery('testkit');
|
|
14
|
+
/**
|
|
15
|
+
* Discover and load all testkits.
|
|
16
|
+
* - Scans for testkit packages
|
|
17
|
+
* - Generates .d.ts file for IDE support
|
|
18
|
+
* - Dynamically imports testkits for runtime
|
|
19
|
+
*/
|
|
20
|
+
static async load() {
|
|
21
|
+
await this.discovery.load();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=GGTestkitExtensionsDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestkitExtensionsDiscovery.js","sourceRoot":"","sources":["../../src/GGTestkitExtensionsDiscovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,OAAO,4BAA4B;IAE7B,MAAM,CAAC,SAAS,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAE/D;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI;QACpB,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for discovery server used by GGTestRunner.
|
|
3
|
+
* Implemented by GGLocalDiscoveryServer in @grest-ts/discovery.
|
|
4
|
+
* This interface allows @grest-ts/testkit to not depend on @grest-ts/discovery.
|
|
5
|
+
*/
|
|
6
|
+
export interface IGGLocalDiscoveryServer {
|
|
7
|
+
start(): Promise<boolean>;
|
|
8
|
+
teardown(): Promise<void>;
|
|
9
|
+
getRoutingUrl(api: string): string;
|
|
10
|
+
}
|
|
11
|
+
export interface IServiceRoute {
|
|
12
|
+
api: string;
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
pathPrefix: string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=IGGLocalDiscoveryServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IGGLocalDiscoveryServer.d.ts","sourceRoot":"","sources":["../../src/IGGLocalDiscoveryServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IGGLocalDiscoveryServer.js","sourceRoot":"","sources":["../../src/IGGLocalDiscoveryServer.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selector extension that adds targeted callOn to selectors.
|
|
3
|
+
*
|
|
4
|
+
* This allows explicitly targeting specific runtimes when multiple
|
|
5
|
+
* different runtime classes have the same service registered.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const f = GGTest.startWorker({chain: ChainRuntime, weather: WeatherOnlyRuntime});
|
|
9
|
+
*
|
|
10
|
+
* // Both have WeatherService - explicitly target one:
|
|
11
|
+
* await f.chain.callOn(WeatherService).getWeather("Test").toMatchObject({...})
|
|
12
|
+
* await f.weather.callOn(WeatherService).getWeather("Test").toMatchObject({...})
|
|
13
|
+
*/
|
|
14
|
+
import { GGContext } from "@grest-ts/context";
|
|
15
|
+
import { GGTestSelectorExtension } from "../testers/GGTestSelector";
|
|
16
|
+
import { RuntimeConstructor } from "../testers/RuntimeSelector";
|
|
17
|
+
import { GGTestCallOn } from "./callOn";
|
|
18
|
+
import type { GGTestRuntime } from "../GGTestRuntime";
|
|
19
|
+
/**
|
|
20
|
+
* Type for the callable callOn extension.
|
|
21
|
+
* Can be called as a function to invoke targeted callOn.
|
|
22
|
+
*/
|
|
23
|
+
export interface GGCallOnSelectorCallable {
|
|
24
|
+
<T>(target: T, ctx?: GGContext): GGTestCallOn<T>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extension that adds .callOn() as a callable to Selectors.
|
|
28
|
+
* Uses the selector's runtimes to target specific instances.
|
|
29
|
+
*
|
|
30
|
+
* Returns a callable that can be used directly: f.chain.callOn(WeatherService)
|
|
31
|
+
*/
|
|
32
|
+
export declare class GGCallOnSelector extends GGTestSelectorExtension {
|
|
33
|
+
static readonly PROPERTY_NAME = "callOn";
|
|
34
|
+
constructor(runtimes: GGTestRuntime[]);
|
|
35
|
+
}
|
|
36
|
+
declare module "@grest-ts/testkit" {
|
|
37
|
+
interface SelectorExtensions<T extends RuntimeConstructor[]> {
|
|
38
|
+
callOn: GGCallOnSelectorCallable;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export type _RuntimeConstructorRef = RuntimeConstructor;
|
|
42
|
+
//# sourceMappingURL=GGCallOnSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGCallOnSelector.d.ts","sourceRoot":"","sources":["../../../src/callOn/GGCallOnSelector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAiB,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAiB,YAAY,EAAC,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACrC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;CACpD;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,uBAAuB;IAEzD,gBAAuB,aAAa,YAAY;gBAEpC,QAAQ,EAAE,aAAa,EAAE;CAQxC;AAGD,OAAO,QAAQ,mBAAmB,CAAC;IAE/B,UAAU,kBAAkB,CAAC,CAAC,SAAS,kBAAkB,EAAE;QACvD,MAAM,EAAE,wBAAwB,CAAC;KACpC;CACJ;AAGD,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selector extension that adds targeted callOn to selectors.
|
|
3
|
+
*
|
|
4
|
+
* This allows explicitly targeting specific runtimes when multiple
|
|
5
|
+
* different runtime classes have the same service registered.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const f = GGTest.startWorker({chain: ChainRuntime, weather: WeatherOnlyRuntime});
|
|
9
|
+
*
|
|
10
|
+
* // Both have WeatherService - explicitly target one:
|
|
11
|
+
* await f.chain.callOn(WeatherService).getWeather("Test").toMatchObject({...})
|
|
12
|
+
* await f.weather.callOn(WeatherService).getWeather("Test").toMatchObject({...})
|
|
13
|
+
*/
|
|
14
|
+
import { GGTestSelector, GGTestSelectorExtension } from "../testers/GGTestSelector.js";
|
|
15
|
+
import { callOnTargeted } from "./callOn.js";
|
|
16
|
+
/**
|
|
17
|
+
* Extension that adds .callOn() as a callable to Selectors.
|
|
18
|
+
* Uses the selector's runtimes to target specific instances.
|
|
19
|
+
*
|
|
20
|
+
* Returns a callable that can be used directly: f.chain.callOn(WeatherService)
|
|
21
|
+
*/
|
|
22
|
+
export class GGCallOnSelector extends GGTestSelectorExtension {
|
|
23
|
+
static PROPERTY_NAME = "callOn";
|
|
24
|
+
constructor(runtimes) {
|
|
25
|
+
super(runtimes);
|
|
26
|
+
// Return a callable function instead of this instance
|
|
27
|
+
const callable = (target, ctx) => {
|
|
28
|
+
return callOnTargeted(target, runtimes, ctx);
|
|
29
|
+
};
|
|
30
|
+
return callable;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Register the extension
|
|
34
|
+
GGTestSelector.addExtension(GGCallOnSelector);
|
|
35
|
+
//# sourceMappingURL=GGCallOnSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGCallOnSelector.js","sourceRoot":"","sources":["../../../src/callOn/GGCallOnSelector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,cAAc,EAAE,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAElF,OAAO,EAAC,cAAc,EAAe,MAAM,UAAU,CAAC;AAWtD;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,uBAAuB;IAElD,MAAM,CAAU,aAAa,GAAG,QAAQ,CAAC;IAEhD,YAAY,QAAyB;QACjC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,sDAAsD;QACtD,MAAM,QAAQ,GAAG,CAAI,MAAS,EAAE,GAAe,EAAmB,EAAE;YAChE,OAAO,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,OAAO,QAA2B,CAAC;IACvC,CAAC;;AAcL,yBAAyB;AACzB,cAAc,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patches GGContractClass.implement() to auto-register contract instances in GGLocator.
|
|
3
|
+
*
|
|
4
|
+
* This enables callOn(ContractClass) to work without each protocol (HTTP, WebSocket, etc.)
|
|
5
|
+
* needing to manually register the contract instance.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LOCATOR_KEY_PREFIX_FOR_CONTRACT = "@contract:";
|
|
8
|
+
//# sourceMappingURL=GGContractClass.implement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGContractClass.implement.d.ts","sourceRoot":"","sources":["../../../src/callOn/GGContractClass.implement.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,eAAO,MAAM,+BAA+B,eAAe,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patches GGContractClass.implement() to auto-register contract instances in GGLocator.
|
|
3
|
+
*
|
|
4
|
+
* This enables callOn(ContractClass) to work without each protocol (HTTP, WebSocket, etc.)
|
|
5
|
+
* needing to manually register the contract instance.
|
|
6
|
+
*/
|
|
7
|
+
import { GGContractClass } from "@grest-ts/schema";
|
|
8
|
+
import { GGLocator, GGLocatorKey } from "@grest-ts/locator";
|
|
9
|
+
// Store the original implement method
|
|
10
|
+
const originalImplement = GGContractClass.prototype.implement;
|
|
11
|
+
export const LOCATOR_KEY_PREFIX_FOR_CONTRACT = "@contract:";
|
|
12
|
+
/**
|
|
13
|
+
* Patched implement() that registers the returned client in GGLocator.
|
|
14
|
+
*/
|
|
15
|
+
GGContractClass.prototype.implement = function (instance, options) {
|
|
16
|
+
const contractName = this.name;
|
|
17
|
+
// Get the client from original implement
|
|
18
|
+
const client = originalImplement.call(this, instance, options);
|
|
19
|
+
// Register in GGLocator for callOn(Contract) access
|
|
20
|
+
const scope = GGLocator.tryGetScope();
|
|
21
|
+
if (scope) {
|
|
22
|
+
const key = new GGLocatorKey(LOCATOR_KEY_PREFIX_FOR_CONTRACT + contractName);
|
|
23
|
+
if (scope.has(key)) {
|
|
24
|
+
throw new Error(`Contract '${contractName}' is already registered in this scope. ` +
|
|
25
|
+
`If you need multiple instances, use different contract names.`);
|
|
26
|
+
}
|
|
27
|
+
scope.set(key, client);
|
|
28
|
+
}
|
|
29
|
+
return client;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=GGContractClass.implement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGContractClass.implement.js","sourceRoot":"","sources":["../../../src/callOn/GGContractClass.implement.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAC,SAAS,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE1D,sCAAsC;AACtC,MAAM,iBAAiB,GAAG,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC;AAE9D,MAAM,CAAC,MAAM,+BAA+B,GAAG,YAAY,CAAA;AAE3D;;GAEG;AACH,eAAe,CAAC,SAAS,CAAC,SAAS,GAAG,UAElC,QAAa,EACb,OAAa;IAEb,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC;IAE/B,yCAAyC;IACzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE/D,oDAAoD;IACpD,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,KAAK,EAAE,CAAC;QACR,MAAM,GAAG,GAAG,IAAI,YAAY,CAAgB,+BAA+B,GAAG,YAAY,CAAC,CAAC;QAC5F,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACX,aAAa,YAAY,yCAAyC;gBAClE,+DAA+D,CAClE,CAAC;QACN,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test action for invoking methods via GGLocator lookup.
|
|
3
|
+
*
|
|
4
|
+
* Used for:
|
|
5
|
+
* - @testable services (key: @testable:ClassName)
|
|
6
|
+
* - Direct contract calls (key: @contract:ContractName)
|
|
7
|
+
* - Custom GGLocatorKey lookups
|
|
8
|
+
*
|
|
9
|
+
* Extends GGTestAction to support .with() for mocks/spies and
|
|
10
|
+
* response expectations like .toMatchObject(), .toEqual().
|
|
11
|
+
*/
|
|
12
|
+
import { GGTestAction, tActionRawData } from "../testers/GGTestAction";
|
|
13
|
+
import { GGContext } from "@grest-ts/context";
|
|
14
|
+
import type { GGTestRuntime } from "../GGTestRuntime";
|
|
15
|
+
/**
|
|
16
|
+
* Action for invoking a method via GGLocator lookup over IPC.
|
|
17
|
+
*
|
|
18
|
+
* @typeParam T - The expected return type of the method
|
|
19
|
+
*/
|
|
20
|
+
export declare class GGTestActionForLocatorOnCall<T> extends GGTestAction<T> {
|
|
21
|
+
private readonly keyName;
|
|
22
|
+
private readonly methodName;
|
|
23
|
+
private readonly args;
|
|
24
|
+
private readonly targetRuntimes?;
|
|
25
|
+
constructor(ctx: GGContext, keyName: string, methodName: string, args: any[], targetRuntimes?: GGTestRuntime[]);
|
|
26
|
+
protected executeAction(): Promise<tActionRawData>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=GGTestActionForLocatorOnCall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestActionForLocatorOnCall.d.ts","sourceRoot":"","sources":["../../../src/callOn/GGTestActionForLocatorOnCall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAC,YAAY,EAAsB,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAIzF,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAuBpD;;;;GAIG;AACH,qBAAa,4BAA4B,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAkB;gBAEtC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,EAAE,aAAa,EAAE;cAmB9F,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC;CA8D3D"}
|