@holokai/holo-test 1.4.2 → 1.5.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.
Files changed (169) hide show
  1. package/README.md +217 -80
  2. package/dist/conformance/audit-tests.d.ts +4 -0
  3. package/dist/conformance/audit-tests.d.ts.map +1 -0
  4. package/dist/conformance/audit-tests.js +55 -0
  5. package/dist/conformance/audit-tests.js.map +1 -0
  6. package/dist/conformance/datastore-tests.d.ts +13 -0
  7. package/dist/conformance/datastore-tests.d.ts.map +1 -0
  8. package/dist/conformance/datastore-tests.js +121 -0
  9. package/dist/conformance/datastore-tests.js.map +1 -0
  10. package/dist/conformance/holo-fixture-loader.d.ts +4 -0
  11. package/dist/conformance/holo-fixture-loader.d.ts.map +1 -0
  12. package/dist/conformance/holo-fixture-loader.js +79 -0
  13. package/dist/conformance/holo-fixture-loader.js.map +1 -0
  14. package/dist/conformance/holo-fixture-tests.d.ts +4 -0
  15. package/dist/conformance/holo-fixture-tests.d.ts.map +1 -0
  16. package/dist/conformance/holo-fixture-tests.js +273 -0
  17. package/dist/conformance/holo-fixture-tests.js.map +1 -0
  18. package/dist/conformance/holo-fixture-types.d.ts +93 -0
  19. package/dist/conformance/holo-fixture-types.d.ts.map +1 -0
  20. package/dist/conformance/holo-fixture-types.js +2 -0
  21. package/dist/conformance/holo-fixture-types.js.map +1 -0
  22. package/dist/conformance/loader.d.ts +7 -0
  23. package/dist/conformance/loader.d.ts.map +1 -0
  24. package/dist/conformance/loader.js +71 -0
  25. package/dist/conformance/loader.js.map +1 -0
  26. package/dist/conformance/pipeline-tests.d.ts +4 -0
  27. package/dist/conformance/pipeline-tests.d.ts.map +1 -0
  28. package/dist/conformance/pipeline-tests.js +73 -0
  29. package/dist/conformance/pipeline-tests.js.map +1 -0
  30. package/dist/conformance/runner.d.ts +2 -0
  31. package/dist/conformance/runner.d.ts.map +1 -0
  32. package/dist/conformance/runner.js +102 -0
  33. package/dist/conformance/runner.js.map +1 -0
  34. package/dist/conformance/sdk-tests.d.ts +12 -0
  35. package/dist/conformance/sdk-tests.d.ts.map +1 -0
  36. package/dist/{services/http-fixture-server.js → conformance/sdk-tests.js} +56 -17
  37. package/dist/conformance/sdk-tests.js.map +1 -0
  38. package/dist/conformance/translator-tests.d.ts +4 -0
  39. package/dist/conformance/translator-tests.d.ts.map +1 -0
  40. package/dist/conformance/translator-tests.js +49 -0
  41. package/dist/conformance/translator-tests.js.map +1 -0
  42. package/dist/conformance/types.d.ts +81 -0
  43. package/dist/conformance/types.d.ts.map +1 -0
  44. package/dist/conformance/types.js +2 -0
  45. package/dist/conformance/types.js.map +1 -0
  46. package/dist/conformance/wire-tests.d.ts +4 -0
  47. package/dist/conformance/wire-tests.d.ts.map +1 -0
  48. package/dist/conformance/wire-tests.js +52 -0
  49. package/dist/conformance/wire-tests.js.map +1 -0
  50. package/dist/fixtures/plugin.d.ts +27 -0
  51. package/dist/fixtures/plugin.d.ts.map +1 -0
  52. package/dist/fixtures/plugin.js +110 -0
  53. package/dist/fixtures/plugin.js.map +1 -0
  54. package/dist/helpers/env.d.ts +2 -0
  55. package/dist/helpers/env.d.ts.map +1 -1
  56. package/dist/helpers/env.js +5 -0
  57. package/dist/helpers/env.js.map +1 -1
  58. package/dist/helpers/ids.d.ts +2 -0
  59. package/dist/helpers/ids.d.ts.map +1 -0
  60. package/dist/helpers/ids.js +5 -0
  61. package/dist/helpers/ids.js.map +1 -0
  62. package/dist/helpers/matrix.d.ts +9 -1
  63. package/dist/helpers/matrix.d.ts.map +1 -1
  64. package/dist/helpers/matrix.js +8 -3
  65. package/dist/helpers/matrix.js.map +1 -1
  66. package/dist/helpers/mocks.d.ts +4 -0
  67. package/dist/helpers/mocks.d.ts.map +1 -0
  68. package/dist/helpers/mocks.js +37 -0
  69. package/dist/helpers/mocks.js.map +1 -0
  70. package/dist/helpers/polling.d.ts +3 -0
  71. package/dist/helpers/polling.d.ts.map +1 -0
  72. package/dist/helpers/polling.js +24 -0
  73. package/dist/helpers/polling.js.map +1 -0
  74. package/dist/helpers/vitest-helpers.d.ts +1 -1
  75. package/dist/helpers/vitest-helpers.d.ts.map +1 -1
  76. package/dist/index.d.ts +26 -23
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +22 -21
  79. package/dist/index.js.map +1 -1
  80. package/dist/live/assertions.d.ts.map +1 -1
  81. package/dist/live/assertions.js +54 -21
  82. package/dist/live/assertions.js.map +1 -1
  83. package/dist/live/error-payloads.d.ts +5 -0
  84. package/dist/live/error-payloads.d.ts.map +1 -0
  85. package/dist/live/error-payloads.js +47 -0
  86. package/dist/live/error-payloads.js.map +1 -0
  87. package/dist/live/error-tester.d.ts +3 -0
  88. package/dist/live/error-tester.d.ts.map +1 -0
  89. package/dist/live/error-tester.js +121 -0
  90. package/dist/live/error-tester.js.map +1 -0
  91. package/dist/live/index.d.ts +3 -1
  92. package/dist/live/index.d.ts.map +1 -1
  93. package/dist/live/index.js +2 -0
  94. package/dist/live/index.js.map +1 -1
  95. package/dist/live/live-tester.d.ts.map +1 -1
  96. package/dist/live/live-tester.js +17 -3
  97. package/dist/live/live-tester.js.map +1 -1
  98. package/dist/live/types.d.ts +9 -0
  99. package/dist/live/types.d.ts.map +1 -1
  100. package/dist/services/plugin-loader.d.ts +4 -2
  101. package/dist/services/plugin-loader.d.ts.map +1 -1
  102. package/dist/services/plugin-loader.js +14 -2
  103. package/dist/services/plugin-loader.js.map +1 -1
  104. package/dist/types.d.ts +0 -37
  105. package/dist/types.d.ts.map +1 -1
  106. package/package.json +3 -6
  107. package/dist/cli.d.ts +0 -3
  108. package/dist/cli.d.ts.map +0 -1
  109. package/dist/cli.js +0 -83
  110. package/dist/cli.js.map +0 -1
  111. package/dist/contracts/audit-contract.d.ts +0 -3
  112. package/dist/contracts/audit-contract.d.ts.map +0 -1
  113. package/dist/contracts/audit-contract.js +0 -11
  114. package/dist/contracts/audit-contract.js.map +0 -1
  115. package/dist/contracts/pipeline-contract.d.ts +0 -3
  116. package/dist/contracts/pipeline-contract.d.ts.map +0 -1
  117. package/dist/contracts/pipeline-contract.js +0 -9
  118. package/dist/contracts/pipeline-contract.js.map +0 -1
  119. package/dist/contracts/roundtrip-contract.d.ts +0 -3
  120. package/dist/contracts/roundtrip-contract.d.ts.map +0 -1
  121. package/dist/contracts/roundtrip-contract.js +0 -9
  122. package/dist/contracts/roundtrip-contract.js.map +0 -1
  123. package/dist/contracts/wire-contract.d.ts +0 -3
  124. package/dist/contracts/wire-contract.d.ts.map +0 -1
  125. package/dist/contracts/wire-contract.js +0 -9
  126. package/dist/contracts/wire-contract.js.map +0 -1
  127. package/dist/dsl/assertions.d.ts +0 -6
  128. package/dist/dsl/assertions.d.ts.map +0 -1
  129. package/dist/dsl/assertions.js +0 -54
  130. package/dist/dsl/assertions.js.map +0 -1
  131. package/dist/dsl/suite-builder.d.ts +0 -25
  132. package/dist/dsl/suite-builder.d.ts.map +0 -1
  133. package/dist/dsl/suite-builder.js +0 -96
  134. package/dist/dsl/suite-builder.js.map +0 -1
  135. package/dist/factories/worker-request-factory.d.ts +0 -5
  136. package/dist/factories/worker-request-factory.d.ts.map +0 -1
  137. package/dist/factories/worker-request-factory.js +0 -19
  138. package/dist/factories/worker-request-factory.js.map +0 -1
  139. package/dist/fixtures/fixture-loader.d.ts +0 -6
  140. package/dist/fixtures/fixture-loader.d.ts.map +0 -1
  141. package/dist/fixtures/fixture-loader.js +0 -23
  142. package/dist/fixtures/fixture-loader.js.map +0 -1
  143. package/dist/runner/test-reporter.d.ts +0 -3
  144. package/dist/runner/test-reporter.d.ts.map +0 -1
  145. package/dist/runner/test-reporter.js +0 -43
  146. package/dist/runner/test-reporter.js.map +0 -1
  147. package/dist/runner/test-runner.d.ts +0 -12
  148. package/dist/runner/test-runner.d.ts.map +0 -1
  149. package/dist/runner/test-runner.js +0 -37
  150. package/dist/runner/test-runner.js.map +0 -1
  151. package/dist/services/http-fixture-server.d.ts +0 -14
  152. package/dist/services/http-fixture-server.d.ts.map +0 -1
  153. package/dist/services/http-fixture-server.js.map +0 -1
  154. package/dist/testers/audit-tester.d.ts +0 -4
  155. package/dist/testers/audit-tester.d.ts.map +0 -1
  156. package/dist/testers/audit-tester.js +0 -74
  157. package/dist/testers/audit-tester.js.map +0 -1
  158. package/dist/testers/pipeline-tester.d.ts +0 -4
  159. package/dist/testers/pipeline-tester.d.ts.map +0 -1
  160. package/dist/testers/pipeline-tester.js +0 -62
  161. package/dist/testers/pipeline-tester.js.map +0 -1
  162. package/dist/testers/roundtrip-tester.d.ts +0 -3
  163. package/dist/testers/roundtrip-tester.d.ts.map +0 -1
  164. package/dist/testers/roundtrip-tester.js +0 -77
  165. package/dist/testers/roundtrip-tester.js.map +0 -1
  166. package/dist/testers/wire-tester.d.ts +0 -4
  167. package/dist/testers/wire-tester.d.ts.map +0 -1
  168. package/dist/testers/wire-tester.js +0 -87
  169. package/dist/testers/wire-tester.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ import { expect, it } from 'vitest';
