@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.
Files changed (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -0
  3. package/dist/src/GGBundleTest.d.ts +8 -0
  4. package/dist/src/GGBundleTest.d.ts.map +1 -0
  5. package/dist/src/GGBundleTest.js +75 -0
  6. package/dist/src/GGBundleTest.js.map +1 -0
  7. package/dist/src/GGTest.d.ts +131 -0
  8. package/dist/src/GGTest.d.ts.map +1 -0
  9. package/dist/src/GGTest.js +245 -0
  10. package/dist/src/GGTest.js.map +1 -0
  11. package/dist/src/GGTestContext.d.ts +36 -0
  12. package/dist/src/GGTestContext.d.ts.map +1 -0
  13. package/dist/src/GGTestContext.js +63 -0
  14. package/dist/src/GGTestContext.js.map +1 -0
  15. package/dist/src/GGTestRunner.d.ts +108 -0
  16. package/dist/src/GGTestRunner.d.ts.map +1 -0
  17. package/dist/src/GGTestRunner.js +242 -0
  18. package/dist/src/GGTestRunner.js.map +1 -0
  19. package/dist/src/GGTestRuntime.d.ts +103 -0
  20. package/dist/src/GGTestRuntime.d.ts.map +1 -0
  21. package/dist/src/GGTestRuntime.js +219 -0
  22. package/dist/src/GGTestRuntime.js.map +1 -0
  23. package/dist/src/GGTestRuntimeWorker.d.ts +41 -0
  24. package/dist/src/GGTestRuntimeWorker.d.ts.map +1 -0
  25. package/dist/src/GGTestRuntimeWorker.js +136 -0
  26. package/dist/src/GGTestRuntimeWorker.js.map +1 -0
  27. package/dist/src/GGTestSharedRef.d.ts +35 -0
  28. package/dist/src/GGTestSharedRef.d.ts.map +1 -0
  29. package/dist/src/GGTestSharedRef.js +126 -0
  30. package/dist/src/GGTestSharedRef.js.map +1 -0
  31. package/dist/src/GGTestkitExtensionsDiscovery.d.ts +21 -0
  32. package/dist/src/GGTestkitExtensionsDiscovery.d.ts.map +1 -0
  33. package/dist/src/GGTestkitExtensionsDiscovery.js +24 -0
  34. package/dist/src/GGTestkitExtensionsDiscovery.js.map +1 -0
  35. package/dist/src/IGGLocalDiscoveryServer.d.ts +16 -0
  36. package/dist/src/IGGLocalDiscoveryServer.d.ts.map +1 -0
  37. package/dist/src/IGGLocalDiscoveryServer.js +2 -0
  38. package/dist/src/IGGLocalDiscoveryServer.js.map +1 -0
  39. package/dist/src/callOn/GGCallOnSelector.d.ts +42 -0
  40. package/dist/src/callOn/GGCallOnSelector.d.ts.map +1 -0
  41. package/dist/src/callOn/GGCallOnSelector.js +35 -0
  42. package/dist/src/callOn/GGCallOnSelector.js.map +1 -0
  43. package/dist/src/callOn/GGContractClass.implement.d.ts +8 -0
  44. package/dist/src/callOn/GGContractClass.implement.d.ts.map +1 -0
  45. package/dist/src/callOn/GGContractClass.implement.js +31 -0
  46. package/dist/src/callOn/GGContractClass.implement.js.map +1 -0
  47. package/dist/src/callOn/GGTestActionForLocatorOnCall.d.ts +28 -0
  48. package/dist/src/callOn/GGTestActionForLocatorOnCall.d.ts.map +1 -0
  49. package/dist/src/callOn/GGTestActionForLocatorOnCall.js +118 -0
  50. package/dist/src/callOn/GGTestActionForLocatorOnCall.js.map +1 -0
  51. package/dist/src/callOn/TestableIPC.d.ts +72 -0
  52. package/dist/src/callOn/TestableIPC.d.ts.map +1 -0
  53. package/dist/src/callOn/TestableIPC.js +34 -0
  54. package/dist/src/callOn/TestableIPC.js.map +1 -0
  55. package/dist/src/callOn/callOn.d.ts +113 -0
  56. package/dist/src/callOn/callOn.d.ts.map +1 -0
  57. package/dist/src/callOn/callOn.js +122 -0
  58. package/dist/src/callOn/callOn.js.map +1 -0
  59. package/dist/src/callOn/registerOnCallHandler.d.ts +13 -0
  60. package/dist/src/callOn/registerOnCallHandler.d.ts.map +1 -0
  61. package/dist/src/callOn/registerOnCallHandler.js +111 -0
  62. package/dist/src/callOn/registerOnCallHandler.js.map +1 -0
  63. package/dist/src/index-node.d.ts +35 -0
  64. package/dist/src/index-node.d.ts.map +1 -0
  65. package/dist/src/index-node.js +50 -0
  66. package/dist/src/index-node.js.map +1 -0
  67. package/dist/src/mockable/GGMockable.d.ts +19 -0
  68. package/dist/src/mockable/GGMockable.d.ts.map +1 -0
  69. package/dist/src/mockable/GGMockable.js +2 -0
  70. package/dist/src/mockable/GGMockable.js.map +1 -0
  71. package/dist/src/mockable/GGMockableCall.d.ts +2 -0
  72. package/dist/src/mockable/GGMockableCall.d.ts.map +1 -0
  73. package/dist/src/mockable/GGMockableCall.js +41 -0
  74. package/dist/src/mockable/GGMockableCall.js.map +1 -0
  75. package/dist/src/mockable/GGMockableIPC.d.ts +17 -0
  76. package/dist/src/mockable/GGMockableIPC.d.ts.map +1 -0
  77. package/dist/src/mockable/GGMockableIPC.js +8 -0
  78. package/dist/src/mockable/GGMockableIPC.js.map +1 -0
  79. package/dist/src/mockable/GGMockableInterceptor.d.ts +24 -0
  80. package/dist/src/mockable/GGMockableInterceptor.d.ts.map +1 -0
  81. package/dist/src/mockable/GGMockableInterceptor.js +32 -0
  82. package/dist/src/mockable/GGMockableInterceptor.js.map +1 -0
  83. package/dist/src/mockable/GGMockableInterceptorsServer.d.ts +12 -0
  84. package/dist/src/mockable/GGMockableInterceptorsServer.d.ts.map +1 -0
  85. package/dist/src/mockable/GGMockableInterceptorsServer.js +55 -0
  86. package/dist/src/mockable/GGMockableInterceptorsServer.js.map +1 -0
  87. package/dist/src/mockable/mockable.d.ts +46 -0
  88. package/dist/src/mockable/mockable.d.ts.map +1 -0
  89. package/dist/src/mockable/mockable.js +47 -0
  90. package/dist/src/mockable/mockable.js.map +1 -0
  91. package/dist/src/runner/InlineRunner.d.ts +12 -0
  92. package/dist/src/runner/InlineRunner.d.ts.map +1 -0
  93. package/dist/src/runner/InlineRunner.js +42 -0
  94. package/dist/src/runner/InlineRunner.js.map +1 -0
  95. package/dist/src/runner/IsolatedRunner.d.ts +17 -0
  96. package/dist/src/runner/IsolatedRunner.d.ts.map +1 -0
  97. package/dist/src/runner/IsolatedRunner.js +155 -0
  98. package/dist/src/runner/IsolatedRunner.js.map +1 -0
  99. package/dist/src/runner/RuntimeRunner.d.ts +14 -0
  100. package/dist/src/runner/RuntimeRunner.d.ts.map +1 -0
  101. package/dist/src/runner/RuntimeRunner.js +2 -0
  102. package/dist/src/runner/RuntimeRunner.js.map +1 -0
  103. package/dist/src/runner/WorkerRunner.d.ts +17 -0
  104. package/dist/src/runner/WorkerRunner.d.ts.map +1 -0
  105. package/dist/src/runner/WorkerRunner.js +155 -0
  106. package/dist/src/runner/WorkerRunner.js.map +1 -0
  107. package/dist/src/runner/isolated-loader.mjs +91 -0
  108. package/dist/src/runner/worker-loader.mjs +49 -0
  109. package/dist/src/testers/GGCallInterceptor.d.ts +71 -0
  110. package/dist/src/testers/GGCallInterceptor.d.ts.map +1 -0
  111. package/dist/src/testers/GGCallInterceptor.js +170 -0
  112. package/dist/src/testers/GGCallInterceptor.js.map +1 -0
  113. package/dist/src/testers/GGMockWith.d.ts +30 -0
  114. package/dist/src/testers/GGMockWith.d.ts.map +1 -0
  115. package/dist/src/testers/GGMockWith.js +70 -0
  116. package/dist/src/testers/GGMockWith.js.map +1 -0
  117. package/dist/src/testers/GGSpyWith.d.ts +40 -0
  118. package/dist/src/testers/GGSpyWith.d.ts.map +1 -0
  119. package/dist/src/testers/GGSpyWith.js +90 -0
  120. package/dist/src/testers/GGSpyWith.js.map +1 -0
  121. package/dist/src/testers/GGTestAction.d.ts +126 -0
  122. package/dist/src/testers/GGTestAction.d.ts.map +1 -0
  123. package/dist/src/testers/GGTestAction.js +245 -0
  124. package/dist/src/testers/GGTestAction.js.map +1 -0
  125. package/dist/src/testers/GGTestComponent.d.ts +15 -0
  126. package/dist/src/testers/GGTestComponent.d.ts.map +1 -0
  127. package/dist/src/testers/GGTestComponent.js +2 -0
  128. package/dist/src/testers/GGTestComponent.js.map +1 -0
  129. package/dist/src/testers/GGTestSelector.d.ts +54 -0
  130. package/dist/src/testers/GGTestSelector.d.ts.map +1 -0
  131. package/dist/src/testers/GGTestSelector.js +179 -0
  132. package/dist/src/testers/GGTestSelector.js.map +1 -0
  133. package/dist/src/testers/IGGTestInterceptor.d.ts +8 -0
  134. package/dist/src/testers/IGGTestInterceptor.d.ts.map +1 -0
  135. package/dist/src/testers/IGGTestInterceptor.js +2 -0
  136. package/dist/src/testers/IGGTestInterceptor.js.map +1 -0
  137. package/dist/src/testers/IGGTestWith.d.ts +13 -0
  138. package/dist/src/testers/IGGTestWith.d.ts.map +1 -0
  139. package/dist/src/testers/IGGTestWith.js +2 -0
  140. package/dist/src/testers/IGGTestWith.js.map +1 -0
  141. package/dist/src/testers/RuntimeSelector.d.ts +117 -0
  142. package/dist/src/testers/RuntimeSelector.d.ts.map +1 -0
  143. package/dist/src/testers/RuntimeSelector.js +2 -0
  144. package/dist/src/testers/RuntimeSelector.js.map +1 -0
  145. package/dist/src/tsconfig.json +17 -0
  146. package/dist/src/utils/GGExpectations.d.ts +18 -0
  147. package/dist/src/utils/GGExpectations.d.ts.map +1 -0
  148. package/dist/src/utils/GGExpectations.js +59 -0
  149. package/dist/src/utils/GGExpectations.js.map +1 -0
  150. package/dist/src/utils/GGTestError.d.ts +13 -0
  151. package/dist/src/utils/GGTestError.d.ts.map +1 -0
  152. package/dist/src/utils/GGTestError.js +26 -0
  153. package/dist/src/utils/GGTestError.js.map +1 -0
  154. package/dist/src/utils/captureStack.d.ts +9 -0
  155. package/dist/src/utils/captureStack.d.ts.map +1 -0
  156. package/dist/src/utils/captureStack.js +51 -0
  157. package/dist/src/utils/captureStack.js.map +1 -0
  158. package/dist/tsconfig.publish.tsbuildinfo +1 -0
  159. package/package.json +66 -0
  160. package/src/GGBundleTest.ts +89 -0
  161. package/src/GGTest.ts +318 -0
  162. package/src/GGTestContext.ts +74 -0
  163. package/src/GGTestRunner.ts +308 -0
  164. package/src/GGTestRuntime.ts +265 -0
  165. package/src/GGTestRuntimeWorker.ts +159 -0
  166. package/src/GGTestSharedRef.ts +116 -0
  167. package/src/GGTestkitExtensionsDiscovery.ts +26 -0
  168. package/src/IGGLocalDiscoveryServer.ts +16 -0
  169. package/src/callOn/GGCallOnSelector.ts +61 -0
  170. package/src/callOn/GGContractClass.implement.ts +43 -0
  171. package/src/callOn/GGTestActionForLocatorOnCall.ts +134 -0
  172. package/src/callOn/TestableIPC.ts +81 -0
  173. package/src/callOn/callOn.ts +224 -0
  174. package/src/callOn/registerOnCallHandler.ts +123 -0
  175. package/src/index-node.ts +64 -0
  176. package/src/mockable/GGMockable.ts +22 -0
  177. package/src/mockable/GGMockableCall.ts +45 -0
  178. package/src/mockable/GGMockableIPC.ts +20 -0
  179. package/src/mockable/GGMockableInterceptor.ts +44 -0
  180. package/src/mockable/GGMockableInterceptorsServer.ts +69 -0
  181. package/src/mockable/mockable.ts +71 -0
  182. package/src/runner/InlineRunner.ts +47 -0
  183. package/src/runner/IsolatedRunner.ts +179 -0
  184. package/src/runner/RuntimeRunner.ts +15 -0
  185. package/src/runner/WorkerRunner.ts +179 -0
  186. package/src/runner/isolated-loader.mjs +91 -0
  187. package/src/runner/worker-loader.mjs +49 -0
  188. package/src/testers/GGCallInterceptor.ts +224 -0
  189. package/src/testers/GGMockWith.ts +92 -0
  190. package/src/testers/GGSpyWith.ts +115 -0
  191. package/src/testers/GGTestAction.ts +333 -0
  192. package/src/testers/GGTestComponent.ts +16 -0
  193. package/src/testers/GGTestSelector.ts +223 -0
  194. package/src/testers/IGGTestInterceptor.ts +11 -0
  195. package/src/testers/IGGTestWith.ts +15 -0
  196. package/src/testers/RuntimeSelector.ts +151 -0
  197. package/src/tsconfig.json +17 -0
  198. package/src/utils/GGExpectations.ts +78 -0
  199. package/src/utils/GGTestError.ts +37 -0
  200. package/src/utils/captureStack.ts +54 -0
@@ -0,0 +1,118 @@
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 } from "../testers/GGTestAction.js";
13
+ import { GG_TEST_RUNNER } from "../GGTestRunner.js";
14
+ import { TestableIPC } from "./TestableIPC.js";
15
+ import { GGTestError } from "../utils/GGTestError.js";
16
+ /**
17
+ * Serialize a GGContext to a plain object for IPC transfer.
18
+ * Flattens the context hierarchy into a single object.
19
+ */
20
+ function serializeContext(ctx) {
21
+ const result = {};
22
+ // Access the private values map via type assertion
23
+ const ctxAny = ctx;
24
+ if (ctxAny.values instanceof Map) {
25
+ for (const [key, value] of ctxAny.values) {
26
+ result[key] = value;
27
+ }
28
+ }
29
+ // Also serialize parent context values (child values take precedence)
30
+ if (ctxAny.parent) {
31
+ const parentValues = serializeContext(ctxAny.parent);
32
+ return { ...parentValues, ...result };
33
+ }
34
+ return result;
35
+ }
36
+ /**
37
+ * Action for invoking a method via GGLocator lookup over IPC.
38
+ *
39
+ * @typeParam T - The expected return type of the method
40
+ */
41
+ export class GGTestActionForLocatorOnCall extends GGTestAction {
42
+ keyName;
43
+ methodName;
44
+ args;
45
+ targetRuntimes;
46
+ constructor(ctx, keyName, methodName, args, targetRuntimes) {
47
+ const config = {
48
+ noResponse: false,
49
+ logData: {
50
+ message: `[${keyName}.${methodName}]`,
51
+ request: args.length > 0 ? args : undefined
52
+ }
53
+ };
54
+ super(ctx, config);
55
+ this.keyName = keyName;
56
+ this.methodName = methodName;
57
+ this.args = args;
58
+ this.targetRuntimes = targetRuntimes;
59
+ }
60
+ // -------------------------------------------------
61
+ // Action execution
62
+ // -------------------------------------------------
63
+ async executeAction() {
64
+ const runner = GG_TEST_RUNNER.get();
65
+ // Use target runtimes if provided, otherwise all runtimes
66
+ const searchRuntimes = this.targetRuntimes ?? runner.getAllRuntimes();
67
+ // Find runtimes that have this key registered
68
+ const candidates = searchRuntimes.filter(r => r.hasLocatorKey(this.keyName));
69
+ if (candidates.length === 0) {
70
+ // No runtime has this key - provide helpful error
71
+ const allRuntimes = runner.getAllRuntimes();
72
+ if (allRuntimes.length === 0) {
73
+ throw new GGTestError({
74
+ test: `No runtimes available to invoke ${this.keyName}.${this.methodName}`,
75
+ expected: "At least one runtime to be started",
76
+ received: "No runtimes found"
77
+ });
78
+ }
79
+ throw new GGTestError({
80
+ test: `Instance '${this.keyName}' not found in any runtime`,
81
+ expected: `A @testable instance registered with key '${this.keyName}'`,
82
+ received: `Key not registered in any of ${allRuntimes.length} runtime(s): ${allRuntimes.map(r => r.name).join(', ')}`
83
+ });
84
+ }
85
+ if (candidates.length > 1) {
86
+ // Check if all candidates are the same runtime class - if so, just use first one
87
+ const uniqueClassNames = new Set(candidates.map(r => r.className));
88
+ if (uniqueClassNames.size > 1) {
89
+ // Different runtime classes have this key - actual ambiguity
90
+ throw new GGTestError({
91
+ test: `Multiple different runtimes have '${this.keyName}' registered`,
92
+ expected: `Key '${this.keyName}' to be unique across different runtime classes, or use explicit runtime targeting`,
93
+ received: `Found in ${candidates.length} runtimes with different classes: ${[...uniqueClassNames].join(', ')}`
94
+ });
95
+ }
96
+ // Same runtime class - just use first instance (they're identical)
97
+ }
98
+ // Exactly one runtime has this key - send IPC directly
99
+ const runtime = candidates[0];
100
+ const context = this.ctx ? serializeContext(this.ctx) : undefined;
101
+ const result = await runtime.sendCommand(TestableIPC.invoke, {
102
+ keyName: this.keyName,
103
+ methodName: this.methodName,
104
+ args: this.args,
105
+ context
106
+ });
107
+ if (result.success) {
108
+ return result.result;
109
+ }
110
+ throw new GGTestError({
111
+ test: `Error invoking ${this.keyName}.${this.methodName}`,
112
+ expected: "Method to execute successfully",
113
+ received: result.error || "Unknown error",
114
+ extra: result.stack
115
+ });
116
+ }
117
+ }
118
+ //# sourceMappingURL=GGTestActionForLocatorOnCall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGTestActionForLocatorOnCall.js","sourceRoot":"","sources":["../../../src/callOn/GGTestActionForLocatorOnCall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * IPC protocol definitions for GGLocator-based service invocation.
3
+ *
4
+ * Defines the messages exchanged between test runner and runtime worker
5
+ * for invoking methods on registered instances (@testable, @contract, etc.).
6
+ */
7
+ /**
8
+ * Serialized context data for IPC transfer.
9
+ * Contains flattened key-value pairs from GGContext.
10
+ */
11
+ export type SerializedContext = Record<string, any>;
12
+ /**
13
+ * Payload for invoking a method on a registered instance.
14
+ */
15
+ export interface TestableInvokePayload {
16
+ /** The GGLocatorKey name (e.g., "@testable:ServiceB", "@contract:ChainApi", or custom key) */
17
+ keyName: string;
18
+ /** The method name to invoke */
19
+ methodName: string;
20
+ /** Arguments to pass to the method (as array) */
21
+ args: any[];
22
+ /** Serialized GGContext data to restore on the worker side */
23
+ context?: SerializedContext;
24
+ }
25
+ /**
26
+ * Result from invoking a testable method.
27
+ */
28
+ export interface TestableInvokeResult {
29
+ /** Whether the invocation succeeded */
30
+ success: boolean;
31
+ /** The return value from the method (if success) */
32
+ result?: any;
33
+ /** Error message (if failed) */
34
+ error?: string;
35
+ /** Error stack trace (if failed) */
36
+ stack?: string;
37
+ }
38
+ /**
39
+ * Payload for registering locator keys from a runtime.
40
+ */
41
+ export interface KeyRegistrationPayload {
42
+ /** Runtime ID sending the registration */
43
+ runtimeId: string;
44
+ /** All GGLocatorKey names registered in this runtime */
45
+ keys: string[];
46
+ }
47
+ /**
48
+ * IPC endpoints for testable service invocation.
49
+ */
50
+ export declare const TestableIPC: {
51
+ /**
52
+ * Messages FROM test server TO worker.
53
+ */
54
+ client: {
55
+ /**
56
+ * Invoke a method on a testable service instance.
57
+ */
58
+ invoke: import("@grest-ts/ipc").IPCClientRequest<TestableInvokePayload, TestableInvokeResult>;
59
+ };
60
+ /**
61
+ * Messages FROM worker TO test server.
62
+ */
63
+ server: {
64
+ /**
65
+ * Register all locator keys available in a runtime.
66
+ * Sent from worker to test runner after compose completes.
67
+ */
68
+ registerKeys: import("@grest-ts/ipc").IPCServerRequest<KeyRegistrationPayload, void>;
69
+ };
70
+ invoke: import("@grest-ts/ipc").IPCClientRequest<TestableInvokePayload, TestableInvokeResult>;
71
+ };
72
+ //# sourceMappingURL=TestableIPC.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestableIPC.d.ts","sourceRoot":"","sources":["../../../src/callOn/TestableIPC.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,8DAA8D;IAC9D,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,IAAI,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;IACpB;;OAEG;;QAEC;;WAEG;;;IAIP;;OAEG;;QAEC;;;WAGG;;;;CAMV,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * IPC protocol definitions for GGLocator-based service invocation.
3
+ *
4
+ * Defines the messages exchanged between test runner and runtime worker
5
+ * for invoking methods on registered instances (@testable, @contract, etc.).
6
+ */
7
+ import { IPCClient, IPCServer } from "@grest-ts/ipc";
8
+ /**
9
+ * IPC endpoints for testable service invocation.
10
+ */
11
+ export const TestableIPC = {
12
+ /**
13
+ * Messages FROM test server TO worker.
14
+ */
15
+ client: {
16
+ /**
17
+ * Invoke a method on a testable service instance.
18
+ */
19
+ invoke: IPCClient.defineRequest("testable/invoke"),
20
+ },
21
+ /**
22
+ * Messages FROM worker TO test server.
23
+ */
24
+ server: {
25
+ /**
26
+ * Register all locator keys available in a runtime.
27
+ * Sent from worker to test runner after compose completes.
28
+ */
29
+ registerKeys: IPCServer.defineRequest("testable/register-keys"),
30
+ },
31
+ // Legacy alias for backwards compatibility
32
+ invoke: IPCClient.defineRequest("testable/invoke"),
33
+ };
34
+ //# sourceMappingURL=TestableIPC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestableIPC.js","sourceRoot":"","sources":["../../../src/callOn/TestableIPC.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,eAAe,CAAC;AA8CnD;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB;;OAEG;IACH,MAAM,EAAE;QACJ;;WAEG;QACH,MAAM,EAAE,SAAS,CAAC,aAAa,CAA8C,iBAAiB,CAAC;KAClG;IAED;;OAEG;IACH,MAAM,EAAE;QACJ;;;WAGG;QACH,YAAY,EAAE,SAAS,CAAC,aAAa,CAA+B,wBAAwB,CAAC;KAChG;IAED,2CAA2C;IAC3C,MAAM,EAAE,SAAS,CAAC,aAAa,CAA8C,iBAAiB,CAAC;CAClG,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Unified callOn function for invoking methods on runtime instances.
3
+ *
4
+ * Works with:
5
+ * - @testable classes: Direct service invocation via IPC
6
+ * - GGLocatorKey: Direct instance lookup via IPC
7
+ * - GGContractClass: Contract implementation lookup via IPC
8
+ * - Contract holders (HTTP APIs, etc.): Delegated to their own factory
9
+ *
10
+ * @example
11
+ * // Call @testable service
12
+ * await callOn(MyService).doSomething("hello")
13
+ *
14
+ * // Call HTTP API (goes through HTTP transport)
15
+ * await callOn(ChainApi).quickWeatherCheck({city: "NYC"})
16
+ *
17
+ * // Call contract directly (skips HTTP, uses IPC)
18
+ * await callOn(ChainApiContract).quickWeatherCheck({city: "NYC"})
19
+ *
20
+ * // With context
21
+ * await callOn(MyService, ctx).doSomething("hello")
22
+ */
23
+ import { GGLocatorKey } from "@grest-ts/locator";
24
+ import { GGTestActionForLocatorOnCall } from "./GGTestActionForLocatorOnCall";
25
+ import { GGContractApiDefinition, GGContractClass, GGContractMethod } from "@grest-ts/schema";
26
+ import { GGContext } from "@grest-ts/context";
27
+ import type { GGTestRuntime } from "../GGTestRuntime";
28
+ /**
29
+ * Symbol used by contract holders (HTTP APIs, WebSocket APIs, etc.) to provide
30
+ * their own callOn proxy. This allows protocols to control how calls are made
31
+ * without callOn needing to know about specific protocols.
32
+ *
33
+ * The factory can return anything - there's no constraint on the return type.
34
+ * Each protocol fully controls what methods and types are available.
35
+ */
36
+ export declare const CALL_ON_FACTORY: unique symbol;
37
+ /**
38
+ * Marker interface for targets that provide their own callOn proxy.
39
+ * The factory can return any type - protocols have full control.
40
+ */
41
+ export interface GGCallOnFactory {
42
+ [CALL_ON_FACTORY](ctx?: GGContext): unknown;
43
+ }
44
+ /**
45
+ * Maps a class's async methods to GGLocatorLookupTestAction calls.
46
+ * Used for @testable classes and GGLocatorKey lookups.
47
+ */
48
+ export type LocatorLookupAccess<T> = {
49
+ [K in keyof T]: T[K] extends (...args: infer A) => Promise<infer R> ? (...args: A) => GGTestActionForLocatorOnCall<R> : never;
50
+ };
51
+ /**
52
+ * Maps contract methods to GGLocatorLookupTestAction calls.
53
+ * Used for direct GGContractClass lookups via IPC.
54
+ */
55
+ export type ContractLocatorAccess<TContract> = {
56
+ [K in keyof TContract]: TContract[K] extends GGContractMethod<infer Input, infer Output> ? Input extends undefined ? () => GGTestActionForLocatorOnCall<Output> : (data: Input) => GGTestActionForLocatorOnCall<Output> : never;
57
+ };
58
+ export type GGTestCallOnCollection<T> = {
59
+ [K in keyof T]: GGTestCallOn<T[K]>;
60
+ };
61
+ /**
62
+ * Resolves the return type for callOn(target):
63
+ * - Factory targets → extract factory's return type (protocol controls everything)
64
+ * - GGContractClass → ContractLocatorAccess (IPC)
65
+ * - Constructor/GGLocatorKey → LocatorLookupAccess (IPC)
66
+ * - Plain objects → recurse into properties
67
+ */
68
+ export type GGTestCallOn<T> = T extends {
69
+ [CALL_ON_FACTORY]: (ctx?: GGContext) => infer R;
70
+ } ? R : T extends GGContractClass<infer TContract> ? ContractLocatorAccess<TContract> : T extends GGLocatorKey<infer Instance> ? LocatorLookupAccess<Instance> : T extends new (...args: any[]) => infer Instance ? LocatorLookupAccess<Instance> : T extends object ? {
71
+ [K in keyof T]: GGTestCallOn<T[K]>;
72
+ } : never;
73
+ /**
74
+ * Invoke methods on runtime instances via a unified interface.
75
+ *
76
+ * Resolution order:
77
+ * 1. Factory symbol (HTTP APIs, WebSocket APIs provide their own)
78
+ * 2. GGContractClass → IPC lookup via @contract: prefix
79
+ * 3. GGLocatorKey → IPC lookup via key name
80
+ * 4. Simple class → IPC lookup via @testable: prefix
81
+ *
82
+ * @example
83
+ * await callOn(MyService, ctx).doSomething("hello")
84
+ * await callOn(ChainApi, ctx).quickWeatherCheck({city: "NYC"})
85
+ * await callOn(ChainApiContract, ctx).quickWeatherCheck({city: "NYC"})
86
+ */
87
+ export declare function callOn<T extends GGCallOnFactory>(target: T, ctx?: GGContext): GGTestCallOn<T>;
88
+ export declare function callOn<T extends GGContractApiDefinition>(target: GGContractClass<T>, ctx?: GGContext): ContractLocatorAccess<T>;
89
+ export declare function callOn<T>(target: GGLocatorKey<T>, ctx?: GGContext): LocatorLookupAccess<T>;
90
+ export declare function callOn<T extends new (...args: any[]) => any>(target: T, ctx?: GGContext): LocatorLookupAccess<InstanceType<T>>;
91
+ export declare function callOn<T extends object>(target: T, ctx?: GGContext): GGTestCallOn<T>;
92
+ /**
93
+ * Invoke methods on runtime instances, targeting specific runtimes.
94
+ * Use this when you need to explicitly select which runtime to call
95
+ * when multiple different runtime classes have the same service.
96
+ *
97
+ * @param target - The target to call (class, GGLocatorKey, or GGContractClass)
98
+ * @param runtimes - The specific runtimes to target
99
+ * @param ctx - Optional context for the call
100
+ *
101
+ * @example
102
+ * const f = GGTest.startWorker({chain: ChainRuntime, weather: WeatherOnlyRuntime});
103
+ * // Both have WeatherService - explicitly target one:
104
+ * await f.chain.callOn(WeatherService).getWeather("Test")
105
+ */
106
+ export declare function callOnTargeted<T>(target: T, runtimes: GGTestRuntime[], ctx?: GGContext): GGTestCallOn<T>;
107
+ /**
108
+ * Process a collection of targets and create callOn proxies for each.
109
+ * It can be a recursive object where all "testable things" are replaced with callOn(X) handlers.
110
+ * {serviceA: ApiA, sub: { serviceB: ApiB}} -> {serviceA: callOn(ApiA), sub: { serviceB: callOn(ApiB)}}
111
+ */
112
+ export declare function callOnCollection<T extends object | any[]>(target: T, ctx?: GGContext): GGTestCallOnCollection<T>;
113
+ //# sourceMappingURL=callOn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callOn.d.ts","sourceRoot":"","sources":["../../../src/callOn/callOn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Unified callOn function for invoking methods on runtime instances.
3
+ *
4
+ * Works with:
5
+ * - @testable classes: Direct service invocation via IPC
6
+ * - GGLocatorKey: Direct instance lookup via IPC
7
+ * - GGContractClass: Contract implementation lookup via IPC
8
+ * - Contract holders (HTTP APIs, etc.): Delegated to their own factory
9
+ *
10
+ * @example
11
+ * // Call @testable service
12
+ * await callOn(MyService).doSomething("hello")
13
+ *
14
+ * // Call HTTP API (goes through HTTP transport)
15
+ * await callOn(ChainApi).quickWeatherCheck({city: "NYC"})
16
+ *
17
+ * // Call contract directly (skips HTTP, uses IPC)
18
+ * await callOn(ChainApiContract).quickWeatherCheck({city: "NYC"})
19
+ *
20
+ * // With context
21
+ * await callOn(MyService, ctx).doSomething("hello")
22
+ */
23
+ import { GGLocatorKey } from "@grest-ts/locator";
24
+ import { GGTestActionForLocatorOnCall } from "./GGTestActionForLocatorOnCall.js";
25
+ import { LOCATOR_KEY_PREFIX_FOR_TESTABLE } from "@grest-ts/testkit-runtime";
26
+ import { GGContractClass } from "@grest-ts/schema";
27
+ import { GGContext } from "@grest-ts/context";
28
+ import { LOCATOR_KEY_PREFIX_FOR_CONTRACT } from "./GGContractClass.implement.js";
29
+ // ============================================================================
30
+ // Factory symbol for protocol-specific callOn support
31
+ // ============================================================================
32
+ /**
33
+ * Symbol used by contract holders (HTTP APIs, WebSocket APIs, etc.) to provide
34
+ * their own callOn proxy. This allows protocols to control how calls are made
35
+ * without callOn needing to know about specific protocols.
36
+ *
37
+ * The factory can return anything - there's no constraint on the return type.
38
+ * Each protocol fully controls what methods and types are available.
39
+ */
40
+ export const CALL_ON_FACTORY = Symbol.for("gg:callOnFactory");
41
+ // ============================================================================
42
+ // The callOn function
43
+ // ============================================================================
44
+ /**
45
+ * Check if target implements the CALL_ON_FACTORY interface.
46
+ */
47
+ function hasCallOnFactory(target) {
48
+ return target != null && typeof target[CALL_ON_FACTORY] === 'function';
49
+ }
50
+ /**
51
+ * Check if target is a simple class (constructor function).
52
+ */
53
+ function isSimpleClass(value) {
54
+ return typeof value === 'function' && value.prototype !== undefined && value.prototype.constructor === value;
55
+ }
56
+ export function callOn(target, ctx) {
57
+ ctx ??= new GGContext("Test");
58
+ if (hasCallOnFactory(target)) {
59
+ return target[CALL_ON_FACTORY](ctx);
60
+ }
61
+ const keyName = resolveKeyName(target);
62
+ return createCallOnProxy(keyName, ctx);
63
+ }
64
+ // ============================================================================
65
+ // Helper functions for key resolution
66
+ // ============================================================================
67
+ /**
68
+ * Resolve a target to its locator key name.
69
+ * Handles GGContractClass, GGLocatorKey, and simple classes.
70
+ */
71
+ function resolveKeyName(target) {
72
+ if (target instanceof GGContractClass) {
73
+ return LOCATOR_KEY_PREFIX_FOR_CONTRACT + target.name;
74
+ }
75
+ if (target instanceof GGLocatorKey) {
76
+ return target.name;
77
+ }
78
+ if (isSimpleClass(target)) {
79
+ return LOCATOR_KEY_PREFIX_FOR_TESTABLE + target.name;
80
+ }
81
+ throw new Error(`Unknown callOn target: ${target?.name ?? target?.constructor?.name ?? typeof target}`);
82
+ }
83
+ /**
84
+ * Create a proxy that intercepts method calls and returns GGTestActionForLocatorOnCall.
85
+ */
86
+ function createCallOnProxy(keyName, ctx, targetRuntimes) {
87
+ return new Proxy({}, {
88
+ get(_, methodName) {
89
+ return (...args) => new GGTestActionForLocatorOnCall(ctx, keyName, methodName, args, targetRuntimes);
90
+ }
91
+ });
92
+ }
93
+ export function callOnTargeted(target, runtimes, ctx) {
94
+ ctx ??= new GGContext("Test");
95
+ // Factory targets don't support runtime targeting - they control their own routing
96
+ if (hasCallOnFactory(target)) {
97
+ return target[CALL_ON_FACTORY](ctx);
98
+ }
99
+ const keyName = resolveKeyName(target);
100
+ return createCallOnProxy(keyName, ctx, runtimes);
101
+ }
102
+ /**
103
+ * Process a collection of targets and create callOn proxies for each.
104
+ * It can be a recursive object where all "testable things" are replaced with callOn(X) handlers.
105
+ * {serviceA: ApiA, sub: { serviceB: ApiB}} -> {serviceA: callOn(ApiA), sub: { serviceB: callOn(ApiB)}}
106
+ */
107
+ export function callOnCollection(target, ctx) {
108
+ const result = Array.isArray(target) ? [] : {};
109
+ for (const key in target) {
110
+ const value = target[key];
111
+ if (value != null) {
112
+ if (hasCallOnFactory(value) || value instanceof GGContractClass || value instanceof GGLocatorKey || isSimpleClass(value)) {
113
+ result[key] = callOn(value, ctx);
114
+ }
115
+ else if (typeof value === 'object') {
116
+ result[key] = callOnCollection(value, ctx);
117
+ }
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+ //# sourceMappingURL=callOn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callOn.js","sourceRoot":"","sources":["../../../src/callOn/callOn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Worker-side handler for GGLocator-based service invocation.
3
+ *
4
+ * Receives IPC requests from tests to invoke methods on registered instances
5
+ * (@testable, @contract, etc.) and returns the results.
6
+ */
7
+ import { GGTestRuntimeWorker } from "../GGTestRuntimeWorker";
8
+ /**
9
+ * Register the locator lookup handler on the worker.
10
+ * Called during worker initialization.
11
+ */
12
+ export declare function registerOnCallHandler(worker: GGTestRuntimeWorker): void;
13
+ //# sourceMappingURL=registerOnCallHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerOnCallHandler.d.ts","sourceRoot":"","sources":["../../../src/callOn/registerOnCallHandler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAC,mBAAmB,EAAC,MAAM,wBAAwB,CAAC;AAsB3D;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CA8DvE"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Worker-side handler for GGLocator-based service invocation.
3
+ *
4
+ * Receives IPC requests from tests to invoke methods on registered instances
5
+ * (@testable, @contract, etc.) and returns the results.
6
+ */
7
+ import { GGLocator, GGLocatorKey } from "@grest-ts/locator";
8
+ import { GGLog } from "@grest-ts/logger";
9
+ import { TestableIPC } from "./TestableIPC.js";
10
+ import { GGContext } from "@grest-ts/context";
11
+ /**
12
+ * Context for logging
13
+ */
14
+ const LOG_CONTEXT = { name: "GGLocatorWorkerHandler" };
15
+ /**
16
+ * Deserialize context data into a GGContext.
17
+ * Directly populates the internal values map.
18
+ */
19
+ function deserializeContext(data) {
20
+ const ctx = new GGContext("ipc-context");
21
+ // Access internal values map and populate directly
22
+ const ctxAny = ctx;
23
+ for (const [keyName, value] of Object.entries(data)) {
24
+ ctxAny.values.set(keyName, value);
25
+ }
26
+ return ctx;
27
+ }
28
+ /**
29
+ * Register the locator lookup handler on the worker.
30
+ * Called during worker initialization.
31
+ */
32
+ export function registerOnCallHandler(worker) {
33
+ worker.onIpcRequest(TestableIPC.invoke, async (payload) => {
34
+ const { keyName, methodName, args, context } = payload;
35
+ GGLog.debug(LOG_CONTEXT, `Invoking ${keyName}.${methodName}`, { args, hasContext: !!context });
36
+ try {
37
+ // Look up the instance in the current scope
38
+ const scope = GGLocator.tryGetScope();
39
+ if (!scope) {
40
+ return {
41
+ success: false,
42
+ error: `No GGLocator scope available - is the runtime running?`
43
+ };
44
+ }
45
+ const key = new GGLocatorKey(keyName);
46
+ const instance = scope.tryGet(key);
47
+ if (!instance) {
48
+ return {
49
+ success: false,
50
+ error: `Instance '${keyName}' not found in GGLocator. ` +
51
+ `Make sure the class is decorated with @testable or registered during compose().`
52
+ };
53
+ }
54
+ // Check if method exists
55
+ const method = instance[methodName];
56
+ if (typeof method !== 'function') {
57
+ return {
58
+ success: false,
59
+ error: `Method '${methodName}' not found on instance '${keyName}'. ` +
60
+ `Available methods: ${getMethodNames(instance).join(', ')}`
61
+ };
62
+ }
63
+ // Invoke the method, optionally within the provided context
64
+ let result;
65
+ if (context) {
66
+ const ctx = deserializeContext(context);
67
+ result = await ctx.run(() => method.apply(instance, args));
68
+ }
69
+ else {
70
+ result = await method.apply(instance, args);
71
+ }
72
+ GGLog.debug(LOG_CONTEXT, `Invocation ${keyName}.${methodName} completed`, { result });
73
+ return {
74
+ success: true,
75
+ result
76
+ };
77
+ }
78
+ catch (error) {
79
+ GGLog.error(LOG_CONTEXT, `Error invoking ${keyName}.${methodName}`, error);
80
+ return {
81
+ success: false,
82
+ error: error.message || String(error),
83
+ stack: error.stack
84
+ };
85
+ }
86
+ });
87
+ }
88
+ /**
89
+ * Get method names from an instance for error messages.
90
+ */
91
+ function getMethodNames(instance) {
92
+ const names = [];
93
+ let proto = Object.getPrototypeOf(instance);
94
+ while (proto && proto !== Object.prototype) {
95
+ const propNames = Object.getOwnPropertyNames(proto)
96
+ .filter(name => {
97
+ if (name === 'constructor')
98
+ return false;
99
+ try {
100
+ return typeof proto[name] === 'function';
101
+ }
102
+ catch {
103
+ return false;
104
+ }
105
+ });
106
+ names.push(...propNames);
107
+ proto = Object.getPrototypeOf(proto);
108
+ }
109
+ return [...new Set(names)].sort();
110
+ }
111
+ //# sourceMappingURL=registerOnCallHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerOnCallHandler.js","sourceRoot":"","sources":["../../../src/callOn/registerOnCallHandler.ts"],"names":[],"mappings":"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"}