@olane/o-test 0.8.2 → 0.8.4
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 +63 -18
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
> Testing utilities and best practices for O-Network node development
|
|
4
4
|
|
|
5
|
-
## ⚠️ Important:
|
|
5
|
+
## ⚠️ Important: Testing Framework Notes
|
|
6
6
|
|
|
7
|
-
Since O-Network is built on the **libp2p ecosystem**,
|
|
7
|
+
Since O-Network is built on the **libp2p ecosystem**, the primary test runner is **aegir** with **Mocha** syntax.
|
|
8
8
|
|
|
9
|
-
- ✅
|
|
10
|
-
-
|
|
9
|
+
- ✅ Primary: `aegir`, `chai`, Mocha syntax (`before`, `after`, `.to.equal()`)
|
|
10
|
+
- ✅ Also available: `jest` and `@types/jest` are included in devDependencies (^30.0.0) for packages that need Jest-style testing
|
|
11
|
+
|
|
12
|
+
> **Note**: Both test frameworks are available in this package. The `package.json` includes `jest`, `@types/jest`, and `ts-jest` in devDependencies alongside `aegir` and `chai`. The `test` script uses `aegir test` by default, but Jest can be used for individual packages or specific test scenarios. When writing new tests, follow the conventions of the file you are editing -- Mocha/Chai for aegir-based tests, or Jest assertions if the test file uses Jest.
|
|
11
13
|
|
|
12
14
|
See [MOCHA-MIGRATION.md](./MOCHA-MIGRATION.md) for migration guide.
|
|
13
15
|
|
|
@@ -74,13 +76,13 @@ describe('MyTool', () => {
|
|
|
74
76
|
});
|
|
75
77
|
|
|
76
78
|
it('should execute method', async () => {
|
|
77
|
-
const
|
|
79
|
+
const response = await tool.useSelf({
|
|
78
80
|
method: 'my_method',
|
|
79
81
|
params: { test: 'value' },
|
|
80
82
|
});
|
|
81
83
|
|
|
82
|
-
expect(result.success).to.be.true;
|
|
83
|
-
expect(
|
|
84
|
+
expect(response.result.success).to.be.true;
|
|
85
|
+
expect(response.result.data).to.exist;
|
|
84
86
|
});
|
|
85
87
|
});
|
|
86
88
|
```
|
|
@@ -176,17 +178,56 @@ export default {
|
|
|
176
178
|
- Create leader node before child nodes
|
|
177
179
|
- Inject `hookInitializeFinished` for parent-child registration
|
|
178
180
|
- Clean up all nodes in `afterEach`
|
|
179
|
-
- Access response data via `
|
|
181
|
+
- Access response data via `response.result.data`
|
|
180
182
|
- Test both success and error paths
|
|
181
183
|
|
|
182
184
|
### L DON'T:
|
|
183
185
|
|
|
184
186
|
- Override `start()` method (use hooks instead)
|
|
185
187
|
- Forget to call `stop()` on nodes
|
|
186
|
-
- Access `
|
|
188
|
+
- Access `response.data` directly (use `response.result.data`)
|
|
187
189
|
- Use mocks for node instances (use real nodes)
|
|
188
190
|
- Share mutable state between tests
|
|
189
191
|
|
|
192
|
+
## Response Structure
|
|
193
|
+
|
|
194
|
+
When testing `node.use()` or `node.useSelf()` calls, responses are wrapped in the standard O-Network response structure. Understanding this structure is critical for writing correct assertions.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// Response from use() / useSelf():
|
|
198
|
+
// {
|
|
199
|
+
// jsonrpc: "2.0",
|
|
200
|
+
// id: "request-id",
|
|
201
|
+
// result: {
|
|
202
|
+
// success: boolean, // Whether the operation succeeded
|
|
203
|
+
// data: any, // The returned data (on success)
|
|
204
|
+
// error?: string // Error details (on failure)
|
|
205
|
+
// }
|
|
206
|
+
// }
|
|
207
|
+
|
|
208
|
+
// Correct assertion patterns:
|
|
209
|
+
const response = await tool.useSelf({
|
|
210
|
+
method: 'my_method',
|
|
211
|
+
params: { key: 'value' },
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Success case
|
|
215
|
+
expect(response.result.success).to.be.true;
|
|
216
|
+
expect(response.result.data).to.exist;
|
|
217
|
+
expect(response.result.data.someField).to.equal('expected');
|
|
218
|
+
|
|
219
|
+
// Error case
|
|
220
|
+
expect(response.result.success).to.be.false;
|
|
221
|
+
expect(response.result.error).to.include('error message');
|
|
222
|
+
|
|
223
|
+
// WRONG - these will not work:
|
|
224
|
+
// expect(response.success).to.be.true; // undefined!
|
|
225
|
+
// expect(response.data).to.exist; // undefined!
|
|
226
|
+
// expect(response.error).to.include('...'); // undefined!
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
> **Key rule**: Always access response fields through `response.result.success`, `response.result.data`, and `response.result.error`. Never access `response.success`, `response.data`, or `response.error` directly.
|
|
230
|
+
|
|
190
231
|
## Testing Philosophy
|
|
191
232
|
|
|
192
233
|
We prioritize **practical, integration-oriented tests** that validate real node behavior:
|
|
@@ -220,13 +261,13 @@ it('should start and stop successfully', async () => {
|
|
|
220
261
|
|
|
221
262
|
```typescript
|
|
222
263
|
it('should validate required parameters', async () => {
|
|
223
|
-
const
|
|
264
|
+
const response = await tool.useSelf({
|
|
224
265
|
method: 'my_method',
|
|
225
266
|
params: {}, // Missing required params
|
|
226
267
|
});
|
|
227
268
|
|
|
228
|
-
expect(result.success).to.be.false;
|
|
229
|
-
expect(result.error).to.include('required');
|
|
269
|
+
expect(response.result.success).to.be.false;
|
|
270
|
+
expect(response.result.error).to.include('required');
|
|
230
271
|
});
|
|
231
272
|
```
|
|
232
273
|
|
|
@@ -235,14 +276,14 @@ it('should validate required parameters', async () => {
|
|
|
235
276
|
```typescript
|
|
236
277
|
it('should create and route to child', async () => {
|
|
237
278
|
// Create child
|
|
238
|
-
const
|
|
279
|
+
const createResponse = await manager.useSelf({
|
|
239
280
|
method: 'create_worker',
|
|
240
281
|
params: { workerId: 'worker-1' },
|
|
241
282
|
});
|
|
242
|
-
expect(
|
|
283
|
+
expect(createResponse.result.success).to.be.true;
|
|
243
284
|
|
|
244
285
|
// Route to child
|
|
245
|
-
const
|
|
286
|
+
const routeResponse = await manager.useSelf({
|
|
246
287
|
method: 'use_worker',
|
|
247
288
|
params: {
|
|
248
289
|
workerId: 'worker-1',
|
|
@@ -250,7 +291,7 @@ it('should create and route to child', async () => {
|
|
|
250
291
|
params: { data: 'test' },
|
|
251
292
|
},
|
|
252
293
|
});
|
|
253
|
-
expect(
|
|
294
|
+
expect(routeResponse.result.success).to.be.true;
|
|
254
295
|
});
|
|
255
296
|
```
|
|
256
297
|
|
|
@@ -292,10 +333,14 @@ afterEach(async () => {
|
|
|
292
333
|
|
|
293
334
|
```typescript
|
|
294
335
|
// L WRONG
|
|
295
|
-
const data =
|
|
336
|
+
const data = response.data; // undefined!
|
|
337
|
+
const success = response.success; // undefined!
|
|
338
|
+
const error = response.error; // undefined!
|
|
296
339
|
|
|
297
340
|
// CORRECT
|
|
298
|
-
const data =
|
|
341
|
+
const data = response.result.data;
|
|
342
|
+
const success = response.result.success;
|
|
343
|
+
const error = response.result.error;
|
|
299
344
|
```
|
|
300
345
|
|
|
301
346
|
## Test Helpers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-test",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"typescript": "5.4.5"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@olane/o-core": "0.8.
|
|
72
|
+
"@olane/o-core": "0.8.4",
|
|
73
73
|
"chalk": "^5.4.1",
|
|
74
74
|
"debug": "^4.4.1",
|
|
75
75
|
"dotenv": "^16.5.0"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
|
|
78
78
|
}
|