@kindgi/testing 0.1.4-rc.5 → 0.1.5-rc.0

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/README.md CHANGED
@@ -12,6 +12,9 @@ Most API tests exercise one route family and never touch the others.
12
12
  app with no database and no runtime — and any code path that reaches an
13
13
  unprovided binding fails loudly instead of silently returning nothing.
14
14
 
15
+ The helpers are defined in `@kindgi/api/testing` and re-exported here
16
+ unchanged; import from either.
17
+
15
18
  ## Exports
16
19
 
17
20
  | Export | Kind | Description |
package/dist/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * `@kindgi/testing` — test helpers for Kindgi apps and packages.
3
+ *
4
+ * The stub bindings live in `@kindgi/api/testing`, beside the
5
+ * `CreateAppInput` they stub, so `@kindgi/api`'s own tests use them with no
6
+ * dependency on this package (which would be a cycle). They're re-exported
7
+ * here unchanged.
3
8
  */
4
- export { createStubAppBindings, createStubKernelBinding, type StubAppBindings, } from './app-bindings.js';
5
- export { StubBindingError, createStubBinding, type StubMethods } from './stub-binding.js';
9
+ export { StubBindingError, createInMemoryTriggerRegistry, createStubAppBindings, createStubBinding, createStubKernelBinding, type InMemoryTriggerRegistry, type StubAppBindings, type StubMethods, } from '@kindgi/api/testing';
6
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,OAAO,EACL,gBAAgB,EAChB,6BAA6B,EAC7B,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,11 @@
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  /**
4
4
  * `@kindgi/testing` — test helpers for Kindgi apps and packages.
5
+ *
6
+ * The stub bindings live in `@kindgi/api/testing`, beside the
7
+ * `CreateAppInput` they stub, so `@kindgi/api`'s own tests use them with no
8
+ * dependency on this package (which would be a cycle). They're re-exported
9
+ * here unchanged.
5
10
  */
6
- export { createStubAppBindings, createStubKernelBinding, } from './app-bindings.js';
7
- export { StubBindingError, createStubBinding } from './stub-binding.js';
11
+ export { StubBindingError, createInMemoryTriggerRegistry, createStubAppBindings, createStubBinding, createStubKernelBinding, } from '@kindgi/api/testing';
8
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;GAEG;AAEH,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;GAOG;AAEH,OAAO,EACL,gBAAgB,EAChB,6BAA6B,EAC7B,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,GAIxB,MAAM,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/testing",
3
- "version": "0.1.4-rc.5",
3
+ "version": "0.1.5-rc.0",
4
4
  "description": "Test helpers for Kindgi apps and packages. `createStubAppBindings()` supplies every binding `createApp` requires as a typed stub that throws a descriptive `StubBindingError` if called — mount the API for contract / route-shape tests without a database or the Kindgi runtime.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -29,14 +29,10 @@
29
29
  "type-manifest.json"
30
30
  ],
31
31
  "dependencies": {
32
- "@kindgi/agents": "0.1.4-rc.5",
33
- "@kindgi/api": "0.1.4-rc.5",
34
- "@kindgi/memory": "0.1.4-rc.5",
35
- "@kindgi/platform": "0.1.4-rc.5",
36
- "@kindgi/runtime": "0.1.4-rc.5"
32
+ "@kindgi/api": "0.1.5-rc.0"
37
33
  },
