@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.
- package/README.md +217 -80
- package/dist/conformance/audit-tests.d.ts +4 -0
- package/dist/conformance/audit-tests.d.ts.map +1 -0
- package/dist/conformance/audit-tests.js +55 -0
- package/dist/conformance/audit-tests.js.map +1 -0
- package/dist/conformance/datastore-tests.d.ts +13 -0
- package/dist/conformance/datastore-tests.d.ts.map +1 -0
- package/dist/conformance/datastore-tests.js +121 -0
- package/dist/conformance/datastore-tests.js.map +1 -0
- package/dist/conformance/holo-fixture-loader.d.ts +4 -0
- package/dist/conformance/holo-fixture-loader.d.ts.map +1 -0
- package/dist/conformance/holo-fixture-loader.js +79 -0
- package/dist/conformance/holo-fixture-loader.js.map +1 -0
- package/dist/conformance/holo-fixture-tests.d.ts +4 -0
- package/dist/conformance/holo-fixture-tests.d.ts.map +1 -0
- package/dist/conformance/holo-fixture-tests.js +273 -0
- package/dist/conformance/holo-fixture-tests.js.map +1 -0
- package/dist/conformance/holo-fixture-types.d.ts +93 -0
- package/dist/conformance/holo-fixture-types.d.ts.map +1 -0
- package/dist/conformance/holo-fixture-types.js +2 -0
- package/dist/conformance/holo-fixture-types.js.map +1 -0
- package/dist/conformance/loader.d.ts +7 -0
- package/dist/conformance/loader.d.ts.map +1 -0
- package/dist/conformance/loader.js +71 -0
- package/dist/conformance/loader.js.map +1 -0
- package/dist/conformance/pipeline-tests.d.ts +4 -0
- package/dist/conformance/pipeline-tests.d.ts.map +1 -0
- package/dist/conformance/pipeline-tests.js +73 -0
- package/dist/conformance/pipeline-tests.js.map +1 -0
- package/dist/conformance/runner.d.ts +2 -0
- package/dist/conformance/runner.d.ts.map +1 -0
- package/dist/conformance/runner.js +102 -0
- package/dist/conformance/runner.js.map +1 -0
- package/dist/conformance/sdk-tests.d.ts +12 -0
- package/dist/conformance/sdk-tests.d.ts.map +1 -0
- package/dist/{services/http-fixture-server.js → conformance/sdk-tests.js} +56 -17
- package/dist/conformance/sdk-tests.js.map +1 -0
- package/dist/conformance/translator-tests.d.ts +4 -0
- package/dist/conformance/translator-tests.d.ts.map +1 -0
- package/dist/conformance/translator-tests.js +49 -0
- package/dist/conformance/translator-tests.js.map +1 -0
- package/dist/conformance/types.d.ts +81 -0
- package/dist/conformance/types.d.ts.map +1 -0
- package/dist/conformance/types.js +2 -0
- package/dist/conformance/types.js.map +1 -0
- package/dist/conformance/wire-tests.d.ts +4 -0
- package/dist/conformance/wire-tests.d.ts.map +1 -0
- package/dist/conformance/wire-tests.js +52 -0
- package/dist/conformance/wire-tests.js.map +1 -0
- package/dist/fixtures/plugin.d.ts +27 -0
- package/dist/fixtures/plugin.d.ts.map +1 -0
- package/dist/fixtures/plugin.js +110 -0
- package/dist/fixtures/plugin.js.map +1 -0
- package/dist/helpers/env.d.ts +2 -0
- package/dist/helpers/env.d.ts.map +1 -1
- package/dist/helpers/env.js +5 -0
- package/dist/helpers/env.js.map +1 -1
- package/dist/helpers/ids.d.ts +2 -0
- package/dist/helpers/ids.d.ts.map +1 -0
- package/dist/helpers/ids.js +5 -0
- package/dist/helpers/ids.js.map +1 -0
- package/dist/helpers/matrix.d.ts +9 -1
- package/dist/helpers/matrix.d.ts.map +1 -1
- package/dist/helpers/matrix.js +8 -3
- package/dist/helpers/matrix.js.map +1 -1
- package/dist/helpers/mocks.d.ts +4 -0
- package/dist/helpers/mocks.d.ts.map +1 -0
- package/dist/helpers/mocks.js +37 -0
- package/dist/helpers/mocks.js.map +1 -0
- package/dist/helpers/polling.d.ts +3 -0
- package/dist/helpers/polling.d.ts.map +1 -0
- package/dist/helpers/polling.js +24 -0
- package/dist/helpers/polling.js.map +1 -0
- package/dist/helpers/vitest-helpers.d.ts +1 -1
- package/dist/helpers/vitest-helpers.d.ts.map +1 -1
- package/dist/index.d.ts +26 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -21
- package/dist/index.js.map +1 -1
- package/dist/live/assertions.d.ts.map +1 -1
- package/dist/live/assertions.js +54 -21
- package/dist/live/assertions.js.map +1 -1
- package/dist/live/error-payloads.d.ts +5 -0
- package/dist/live/error-payloads.d.ts.map +1 -0
- package/dist/live/error-payloads.js +47 -0
- package/dist/live/error-payloads.js.map +1 -0
- package/dist/live/error-tester.d.ts +3 -0
- package/dist/live/error-tester.d.ts.map +1 -0
- package/dist/live/error-tester.js +121 -0
- package/dist/live/error-tester.js.map +1 -0
- package/dist/live/index.d.ts +3 -1
- package/dist/live/index.d.ts.map +1 -1
- package/dist/live/index.js +2 -0
- package/dist/live/index.js.map +1 -1
- package/dist/live/live-tester.d.ts.map +1 -1
- package/dist/live/live-tester.js +17 -3
- package/dist/live/live-tester.js.map +1 -1
- package/dist/live/types.d.ts +9 -0
- package/dist/live/types.d.ts.map +1 -1
- package/dist/services/plugin-loader.d.ts +4 -2
- package/dist/services/plugin-loader.d.ts.map +1 -1
- package/dist/services/plugin-loader.js +14 -2
- package/dist/services/plugin-loader.js.map +1 -1
- package/dist/types.d.ts +0 -37
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -6
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -83
- package/dist/cli.js.map +0 -1
- package/dist/contracts/audit-contract.d.ts +0 -3
- package/dist/contracts/audit-contract.d.ts.map +0 -1
- package/dist/contracts/audit-contract.js +0 -11
- package/dist/contracts/audit-contract.js.map +0 -1
- package/dist/contracts/pipeline-contract.d.ts +0 -3
- package/dist/contracts/pipeline-contract.d.ts.map +0 -1
- package/dist/contracts/pipeline-contract.js +0 -9
- package/dist/contracts/pipeline-contract.js.map +0 -1
- package/dist/contracts/roundtrip-contract.d.ts +0 -3
- package/dist/contracts/roundtrip-contract.d.ts.map +0 -1
- package/dist/contracts/roundtrip-contract.js +0 -9
- package/dist/contracts/roundtrip-contract.js.map +0 -1
- package/dist/contracts/wire-contract.d.ts +0 -3
- package/dist/contracts/wire-contract.d.ts.map +0 -1
- package/dist/contracts/wire-contract.js +0 -9
- package/dist/contracts/wire-contract.js.map +0 -1
- package/dist/dsl/assertions.d.ts +0 -6
- package/dist/dsl/assertions.d.ts.map +0 -1
- package/dist/dsl/assertions.js +0 -54
- package/dist/dsl/assertions.js.map +0 -1
- package/dist/dsl/suite-builder.d.ts +0 -25
- package/dist/dsl/suite-builder.d.ts.map +0 -1
- package/dist/dsl/suite-builder.js +0 -96
- package/dist/dsl/suite-builder.js.map +0 -1
- package/dist/factories/worker-request-factory.d.ts +0 -5
- package/dist/factories/worker-request-factory.d.ts.map +0 -1
- package/dist/factories/worker-request-factory.js +0 -19
- package/dist/factories/worker-request-factory.js.map +0 -1
- package/dist/fixtures/fixture-loader.d.ts +0 -6
- package/dist/fixtures/fixture-loader.d.ts.map +0 -1
- package/dist/fixtures/fixture-loader.js +0 -23
- package/dist/fixtures/fixture-loader.js.map +0 -1
- package/dist/runner/test-reporter.d.ts +0 -3
- package/dist/runner/test-reporter.d.ts.map +0 -1
- package/dist/runner/test-reporter.js +0 -43
- package/dist/runner/test-reporter.js.map +0 -1
- package/dist/runner/test-runner.d.ts +0 -12
- package/dist/runner/test-runner.d.ts.map +0 -1
- package/dist/runner/test-runner.js +0 -37
- package/dist/runner/test-runner.js.map +0 -1
- package/dist/services/http-fixture-server.d.ts +0 -14
- package/dist/services/http-fixture-server.d.ts.map +0 -1
- package/dist/services/http-fixture-server.js.map +0 -1
- package/dist/testers/audit-tester.d.ts +0 -4
- package/dist/testers/audit-tester.d.ts.map +0 -1
- package/dist/testers/audit-tester.js +0 -74
- package/dist/testers/audit-tester.js.map +0 -1
- package/dist/testers/pipeline-tester.d.ts +0 -4
- package/dist/testers/pipeline-tester.d.ts.map +0 -1
- package/dist/testers/pipeline-tester.js +0 -62
- package/dist/testers/pipeline-tester.js.map +0 -1
- package/dist/testers/roundtrip-tester.d.ts +0 -3
- package/dist/testers/roundtrip-tester.d.ts.map +0 -1
- package/dist/testers/roundtrip-tester.js +0 -77
- package/dist/testers/roundtrip-tester.js.map +0 -1
- package/dist/testers/wire-tester.d.ts +0 -4
- package/dist/testers/wire-tester.d.ts.map +0 -1
- package/dist/testers/wire-tester.js +0 -87
- 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 @@
|
|
|
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
|
|
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(
|
|
9
|
-
const route = adapter.routes(
|
|
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: '
|
|
15
|
-
isStreaming:
|
|
16
|
-
protocol:
|
|
37
|
+
requestId: 'sdk-test',
|
|
38
|
+
isStreaming: scenario.streaming === true,
|
|
39
|
+
protocol: scenario.protocol,
|
|
17
40
|
});
|
|
18
|
-
const events = buildProviderEvents(
|
|
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(
|
|
49
|
-
const port = options?.port ?? 0;
|
|
71
|
+
async start() {
|
|
50
72
|
return new Promise((resolve, reject) => {
|
|
51
|
-
this.server = this.app.listen(
|
|
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(
|
|
72
|
-
return
|
|
73
|
-
const isLast = i ===
|
|
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: '
|
|
99
|
+
requestId: 'sdk-test',
|
|
78
100
|
seq: i,
|
|
79
101
|
message: chunk,
|
|
80
|
-
text:
|
|
102
|
+
text: scenario.expectedText ?? '',
|
|
81
103
|
ts: Date.now(),
|
|
82
104
|
};
|
|
83
105
|
}
|
|
84
106
|
return {
|
|
85
107
|
type: 'stream_event',
|
|
86
|
-
requestId: '
|
|
108
|
+
requestId: 'sdk-test',
|
|
87
109
|
seq: i,
|
|
88
110
|
event: chunk,
|
|
89
111
|
ts: Date.now(),
|
|
90
112
|
};
|
|
91
113
|
});
|
|
92
114
|
}
|
|
93
|
-
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conformance/types.ts"],"names":[],"mappings":""}
|
|
@@ -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"}
|