@aigne/afs-testing 1.11.0-beta.7

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.
@@ -0,0 +1,394 @@
1
+ import * as bun_test0 from "bun:test";
2
+ import { AFSEntry, AFSListResult, AFSModule, AFSReadResult, AFSSearchResult, AFSStatResult } from "@aigne/afs";
3
+
4
+ //#region src/assertions.d.ts
5
+ /**
6
+ * Validate that a result conforms to AFSListResult structure.
7
+ */
8
+ declare function validateListResult(result: unknown): asserts result is AFSListResult;
9
+ /**
10
+ * Validate that an object conforms to AFSEntry structure.
11
+ */
12
+ declare function validateEntry(entry: unknown): asserts entry is AFSEntry;
13
+ /**
14
+ * Validate that a result conforms to AFSReadResult structure.
15
+ */
16
+ declare function validateReadResult(result: unknown): asserts result is AFSReadResult;
17
+ /**
18
+ * Validate that a result conforms to AFSSearchResult structure.
19
+ */
20
+ declare function validateSearchResult(result: unknown): asserts result is AFSSearchResult;
21
+ /**
22
+ * Validate that a result conforms to AFSStatResult structure.
23
+ */
24
+ declare function validateStatResult(result: unknown): asserts result is AFSStatResult;
25
+ //#endregion
26
+ //#region src/types.d.ts
27
+ /**
28
+ * Expected action declaration for a test node.
29
+ * Used to verify that actions are correctly exposed on nodes.
30
+ */
31
+ interface TestActionDeclaration {
32
+ /** Action name */
33
+ name: string;
34
+ /** Optional description to verify */
35
+ description?: string;
36
+ }
37
+ /**
38
+ * A node in the test tree structure.
39
+ * - If `children` is defined and non-empty, it's a directory
40
+ * - If `content` is defined, it's a file
41
+ * - Root node has name "" (empty string)
42
+ */
43
+ interface TestTreeNode {
44
+ /** Node name (not full path). Root node uses empty string. */
45
+ name: string;
46
+ /** For files: expected content (optional, for read verification) */
47
+ content?: string;
48
+ /** For directories: child nodes. Presence with length > 0 indicates directory. */
49
+ children?: TestTreeNode[];
50
+ /** Expected meta for this node */
51
+ meta?: Record<string, unknown>;
52
+ /**
53
+ * Expected actions for this node.
54
+ * If specified, the framework will verify these actions exist via list(.actions).
55
+ */
56
+ actions?: TestActionDeclaration[];
57
+ }
58
+ /**
59
+ * Describes the test data structure using a tree.
60
+ */
61
+ interface TestDataStructure {
62
+ /**
63
+ * Root of the tree structure representing "/".
64
+ * All paths are derived from traversing this tree.
65
+ * The framework validates that provider data matches this tree.
66
+ */
67
+ root: TestTreeNode;
68
+ }
69
+ /**
70
+ * A flattened node with its computed path.
71
+ * Used internally for iterating over the tree.
72
+ */
73
+ interface FlattenedNode {
74
+ /** Full path from root (e.g., "/docs/readme.md") */
75
+ path: string;
76
+ /** The tree node */
77
+ node: TestTreeNode;
78
+ /** Depth from root (root = 0) */
79
+ depth: number;
80
+ }
81
+ /**
82
+ * Check if a tree node represents a directory (has children).
83
+ */
84
+ declare function isDirectory(node: TestTreeNode): boolean;
85
+ /**
86
+ * Check if a tree node represents a file (has content or is a leaf without children).
87
+ */
88
+ declare function isFile(node: TestTreeNode): boolean;
89
+ /**
90
+ * Compute the full path for a node given its parent path.
91
+ */
92
+ declare function computePath(parentPath: string, nodeName: string): string;
93
+ /**
94
+ * Flatten a tree into an array of nodes with their paths.
95
+ * Traverses in BFS order.
96
+ */
97
+ declare function flattenTree(root: TestTreeNode): FlattenedNode[];
98
+ /**
99
+ * Find a node in the tree by path.
100
+ */
101
+ declare function findNode(root: TestTreeNode, targetPath: string): TestTreeNode | undefined;
102
+ /**
103
+ * Find the first file node in the tree (excluding root).
104
+ */
105
+ declare function findFirstFile(root: TestTreeNode): FlattenedNode | undefined;
106
+ /**
107
+ * Find the first directory node in the tree (excluding root).
108
+ */
109
+ declare function findFirstDirectory(root: TestTreeNode): FlattenedNode | undefined;
110
+ /**
111
+ * Find a nested directory (depth >= 2) in the tree.
112
+ */
113
+ declare function findNestedDirectory(root: TestTreeNode): FlattenedNode | undefined;
114
+ /**
115
+ * Get all file nodes from the tree.
116
+ */
117
+ declare function getAllFiles(root: TestTreeNode): FlattenedNode[];
118
+ /**
119
+ * Get all directory nodes from the tree.
120
+ */
121
+ declare function getAllDirectories(root: TestTreeNode): FlattenedNode[];
122
+ /**
123
+ * Configuration options for test behavior.
124
+ */
125
+ interface TestConfig {
126
+ /** Custom timeout for slow providers (ms) */
127
+ timeout?: number;
128
+ }
129
+ /**
130
+ * Validator function for execute test output.
131
+ * Use expect() assertions inside to validate the output.
132
+ * @example
133
+ * ```typescript
134
+ * (output, expect) => {
135
+ * expect(output.content).toBeDefined();
136
+ * expect(output.content[0].text).toContain("hello");
137
+ * }
138
+ * ```
139
+ */
140
+ type ExecuteOutputValidator = (output: Record<string, unknown>, expect: typeof bun_test0.expect) => void;
141
+ /**
142
+ * Expected output specification for execute tests.
143
+ * Can be:
144
+ * - An exact object to match (deep equality)
145
+ * - A validator function that uses expect() assertions
146
+ * - An object with `contains` for partial matching
147
+ */
148
+ type ExecuteExpectedOutput = Record<string, unknown> | ExecuteOutputValidator | {
149
+ contains: Record<string, unknown>;
150
+ };
151
+ /**
152
+ * A single execute test case.
153
+ */
154
+ interface ExecuteTestCase {
155
+ /** Test case name/description */
156
+ name: string;
157
+ /** Path to execute (e.g., "/tools/echo") */
158
+ path: string;
159
+ /** Input arguments for execution */
160
+ args: Record<string, unknown>;
161
+ /**
162
+ * Expected output validation.
163
+ * - Object: exact deep equality match
164
+ * - Function: custom validator
165
+ * - { contains: ... }: partial match (output should contain these keys/values)
166
+ */
167
+ expected?: ExecuteExpectedOutput;
168
+ /**
169
+ * If true, the execution is expected to throw an error.
170
+ * Can also be a string/regex to match the error message.
171
+ */
172
+ shouldThrow?: boolean | string | RegExp;
173
+ }
174
+ /**
175
+ * Validator function for write test result.
176
+ * Uses a more flexible type to accommodate AFSWriteResult structure.
177
+ */
178
+ type WriteOutputValidator = (result: {
179
+ data?: {
180
+ path: string;
181
+ content?: unknown;
182
+ meta?: Record<string, unknown> | null;
183
+ };
184
+ }, expect: typeof bun_test0.expect) => void;
185
+ /**
186
+ * Expected output specification for write tests.
187
+ */
188
+ type WriteExpectedOutput = {
189
+ content: unknown;
190
+ } | {
191
+ contentContains: string;
192
+ } | {
193
+ meta: Record<string, unknown>;
194
+ } | WriteOutputValidator;
195
+ /**
196
+ * A single write test case.
197
+ * Tests write operations including content and meta writes.
198
+ */
199
+ interface WriteTestCase {
200
+ /** Test case name/description */
201
+ name: string;
202
+ /**
203
+ * Path to write to.
204
+ * - Can be an existing path from structure (tests overwrite)
205
+ * - Can be a new path (tests creation)
206
+ * - Use payload.meta for meta-only writes (.meta paths are read-only)
207
+ */
208
+ path: string;
209
+ /**
210
+ * Payload to write.
211
+ * At least one of content or meta should be provided.
212
+ */
213
+ payload: {
214
+ content?: string | Record<string, unknown>;
215
+ meta?: Record<string, unknown>;
216
+ };
217
+ /**
218
+ * Expected output validation.
219
+ * - { content: ... }: verify written content matches
220
+ * - { contentContains: ... }: verify content contains string
221
+ * - { meta: ... }: verify meta matches
222
+ * - Function: custom validator with expect()
223
+ */
224
+ expected?: WriteExpectedOutput;
225
+ /**
226
+ * If true, the write is expected to throw an error.
227
+ * Can also be a string/regex to match the error message.
228
+ */
229
+ shouldThrow?: boolean | string | RegExp;
230
+ }
231
+ /**
232
+ * A single delete test case.
233
+ * Tests delete operations on paths from the structure.
234
+ */
235
+ interface DeleteTestCase {
236
+ /** Test case name/description */
237
+ name: string;
238
+ /**
239
+ * Path to delete.
240
+ * Should typically be a path that exists in the structure.
241
+ */
242
+ path: string;
243
+ /**
244
+ * If true, the delete is expected to throw an error.
245
+ * Can also be a string/regex to match the error message.
246
+ */
247
+ shouldThrow?: boolean | string | RegExp;
248
+ /**
249
+ * If true, verify the path no longer exists after deletion.
250
+ * Uses list() or read() to confirm deletion.
251
+ * @default true
252
+ */
253
+ verifyDeleted?: boolean;
254
+ }
255
+ /**
256
+ * Validator function for action test output.
257
+ * Use expect() assertions inside to validate the output.
258
+ * @example
259
+ * ```typescript
260
+ * (result, expect) => {
261
+ * expect(result.success).toBe(true);
262
+ * expect(result.data?.newId).toBeDefined();
263
+ * }
264
+ * ```
265
+ */
266
+ type ActionOutputValidator = (result: {
267
+ success: boolean;
268
+ data?: Record<string, unknown>;
269
+ error?: {
270
+ code: string;
271
+ message: string;
272
+ };
273
+ }, expect: typeof bun_test0.expect) => void;
274
+ /**
275
+ * Expected output specification for action tests.
276
+ * Can be:
277
+ * - An exact object to match (deep equality on data field)
278
+ * - A validator function that uses expect() assertions
279
+ * - An object with `contains` for partial matching
280
+ * - An object with `success` to just check success/failure
281
+ */
282
+ type ActionExpectedOutput = {
283
+ success: boolean;
284
+ } | {
285
+ data: Record<string, unknown>;
286
+ } | {
287
+ contains: Record<string, unknown>;
288
+ } | ActionOutputValidator;
289
+ /**
290
+ * A single action test case.
291
+ * Tests input/output behavior of actions on nodes.
292
+ */
293
+ interface ActionTestCase {
294
+ /** Test case name/description */
295
+ name: string;
296
+ /**
297
+ * Path to the action (e.g., "/users/.actions/insert" or "/.actions/create-table").
298
+ * This is the full action path including the .actions segment.
299
+ */
300
+ path: string;
301
+ /** Input arguments for the action */
302
+ args: Record<string, unknown>;
303
+ /**
304
+ * Expected output validation.
305
+ * - { success: true/false }: just check success status
306
+ * - { data: ... }: exact match on result.data
307
+ * - { contains: ... }: partial match on result.data
308
+ * - Function: custom validator
309
+ */
310
+ expected?: ActionExpectedOutput;
311
+ /**
312
+ * If true, the action execution is expected to throw an error.
313
+ * Can also be a string/regex to match the error message.
314
+ */
315
+ shouldThrow?: boolean | string | RegExp;
316
+ }
317
+ /**
318
+ * Fixture interface for provider conformance tests.
319
+ * Providers implement this to define their test environment.
320
+ */
321
+ interface ProviderTestFixture<T extends AFSModule = AFSModule> {
322
+ /** Human-readable name for test output */
323
+ name: string;
324
+ /** Create a fresh provider instance */
325
+ createProvider: () => Promise<T> | T;
326
+ /** Describe the test data structure that will be available */
327
+ structure: TestDataStructure;
328
+ /**
329
+ * Execute test cases.
330
+ * Tests input/output behavior of executable nodes (e.g., tools, prompts).
331
+ */
332
+ executeCases?: ExecuteTestCase[];
333
+ /**
334
+ * Action test cases.
335
+ * Tests action execution on nodes (e.g., create-table, insert, delete).
336
+ * Actions are executed via exec() on .actions paths.
337
+ * These tests run LAST because they may modify the data structure.
338
+ */
339
+ actionCases?: ActionTestCase[];
340
+ /**
341
+ * Write test cases.
342
+ * Tests write operations including content and meta writes.
343
+ * These tests run LAST because they may modify the data structure.
344
+ */
345
+ writeCases?: WriteTestCase[];
346
+ /**
347
+ * Delete test cases.
348
+ * Tests delete operations on paths from the structure.
349
+ * These tests run LAST because they modify the data structure.
350
+ */
351
+ deleteCases?: DeleteTestCase[];
352
+ /** Optional lifecycle hooks */
353
+ beforeAll?: () => Promise<void> | void;
354
+ afterAll?: () => Promise<void> | void;
355
+ beforeEach?: () => Promise<void> | void;
356
+ afterEach?: () => Promise<void> | void;
357
+ /** Optional test configuration */
358
+ config?: TestConfig;
359
+ }
360
+ //#endregion
361
+ //#region src/runner.d.ts
362
+ /**
363
+ * Run provider conformance tests.
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * import { runProviderTests } from "@aigne/afs/testing";
368
+ *
369
+ * describe("MyProvider Conformance", () => {
370
+ * runProviderTests({
371
+ * name: "MyProvider",
372
+ * createProvider: () => new MyProvider({ ... }),
373
+ * structure: {
374
+ * root: {
375
+ * name: "",
376
+ * children: [
377
+ * { name: "file.txt", content: "Hello" },
378
+ * {
379
+ * name: "docs",
380
+ * children: [
381
+ * { name: "readme.md", content: "# Readme" },
382
+ * ],
383
+ * },
384
+ * ],
385
+ * },
386
+ * },
387
+ * });
388
+ * });
389
+ * ```
390
+ */
391
+ declare function runProviderTests<T extends AFSModule>(fixture: ProviderTestFixture<T>): void;
392
+ //#endregion
393
+ export { type ActionExpectedOutput, type ActionOutputValidator, type ActionTestCase, type DeleteTestCase, type ExecuteExpectedOutput, type ExecuteOutputValidator, type ExecuteTestCase, type FlattenedNode, type ProviderTestFixture, type TestActionDeclaration, type TestConfig, type TestDataStructure, type TestTreeNode, type WriteExpectedOutput, type WriteOutputValidator, type WriteTestCase, computePath, findFirstDirectory, findFirstFile, findNestedDirectory, findNode, flattenTree, getAllDirectories, getAllFiles, isDirectory, isFile, runProviderTests, validateEntry, validateListResult, validateReadResult, validateSearchResult, validateStatResult };
394
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/assertions.ts","../src/types.ts","../src/runner.ts"],"mappings":";;;;;;;iBAYgB,kBAAA,CAAmB,MAAA,oBAA0B,MAAA,IAAU,aAAA;;;;iBAkBvD,aAAA,CAAc,KAAA,oBAAyB,KAAA,IAAS,QAAA;;;;iBAgChD,kBAAA,CAAmB,MAAA,oBAA0B,MAAA,IAAU,aAAA;AAhCvE;;;AAAA,iBAgDgB,oBAAA,CAAqB,MAAA,oBAA0B,MAAA,IAAU,eAAA;;;;iBAazD,kBAAA,CAAmB,MAAA,oBAA0B,MAAA,IAAU,aAAA;;;;;;AA/EvE;UCLiB,qBAAA;;EAEf,IAAA;EDGiC;ECDjC,WAAA;AAAA;;;ADmBF;;;;UCViB,YAAA;EDUsC;ECRrD,IAAA;EDQsE;ECLtE,OAAA;EDqCc;EClCd,QAAA,GAAW,YAAA;;EAGX,IAAA,GAAO,MAAA;ED+B0B;;;;ECzBjC,OAAA,GAAU,qBAAA;AAAA;;;;UAMK,iBAAA;EDmC8C;;;;AAa/D;EC1CE,IAAA,EAAM,YAAA;AAAA;;;;;UASS,aAAA;EDiCmE;EC/BlF,IAAA;;EAGA,IAAA,EAAM,YAAA;EAxDS;EA2Df,KAAA;AAAA;;;AA9CF;iBAsDgB,WAAA,CAAY,IAAA,EAAM,YAAA;;;;iBAOlB,MAAA,CAAO,IAAA,EAAM,YAAA;;;;iBAOb,WAAA,CAAY,UAAA,UAAoB,QAAA;;;;;iBAShC,WAAA,CAAY,IAAA,EAAM,YAAA,GAAe,aAAA;;;;iBAwBjC,QAAA,CAAS,IAAA,EAAM,YAAA,EAAc,UAAA,WAAqB,YAAA;;;;iBAkBlD,aAAA,CAAc,IAAA,EAAM,YAAA,GAAe,aAAA;AAjFnD;;;AAAA,iBAyFgB,kBAAA,CAAmB,IAAA,EAAM,YAAA,GAAe,aAAA;;;;iBAQxC,mBAAA,CAAoB,IAAA,EAAM,YAAA,GAAe,aAAA;;;AAjFzD;iBAyFgB,WAAA,CAAY,IAAA,EAAM,YAAA,GAAe,aAAA;;;;iBAOjC,iBAAA,CAAkB,IAAA,EAAM,YAAA,GAAe,aAAA;;;;UAOtC,UAAA;EAzFD;EA2Fd,OAAA;AAAA;;;AAlFF;;;;;;;;;KAkGY,sBAAA,IACV,MAAA,EAAQ,MAAA,mBACR,MAAA,SADc,SAAA,CACoB,MAAA;;;;;;;;KAUxB,qBAAA,GACR,MAAA,oBACA,sBAAA;EACE,QAAA,EAAU,MAAA;AAAA;;;;UAKC,eAAA;EA5Ea;EA8E5B,IAAA;EA9E8D;EAiF9D,IAAA;EAzEc;EA4Ed,IAAA,EAAM,MAAA;;;;;;;EAQN,QAAA,GAAW,qBAAA;EA5EG;;;;EAkFd,WAAA,sBAAiC,MAAA;AAAA;;;;AA1EnC;KAmFY,oBAAA,IACV,MAAA;EAAU,IAAA;IAAS,IAAA;IAAc,OAAA;IAAmB,IAAA,GAAO,MAAA;EAAA;AAAA,GAC3D,MAAA,SADiE,SAAA,CAC/B,MAAA;;AA9EpC;;KAoFY,mBAAA;EACN,OAAA;AAAA;EACA,eAAA;AAAA;EACA,IAAA,EAAM,MAAA;AAAA,IACR,oBAAA;AAjFJ;;;;AAAA,UAuFiB,aAAA;EArEL;EAuEV,IAAA;;;;;;;EAQA,IAAA;EA7EwC;AAU1C;;;EAyEE,OAAA;IACE,OAAA,YAAmB,MAAA;IACnB,IAAA,GAAO,MAAA;EAAA;EAxEW;;;;;;;EAkFpB,QAAA,GAAW,mBAAA;EA7EmB;;;;EAmF9B,WAAA,sBAAiC,MAAA;AAAA;;;;;UASlB,cAAA;EA5Ef;EA8EA,IAAA;EAxEA;;;;EA8EA,IAAA;EArE8B;;;;EA2E9B,WAAA,sBAAiC,MAAA;EA1EA;;;;;EAiFjC,aAAA;AAAA;;AA1EF;;;;;;;;;;KA0FY,qBAAA,IACV,MAAA;EACE,OAAA;EACA,IAAA,GAAO,MAAA;EACP,KAAA;IAAU,IAAA;IAAc,OAAA;EAAA;AAAA,GAE1B,MAAA,SAHe,SAAA,CAGmB,MAAA;;;;;;;;;KAWxB,oBAAA;EACN,OAAA;AAAA;EACA,IAAA,EAAM,MAAA;AAAA;EACN,QAAA,EAAU,MAAA;AAAA,IACZ,qBAAA;AA1DJ;;;;AAAA,UAgEiB,cAAA;EAxDf;EA0DA,IAAA;EApDiC;;;;EA0DjC,IAAA;EAnC+B;EAsC/B,IAAA,EAAM,MAAA;EAhCkC;;;;;;;EAyCxC,QAAA,GAAW,oBAAA;EA1CV;;;;EAgDD,WAAA,sBAAiC,MAAA;AAAA;;;;;UAOlB,mBAAA,WAA8B,SAAA,GAAY,SAAA;EAvClC;EAyCvB,IAAA;EA3CI;EA8CJ,cAAA,QAAsB,OAAA,CAAQ,CAAA,IAAK,CAAA;EA7C/B;EAgDJ,SAAA,EAAW,iBAAA;EA/CT;;;AAMJ;EA+CE,YAAA,GAAe,eAAA;;;;;;;EAQf,WAAA,GAAc,cAAA;EA/Cd;;;;;EAsDA,UAAA,GAAa,aAAA;EApCoB;;;AAOnC;;EAoCE,WAAA,GAAc,cAAA;EApC+B;EAuC7C,SAAA,SAAkB,OAAA;EAClB,QAAA,SAAiB,OAAA;EACjB,UAAA,SAAmB,OAAA;EACnB,SAAA,SAAkB,OAAA;EAlCP;EAqCX,MAAA,GAAS,UAAA;AAAA;;;;;ADrbX;;;;;;;;;AAkBA;;;;;;;;;AAgCA;;;;;;;;;iBEPgB,gBAAA,WAA2B,SAAA,CAAA,CAAW,OAAA,EAAS,mBAAA,CAAoB,CAAA"}