2
+ import { createResponseEnvelope, createWorkerRequest, processProviderEvents } from '@holokai/holo-sdk/provider';
3
+ import { toAsyncIter } from '@holokai/holo-sdk';
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ export function registerPipelineTests(family, plugin, scenario) {
6
+ if (!scenario.pipeline || !scenario.providerChunks?.length)
7
+ return;
8
+ const expectedFailure = scenario.expectedFailure?.pipeline === true;
9
+ const t = expectedFailure ? it.fails : it;
10
+ t('pipeline', async () => {
11
+ const protocol = { id: uuidv4(), name: scenario.protocol, capability: 'chat' };
12
+ const workerRequest = createWorkerRequest({
13
+ provider: { id: uuidv4(), name: family },
14
+ protocol,
15
+ payload: {},
16
+ sourceId: uuidv4(),
17
+ requestId: uuidv4(),
18
+ organizationId: 'test-org',
19
+ isStreaming: scenario.streaming === true,
20
+ httpRequestDetails: { path: '/test', method: 'POST' },
21
+ });
22
+ const envelope = createResponseEnvelope(workerRequest, scenario.audit?.access_model ?? 'unknown');
23
+ const wire = await plugin.createWireAdapter({
24
+ requestId: workerRequest.requestId,
25
+ isStreaming: scenario.streaming === true,
26
+ protocol: scenario.protocol,
27
+ });
28
+ const providerEvents = scenario.providerChunks.map((chunk, i) => {
29
+ const isLast = i === scenario.providerChunks.length - 1;
30
+ if (isLast) {
31
+ return {
32
+ type: 'done',
33
+ requestId: workerRequest.requestId,
34
+ seq: i,
35
+ message: chunk,
36
+ text: scenario.expectedText ?? '',
37
+ ts: Date.now(),
38
+ };
39
+ }
40
+ return {
41
+ type: 'stream_event',
42
+ requestId: workerRequest.requestId,
43
+ seq: i,
44
+ event: chunk,
45
+ ts: Date.now(),
46
+ };
47
+ });
48
+ const collectedChunks = [];
49
+ let auditedRecord = null;
50
+ const publisher = {
51
+ publishChunk: async (_s, _r, data) => {
52
+ collectedChunks.push(data);
53
+ },
54
+ publishFinal: async (data) => {
55
+ auditedRecord = data;
56
+ },
57
+ };
58
+ const result = await processProviderEvents(toAsyncIter(providerEvents), wire, workerRequest, envelope, publisher);
59
+ expect(result.text).toBe(scenario.expectedText ?? '');
60
+ if (scenario.audit && auditedRecord) {
61
+ expect(auditedRecord.providerEvent).toBeTruthy();
62
+ }
63
+ if (scenario.expectedPipelineChunks) {
64
+ expect(collectedChunks).toEqual(scenario.expectedPipelineChunks);
65
+ }
66
+ else if (scenario.streaming) {
67
+ expect(collectedChunks.length).toBeGreaterThan(0);
68
+ const last = collectedChunks[collectedChunks.length - 1];
69
+ expect(Boolean(last?.done)).toBe(true);
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=pipeline-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-tests.js","sourceRoot":"","sources":["../../src/conformance/pipeline-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runConformance(): Promise<void>;
2
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/conformance/runner.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA0GpD"}
@@ -0,0 +1,102 @@
1
+ import { describe, it } from 'vitest';
2
+ import { discoverDatastorePlugins, discoverPlugins, loadDatastorePlugin, loadPlugin, } from '../services/plugin-loader';
3
+ import { loadDatastoreConfig, loadScenarios, loadSdkAdapter } from './loader';
4
+ import { loadHoloFixtures, loadPluginHoloScenarios } from './holo-fixture-loader';
5
+ import { registerHoloFixtureTests } from './holo-fixture-tests';
6
+ import { registerTranslatorTests } from './translator-tests';
7
+ import { registerWireTests } from './wire-tests';
8
+ import { registerAuditTests } from './audit-tests';
9
+ import { registerPipelineTests } from './pipeline-tests';
10
+ import { registerSdkTests } from './sdk-tests';
11
+ import { registerDatastoreTests } from './datastore-tests';
12
+ export async function runConformance() {
13
+ let registered = 0;
14
+ const providerPackages = await discoverPlugins();
15
+ for (const pkg of providerPackages) {
16
+ const family = pkg.replace('@holokai/holo-provider-', '');
17
+ const plugin = await loadPlugin(family);
18
+ const scenarios = await loadScenarios(family);
19
+ if (!scenarios.length)
20
+ continue;
21
+ const declaredProtocols = new Set(Object.values(plugin.protocols ?? {}));
22
+ const sdkAdapter = scenarios.some(s => s.sdk) ? await loadSdkAdapter(family) : undefined;
23
+ describe(family, () => {
24
+ for (const scenario of scenarios) {
25
+ if (!declaredProtocols.has(scenario.protocol)) {
26
+ throw new Error(`${family}: scenario "${scenario.name}" declares protocol "${scenario.protocol}", which is not in plugin.protocols (${[...declaredProtocols].join(', ')})`);
27
+ }
28
+ describe(`${scenario.protocol}/${scenario.name}`, () => {
29
+ registerTranslatorTests(plugin.translator, scenario);
30
+ registerWireTests(plugin, scenario);
31
+ registerAuditTests(plugin, scenario);
32
+ registerPipelineTests(family, plugin, scenario);
33
+ registerSdkTests(plugin, scenario, sdkAdapter);
34
+ });
35
+ }
36
+ });
37
+ registered += scenarios.length;
38
+ }
39
+ // Holo-fixture conformance: each fixture pins one Holo shape (request, response,
40
+ // or streaming chunk array); each plugin contributes a native counterpart at
41
+ // tests/data/holo/. The framework auto-generates per-plugin tests + N×N cross
42
+ // tests per fixture.
43
+ const holoFixtures = await loadHoloFixtures();
44
+ if (holoFixtures.length) {
45
+ const allFamilies = providerPackages.map(pkg => pkg.replace('@holokai/holo-provider-', ''));
46
+ const translators = new Map();
47
+ const scenariosByFamily = new Map();
48
+ for (const family of allFamilies) {
49
+ const plugin = await loadPlugin(family);
50
+ translators.set(family, plugin.translator);
51
+ const pluginScenarios = await loadPluginHoloScenarios(family);
52
+ if (pluginScenarios.length)
53
+ scenariosByFamily.set(family, pluginScenarios);
54
+ }
55
+ // Group plugin scenarios by Holo fixture id.
56
+ const byHoloId = new Map();
57
+ for (const [family, scenarios] of scenariosByFamily) {
58
+ for (const scenario of scenarios) {
59
+ let map = byHoloId.get(scenario.holoId);
60
+ if (!map) {
61
+ map = new Map();
62
+ byHoloId.set(scenario.holoId, map);
63
+ }
64
+ map.set(family, scenario);
65
+ }
66
+ }
67
+ // Validate every holoId on a plugin scenario maps to an existing fixture.
68
+ const fixtureIds = new Set(holoFixtures.map(f => f.id));
69
+ for (const id of byHoloId.keys()) {
70
+ if (!fixtureIds.has(id)) {
71
+ throw new Error(`Plugin scenario references holoId "${id}" but no Holo fixture with that id exists in packages/holo-test/holo/.`);
72
+ }
73
+ }
74
+ describe('holo-fixtures', () => {
75
+ for (const fixture of holoFixtures) {
76
+ const pluginScenarios = byHoloId.get(fixture.id) ?? new Map();
77
+ registerHoloFixtureTests(fixture, pluginScenarios, translators);
78
+ }
79
+ });
80
+ registered += holoFixtures.length;
81
+ }
82
+ const datastorePackages = await discoverDatastorePlugins();
83
+ for (const pkg of datastorePackages) {
84
+ const family = pkg.replace('@holokai/holo-datastore-', '');
85
+ const config = await loadDatastoreConfig(family);
86
+ if (!config)
87
+ continue;
88
+ const plugin = await loadDatastorePlugin(family);
89
+ describe(`datastore-${family}`, () => {
90
+ registerDatastoreTests(plugin, config);
91
+ });
92
+ registered += 1;
93
+ }
94
+ if (registered === 0) {
95
+ describe('conformance', () => {
96
+ it('no scenario data files or datastore configs found under any plugin', () => {
97
+ // Sentinel to keep vitest happy until something is authored.
98
+ });
99
+ });
100
+ }
101
+ }
102
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/conformance/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IProviderPlugin } from '@holokai/holo-types/plugin';
2
+ import type { HoloScenario } from './types';
3
+ export interface ScenarioSdkAdapter {
4
+ family: string;
5
+ call(scenario: HoloScenario, port: number): Promise<unknown>;
6
+ routes(scenario: HoloScenario): {
7
+ method: string;
8
+ path: string;
9
+ } | undefined;
10
+ }
11
+ export declare function registerSdkTests(plugin: IProviderPlugin, scenario: HoloScenario, adapter: ScenarioSdkAdapter | undefined): void;
12
+ //# sourceMappingURL=sdk-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/sdk-tests.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAChF;AAED,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACxC,IAAI,CAsBN"}
@@ -1,21 +1,44 @@
1
+ import { expect, it } from 'vitest';
1
2
  import express from 'express';
2
- export class HttpFixtureServer {
3
+ export function registerSdkTests(plugin, scenario, adapter) {
4
+ if (!scenario.sdk || !scenario.providerChunks?.length)
5
+ return;
6
+ if (!adapter) {
7
+ it.todo(`sdk (no sdk-adapter found for plugin)`);
8
+ return;
9
+ }
10
+ const expectedFailure = scenario.expectedFailure?.sdk === true;
11
+ const t = expectedFailure ? it.fails : it;
12
+ t('sdk', async () => {
13
+ const server = new HoloFixtureServer();
14
+ server.mount(scenario, plugin, adapter);
15
+ const port = await server.start();
16
+ try {
17
+ const result = await adapter.call(scenario, port);
18
+ assertPartialMatch(result, scenario.sdk.expectedResult);
19
+ }
20
+ finally {
21
+ await server.stop();
22
+ }
23
+ });
24
+ }
25
+ class HoloFixtureServer {
3
26
  server = null;
4
27
  app = express();
5
28
  constructor() {
6
29
  this.app.use(express.json());
7
30
  }
8
- mount(fixture, plugin, adapter) {
9
- const route = adapter.routes(fixture);
31
+ mount(scenario, plugin, adapter) {
32
+ const route = adapter.routes(scenario);
10
33
  if (!route)
11
34
  return;
12
35
  const handler = async (_req, res) => {
13
36
  const wire = await plugin.createWireAdapter({
14
- requestId: 'roundtrip-req',
15
- isStreaming: fixture.streaming,
16
- protocol: fixture.protocol,
37
+ requestId: 'sdk-test',
38
+ isStreaming: scenario.streaming === true,
39
+ protocol: scenario.protocol,
17
40
  });
18
- const events = buildProviderEvents(fixture);
41
+ const events = buildProviderEvents(scenario);
19
42
  let headersSent = false;
20
43
  for (const evt of events) {
21
44
  const chunks = await wire.fromProviderEvent(evt);
@@ -45,10 +68,9 @@ export class HttpFixtureServer {
45
68
  this.app.get(route.path, handler);
46
69
  }
47
70
  }
48
- async start(options) {
49
- const port = options?.port ?? 0;
71
+ async start() {
50
72
  return new Promise((resolve, reject) => {
51
- this.server = this.app.listen(port, () => {
73
+ this.server = this.app.listen(0, () => {
52
74
  const addr = this.server.address();
53
75
  if (typeof addr === 'object' && addr) {
54
76
  resolve(addr.port);
@@ -68,26 +90,43 @@ export class HttpFixtureServer {
68
90
  });
69
91
  }
70
92
  }
71
- function buildProviderEvents(fixture) {
72
- return fixture.providerChunks.map((chunk, i) => {
73
- const isLast = i === fixture.providerChunks.length - 1;
93
+ function buildProviderEvents(scenario) {
94
+ return scenario.providerChunks.map((chunk, i) => {
95
+ const isLast = i === scenario.providerChunks.length - 1;
74
96
  if (isLast) {
75
97
  return {
76
98
  type: 'done',
77
- requestId: 'roundtrip-req',
99
+ requestId: 'sdk-test',
78
100
  seq: i,
79
101
  message: chunk,
80
- text: fixture.expectedText,
102
+ text: scenario.expectedText ?? '',
81
103
  ts: Date.now(),
82
104
  };
83
105
  }
84
106
  return {
85
107
  type: 'stream_event',
86
- requestId: 'roundtrip-req',
108
+ requestId: 'sdk-test',
87
109
  seq: i,
88
110
  event: chunk,
89
111
  ts: Date.now(),
90
112
  };
91
113
  });
92
114
  }
93
- //# sourceMappingURL=http-fixture-server.js.map
115
+ function assertPartialMatch(actual, expected, path = 'sdk.result') {
116
+ if (Array.isArray(expected)) {
117
+ expect(Array.isArray(actual), `${path} should be array`).toBe(true);
118
+ const arr = actual;
119
+ expect(arr.length, `${path}.length`).toBe(expected.length);
120
+ expected.forEach((item, i) => assertPartialMatch(arr[i], item, `${path}[${i}]`));
121
+ return;
122
+ }
123
+ if (expected && typeof expected === 'object') {
124
+ expect(actual, path).toBeTypeOf('object');
125
+ for (const [k, v] of Object.entries(expected)) {
126
+ assertPartialMatch(actual?.[k], v, `${path}.${k}`);
127
+ }
128
+ return;
129
+ }
130
+ expect(actual, path).toEqual(expected);
131
+ }
132
+ //# sourceMappingURL=sdk-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-tests.js","sourceRoot":"","sources":["../../src/conformance/sdk-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { IProviderTranslator } from '@holokai/holo-types/provider';
2
+ import type { HoloScenario } from './types';
3
+ export declare function registerTranslatorTests(translator: IProviderTranslator, scenario: HoloScenario): void;
4
+ //# sourceMappingURL=translator-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/translator-tests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAEtE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAmB1C,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,YAAY,GACvB,IAAI,CA6DN"}
@@ -0,0 +1,49 @@
1
+ import { expect, it } from 'vitest';
2
+ function isExpectedFailure(scenario, side, direction) {
3
+ const flag = scenario.expectedFailure?.[side];
4
+ if (flag === undefined)
5
+ return false;
6
+ if (typeof flag === 'boolean')
7
+ return flag;
8
+ return flag[direction] === true;
9
+ }
10
+ function maybeFailing(expectedFailure) {
11
+ return expectedFailure ? it.fails : it;
12
+ }
13
+ export function registerTranslatorTests(translator, scenario) {
14
+ if (scenario.request) {
15
+ const { native, holo } = scenario.request;
16
+ maybeFailing(isExpectedFailure(scenario, 'request', 'toHolo'))('request: toHolo', async () => {
17
+ const result = await translator.toHoloRequest(native);
18
+ expect(result).toEqual(holo);
19
+ });
20
+ maybeFailing(isExpectedFailure(scenario, 'request', 'fromHolo'))('request: fromHolo', async () => {
21
+ const result = await translator.fromHoloRequest(holo);
22
+ expect(result).toEqual(native);
23
+ });
24
+ maybeFailing(isExpectedFailure(scenario, 'request', 'roundTrip'))('request: round-trip (native → Holo → native)', async () => {
25
+ const intermediate = await translator.toHoloRequest(native);
26
+ const back = await translator.fromHoloRequest(intermediate);
27
+ expect(back).toEqual(native);
28
+ });
29
+ }
30
+ if (scenario.response) {
31
+ const { native, holo } = scenario.response;
32
+ maybeFailing(isExpectedFailure(scenario, 'response', 'toHolo'))('response: toHolo', async () => {
33
+ const result = await translator.toHoloResponse(native);
34
+ expect(result).toEqual(holo);
35
+ });
36
+ maybeFailing(isExpectedFailure(scenario, 'response', 'fromHolo'))('response: fromHolo', async () => {
37
+ const result = await translator.fromHoloResponse(holo);
38
+ expect(result).toEqual(native);
39
+ });
40
+ maybeFailing(isExpectedFailure(scenario, 'response', 'roundTrip'))('response: round-trip (native → Holo → native)', async () => {
41
+ const intermediate = await translator.toHoloResponse(native);
42
+ const back = await translator.fromHoloResponse(intermediate);
43
+ expect(back).toEqual(native);
44
+ });
45
+ }
46
+ // Streaming-translator round-trip is exercised via the holo-fixture
47
+ // `fromHoloStream` / `toHoloStream` tests in holo-fixture-tests.ts.
48
+ }
49
+ //# sourceMappingURL=translator-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator-tests.js","sourceRoot":"","sources":["../../src/conformance/translator-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { HoloRequest, HoloResponse } from '@holokai/holo-types/holo';
2
+ import type { ProviderResponseStatus } from '@holokai/holo-types/entities';
3
+ export interface HoloScenarioRequest<TNative = unknown> {
4
+ native: TNative;
5
+ holo: Partial<HoloRequest>;
6
+ }
7
+ export interface HoloScenarioResponse<TNative = unknown> {
8
+ native: TNative;
9
+ holo: Partial<HoloResponse>;
10
+ }
11
+ export interface HoloScenarioWire {
12
+ expectedStatus: number;
13
+ expectedHeaders: Record<string, string>;
14
+ expectedWire: string[];
15
+ }
16
+ export interface HoloScenarioAudit {
17
+ access_model?: string;
18
+ input_tokens?: number;
19
+ output_tokens?: number;
20
+ status: ProviderResponseStatus;
21
+ metadata?: Record<string, unknown>;
22
+ }
23
+ export interface HoloScenarioSdk<TRequest = unknown, TResult = unknown> {
24
+ request: TRequest;
25
+ expectedResult: TResult;
26
+ }
27
+ type ExpectedFailureFlag<TDirection extends string = string> = boolean | (Partial<Record<TDirection, boolean>>);
28
+ export interface HoloScenario<TNativeRequest = unknown, TNativeResponse = unknown, TNativeChunk = unknown, TSdkRequest = unknown, TSdkResult = unknown> {
29
+ name: string;
30
+ protocol: string;
31
+ /** Request-side translator data. */
32
+ request?: HoloScenarioRequest<TNativeRequest>;
33
+ /** Response-side translator data. */
34
+ response?: HoloScenarioResponse<TNativeResponse>;
35
+ /**
36
+ * Streaming mode flag. Used by wire/audit/pipeline/sdk tests to set up the
37
+ * provider event sequence and the wire adapter's `isStreaming`.
38
+ */
39
+ streaming?: boolean;
40
+ /**
41
+ * Provider response chunks consumed by wire/audit/pipeline/sdk tests.
42
+ * For non-streaming, a single-element array. For streaming, the chunk sequence.
43
+ */
44
+ providerChunks?: TNativeChunk[];
45
+ /**
46
+ * Concatenated text result expected after consuming all chunks.
47
+ * Used by wire (final `done` event), audit (token accounting), and pipeline (text assertion).
48
+ */
49
+ expectedText?: string;
50
+ /** Wire-conformance assertions (chunk bodies, status, headers). */
51
+ wire?: HoloScenarioWire;
52
+ /** Audit-conformance assertions on the produced ProviderResponse. */
53
+ audit?: HoloScenarioAudit;
54
+ /** SDK pipeline (real client → fixture HTTP server → assertion). */
55
+ sdk?: HoloScenarioSdk<TSdkRequest, TSdkResult>;
56
+ /** Enable the pipeline test path. Reuses providerChunks/expectedText. */
57
+ pipeline?: boolean;
58
+ /**
59
+ * Optional chunk-level shape assertion for pipeline-tests. When provided, the
60
+ * collected `WireChunk[]` (what `publishChunk` receives during the run) must
61
+ * match this expected sequence. Inputs are compared after `stripProviderMetadata`
62
+ * to ignore translator pass-through fields.
63
+ *
64
+ * When omitted, pipeline-tests still verifies structural invariants (count > 0,
65
+ * last chunk carries `done`) and — when the protocol declares one — runs
66
+ * `assertEventSequence` against the input ProviderEvents.
67
+ */
68
+ expectedPipelineChunks?: unknown[];
69
+ /** Pin known translator/wire/audit losses without polluting CI red. */
70
+ expectedFailure?: {
71
+ request?: ExpectedFailureFlag<'toHolo' | 'fromHolo' | 'roundTrip'>;
72
+ response?: ExpectedFailureFlag<'toHolo' | 'fromHolo' | 'roundTrip'>;
73
+ wire?: boolean;
74
+ audit?: boolean;
75
+ sdk?: boolean;
76
+ pipeline?: boolean;
77
+ reason?: string;
78
+ };
79
+ }
80
+ export {};
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/conformance/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAEzE,MAAM,WAAW,mBAAmB,CAAC,OAAO,GAAG,OAAO;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,GAAG,OAAO;IACnD,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAClE,OAAO,EAAE,QAAQ,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;CAC3B;AAED,KAAK,mBAAmB,CAAC,UAAU,SAAS,MAAM,GAAG,MAAM,IACrD,OAAO,GACP,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7C,MAAM,WAAW,YAAY,CACzB,cAAc,GAAG,OAAO,EACxB,eAAe,GAAG,OAAO,EACzB,YAAY,GAAG,OAAO,EACtB,WAAW,GAAG,OAAO,EACrB,UAAU,GAAG,OAAO;IAEpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IAEjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAC9C,qCAAqC;IACrC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAEjD;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAEhC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,IAAI,CAAC,EAAE,gBAAgB,CAAC;IAExB,qEAAqE;IACrE,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B,oEAAoE;IACpE,GAAG,CAAC,EAAE,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAE/C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,OAAO,EAAE,CAAC;IAEnC,uEAAuE;IACvE,eAAe,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,mBAAmB,CAAC,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;QACnE,QAAQ,CAAC,EAAE,mBAAmB,CAAC,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;QACpE,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACL"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conformance/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { IProviderPlugin } from '@holokai/holo-types/plugin';
2
+ import type { HoloScenario } from './types';
3
+ export declare function registerWireTests(plugin: IProviderPlugin, scenario: HoloScenario): void;
4
+ //# sourceMappingURL=wire-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/wire-tests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAE1C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAmCvF"}
@@ -0,0 +1,52 @@
1
+ import { expect, it } from 'vitest';
2
+ export function registerWireTests(plugin, scenario) {
3
+ if (!scenario.wire || !scenario.providerChunks?.length)
4
+ return;
5
+ const expectedFailure = scenario.expectedFailure?.wire === true;
6
+ const t = expectedFailure ? it.fails : it;
7
+ t('wire', async () => {
8
+ const wire = await plugin.createWireAdapter({
9
+ requestId: 'test-req',
10
+ isStreaming: scenario.streaming === true,
11
+ protocol: scenario.protocol,
12
+ });
13
+ const allChunks = [];
14
+ for (let i = 0; i < scenario.providerChunks.length; i++) {
15
+ const isLast = i === scenario.providerChunks.length - 1;
16
+ const event = toProviderEvent(scenario, i, isLast);
17
+ const chunks = await wire.fromProviderEvent(event);
18
+ allChunks.push(...chunks);
19
+ }
20
+ const firstChunk = allChunks[0];
21
+ expect(firstChunk, 'wire emitted no chunks').toBeDefined();
22
+ expect(firstChunk.status).toBe(scenario.wire.expectedStatus);
23
+ for (const [k, v] of Object.entries(scenario.wire.expectedHeaders)) {
24
+ expect(firstChunk.headers?.[k], `header ${k}`).toBe(v);
25
+ }
26
+ const lastChunk = allChunks[allChunks.length - 1];
27
+ expect(lastChunk.done, 'last chunk must mark done').toBe(true);
28
+ const wireBodies = allChunks.map(c => c.body);
29
+ expect(wireBodies).toEqual(scenario.wire.expectedWire);
30
+ });
31
+ }
32
+ function toProviderEvent(scenario, index, isLast) {
33
+ const chunk = scenario.providerChunks[index];
34
+ if (isLast) {
35
+ return {
36
+ type: 'done',
37
+ requestId: 'test-req',
38
+ seq: index,
39
+ message: chunk,
40
+ text: scenario.expectedText ?? '',
41
+ ts: Date.now(),
42
+ };
43
+ }
44
+ return {
45
+ type: 'stream_event',
46
+ requestId: 'test-req',
47
+ seq: index,
48
+ event: chunk,
49
+ ts: Date.now(),
50
+ };
51
+ }
52
+ //# sourceMappingURL=wire-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-tests.js","sourceRoot":"","sources":["../../src/conformance/wire-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ declare const TEST_SCOPE = "@holokai-test";
2
+ declare const TEST_VERSION = "0.1.0";
3
+ export interface TestPluginOpts {
4
+ name: string;
5
+ version?: string;
6
+ type?: 'PROVIDER' | 'DATASTORE';
7
+ dependencies?: Record<string, string>;
8
+ }
9
+ declare function testFamily(name: string): string;
10
+ declare function testPackageName(name: string): string;
11
+ export declare function createTempDir(prefix?: string): Promise<string>;
12
+ export declare function createTestPlugin(baseDir: string, opts: TestPluginOpts): Promise<{
13
+ dir: string;
14
+ packageName: string;
15
+ family: string;
16
+ version: string;
17
+ }>;
18
+ export declare function createTestBuiltinPlugin(baseDir: string, opts: TestPluginOpts): Promise<{
19
+ dir: string;
20
+ packageName: string;
21
+ family: string;
22
+ version: string;
23
+ }>;
24
+ export declare function packPluginFixture(pluginDir: string): Promise<Buffer>;
25
+ export declare function cleanupTempDir(dir: string): Promise<void>;
26
+ export { TEST_SCOPE, TEST_VERSION, testFamily, testPackageName };
27
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/fixtures/plugin.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,UAAU,kBAAkB,CAAC;AACnC,QAAA,MAAM,YAAY,UAAU,CAAC;AAE7B,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,iBAAS,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAsB,aAAa,CAAC,MAAM,SAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1E;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC,CA8CD;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;IAC1F,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC,CAwCD;AAED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW1E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D;AAED,OAAO,EAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAC,CAAC"}