@olane/o-test 0.7.12

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 (60) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +400 -0
  3. package/dist/src/builders/index.d.ts +7 -0
  4. package/dist/src/builders/index.d.ts.map +1 -0
  5. package/dist/src/builders/index.js +6 -0
  6. package/dist/src/builders/leader-child-builder.d.ts +50 -0
  7. package/dist/src/builders/leader-child-builder.d.ts.map +1 -0
  8. package/dist/src/builders/leader-child-builder.js +59 -0
  9. package/dist/src/builders/manager-worker-builder.d.ts +49 -0
  10. package/dist/src/builders/manager-worker-builder.d.ts.map +1 -0
  11. package/dist/src/builders/manager-worker-builder.js +79 -0
  12. package/dist/src/builders/simple-node-builder.d.ts +49 -0
  13. package/dist/src/builders/simple-node-builder.d.ts.map +1 -0
  14. package/dist/src/builders/simple-node-builder.js +66 -0
  15. package/dist/src/example-tool.tool.d.ts +58 -0
  16. package/dist/src/example-tool.tool.d.ts.map +1 -0
  17. package/dist/src/example-tool.tool.js +89 -0
  18. package/dist/src/fixtures/index.d.ts +6 -0
  19. package/dist/src/fixtures/index.d.ts.map +1 -0
  20. package/dist/src/fixtures/index.js +5 -0
  21. package/dist/src/fixtures/mock-data.d.ts +201 -0
  22. package/dist/src/fixtures/mock-data.d.ts.map +1 -0
  23. package/dist/src/fixtures/mock-data.js +180 -0
  24. package/dist/src/fixtures/test-methods.d.ts +33 -0
  25. package/dist/src/fixtures/test-methods.d.ts.map +1 -0
  26. package/dist/src/fixtures/test-methods.js +185 -0
  27. package/dist/src/index.d.ts +18 -0
  28. package/dist/src/index.d.ts.map +1 -0
  29. package/dist/src/index.js +25 -0
  30. package/dist/src/methods/example.methods.d.ts +9 -0
  31. package/dist/src/methods/example.methods.d.ts.map +1 -0
  32. package/dist/src/methods/example.methods.js +50 -0
  33. package/dist/src/test-environment.d.ts +185 -0
  34. package/dist/src/test-environment.d.ts.map +1 -0
  35. package/dist/src/test-environment.js +260 -0
  36. package/dist/src/utils/assertions.d.ts +159 -0
  37. package/dist/src/utils/assertions.d.ts.map +1 -0
  38. package/dist/src/utils/assertions.js +201 -0
  39. package/dist/src/utils/chunk-capture.d.ts +108 -0
  40. package/dist/src/utils/chunk-capture.d.ts.map +1 -0
  41. package/dist/src/utils/chunk-capture.js +156 -0
  42. package/dist/src/utils/index.d.ts +8 -0
  43. package/dist/src/utils/index.d.ts.map +1 -0
  44. package/dist/src/utils/index.js +7 -0
  45. package/dist/src/utils/mock-factories.d.ts +211 -0
  46. package/dist/src/utils/mock-factories.d.ts.map +1 -0
  47. package/dist/src/utils/mock-factories.js +181 -0
  48. package/dist/src/utils/wait-for.d.ts +42 -0
  49. package/dist/src/utils/wait-for.d.ts.map +1 -0
  50. package/dist/src/utils/wait-for.js +59 -0
  51. package/dist/test/example.spec.d.ts +1 -0
  52. package/dist/test/example.spec.d.ts.map +1 -0
  53. package/dist/test/example.spec.js +240 -0
  54. package/dist/test/fixtures/mock-data.d.ts +1 -0
  55. package/dist/test/fixtures/mock-data.d.ts.map +1 -0
  56. package/dist/test/fixtures/mock-data.js +90 -0
  57. package/dist/test/test-environment.spec.d.ts +8 -0
  58. package/dist/test/test-environment.spec.d.ts.map +1 -0
  59. package/dist/test/test-environment.spec.js +393 -0
  60. package/package.json +87 -0