38
34
  "devDependencies": {
39
- "@kindgi/types": "0.1.4-rc.5",
35
+ "@kindgi/types": "0.1.5-rc.0",
40
36
  "@types/node": "^22.10.5",
41
37
  "typescript": "^5.7.3",
42
38
  "vitest": "^2.1.8"
package/src/index.ts CHANGED
@@ -3,11 +3,20 @@
3
3
 
4
4
  /**
5
5
  * `@kindgi/testing` — test helpers for Kindgi apps and packages.
6
+ *
7
+ * The stub bindings live in `@kindgi/api/testing`, beside the
8
+ * `CreateAppInput` they stub, so `@kindgi/api`'s own tests use them with no
9
+ * dependency on this package (which would be a cycle). They're re-exported
10
+ * here unchanged.
6
11
  */
7
12
 
8
13
  export {
14
+ StubBindingError,
15
+ createInMemoryTriggerRegistry,
9
16
  createStubAppBindings,
17
+ createStubBinding,
10
18
  createStubKernelBinding,
19
+ type InMemoryTriggerRegistry,
11
20
  type StubAppBindings,
12
- } from './app-bindings.js';
13
- export { StubBindingError, createStubBinding, type StubMethods } from './stub-binding.js';
21
+ type StubMethods,
22
+ } from '@kindgi/api/testing';
@@ -1,33 +0,0 @@
1
- import type { CreateAppInput } from '@kindgi/api';
2
- import type { KernelBinding } from '@kindgi/runtime';
3
- /**
4
- * The bindings `createApp` requires that tests usually don't exercise —
5
- * everything in `CreateAppInput` that is mandatory except the
6
- * caller-specific `resolveToken` and `runHandler`.
7
- */
8
- export type StubAppBindings = Pick<CreateAppInput, 'conversationBinding' | 'runSnapshotBinding' | 'kernelBinding' | 'tenantHierarchyBinding' | 'memoryBinding' | 'provenanceBinding'>;
9
- /**
10
- * Stubs for every required `createApp` binding. Mount the API for
11
- * contract, route-shape, and handler tests without a database or the
12
- * Kindgi runtime; any route that reaches one of these bindings fails
13
- * loudly with a `StubBindingError` naming the binding and method.
14
- *
15
- * Override the ones a test needs:
16
- *
17
- * ```ts
18
- * const app = createApp({
19
- * ...createStubAppBindings(),
20
- * resolveToken,
21
- * runHandler,
22
- * agentRegistry: myInMemoryAgentRegistry,
23
- * });
24
- * ```
25
- */
26
- export declare function createStubAppBindings(): StubAppBindings;
27
- /**
28
- * Stub `KernelBinding`: each sub-binding is a stub named
29
- * `kernelBinding.<sub>`. The optional `eventBus` is omitted (absent), so
30
- * code that feature-checks it takes the no-event-bus path.
31
- */
32
- export declare function createStubKernelBinding(): KernelBinding;
33
- //# sourceMappingURL=app-bindings.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-bindings.d.ts","sourceRoot":"","sources":["../src/app-bindings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,iBAAiB,CAAC;AAIzB;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,cAAc,EACZ,qBAAqB,GACrB,oBAAoB,GACpB,eAAe,GACf,wBAAwB,GACxB,eAAe,GACf,mBAAmB,CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CA0CvD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,aAAa,CAqCvD"}
@@ -1,107 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // Copyright (C) 2026 Kindgi Inc.
3
- import { createStubBinding } from './stub-binding.js';
4
- /**
5
- * Stubs for every required `createApp` binding. Mount the API for
6
- * contract, route-shape, and handler tests without a database or the
7
- * Kindgi runtime; any route that reaches one of these bindings fails
8
- * loudly with a `StubBindingError` naming the binding and method.
9
- *
10
- * Override the ones a test needs:
11
- *
12
- * ```ts
13
- * const app = createApp({
14
- * ...createStubAppBindings(),
15
- * resolveToken,
16
- * runHandler,
17
- * agentRegistry: myInMemoryAgentRegistry,
18
- * });
19
- * ```
20
- */
21
- export function createStubAppBindings() {
22
- return {
23
- conversationBinding: createStubBinding('conversationBinding', {
24
- openConversation: true,
25
- getConversation: true,
26
- listConversations: true,
27
- listConversationsPage: true,
28
- closeConversation: true,
29
- deleteConversation: true,
30
- appendMessage: true,
31
- readMessages: true,
32
- }),
33
- runSnapshotBinding: createStubBinding('runSnapshotBinding', {
34
- write: true,
35
- read: true,
36
- }),
37
- kernelBinding: createStubKernelBinding(),
38
- tenantHierarchyBinding: createStubBinding('tenantHierarchyBinding', {
39
- createOrg: true,
40
- createTeam: true,
41
- createProject: true,
42
- addTeamMember: true,
43
- addProjectMember: true,
44
- removeTeamMember: true,
45
- updateTeamMemberRole: true,
46
- removeProjectMember: true,
47
- updateProjectMemberRole: true,
48
- getTenant: true,
49
- }),
50
- memoryBinding: createStubBinding('memoryBinding', {
51
- listFacts: true,
52
- searchByKeyword: true,
53
- searchBySemantic: true,
54
- appendLog: true,
55
- readLog: true,
56
- }),
57
- provenanceBinding: createStubBinding('provenanceBinding', {
58
- listRecords: true,
59
- getByRunId: true,
60
- getCallUsage: true,
61
- }),
62
- };
63
- }
64
- /**
65
- * Stub `KernelBinding`: each sub-binding is a stub named
66
- * `kernelBinding.<sub>`. The optional `eventBus` is omitted (absent), so
67
- * code that feature-checks it takes the no-event-bus path.
68
- */
69
- export function createStubKernelBinding() {
70
- return {
71
- run: createStubBinding('kernelBinding.run', {
72
- runGraph: true,
73
- resumeRun: true,
74
- cancelRun: true,
75
- cancelToken: true,
76
- completeToken: true,
77
- readJournal: true,
78
- startRun: true,
79
- deleteRun: true,
80
- getRun: true,
81
- listRuns: true,
82
- }),
83
- scheduler: createStubBinding('kernelBinding.scheduler', {
84
- startCronScheduler: true,
85
- startEventTriggerScheduler: true,
86
- fireByWebhookId: true,
87
- initialNextFireAt: true,
88
- }),
89
- waitpoint: createStubBinding('kernelBinding.waitpoint', {
90
- startTimeoutSleeper: true,
91
- }),
92
- retention: createStubBinding('kernelBinding.retention', {
93
- createRetentionAdapter: true,
94
- }),
95
- triggers: createStubBinding('kernelBinding.triggers', {
96
- register: true,
97
- update: true,
98
- list: true,
99
- get: true,
100
- pause: true,
101
- resume: true,
102
- unregister: true,
103
- fetchActiveByWebhookId: true,
104
- }),
105
- };
106
- }
107
- //# sourceMappingURL=app-bindings.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-bindings.js","sourceRoot":"","sources":["../src/app-bindings.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAejC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAiBtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,mBAAmB,EAAE,iBAAiB,CAAsB,qBAAqB,EAAE;YACjF,gBAAgB,EAAE,IAAI;YACtB,eAAe,EAAE,IAAI;YACrB,iBAAiB,EAAE,IAAI;YACvB,qBAAqB,EAAE,IAAI;YAC3B,iBAAiB,EAAE,IAAI;YACvB,kBAAkB,EAAE,IAAI;YACxB,aAAa,EAAE,IAAI;YACnB,YAAY,EAAE,IAAI;SACnB,CAAC;QACF,kBAAkB,EAAE,iBAAiB,CAAqB,oBAAoB,EAAE;YAC9E,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC;QACF,aAAa,EAAE,uBAAuB,EAAE;QACxC,sBAAsB,EAAE,iBAAiB,CAAyB,wBAAwB,EAAE;YAC1F,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,aAAa,EAAE,IAAI;YACnB,gBAAgB,EAAE,IAAI;YACtB,gBAAgB,EAAE,IAAI;YACtB,oBAAoB,EAAE,IAAI;YAC1B,mBAAmB,EAAE,IAAI;YACzB,uBAAuB,EAAE,IAAI;YAC7B,SAAS,EAAE,IAAI;SAChB,CAAC;QACF,aAAa,EAAE,iBAAiB,CAAqB,eAAe,EAAE;YACpE,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,IAAI;YACrB,gBAAgB,EAAE,IAAI;YACtB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;SACd,CAAC;QACF,iBAAiB,EAAE,iBAAiB,CAAsC,mBAAmB,EAAE;YAC7F,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;SACnB,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,GAAG,EAAE,iBAAiB,CAAa,mBAAmB,EAAE;YACtD,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,SAAS,EAAE,iBAAiB,CAAmB,yBAAyB,EAAE;YACxE,kBAAkB,EAAE,IAAI;YACxB,0BAA0B,EAAE,IAAI;YAChC,eAAe,EAAE,IAAI;YACrB,iBAAiB,EAAE,IAAI;SACxB,CAAC;QACF,SAAS,EAAE,iBAAiB,CAAmB,yBAAyB,EAAE;YACxE,mBAAmB,EAAE,IAAI;SAC1B,CAAC;QACF,SAAS,EAAE,iBAAiB,CAAsB,yBAAyB,EAAE;YAC3E,sBAAsB,EAAE,IAAI;SAC7B,CAAC;QACF,QAAQ,EAAE,iBAAiB,CAAyB,wBAAwB,EAAE;YAC5E,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,IAAI;YACT,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,IAAI;YAChB,sBAAsB,EAAE,IAAI;SAC7B,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1,34 +0,0 @@
1
- /**
2
- * Thrown when code under test calls a method on a stub binding. The
3
- * message names the binding and method so the fix — supply a real
4
- * implementation or a test double for that binding — is obvious.
5
- */
6
- export declare class StubBindingError extends Error {
7
- readonly binding: string;
8
- readonly method: string;
9
- constructor(binding: string, method: string);
10
- }
11
- /**
12
- * One `true` entry per method of `T`. Typed as a complete mapping, so a
13
- * method added to the interface (or a stale one left behind) fails to
14
- * compile at the stub definition instead of slipping through at runtime.
15
- */
16
- export type StubMethods<T> = {
17
- readonly [K in keyof T]-?: true;
18
- };
19
- /**
20
- * Build a stub implementation of the binding interface `T`: every method
21
- * listed in `methods` throws {@link StubBindingError} when called.
22
- *
23
- * ```ts
24
- * const memory = createStubBinding<MemoryQueryBinding>('memoryBinding', {
25
- * listFacts: true,
26
- * searchByKeyword: true,
27
- * searchBySemantic: true,
28
- * appendLog: true,
29
- * readLog: true,
30
- * });
31
- * ```
32
- */
33
- export declare function createStubBinding<T extends object>(name: string, methods: StubMethods<T>): T;
34
- //# sourceMappingURL=stub-binding.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stub-binding.d.ts","sourceRoot":"","sources":["../src/stub-binding.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAS5C;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;CAAE,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAQ5F"}
@@ -1,42 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // Copyright (C) 2026 Kindgi Inc.
3
- /**
4
- * Thrown when code under test calls a method on a stub binding. The
5
- * message names the binding and method so the fix — supply a real
6
- * implementation or a test double for that binding — is obvious.
7
- */
8
- export class StubBindingError extends Error {
9
- binding;
10
- method;
11
- constructor(binding, method) {
12
- super(`${binding}.${method}() was called on a stub binding from @kindgi/testing. ` +
13
- `Pass a real implementation or a test double for \`${binding}\` to exercise this code path.`);
14
- this.name = 'StubBindingError';
15
- this.binding = binding;
16
- this.method = method;
17
- }
18
- }
19
- /**
20
- * Build a stub implementation of the binding interface `T`: every method
21
- * listed in `methods` throws {@link StubBindingError} when called.
22
- *
23
- * ```ts
24
- * const memory = createStubBinding<MemoryQueryBinding>('memoryBinding', {
25
- * listFacts: true,
26
- * searchByKeyword: true,
27
- * searchBySemantic: true,
28
- * appendLog: true,
29
- * readLog: true,
30
- * });
31
- * ```
32
- */
33
- export function createStubBinding(name, methods) {
34
- const stub = {};
35
- for (const method of Object.keys(methods)) {
36
- stub[method] = () => {
37
- throw new StubBindingError(name, method);
38
- };
39
- }
40
- return stub;
41
- }
42
- //# sourceMappingURL=stub-binding.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stub-binding.js","sourceRoot":"","sources":["../src/stub-binding.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,OAAO,CAAS;IAChB,MAAM,CAAS;IAExB,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CACH,GAAG,OAAO,IAAI,MAAM,wDAAwD;YAC1E,qDAAqD,OAAO,gCAAgC,CAC/F,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AASD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAmB,IAAY,EAAE,OAAuB;IACvF,MAAM,IAAI,GAAgC,EAAE,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE;YAClB,MAAM,IAAI,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,IAAS,CAAC;AACnB,CAAC"}
@@ -1,137 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // Copyright (C) 2026 Kindgi Inc.
3
-
4
- import type { ConversationBinding, RunSnapshotBinding } from '@kindgi/agents';
5
- import type { CreateAppInput } from '@kindgi/api';
6
- import type { MemoryQueryBinding } from '@kindgi/memory';
7
- import type { TenantHierarchyBinding } from '@kindgi/platform';
8
- import type {
9
- KernelBinding,
10
- RunBinding,
11
- RunRetentionBinding,
12
- SchedulerBinding,
13
- TriggerRegistryBinding,
14
- WaitpointBinding,
15
- } from '@kindgi/runtime';
16
-
17
- import { createStubBinding } from './stub-binding.js';
18
-
19
- /**
20
- * The bindings `createApp` requires that tests usually don't exercise —
21
- * everything in `CreateAppInput` that is mandatory except the
22
- * caller-specific `resolveToken` and `runHandler`.
23
- */
24
- export type StubAppBindings = Pick<
25
- CreateAppInput,
26
- | 'conversationBinding'
27
- | 'runSnapshotBinding'
28
- | 'kernelBinding'
29
- | 'tenantHierarchyBinding'
30
- | 'memoryBinding'
31
- | 'provenanceBinding'
32
- >;
33
-
34
- /**
35
- * Stubs for every required `createApp` binding. Mount the API for
36
- * contract, route-shape, and handler tests without a database or the
37
- * Kindgi runtime; any route that reaches one of these bindings fails
38
- * loudly with a `StubBindingError` naming the binding and method.
39
- *
40
- * Override the ones a test needs:
41
- *
42
- * ```ts
43
- * const app = createApp({
44
- * ...createStubAppBindings(),
45
- * resolveToken,
46
- * runHandler,
47
- * agentRegistry: myInMemoryAgentRegistry,
48
- * });
49
- * ```
50
- */
51
- export function createStubAppBindings(): StubAppBindings {
52
- return {
53
- conversationBinding: createStubBinding<ConversationBinding>('conversationBinding', {
54
- openConversation: true,
55
- getConversation: true,
56
- listConversations: true,
57
- listConversationsPage: true,
58
- closeConversation: true,
59
- deleteConversation: true,
60
- appendMessage: true,
61
- readMessages: true,
62
- }),
63
- runSnapshotBinding: createStubBinding<RunSnapshotBinding>('runSnapshotBinding', {
64
- write: true,
65
- read: true,
66
- }),
67
- kernelBinding: createStubKernelBinding(),
68
- tenantHierarchyBinding: createStubBinding<TenantHierarchyBinding>('tenantHierarchyBinding', {
69
- createOrg: true,
70
- createTeam: true,
71
- createProject: true,
72
- addTeamMember: true,
73
- addProjectMember: true,
74
- removeTeamMember: true,
75
- updateTeamMemberRole: true,
76
- removeProjectMember: true,
77
- updateProjectMemberRole: true,
78
- getTenant: true,
79
- }),
80
- memoryBinding: createStubBinding<MemoryQueryBinding>('memoryBinding', {
81
- listFacts: true,
82
- searchByKeyword: true,
83
- searchBySemantic: true,
84
- appendLog: true,
85
- readLog: true,
86
- }),
87
- provenanceBinding: createStubBinding<CreateAppInput['provenanceBinding']>('provenanceBinding', {
88
- listRecords: true,
89
- getByRunId: true,
90
- getCallUsage: true,
91
- }),
92
- };
93
- }
94
-
95
- /**
96
- * Stub `KernelBinding`: each sub-binding is a stub named
97
- * `kernelBinding.<sub>`. The optional `eventBus` is omitted (absent), so
98
- * code that feature-checks it takes the no-event-bus path.
99
- */
100
- export function createStubKernelBinding(): KernelBinding {
101
- return {
102
- run: createStubBinding<RunBinding>('kernelBinding.run', {
103
- runGraph: true,
104
- resumeRun: true,
105
- cancelRun: true,
106
- cancelToken: true,
107
- completeToken: true,
108
- readJournal: true,
109
- startRun: true,
110
- deleteRun: true,
111
- getRun: true,
112
- listRuns: true,
113
- }),
114
- scheduler: createStubBinding<SchedulerBinding>('kernelBinding.scheduler', {
115
- startCronScheduler: true,
116
- startEventTriggerScheduler: true,
117
- fireByWebhookId: true,
118
- initialNextFireAt: true,
119
- }),
120
- waitpoint: createStubBinding<WaitpointBinding>('kernelBinding.waitpoint', {
121
- startTimeoutSleeper: true,
122
- }),
123
- retention: createStubBinding<RunRetentionBinding>('kernelBinding.retention', {
124
- createRetentionAdapter: true,
125
- }),
126
- triggers: createStubBinding<TriggerRegistryBinding>('kernelBinding.triggers', {
127
- register: true,
128
- update: true,
129
- list: true,
130
- get: true,
131
- pause: true,
132
- resume: true,
133
- unregister: true,
134
- fetchActiveByWebhookId: true,
135
- }),
136
- };
137
- }
@@ -1,53 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // Copyright (C) 2026 Kindgi Inc.
3
-
4
- /**
5
- * Thrown when code under test calls a method on a stub binding. The
6
- * message names the binding and method so the fix — supply a real
7
- * implementation or a test double for that binding — is obvious.
8
- */
9
- export class StubBindingError extends Error {
10
- readonly binding: string;
11
- readonly method: string;
12
-
13
- constructor(binding: string, method: string) {
14
- super(
15
- `${binding}.${method}() was called on a stub binding from @kindgi/testing. ` +
16
- `Pass a real implementation or a test double for \`${binding}\` to exercise this code path.`,
17
- );
18
- this.name = 'StubBindingError';
19
- this.binding = binding;
20
- this.method = method;
21
- }
22
- }
23
-
24
- /**
25
- * One `true` entry per method of `T`. Typed as a complete mapping, so a
26
- * method added to the interface (or a stale one left behind) fails to
27
- * compile at the stub definition instead of slipping through at runtime.
28
- */
29
- export type StubMethods<T> = { readonly [K in keyof T]-?: true };
30
-
31
- /**
32
- * Build a stub implementation of the binding interface `T`: every method
33
- * listed in `methods` throws {@link StubBindingError} when called.
34
- *
35
- * ```ts
36
- * const memory = createStubBinding<MemoryQueryBinding>('memoryBinding', {
37
- * listFacts: true,
38
- * searchByKeyword: true,
39
- * searchBySemantic: true,
40
- * appendLog: true,
41
- * readLog: true,
42
- * });
43
- * ```
44
- */
45
- export function createStubBinding<T extends object>(name: string, methods: StubMethods<T>): T {
46
- const stub: Record<string, () => never> = {};
47
- for (const method of Object.keys(methods)) {
48
- stub[method] = () => {
49
- throw new StubBindingError(name, method);
50
- };
51
- }
52
- return stub as T;
53
- }