@substrat-run/contract-tests 0.86.0 → 0.87.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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/node-only-suite.d.ts +15 -0
- package/dist/node-only-suite.d.ts.map +1 -0
- package/dist/node-only-suite.js +75 -0
- package/dist/node-only-suite.js.map +1 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { listContractSuite } from './list-suite.js';
|
|
|
7
7
|
export { scheduleContractSuite } from './schedule-suite.js';
|
|
8
8
|
export { entityCheckConformanceSuite, planEntityCheckCoverage } from './entity-check-suite.js';
|
|
9
9
|
export type { EntityCheckFixture, EntityCheckSuiteOptions, PlannedCheck } from './entity-check-suite.js';
|
|
10
|
+
export { nodeOnlySuite } from './node-only-suite.js';
|
|
11
|
+
export type { NodeOnlyOptions } from './node-only-suite.js';
|
|
10
12
|
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, searchMod, searchModManifest, listMod, listModManifest, } from './modules.js';
|
|
11
13
|
export { connectorCalls, connectorTestFetch, resetConnectorCalls, type ConnectorCall, } from './connector-fixture.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { searchContractSuite } from './search-suite.js';
|
|
|
5
5
|
export { listContractSuite } from './list-suite.js';
|
|
6
6
|
export { scheduleContractSuite } from './schedule-suite.js';
|
|
7
7
|
export { entityCheckConformanceSuite, planEntityCheckCoverage } from './entity-check-suite.js';
|
|
8
|
+
export { nodeOnlySuite } from './node-only-suite.js';
|
|
8
9
|
export { atomicMod, billedMod, brokenMod, connectorMod, contractTestBareOps, contractTestInitialModules, contractTestModules, permMod, scheduleMod, searchMod, searchModManifest, listMod, listModManifest, } from './modules.js';
|
|
9
10
|
export { connectorCalls, connectorTestFetch, resetConnectorCalls, } from './connector-fixture.js';
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,OAAO,EACP,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface NodeOnlyOptions {
|
|
2
|
+
/** Absolute paths to the module source this claim covers. */
|
|
3
|
+
readonly sources: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Assert a module checks permissions only at the node.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* nodeOnlySuite('engine-metering', {
|
|
10
|
+
* sources: [new URL('../src/index.ts', import.meta.url).pathname],
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function nodeOnlySuite(subjectName: string, options: NodeOnlyOptions): void;
|
|
15
|
+
//# sourceMappingURL=node-only-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-only-suite.d.ts","sourceRoot":"","sources":["../src/node-only-suite.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA4BjF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "This module narrows nowhere" — stated so it can stop being true loudly (#865).
|
|
3
|
+
*
|
|
4
|
+
* The conformance kit next door reads an operation's DECLARATION and drives the
|
|
5
|
+
* pair that proves the handler honours it. Seven packages in this repo have no
|
|
6
|
+
* declared operation surface for it to read: their operations are a map of
|
|
7
|
+
* handlers, and the only description of what each one checks is the handler
|
|
8
|
+
* itself. Building that surface is real work and is filed separately.
|
|
9
|
+
*
|
|
10
|
+
* Meanwhile those packages carry the failure mode #865 named — **absence reading
|
|
11
|
+
* as coverage**. Zero narrowed declarations is indistinguishable from nobody
|
|
12
|
+
* having looked, and the packages where nobody looked are exactly the ones worth
|
|
13
|
+
* looking at. So a module that genuinely checks only at the node says so here,
|
|
14
|
+
* and the statement is wired to something that can go red.
|
|
15
|
+
*
|
|
16
|
+
* ## What this actually checks, and what it cannot
|
|
17
|
+
*
|
|
18
|
+
* It reads the module's own source and asserts no two-argument `ctx.check(perm,
|
|
19
|
+
* entityRef)` appears in it. That is a weaker instrument than the conformance
|
|
20
|
+
* kit by a wide margin, and the difference is worth stating plainly rather than
|
|
21
|
+
* leaving for someone to discover:
|
|
22
|
+
*
|
|
23
|
+
* - It proves an absence, never a behaviour. The kit generates a case that
|
|
24
|
+
* FAILS on a wrong implementation; this one only notices a new call site.
|
|
25
|
+
* - It is lexical. A check assembled indirectly — a helper taking the ref, a
|
|
26
|
+
* call built across lines — is invisible to it. It is a tripwire on the
|
|
27
|
+
* obvious path, not a proof.
|
|
28
|
+
* - It says nothing about whether node-only is *right*. That judgement is the
|
|
29
|
+
* prose each caller writes above it, which is the part a reviewer reads.
|
|
30
|
+
*
|
|
31
|
+
* What it does buy: the day someone narrows an operation in one of these
|
|
32
|
+
* packages, this goes red and the change has to either declare the check and
|
|
33
|
+
* wire the real kit, or rewrite the assessment. Which is the whole point — the
|
|
34
|
+
* assessment stops being a comment that was true once.
|
|
35
|
+
*/
|
|
36
|
+
import { describe, expect, it } from 'vitest';
|
|
37
|
+
import { readFileSync } from 'node:fs';
|
|
38
|
+
/** A two-argument `ctx.check(...)` — the narrowed form, spelled the usual way. */
|
|
39
|
+
const NARROWED_CHECK = /\bctx\.check\(\s*[^()]*\([^()]*\)[^()]*,|\bctx\.check\(\s*[^(),]+\s*,/g;
|
|
40
|
+
/**
|
|
41
|
+
* Assert a module checks permissions only at the node.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* nodeOnlySuite('engine-metering', {
|
|
45
|
+
* sources: [new URL('../src/index.ts', import.meta.url).pathname],
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function nodeOnlySuite(subjectName, options) {
|
|
50
|
+
describe(`checks at the node only: ${subjectName}`, () => {
|
|
51
|
+
it('reads the source it claims to cover', () => {
|
|
52
|
+
// The zero guard, same one the conformance kit has: a suite that read
|
|
53
|
+
// nothing would pass every assertion below it.
|
|
54
|
+
expect(options.sources.length).toBeGreaterThan(0);
|
|
55
|
+
for (const path of options.sources) {
|
|
56
|
+
expect(readFileSync(path, 'utf8').length, `${path} is empty`).toBeGreaterThan(0);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
it('has no operation narrowing a check to an entity', () => {
|
|
60
|
+
const found = [];
|
|
61
|
+
for (const path of options.sources) {
|
|
62
|
+
const lines = readFileSync(path, 'utf8').split('\n');
|
|
63
|
+
lines.forEach((line, i) => {
|
|
64
|
+
NARROWED_CHECK.lastIndex = 0;
|
|
65
|
+
if (NARROWED_CHECK.test(line))
|
|
66
|
+
found.push(`${path}:${i + 1}: ${line.trim()}`);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
expect(found, `${subjectName} is declared node-only, but these narrow to an entity. Either the ` +
|
|
70
|
+
'assessment is stale, or the new check needs a declaration and the conformance ' +
|
|
71
|
+
'kit rather than this tripwire.').toEqual([]);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=node-only-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-only-suite.js","sourceRoot":"","sources":["../src/node-only-suite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,kFAAkF;AAClF,MAAM,cAAc,GAAG,wEAAwE,CAAC;AAOhG;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB,EAAE,OAAwB;IACzE,QAAQ,CAAC,4BAA4B,WAAW,EAAE,EAAE,GAAG,EAAE;QACvD,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,sEAAsE;YACtE,+CAA+C;YAC/C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAClD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACnF,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;oBACxB,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC;oBAC7B,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;wBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChF,CAAC,CAAC,CAAC;YACL,CAAC;YACD,MAAM,CACJ,KAAK,EACL,GAAG,WAAW,oEAAoE;gBAChF,gFAAgF;gBAChF,gCAAgC,CACnC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/contract-tests",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"description": "The suite every scope-host adapter must pass, forever (D-14)",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"vitest": "^3.2.7",
|
|
26
|
-
"@substrat-run/contracts": "^0.
|
|
27
|
-
"@substrat-run/kernel": "^0.
|
|
26
|
+
"@substrat-run/contracts": "^0.87.0",
|
|
27
|
+
"@substrat-run/kernel": "^0.87.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^22.0.0",
|