@interop/was-conformance-suite 0.1.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/LICENSE.md +20 -0
- package/README.md +264 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/main.d.ts +64 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +294 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/reporters/json.d.ts +32 -0
- package/dist/cli/reporters/json.d.ts.map +1 -0
- package/dist/cli/reporters/json.js +30 -0
- package/dist/cli/reporters/json.js.map +1 -0
- package/dist/cli/reporters/pretty.d.ts +21 -0
- package/dist/cli/reporters/pretty.d.ts.map +1 -0
- package/dist/cli/reporters/pretty.js +152 -0
- package/dist/cli/reporters/pretty.js.map +1 -0
- package/dist/harness/assert.d.ts +13 -0
- package/dist/harness/assert.d.ts.map +1 -0
- package/dist/harness/assert.js +13 -0
- package/dist/harness/assert.js.map +1 -0
- package/dist/harness/runner.d.ts +25 -0
- package/dist/harness/runner.d.ts.map +1 -0
- package/dist/harness/runner.js +240 -0
- package/dist/harness/runner.js.map +1 -0
- package/dist/harness/types.d.ts +199 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +2 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/helpers.d.ts +103 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +195 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/suites/changes-query-api.d.ts +9 -0
- package/dist/suites/changes-query-api.d.ts.map +1 -0
- package/dist/suites/changes-query-api.js +115 -0
- package/dist/suites/changes-query-api.js.map +1 -0
- package/dist/suites/client-backends.d.ts +11 -0
- package/dist/suites/client-backends.d.ts.map +1 -0
- package/dist/suites/client-backends.js +198 -0
- package/dist/suites/client-backends.js.map +1 -0
- package/dist/suites/client-delegation.d.ts +21 -0
- package/dist/suites/client-delegation.d.ts.map +1 -0
- package/dist/suites/client-delegation.js +94 -0
- package/dist/suites/client-delegation.js.map +1 -0
- package/dist/suites/client-export-import.d.ts +19 -0
- package/dist/suites/client-export-import.d.ts.map +1 -0
- package/dist/suites/client-export-import.js +74 -0
- package/dist/suites/client-export-import.js.map +1 -0
- package/dist/suites/client-resources.d.ts +11 -0
- package/dist/suites/client-resources.d.ts.map +1 -0
- package/dist/suites/client-resources.js +193 -0
- package/dist/suites/client-resources.js.map +1 -0
- package/dist/suites/client-spaces.d.ts +11 -0
- package/dist/suites/client-spaces.d.ts.map +1 -0
- package/dist/suites/client-spaces.js +347 -0
- package/dist/suites/client-spaces.js.map +1 -0
- package/dist/suites/collection-api.d.ts +7 -0
- package/dist/suites/collection-api.d.ts.map +1 -0
- package/dist/suites/collection-api.js +266 -0
- package/dist/suites/collection-api.js.map +1 -0
- package/dist/suites/encryption-marker-api.d.ts +9 -0
- package/dist/suites/encryption-marker-api.d.ts.map +1 -0
- package/dist/suites/encryption-marker-api.js +266 -0
- package/dist/suites/encryption-marker-api.js.map +1 -0
- package/dist/suites/index.d.ts +23 -0
- package/dist/suites/index.d.ts.map +1 -0
- package/dist/suites/index.js +32 -0
- package/dist/suites/index.js.map +1 -0
- package/dist/suites/policy-api.d.ts +12 -0
- package/dist/suites/policy-api.d.ts.map +1 -0
- package/dist/suites/policy-api.js +187 -0
- package/dist/suites/policy-api.js.map +1 -0
- package/dist/suites/resource-api.d.ts +8 -0
- package/dist/suites/resource-api.d.ts.map +1 -0
- package/dist/suites/resource-api.js +393 -0
- package/dist/suites/resource-api.js.map +1 -0
- package/dist/suites/server.d.ts +3 -0
- package/dist/suites/server.d.ts.map +1 -0
- package/dist/suites/server.js +25 -0
- package/dist/suites/server.js.map +1 -0
- package/dist/suites/spaces-api.d.ts +11 -0
- package/dist/suites/spaces-api.d.ts.map +1 -0
- package/dist/suites/spaces-api.js +411 -0
- package/dist/suites/spaces-api.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import assert from './assert.js';
|
|
5
|
+
/** Generous default: remote servers over a WAN can be slow. */
|
|
6
|
+
export const DEFAULT_TEST_TIMEOUT_MS = 60_000;
|
|
7
|
+
/** Thrown by `ctx.skip()`; the runner records a skip result. */
|
|
8
|
+
class SkipSignal extends Error {
|
|
9
|
+
reason;
|
|
10
|
+
constructor(reason) {
|
|
11
|
+
super(reason ?? 'skipped');
|
|
12
|
+
this.reason = reason;
|
|
13
|
+
this.name = 'SkipSignal';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class TimeoutSignal extends Error {
|
|
17
|
+
constructor(ms) {
|
|
18
|
+
super(`timed out after ${ms}ms`);
|
|
19
|
+
this.name = 'TimeoutSignal';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function withTimeout(fn, ms) {
|
|
23
|
+
let timer;
|
|
24
|
+
try {
|
|
25
|
+
await Promise.race([
|
|
26
|
+
fn(),
|
|
27
|
+
new Promise((_resolve, reject) => {
|
|
28
|
+
timer = setTimeout(() => reject(new TimeoutSignal(ms)), ms);
|
|
29
|
+
})
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function toTestError(err) {
|
|
37
|
+
if (err instanceof assert.AssertionError) {
|
|
38
|
+
return {
|
|
39
|
+
message: err.message,
|
|
40
|
+
expected: err.expected,
|
|
41
|
+
actual: err.actual,
|
|
42
|
+
operator: err.operator,
|
|
43
|
+
stack: err.stack
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (err instanceof Error) {
|
|
47
|
+
return { message: err.message, stack: err.stack };
|
|
48
|
+
}
|
|
49
|
+
return { message: String(err) };
|
|
50
|
+
}
|
|
51
|
+
function emptyCounts() {
|
|
52
|
+
return { total: 0, pass: 0, fail: 0, skip: 0, optionalFail: 0 };
|
|
53
|
+
}
|
|
54
|
+
function tally(counts, result) {
|
|
55
|
+
counts.total++;
|
|
56
|
+
counts[result.status]++;
|
|
57
|
+
if (result.status === 'fail' && result.optional) {
|
|
58
|
+
counts.optionalFail++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function now() {
|
|
62
|
+
return globalThis.performance?.now() ?? Date.now();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Runs the given suites sequentially against a prepared context, emitting
|
|
66
|
+
* progress events along the way. Never throws for test failures -- those are
|
|
67
|
+
* captured in the returned report.
|
|
68
|
+
*
|
|
69
|
+
* @param options {object}
|
|
70
|
+
* @param options.suites {Suite[]} suites to run, in order
|
|
71
|
+
* @param options.ctx {ConformanceContext} context from `createContext()`
|
|
72
|
+
* @param [options.onEvent] {Function} progress-event callback
|
|
73
|
+
* @param [options.testTimeoutMs] {number} per-test (and per-hook) timeout
|
|
74
|
+
* @param [options.failFast] {boolean} stop after the first non-optional
|
|
75
|
+
* failure; remaining tests are reported as skipped
|
|
76
|
+
* @returns {Promise<RunReport>}
|
|
77
|
+
*/
|
|
78
|
+
export async function runSuites({ suites, ctx, onEvent, testTimeoutMs = DEFAULT_TEST_TIMEOUT_MS, failFast = false }) {
|
|
79
|
+
const emit = (event) => {
|
|
80
|
+
onEvent?.(event);
|
|
81
|
+
};
|
|
82
|
+
const runStart = now();
|
|
83
|
+
const startedAt = new Date().toISOString();
|
|
84
|
+
emit({
|
|
85
|
+
type: 'run-start',
|
|
86
|
+
serverUrl: ctx.serverUrl,
|
|
87
|
+
suiteCount: suites.length,
|
|
88
|
+
testCount: suites.reduce((sum, s) => sum + s.tests.length, 0)
|
|
89
|
+
});
|
|
90
|
+
const suiteResults = [];
|
|
91
|
+
const runCounts = emptyCounts();
|
|
92
|
+
// Set once a non-optional test fails under failFast; every test after that
|
|
93
|
+
// is reported as skipped instead of run.
|
|
94
|
+
let aborted = false;
|
|
95
|
+
for (const suite of suites) {
|
|
96
|
+
const suiteStart = now();
|
|
97
|
+
const suiteCounts = emptyCounts();
|
|
98
|
+
const results = [];
|
|
99
|
+
emit({
|
|
100
|
+
type: 'suite-start',
|
|
101
|
+
suiteId: suite.id,
|
|
102
|
+
name: suite.name,
|
|
103
|
+
optional: suite.optional ?? false,
|
|
104
|
+
testCount: suite.tests.length
|
|
105
|
+
});
|
|
106
|
+
let state;
|
|
107
|
+
let setupError;
|
|
108
|
+
if (!aborted && suite.setup) {
|
|
109
|
+
try {
|
|
110
|
+
await withTimeout(async () => {
|
|
111
|
+
state = await suite.setup(ctx);
|
|
112
|
+
}, testTimeoutMs);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
setupError = toTestError(err);
|
|
116
|
+
setupError.message = `suite setup failed: ${setupError.message}`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Group setup hooks run lazily, before the first test of their group;
|
|
120
|
+
// a failed group setup fails that group's tests.
|
|
121
|
+
const groupErrors = new Map();
|
|
122
|
+
const enteredGroups = new Set();
|
|
123
|
+
const runTest = async (test) => {
|
|
124
|
+
const optional = (suite.optional ?? false) || (test.optional ?? false);
|
|
125
|
+
const base = {
|
|
126
|
+
suiteId: suite.id,
|
|
127
|
+
testId: test.id,
|
|
128
|
+
name: test.name,
|
|
129
|
+
...(test.group !== undefined && { group: test.group }),
|
|
130
|
+
optional,
|
|
131
|
+
...(test.specRefs !== undefined && { specRefs: test.specRefs })
|
|
132
|
+
};
|
|
133
|
+
if (aborted) {
|
|
134
|
+
return {
|
|
135
|
+
...base,
|
|
136
|
+
status: 'skip',
|
|
137
|
+
durationMs: 0,
|
|
138
|
+
skipReason: 'skipped (fail-fast)'
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (setupError) {
|
|
142
|
+
return { ...base, status: 'fail', durationMs: 0, error: setupError };
|
|
143
|
+
}
|
|
144
|
+
if (test.group !== undefined && !enteredGroups.has(test.group)) {
|
|
145
|
+
enteredGroups.add(test.group);
|
|
146
|
+
const group = suite.groups?.find(g => g.name === test.group);
|
|
147
|
+
if (group) {
|
|
148
|
+
try {
|
|
149
|
+
await withTimeout(() => group.setup(ctx, state), testTimeoutMs);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
const error = toTestError(err);
|
|
153
|
+
error.message = `group setup failed: ${error.message}`;
|
|
154
|
+
groupErrors.set(test.group, error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const groupError = test.group !== undefined ? groupErrors.get(test.group) : undefined;
|
|
159
|
+
if (groupError) {
|
|
160
|
+
return { ...base, status: 'fail', durationMs: 0, error: groupError };
|
|
161
|
+
}
|
|
162
|
+
const testCtx = {
|
|
163
|
+
...ctx,
|
|
164
|
+
skip: (reason) => {
|
|
165
|
+
throw new SkipSignal(reason);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const testStart = now();
|
|
169
|
+
try {
|
|
170
|
+
await withTimeout(() => test.run(testCtx, state), testTimeoutMs);
|
|
171
|
+
return { ...base, status: 'pass', durationMs: now() - testStart };
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
if (err instanceof SkipSignal) {
|
|
175
|
+
return {
|
|
176
|
+
...base,
|
|
177
|
+
status: 'skip',
|
|
178
|
+
durationMs: now() - testStart,
|
|
179
|
+
...(err.reason !== undefined && { skipReason: err.reason })
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
...base,
|
|
184
|
+
status: 'fail',
|
|
185
|
+
durationMs: now() - testStart,
|
|
186
|
+
error: toTestError(err)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
for (const test of suite.tests) {
|
|
191
|
+
emit({
|
|
192
|
+
type: 'test-start',
|
|
193
|
+
suiteId: suite.id,
|
|
194
|
+
testId: test.id,
|
|
195
|
+
name: test.name,
|
|
196
|
+
...(test.group !== undefined && { group: test.group }),
|
|
197
|
+
optional: (suite.optional ?? false) || (test.optional ?? false)
|
|
198
|
+
});
|
|
199
|
+
const result = await runTest(test);
|
|
200
|
+
tally(suiteCounts, result);
|
|
201
|
+
tally(runCounts, result);
|
|
202
|
+
results.push(result);
|
|
203
|
+
emit({ type: 'test-end', result });
|
|
204
|
+
if (failFast && result.status === 'fail' && !result.optional) {
|
|
205
|
+
aborted = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
let teardownError;
|
|
209
|
+
if (!setupError && suite.teardown) {
|
|
210
|
+
try {
|
|
211
|
+
await withTimeout(() => suite.teardown(ctx, state), testTimeoutMs);
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
teardownError = toTestError(err).message;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const suiteResult = {
|
|
218
|
+
suiteId: suite.id,
|
|
219
|
+
name: suite.name,
|
|
220
|
+
optional: suite.optional ?? false,
|
|
221
|
+
durationMs: now() - suiteStart,
|
|
222
|
+
counts: suiteCounts,
|
|
223
|
+
results,
|
|
224
|
+
...(teardownError !== undefined && { teardownError })
|
|
225
|
+
};
|
|
226
|
+
suiteResults.push(suiteResult);
|
|
227
|
+
emit({ type: 'suite-end', result: suiteResult });
|
|
228
|
+
}
|
|
229
|
+
const report = {
|
|
230
|
+
serverUrl: ctx.serverUrl,
|
|
231
|
+
startedAt,
|
|
232
|
+
durationMs: now() - runStart,
|
|
233
|
+
counts: runCounts,
|
|
234
|
+
conformant: runCounts.fail === runCounts.optionalFail,
|
|
235
|
+
suites: suiteResults
|
|
236
|
+
};
|
|
237
|
+
emit({ type: 'run-end', report });
|
|
238
|
+
return report;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { WasClient, Space } from '@interop/was-client';
|
|
5
|
+
import type { ZcapClient } from '@interop/ezcap';
|
|
6
|
+
import type { ISigner } from '@interop/data-integrity-core';
|
|
7
|
+
/**
|
|
8
|
+
* A test identity with full (root) authority: a low-level ZcapClient for raw
|
|
9
|
+
* request()/delegate() calls and a high-level WasClient wrapping the same
|
|
10
|
+
* signer. Suites may stash per-suite scratch data (space ids, etc.) on a
|
|
11
|
+
* shallow clone of an actor -- never on the shared instance itself.
|
|
12
|
+
*/
|
|
13
|
+
export interface Actor {
|
|
14
|
+
did: string;
|
|
15
|
+
rootClient: ZcapClient;
|
|
16
|
+
was: WasClient;
|
|
17
|
+
}
|
|
18
|
+
/** A delegated-app identity: no root authority, just a signer to invoke with. */
|
|
19
|
+
export interface DelegatedActor {
|
|
20
|
+
did: string;
|
|
21
|
+
signer: ISigner;
|
|
22
|
+
}
|
|
23
|
+
/** The deterministic test identities, built once per run. */
|
|
24
|
+
export interface Actors {
|
|
25
|
+
alice: Actor;
|
|
26
|
+
aliceDelegatedApp: DelegatedActor;
|
|
27
|
+
bob: Actor;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Everything a conformance run needs, built once per run by
|
|
31
|
+
* `createContext()`: the target server, the test identities, and the
|
|
32
|
+
* provisioning/utility helpers bound to that server.
|
|
33
|
+
*/
|
|
34
|
+
export interface ConformanceContext {
|
|
35
|
+
serverUrl: string;
|
|
36
|
+
onboardingToken: string | null;
|
|
37
|
+
actors: Actors;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a space via the onboarding token (if configured) or a signed
|
|
40
|
+
* ZCap request, returning the raw status/headers/data for assertions.
|
|
41
|
+
*/
|
|
42
|
+
createSpace: (options: {
|
|
43
|
+
spaceDescription: object;
|
|
44
|
+
rootClient: ZcapClient;
|
|
45
|
+
}) => Promise<{
|
|
46
|
+
status: number;
|
|
47
|
+
headers: Headers;
|
|
48
|
+
data: any;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Provisions a Space for the high-level WasClient suites, via the
|
|
52
|
+
* onboarding token when configured, else the client's signed createSpace.
|
|
53
|
+
*/
|
|
54
|
+
provisionSpace: (options: {
|
|
55
|
+
was: WasClient;
|
|
56
|
+
name?: string;
|
|
57
|
+
}) => Promise<Space>;
|
|
58
|
+
/** Builds a high-level WAS client for a signer, bound to this server. */
|
|
59
|
+
wasClient: (options: {
|
|
60
|
+
signer: ISigner;
|
|
61
|
+
}) => WasClient;
|
|
62
|
+
/** Builds a low-level ZCap client for a signer. */
|
|
63
|
+
zcapClient: (options: {
|
|
64
|
+
signer: ISigner;
|
|
65
|
+
}) => ZcapClient;
|
|
66
|
+
/** Generates a fresh UUID (space/collection/resource id). */
|
|
67
|
+
generateId: () => string;
|
|
68
|
+
/** Strips the OPTIONAL `createdBy` property before exact-shape comparison. */
|
|
69
|
+
withoutCreatedBy: (value: unknown) => unknown;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The context passed to each test's `run`: the run context plus a
|
|
73
|
+
* first-class skip escape (throws; the runner records a skip result).
|
|
74
|
+
*/
|
|
75
|
+
export interface TestContext extends ConformanceContext {
|
|
76
|
+
skip: (reason?: string) => never;
|
|
77
|
+
}
|
|
78
|
+
export interface TestCase<S = any> {
|
|
79
|
+
/** Stable slug, e.g. 'spaces.create-post'. Unique within the suite. */
|
|
80
|
+
id: string;
|
|
81
|
+
/** Human-readable name -- the original it() description, verbatim. */
|
|
82
|
+
name: string;
|
|
83
|
+
/** Nested describe() label this test belonged to, for display grouping. */
|
|
84
|
+
group?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Marks a test that reflects reference-server behavior rather than a clear
|
|
87
|
+
* spec MUST. Optional tests run by default but their failures are reported
|
|
88
|
+
* as warnings, not conformance failures.
|
|
89
|
+
*/
|
|
90
|
+
optional?: boolean;
|
|
91
|
+
/** Deep links into the WAS spec that this test asserts. */
|
|
92
|
+
specRefs?: string[];
|
|
93
|
+
run: (ctx: TestContext, state: S) => Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
/** A nested describe() that had its own before() hook. */
|
|
96
|
+
export interface SuiteGroup<S = any> {
|
|
97
|
+
/** Matches the `group` field of the tests it sets up. */
|
|
98
|
+
name: string;
|
|
99
|
+
/** Runs once, before the first test of the group. May extend `state`. */
|
|
100
|
+
setup: (ctx: ConformanceContext, state: S) => Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
export interface Suite<S = any> {
|
|
103
|
+
/** Stable slug, e.g. 'spaces-api'. */
|
|
104
|
+
id: string;
|
|
105
|
+
/** Human-readable name -- the original describe() description, verbatim. */
|
|
106
|
+
name: string;
|
|
107
|
+
/** Marks every test in the suite optional (see TestCase.optional). */
|
|
108
|
+
optional?: boolean;
|
|
109
|
+
specRefs?: string[];
|
|
110
|
+
/** Replaces the original before() hook; its return value is the suite state. */
|
|
111
|
+
setup?: (ctx: ConformanceContext) => Promise<S>;
|
|
112
|
+
/** Replaces the original after() hook. Best-effort: failures never affect results. */
|
|
113
|
+
teardown?: (ctx: ConformanceContext, state: S) => Promise<void>;
|
|
114
|
+
/** Setup hooks for nested describes, keyed by group name. */
|
|
115
|
+
groups?: Array<SuiteGroup<S>>;
|
|
116
|
+
/** Ordered flat list; tests carrying a `group` label sit in declaration order. */
|
|
117
|
+
tests: Array<TestCase<S>>;
|
|
118
|
+
}
|
|
119
|
+
export type TestStatus = 'pass' | 'fail' | 'skip';
|
|
120
|
+
export interface TestError {
|
|
121
|
+
message: string;
|
|
122
|
+
/** Present when the failure was an AssertionError. */
|
|
123
|
+
expected?: unknown;
|
|
124
|
+
actual?: unknown;
|
|
125
|
+
operator?: string;
|
|
126
|
+
stack?: string;
|
|
127
|
+
}
|
|
128
|
+
export interface TestResult {
|
|
129
|
+
suiteId: string;
|
|
130
|
+
testId: string;
|
|
131
|
+
name: string;
|
|
132
|
+
group?: string;
|
|
133
|
+
/** Effective flag: the test's own `optional` or its suite's. */
|
|
134
|
+
optional: boolean;
|
|
135
|
+
status: TestStatus;
|
|
136
|
+
durationMs: number;
|
|
137
|
+
error?: TestError;
|
|
138
|
+
skipReason?: string;
|
|
139
|
+
specRefs?: string[];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Aggregate counts. `fail` includes optional-test failures; `optionalFail`
|
|
143
|
+
* is that subset. A run is conformant when `fail === optionalFail`.
|
|
144
|
+
*/
|
|
145
|
+
export interface RunCounts {
|
|
146
|
+
total: number;
|
|
147
|
+
pass: number;
|
|
148
|
+
fail: number;
|
|
149
|
+
skip: number;
|
|
150
|
+
optionalFail: number;
|
|
151
|
+
}
|
|
152
|
+
export interface SuiteResult {
|
|
153
|
+
suiteId: string;
|
|
154
|
+
name: string;
|
|
155
|
+
optional: boolean;
|
|
156
|
+
durationMs: number;
|
|
157
|
+
counts: RunCounts;
|
|
158
|
+
results: TestResult[];
|
|
159
|
+
/** Present when the suite's teardown hook threw (best-effort cleanup). */
|
|
160
|
+
teardownError?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface RunReport {
|
|
163
|
+
serverUrl: string;
|
|
164
|
+
startedAt: string;
|
|
165
|
+
durationMs: number;
|
|
166
|
+
counts: RunCounts;
|
|
167
|
+
/** True when no non-optional test failed. */
|
|
168
|
+
conformant: boolean;
|
|
169
|
+
suites: SuiteResult[];
|
|
170
|
+
}
|
|
171
|
+
export type RunEvent = {
|
|
172
|
+
type: 'run-start';
|
|
173
|
+
serverUrl: string;
|
|
174
|
+
suiteCount: number;
|
|
175
|
+
testCount: number;
|
|
176
|
+
} | {
|
|
177
|
+
type: 'suite-start';
|
|
178
|
+
suiteId: string;
|
|
179
|
+
name: string;
|
|
180
|
+
optional: boolean;
|
|
181
|
+
testCount: number;
|
|
182
|
+
} | {
|
|
183
|
+
type: 'test-start';
|
|
184
|
+
suiteId: string;
|
|
185
|
+
testId: string;
|
|
186
|
+
name: string;
|
|
187
|
+
group?: string;
|
|
188
|
+
optional: boolean;
|
|
189
|
+
} | {
|
|
190
|
+
type: 'test-end';
|
|
191
|
+
result: TestResult;
|
|
192
|
+
} | {
|
|
193
|
+
type: 'suite-end';
|
|
194
|
+
result: SuiteResult;
|
|
195
|
+
} | {
|
|
196
|
+
type: 'run-end';
|
|
197
|
+
report: RunReport;
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/harness/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/harness/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { ZcapClient } from '@interop/ezcap';
|
|
5
|
+
import { WasClient } from '@interop/was-client';
|
|
6
|
+
import type { Space } from '@interop/was-client';
|
|
7
|
+
import type { ISigner } from '@interop/data-integrity-core';
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
import type { Actors, ConformanceContext } from './harness/types.js';
|
|
10
|
+
export declare function zcapClient({ signer }: {
|
|
11
|
+
signer: ISigner;
|
|
12
|
+
}): ZcapClient;
|
|
13
|
+
/**
|
|
14
|
+
* Builds a high-level WAS client wrapping a ZcapClient for the given signer.
|
|
15
|
+
* The `serverUrl` is the base for both URL building and zcap invocationTargets.
|
|
16
|
+
*
|
|
17
|
+
* @param options {object}
|
|
18
|
+
* @param options.serverUrl {string}
|
|
19
|
+
* @param options.signer {ISigner}
|
|
20
|
+
* @returns {WasClient}
|
|
21
|
+
*/
|
|
22
|
+
export declare function wasClient({ serverUrl, signer }: {
|
|
23
|
+
serverUrl: string;
|
|
24
|
+
signer: ISigner;
|
|
25
|
+
}): WasClient;
|
|
26
|
+
export declare function buildZcapClients({ serverUrl }: {
|
|
27
|
+
serverUrl: string;
|
|
28
|
+
}): Promise<Actors>;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a space on the server using an onboarding token (if configured) or
|
|
31
|
+
* the WAS client. Returns a normalized response object for consistent
|
|
32
|
+
* assertion.
|
|
33
|
+
*
|
|
34
|
+
* The ZCap path goes through `WasClient.request()` -- the client's signed
|
|
35
|
+
* escape hatch -- so the conformance harness exercises the client while still
|
|
36
|
+
* surfacing the raw status/headers/data the create-space assertions rely on.
|
|
37
|
+
*
|
|
38
|
+
* @param options {object}
|
|
39
|
+
* @param options.serverUrl {string}
|
|
40
|
+
* @param options.onboardingToken {string|null}
|
|
41
|
+
* @param options.spaceDescription {object}
|
|
42
|
+
* @param options.rootClient {ZcapClient} ZCap client -- used when no onboarding
|
|
43
|
+
* token is set
|
|
44
|
+
* @returns {Promise<{status: number, headers: Headers, data: any}>}
|
|
45
|
+
*/
|
|
46
|
+
export declare function createSpace({ serverUrl, onboardingToken, spaceDescription, rootClient }: {
|
|
47
|
+
serverUrl: string;
|
|
48
|
+
onboardingToken: string | null;
|
|
49
|
+
spaceDescription: object;
|
|
50
|
+
rootClient: ZcapClient;
|
|
51
|
+
}): Promise<{
|
|
52
|
+
status: number;
|
|
53
|
+
headers: Headers;
|
|
54
|
+
data: any;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Provisions a Space for the high-level `WasClient` suites: with an onboarding
|
|
58
|
+
* token configured, creates it via the token path (a plain fetch with
|
|
59
|
+
* `Authorization: Bearer`, the same wire form `createSpace` above uses) and
|
|
60
|
+
* returns the client's lazy handle to the new id; otherwise delegates to the
|
|
61
|
+
* client's own signed `createSpace`. This is what lets the client suites run
|
|
62
|
+
* against a server that gates provisioning behind an onboarding token.
|
|
63
|
+
*
|
|
64
|
+
* @param options {object}
|
|
65
|
+
* @param options.serverUrl {string}
|
|
66
|
+
* @param options.onboardingToken {string|null}
|
|
67
|
+
* @param options.was {WasClient} the suite's high-level client
|
|
68
|
+
* @param [options.name] {string} optional Space name
|
|
69
|
+
* @returns {Promise<Space>}
|
|
70
|
+
*/
|
|
71
|
+
export declare function provisionSpace({ serverUrl, onboardingToken, was, name }: {
|
|
72
|
+
serverUrl: string;
|
|
73
|
+
onboardingToken: string | null;
|
|
74
|
+
was: WasClient;
|
|
75
|
+
name?: string;
|
|
76
|
+
}): Promise<Space>;
|
|
77
|
+
/**
|
|
78
|
+
* Strips a `createdBy` property from a Space/Collection description, if
|
|
79
|
+
* present, before an exact-shape comparison. The spec makes `createdBy`
|
|
80
|
+
* OPTIONAL ("a client MUST treat an absent `createdBy` as not recorded"), so a
|
|
81
|
+
* conforming external server may legitimately omit it -- and one that records
|
|
82
|
+
* it may report a creator this suite cannot predict. Either way the conformance
|
|
83
|
+
* suite must not assert on it.
|
|
84
|
+
*
|
|
85
|
+
* @param value {unknown}
|
|
86
|
+
* @returns {unknown}
|
|
87
|
+
*/
|
|
88
|
+
export declare function withoutCreatedBy(value: unknown): unknown;
|
|
89
|
+
/**
|
|
90
|
+
* Builds the per-run conformance context: the deterministic test identities
|
|
91
|
+
* plus the provisioning/utility helpers bound to the target server.
|
|
92
|
+
*
|
|
93
|
+
* @param options {object}
|
|
94
|
+
* @param options.serverUrl {string}
|
|
95
|
+
* @param [options.onboardingToken] {string|null}
|
|
96
|
+
* @returns {Promise<ConformanceContext>}
|
|
97
|
+
*/
|
|
98
|
+
export declare function createContext({ serverUrl, onboardingToken }: {
|
|
99
|
+
serverUrl: string;
|
|
100
|
+
onboardingToken?: string | null;
|
|
101
|
+
}): Promise<ConformanceContext>;
|
|
102
|
+
export { uuidv4 as generateId };
|
|
103
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAIhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAapE,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,UAAU,CAMtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,MAAM,EACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,SAAS,CAEZ;AAED,wBAAsB,gBAAgB,CAAC,EACrC,SAAS,EACV,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAAC,EAChC,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,UAAU,EACX,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;CACvB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,CAAC,CAwB3D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAAC,EACnC,SAAS,EACT,eAAe,EACf,GAAG,EACH,IAAI,EACL,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,GAAG,EAAE,SAAS,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC,KAAK,CAAC,CAmBjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMxD;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,EAClC,SAAS,EACT,eAAsB,EACvB,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAe9B;AAED,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,CAAA"}
|