package/LICENSE ADDED
@@ -0,0 +1,33 @@
1
+ # Dual License: MIT OR Apache-2.0
2
+
3
+ Copyright (c) 2025 Olane Inc.
4
+
5
+ Olane OS is dual-licensed under your choice of either:
6
+
7
+ - **MIT License** (LICENSE-MIT or https://opensource.org/licenses/MIT)
8
+ - **Apache License, Version 2.0** (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
9
+
10
+ ## Why Dual Licensing?
11
+
12
+ Dual licensing provides developers with flexibility when integrating Olane OS into their projects:
13
+
14
+ - **Choose MIT**: If you prefer a simple, permissive license without patent provisions
15
+ - **Choose Apache 2.0**: If you desire explicit patent protection and other features of the Apache license
16
+
17
+ You may choose either license to govern your use of this software.
18
+
19
+ ## License Terms
20
+
21
+ ### MIT License
22
+ The MIT license is very permissive and allows users to do almost anything with the software, including using, copying, modifying, merging, publishing, distributing, and selling it. The primary requirement is that the original copyright and license notice must be included in all copies of the software.
23
+
24
+ See LICENSE-MIT for the full license text.
25
+
26
+ ### Apache License 2.0
27
+ The Apache License 2.0 is also a permissive free software license. It grants users the right to use, modify, and distribute the software. It also includes provisions regarding patent grants, which are not present in the MIT license.
28
+
29
+ See LICENSE-APACHE for the full license text.
30
+
31
+ ## Contributing
32
+
33
+ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual-licensed as above, without any additional terms or conditions.
package/README.md ADDED
@@ -0,0 +1,400 @@
1
+ # @olane/o-test
2
+
3
+ > Testing utilities and best practices for O-Network node development
4
+
5
+ ## ⚠️ Important: We Use Mocha, Not Jest
6
+
7
+ Since O-Network is built on the **libp2p ecosystem**, we use **aegir** with **Mocha** for testing (NOT Jest).
8
+
9
+ - ✅ Use: `aegir`, `chai`, Mocha syntax (`before`, `after`, `.to.equal()`)
10
+ - ❌ Don't use: `jest`, `@types/jest`, `ts-jest`
11
+
12
+ See [MOCHA-MIGRATION.md](./MOCHA-MIGRATION.md) for migration guide.
13
+
14
+ ## Overview
15
+
16
+ `@olane/o-test` provides comprehensive testing guidelines, utilities, and examples for building reliable O-Network nodes in the Olane OS ecosystem.
17
+
18
+ ## Quick Start
19
+
20
+ ### Installation
21
+
22
+ ```bash
23
+ # From your package directory
24
+ pnpm install --save-dev @olane/o-test
25
+
26
+ # Install testing dependencies (aegir uses Mocha internally)
27
+ pnpm install --save-dev aegir chai
28
+ ```
29
+
30
+ **Important:** Since we're using the **libp2p ecosystem**, we use **aegir** as our test runner, which uses **Mocha** (not Jest). Do not install Jest dependencies.
31
+
32
+ ### Basic Test Structure
33
+
34
+ ```typescript
35
+ import 'dotenv/config';
36
+ import { describe, it, before, after } from 'mocha';
37
+ import { expect } from 'chai';
38
+ import { oLeaderNode } from '@olane/o-leader';
39
+ import { MyTool } from '../src/my-tool.tool.js';
40
+
41
+ describe('MyTool', () => {
42
+ let leaderNode: oLeaderNode;
43
+ let tool: MyTool;
44
+
45
+ before(async () => {
46
+ // Create leader
47
+ leaderNode = new oLeaderNode({
48
+ parent: null,
49
+ leader: null,
50
+ });
51
+ await leaderNode.start();
52
+
53
+ // Create tool
54
+ tool = new MyTool({
55
+ parent: leaderNode.address,
56
+ leader: leaderNode.address,
57
+ });
58
+
59
+ // Register with parent
60
+ (tool as any).hookInitializeFinished = () => {
61
+ leaderNode.addChildNode(tool);
62
+ };
63
+
64
+ await tool.start();
65
+ });
66
+
67
+ after(async () => {
68
+ await tool.stop();
69
+ await leaderNode.stop();
70
+ });
71
+
72
+ it('should start successfully', () => {
73
+ expect(tool.state).to.equal(NodeState.RUNNING);
74
+ });
75
+
76
+ it('should execute method', async () => {
77
+ const result = await tool.useSelf({
78
+ method: 'my_method',
79
+ params: { test: 'value' },
80
+ });
81
+
82
+ expect(result.success).to.be.true;
83
+ expect(result.result.data).to.exist;
84
+ });
85
+ });
86
+ ```
87
+
88
+ ## Documentation
89
+
90
+ ### 📚 [Complete Testing Guide](./TESTING.md)
91
+
92
+ Comprehensive guide covering:
93
+ - Testing philosophy and baseline requirements
94
+ - Testing stack and configuration
95
+ - Lifecycle, method, and parent-child testing patterns
96
+ - Error handling and validation tests
97
+ - Test helpers and utilities
98
+ - CI/CD integration
99
+ - Common pitfalls and troubleshooting
100
+
101
+ ### 🔄 [Jest to Mocha Migration Guide](./MOCHA-MIGRATION.md)
102
+
103
+ Quick reference for converting tests from Jest to Mocha:
104
+ - Side-by-side syntax comparison
105
+ - Complete code examples
106
+ - Common pitfalls and solutions
107
+ - Quick reference table
108
+
109
+ ## Baseline Requirements
110
+
111
+ Every O-Network package **must** have:
112
+
113
+ | Requirement | File/Location |
114
+ |-------------|---------------|
115
+ | Test directory | `/test/` |
116
+ | Lifecycle test | `test/lifecycle.spec.ts` |
117
+ | Method tests | `test/methods.spec.ts` |
118
+ | Aegir config | `.aegir.js` (optional) |
119
+ | Test script | `"test": "aegir test"` in package.json |
120
+
121
+ **Note:** No Jest configuration needed - aegir uses Mocha internally for the libp2p ecosystem.
122
+
123
+ ## Minimum Test Coverage
124
+
125
+ -  All nodes must have lifecycle tests (start/stop)
126
+ -  All public methods (`_tool_*`) must have happy path tests
127
+ -  All required parameters must have validation tests
128
+ -  Parent-child patterns must test registration and routing
129
+ -  Critical error paths must be tested
130
+
131
+ ## Running Tests
132
+
133
+ ```bash
134
+ # Run all tests
135
+ pnpm test
136
+
137
+ # Run in watch mode
138
+ pnpm test:watch
139
+
140
+ # Run specific test file
141
+ pnpm test test/lifecycle.spec.ts
142
+
143
+ # Run with coverage
144
+ pnpm test -- --coverage
145
+ ```
146
+
147
+ ## Configuration Files
148
+
149
+ ### `.aegir.js` (Optional)
150
+
151
+ Aegir works out of the box with sensible defaults. Configuration is only needed for customization:
152
+
153
+ ```javascript
154
+ export default {
155
+ test: {
156
+ target: ['node'], // or ['browser'], or ['node', 'browser']
157
+ },
158
+ build: {
159
+ bundlesizeMax: '100KB',
160
+ },
161
+ };
162
+ ```
163
+
164
+ **Important for libp2p ecosystem:**
165
+ - ✅ Aegir uses **Mocha** as the test runner (not Jest)
166
+ - ✅ Use Mocha syntax: `before`, `after`, `beforeEach`, `afterEach`
167
+ - ✅ Use Chai assertions: `expect().to.equal()`, `expect().to.exist`, etc.
168
+ - ❌ Do NOT install or use `jest`, `@types/jest`, or `ts-jest`
169
+
170
+ ## Critical Testing Rules
171
+
172
+ ###  DO:
173
+
174
+ - Load environment with `import 'dotenv/config'`
175
+ - Use `.js` extensions in imports (ESM requirement)
176
+ - Create leader node before child nodes
177
+ - Inject `hookInitializeFinished` for parent-child registration
178
+ - Clean up all nodes in `afterEach`
179
+ - Access response data via `result.result.data`
180
+ - Test both success and error paths
181
+
182
+ ### L DON'T:
183
+
184
+ - Override `start()` method (use hooks instead)
185
+ - Forget to call `stop()` on nodes
186
+ - Access `result.data` directly (use `result.result.data`)
187
+ - Use mocks for node instances (use real nodes)
188
+ - Share mutable state between tests
189
+
190
+ ## Testing Philosophy
191
+
192
+ We prioritize **practical, integration-oriented tests** that validate real node behavior:
193
+
194
+ -  Real node instances over mocks
195
+ -  Actual lifecycle management
196
+ -  Parent-child relationships
197
+ -  Simple, focused test cases
198
+ -  Integration over unit isolation
199
+
200
+ ## Test Patterns
201
+
202
+ ### Lifecycle Testing
203
+
204
+ ```typescript
205
+ it('should start and stop successfully', async () => {
206
+ const node = new MyTool({
207
+ parent: null,
208
+ leader: null,
209
+ });
210
+
211
+ await node.start();
212
+ expect(node.state).to.equal(NodeState.RUNNING);
213
+
214
+ await node.stop();
215
+ expect(node.state).to.equal(NodeState.STOPPED);
216
+ });
217
+ ```
218
+
219
+ ### Method Testing
220
+
221
+ ```typescript
222
+ it('should validate required parameters', async () => {
223
+ const result = await tool.useSelf({
224
+ method: 'my_method',
225
+ params: {}, // Missing required params
226
+ });
227
+
228
+ expect(result.success).to.be.false;
229
+ expect(result.error).to.include('required');
230
+ });
231
+ ```
232
+
233
+ ### Parent-Child Testing
234
+
235
+ ```typescript
236
+ it('should create and route to child', async () => {
237
+ // Create child
238
+ const createResult = await manager.useSelf({
239
+ method: 'create_worker',
240
+ params: { workerId: 'worker-1' },
241
+ });
242
+ expect(createResult.success).to.be.true;
243
+
244
+ // Route to child
245
+ const routeResult = await manager.useSelf({
246
+ method: 'use_worker',
247
+ params: {
248
+ workerId: 'worker-1',
249
+ method: 'process_task',
250
+ params: { data: 'test' },
251
+ },
252
+ });
253
+ expect(routeResult.success).to.be.true;
254
+ });
255
+ ```
256
+
257
+ ## Common Pitfalls
258
+
259
+ ### Pitfall 1: Missing Hook Injection
260
+
261
+ ```typescript
262
+ // L WRONG
263
+ const tool = new MyTool({ parent: leader.address, leader: leader.address });
264
+ await tool.start(); // Child not registered!
265
+
266
+ //  CORRECT
267
+ const tool = new MyTool({ parent: leader.address, leader: leader.address });
268
+ (tool as any).hookInitializeFinished = () => {
269
+ leaderNode.addChildNode(tool);
270
+ };
271
+ await tool.start();
272
+ ```
273
+
274
+ ### Pitfall 2: No Cleanup
275
+
276
+ ```typescript
277
+ // L WRONG
278
+ it('test', async () => {
279
+ const tool = new MyTool({});
280
+ await tool.start();
281
+ // No cleanup - nodes leak!
282
+ });
283
+
284
+ //  CORRECT
285
+ afterEach(async () => {
286
+ if (tool) await tool.stop();
287
+ if (leader) await leader.stop();
288
+ });
289
+ ```
290
+
291
+ ### Pitfall 3: Wrong Response Access
292
+
293
+ ```typescript
294
+ // L WRONG
295
+ const data = result.data; // undefined!
296
+
297
+ //  CORRECT
298
+ const data = result.result.data;
299
+ ```
300
+
301
+ ## Test Helpers
302
+
303
+ Create shared utilities for common patterns:
304
+
305
+ ```typescript
306
+ // test/helpers/test-utils.ts
307
+ export async function createToolWithLeader<T>(
308
+ ToolClass: new (config: any) => T,
309
+ config: any = {}
310
+ ): Promise<{ leader: oLeaderNode; tool: T }> {
311
+ const leader = new oLeaderNode({ parent: null, leader: null });
312
+ await leader.start();
313
+
314
+ const tool = new ToolClass({
315
+ ...config,
316
+ parent: leader.address,
317
+ leader: leader.address,
318
+ });
319
+
320
+ (tool as any).hookInitializeFinished = () => {
321
+ leader.addChildNode(tool as any);
322
+ };
323
+
324
+ await (tool as any).start();
325
+
326
+ return { leader, tool };
327
+ }
328
+ ```
329
+
330
+ ## Example Tests
331
+
332
+ See the `test/` directory for complete examples:
333
+
334
+ - `test/lifecycle.spec.ts` - Node lifecycle testing
335
+ - `test/methods.spec.ts` - Method validation and execution
336
+ - `test/parent-child.spec.ts` - Manager/worker pattern testing
337
+ - `test/helpers/` - Shared test utilities
338
+
339
+ ## Resources
340
+
341
+ - [TESTING.md](./TESTING.md) - Complete testing guide
342
+ - [CLAUDE.md](./CLAUDE.md) - O-Network node development guide
343
+ - [Olane Documentation](https://docs.olane.ai) - Full ecosystem docs
344
+
345
+ ## Package Structure
346
+
347
+ ```
348
+ o-test/
349
+  src/
350
+   index.ts # Public exports
351
+   example-tool.tool.ts # Example tool implementation
352
+   methods/
353
+   example.methods.ts # Method definitions
354
+  test/
355
+   lifecycle.spec.ts # Lifecycle tests
356
+   methods.spec.ts # Method tests
357
+   parent-child.spec.ts # Parent-child tests
358
+   helpers/
359
+    test-utils.ts # Test utilities
360
+   fixtures/
361
+   mock-data.ts # Test data
362
+  jest.config.js # Jest configuration
363
+  .aegir.js # Aegir configuration
364
+  tsconfig.json # TypeScript configuration
365
+  package.json # Package metadata
366
+  README.md # This file
367
+  TESTING.md # Complete testing guide
368
+  CLAUDE.md # Development guide
369
+ ```
370
+
371
+ ## Contributing
372
+
373
+ When adding tests:
374
+
375
+ 1. Follow the patterns in [TESTING.md](./TESTING.md)
376
+ 2. Ensure all baseline requirements are met
377
+ 3. Test both success and error paths
378
+ 4. Clean up all resources
379
+ 5. Use descriptive test names
380
+
381
+ ## License
382
+
383
+ See the root LICENSE file in the Olane monorepo.
384
+
385
+ ## Support
386
+
387
+ - GitHub Issues: [olane/issues](https://github.com/olane-labs/olane/issues)
388
+ - Documentation: [docs.olane.ai](https://docs.olane.ai)
389
+ - Community: [Discord](https://discord.gg/olane)
390
+
391
+ ---
392
+
393
+ **Remember:**
394
+ -  Real nodes, not mocks
395
+ -  Proper lifecycle management
396
+ -  Clean up in `afterEach`
397
+ -  Test integration, not isolation
398
+ -  Keep it simple
399
+
400
+ For detailed testing patterns and examples, see [TESTING.md](./TESTING.md).
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Test builders - Fluent APIs for common test scenarios
3
+ */
4
+ export { SimpleNodeBuilder } from './simple-node-builder.js';
5
+ export { LeaderChildBuilder, type LeaderConfig } from './leader-child-builder.js';
6
+ export { ManagerWorkerBuilder, type ManagerWorkerResult } from './manager-worker-builder.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/builders/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Test builders - Fluent APIs for common test scenarios
3
+ */
4
+ export { SimpleNodeBuilder } from './simple-node-builder.js';
5
+ export { LeaderChildBuilder } from './leader-child-builder.js';
6
+ export { ManagerWorkerBuilder } from './manager-worker-builder.js';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * LeaderChildBuilder - Fluent API for creating leader-child hierarchies
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const { leader, tool } = await new LeaderChildBuilder(MyTool)
7
+ * .withToolConfig({ apiKey: 'test' })
8
+ * .withLeaderAddress('o://test-leader')
9
+ * .build(env);
10
+ * ```
11
+ */
12
+ import type { oNode, oNodeAddress } from '@olane/o-node';
13
+ import type { TestEnvironment, TestNodeConfig, ToolWithLeaderResult } from '../test-environment.js';
14
+ export interface LeaderConfig {
15
+ address?: oNodeAddress;
16
+ description?: string;
17
+ autoStart?: boolean;
18
+ }
19
+ export declare class LeaderChildBuilder<T extends oNode = any> {
20
+ private toolClass;
21
+ private toolConfig;
22
+ private leaderClass?;
23
+ private leaderConfig;
24
+ constructor(ToolClass: new (config: any) => T);
25
+ /**
26
+ * Set tool configuration
27
+ */
28
+ withToolConfig(config: TestNodeConfig): this;
29
+ /**
30
+ * Set leader class (optional, defaults to oLeaderNode)
31
+ */
32
+ withLeaderClass(LeaderClass: new (config: any) => any): this;
33
+ /**
34
+ * Set leader configuration
35
+ */
36
+ withLeaderConfig(config: LeaderConfig): this;
37
+ /**
38
+ * Set leader address
39
+ */
40
+ withLeaderAddress(address: string | oNodeAddress): this;
41
+ /**
42
+ * Set leader description
43
+ */
44
+ withLeaderDescription(description: string): this;
45
+ /**
46
+ * Build and create the leader-child hierarchy
47
+ */
48
+ build(env: TestEnvironment): Promise<ToolWithLeaderResult<T>>;
49
+ }
50
+ //# sourceMappingURL=leader-child-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leader-child-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/leader-child-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEpG,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,kBAAkB,CAAC,CAAC,SAAS,KAAK,GAAG,GAAG;IACnD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,WAAW,CAAC,CAA2B;IAC/C,OAAO,CAAC,YAAY,CAAoB;gBAE5B,SAAS,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;IAI7C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAK5C;;OAEG;IACH,eAAe,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG,IAAI;IAK5D;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAK5C;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAKvD;;OAEG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKhD;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;CAOpE"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * LeaderChildBuilder - Fluent API for creating leader-child hierarchies
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const { leader, tool } = await new LeaderChildBuilder(MyTool)
7
+ * .withToolConfig({ apiKey: 'test' })
8
+ * .withLeaderAddress('o://test-leader')
9
+ * .build(env);
10
+ * ```
11
+ */
12
+ export class LeaderChildBuilder {
13
+ constructor(ToolClass) {
14
+ this.toolConfig = {};
15
+ this.leaderConfig = {};
16
+ this.toolClass = ToolClass;
17
+ }
18
+ /**
19
+ * Set tool configuration
20
+ */
21
+ withToolConfig(config) {
22
+ this.toolConfig = { ...this.toolConfig, ...config };
23
+ return this;
24
+ }
25
+ /**
26
+ * Set leader class (optional, defaults to oLeaderNode)
27
+ */
28
+ withLeaderClass(LeaderClass) {
29
+ this.leaderClass = LeaderClass;
30
+ return this;
31
+ }
32
+ /**
33
+ * Set leader configuration
34
+ */
35
+ withLeaderConfig(config) {
36
+ this.leaderConfig = { ...this.leaderConfig, ...config };
37
+ return this;
38
+ }
39
+ /**
40
+ * Set leader address
41
+ */
42
+ withLeaderAddress(address) {
43
+ this.leaderConfig.address = address;
44
+ return this;
45
+ }
46
+ /**
47
+ * Set leader description
48
+ */
49
+ withLeaderDescription(description) {
50
+ this.leaderConfig.description = description;
51
+ return this;
52
+ }
53
+ /**
54
+ * Build and create the leader-child hierarchy
55
+ */
56
+ async build(env) {
57
+ return await env.createToolWithLeader(this.toolClass, this.toolConfig, this.leaderClass);
58
+ }
59
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * ManagerWorkerBuilder - Fluent API for manager-worker pattern tests
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const { leader, manager, workers } = await new ManagerWorkerBuilder(MyManager, MyWorker)
7
+ * .withManagerConfig({ maxInstances: 5 })
8
+ * .withWorkerCount(3)
9
+ * .withWorkerConfig({ timeout: 5000 })
10
+ * .build(env);
11
+ * ```
12
+ */
13
+ import type { oNode } from '@olane/o-node';
14
+ import type { TestEnvironment, TestNodeConfig } from '../test-environment.js';
15
+ export interface ManagerWorkerResult<M = any, W = any> {
16
+ leader: any;
17
+ manager: M;
18
+ workers: W[];
19
+ }
20
+ export declare class ManagerWorkerBuilder<M extends oNode = any, W extends oNode = any> {
21
+ private managerClass;
22
+ private workerClass?;
23
+ private managerConfig;
24
+ private workerConfig;
25
+ private workerCount;
26
+ private leaderClass?;
27
+ constructor(ManagerClass: new (config: any) => M, WorkerClass?: new (config: any) => W);
28
+ /**
29
+ * Set manager configuration
30
+ */
31
+ withManagerConfig(config: TestNodeConfig): this;
32
+ /**
33
+ * Set worker configuration
34
+ */
35
+ withWorkerConfig(config: TestNodeConfig): this;
36
+ /**
37
+ * Set number of workers to create
38
+ */
39
+ withWorkerCount(count: number): this;
40
+ /**
41
+ * Set leader class
42
+ */
43
+ withLeaderClass(LeaderClass: new (config: any) => any): this;
44
+ /**
45
+ * Build and create the manager-worker hierarchy
46
+ */
47
+ build(env: TestEnvironment): Promise<ManagerWorkerResult<M, W>>;
48
+ }
49
+ //# sourceMappingURL=manager-worker-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager-worker-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/manager-worker-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;IACnD,MAAM,EAAE,GAAG,CAAC;IACZ,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,CAAC,EAAE,CAAC;CACd;AAED,qBAAa,oBAAoB,CAAC,CAAC,SAAS,KAAK,GAAG,GAAG,EAAE,CAAC,SAAS,KAAK,GAAG,GAAG;IAC5E,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,WAAW,CAAC,CAAyB;IAC7C,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAC,CAA2B;gBAG7C,YAAY,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC,EACpC,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;IAMtC;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAK/C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAK9C;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKpC;;OAEG;IACH,eAAe,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG,IAAI;IAK5D;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAiCtE"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * ManagerWorkerBuilder - Fluent API for manager-worker pattern tests
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const { leader, manager, workers } = await new ManagerWorkerBuilder(MyManager, MyWorker)
7
+ * .withManagerConfig({ maxInstances: 5 })
8
+ * .withWorkerCount(3)
9
+ * .withWorkerConfig({ timeout: 5000 })
10
+ * .build(env);
11
+ * ```
12
+ */
13
+ export class ManagerWorkerBuilder {
14
+ constructor(ManagerClass, WorkerClass) {
15
+ this.managerConfig = {};
16
+ this.workerConfig = {};
17
+ this.workerCount = 0;
18
+ this.managerClass = ManagerClass;
19
+ this.workerClass = WorkerClass;
20
+ }
21
+ /**
22
+ * Set manager configuration
23
+ */
24
+ withManagerConfig(config) {
25
+ this.managerConfig = { ...this.managerConfig, ...config };
26
+ return this;
27
+ }
28
+ /**
29
+ * Set worker configuration
30
+ */
31
+ withWorkerConfig(config) {
32
+ this.workerConfig = { ...this.workerConfig, ...config };
33
+ return this;
34
+ }
35
+ /**
36
+ * Set number of workers to create
37
+ */
38
+ withWorkerCount(count) {
39
+ this.workerCount = count;
40
+ return this;
41
+ }
42
+ /**
43
+ * Set leader class
44
+ */
45
+ withLeaderClass(LeaderClass) {
46
+ this.leaderClass = LeaderClass;
47
+ return this;
48
+ }
49
+ /**
50
+ * Build and create the manager-worker hierarchy
51
+ */
52
+ async build(env) {
53
+ // Create leader and manager
54
+ const { leader, tool: manager } = await env.createToolWithLeader(this.managerClass, this.managerConfig, this.leaderClass);
55
+ const workers = [];
56
+ // Create workers if count specified and worker class provided
57
+ if (this.workerCount > 0 && this.workerClass) {
58
+ for (let i = 0; i < this.workerCount; i++) {
59
+ // Use manager's create_worker method if available
60
+ const createMethod = 'create_worker';
61
+ if (typeof manager.useSelf === 'function') {
62
+ try {
63
+ await manager.useSelf({
64
+ method: createMethod,
65
+ params: {
66
+ workerId: `worker-${i}`,
67
+ config: this.workerConfig,
68
+ },
69
+ });
70
+ }
71
+ catch (error) {
72
+ console.warn(`Could not create worker ${i} via manager method:`, error);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return { leader, manager, workers };
78
+ }
79
+ }