@playfast/reform-proof-vitest 0.0.2
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 +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +27 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +41 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register a function to run immediately before every proof test. Idempotent by
|
|
3
|
+
* reference; intended to be called from a side-effect module the plugin imports
|
|
4
|
+
* into `*.proof.ts` files only.
|
|
5
|
+
*/
|
|
6
|
+
export declare const setProofTestHook: (hook: () => void) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Register every `ProofSuite` among the given values as vitest tests. Non-suite
|
|
9
|
+
* values are ignored, so a whole module's exports can be passed verbatim — which
|
|
10
|
+
* is exactly what `reformProofPlugin` does.
|
|
11
|
+
*/
|
|
12
|
+
export declare const registerSuites: (values: ReadonlyArray<unknown>) => void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,IAAI,KAAG,IAEnD,CAAA;AAqBD;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,aAAa,CAAC,OAAO,CAAC,KAAG,IAM/D,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isProofSuite, withProofRunner } from '@playfast/reform-proof';
|
|
2
|
+
import { describe, test } from 'vitest';
|
|
3
|
+
// reform-proof vitest adapter — turns a reform proof `ProofSuite` into native
|
|
4
|
+
// vitest tests (a `describe` per product, a `test` per requirement), each run
|
|
5
|
+
// through the proof engine via the `ProofRunner` layer. Pair it with
|
|
6
|
+
// `reformProofPlugin` (./plugin), which appends a `registerSuites(...)` call to
|
|
7
|
+
// every `*.proof.ts` so suites become tests with no per-feature wrapper file.
|
|
8
|
+
// A suite registers exactly once even if several modules import it (its own test
|
|
9
|
+
// entry plus any flow test that pulls it in). Identity-keyed, so a suite value is
|
|
10
|
+
// never double-registered within a worker.
|
|
11
|
+
const registered = new WeakSet();
|
|
12
|
+
// Per-proof-test setup hooks. An app registers one (via a module the plugin's
|
|
13
|
+
// `setup` option imports into each `*.proof.ts`) to run app-specific preparation
|
|
14
|
+
// right before each proof renders — e.g. installing a render-free React-hooks
|
|
15
|
+
// dispatcher for view bodies that reach for hooks. The adapter stays view-agnostic:
|
|
16
|
+
// it just runs whatever the app registered, only inside proof-test bodies, so a
|
|
17
|
+
// `*.test.ts` that controls global state is never disturbed.
|
|
18
|
+
const setupHooks = new Set();
|
|
19
|
+
/**
|
|
20
|
+
* Register a function to run immediately before every proof test. Idempotent by
|
|
21
|
+
* reference; intended to be called from a side-effect module the plugin imports
|
|
22
|
+
* into `*.proof.ts` files only.
|
|
23
|
+
*/
|
|
24
|
+
export const setProofTestHook = (hook) => {
|
|
25
|
+
setupHooks.add(hook);
|
|
26
|
+
};
|
|
27
|
+
const runSetupHooks = () => {
|
|
28
|
+
for (const hook of setupHooks)
|
|
29
|
+
hook();
|
|
30
|
+
};
|
|
31
|
+
const registerSuite = (suite) => {
|
|
32
|
+
describe(suite.product.manifest.name, () => {
|
|
33
|
+
for (const proof of suite.proofs) {
|
|
34
|
+
const statement = proof.requirement.manifest.statement;
|
|
35
|
+
test(statement, async () => {
|
|
36
|
+
runSetupHooks();
|
|
37
|
+
const result = await withProofRunner((runner) => runner.executeProof(proof));
|
|
38
|
+
if (!result.ok) {
|
|
39
|
+
throw new Error(`reform-proof: ${statement} — ${result.error ?? 'failed'}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Register every `ProofSuite` among the given values as vitest tests. Non-suite
|
|
47
|
+
* values are ignored, so a whole module's exports can be passed verbatim — which
|
|
48
|
+
* is exactly what `reformProofPlugin` does.
|
|
49
|
+
*/
|
|
50
|
+
export const registerSuites = (values) => {
|
|
51
|
+
for (const value of values) {
|
|
52
|
+
if (!isProofSuite(value) || registered.has(value))
|
|
53
|
+
continue;
|
|
54
|
+
registered.add(value);
|
|
55
|
+
registerSuite(value);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAEvC,8EAA8E;AAC9E,8EAA8E;AAC9E,qEAAqE;AACrE,gFAAgF;AAChF,8EAA8E;AAE9E,iFAAiF;AACjF,kFAAkF;AAClF,2CAA2C;AAC3C,MAAM,UAAU,GAAG,IAAI,OAAO,EAAc,CAAA;AAE5C,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAC9E,oFAAoF;AACpF,gFAAgF;AAChF,6DAA6D;AAC7D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAc,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAgB,EAAQ,EAAE;IACzD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,GAAS,EAAE;IAC/B,KAAK,MAAM,IAAI,IAAI,UAAU;QAAE,IAAI,EAAE,CAAA;AACvC,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,KAAiB,EAAQ,EAAE;IAChD,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE;QACzC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAA;YACtD,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACzB,aAAa,EAAE,CAAA;gBACf,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC5E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,MAAM,MAAM,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC,CAAA;gBAC7E,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAA8B,EAAQ,EAAE;IACrE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC3D,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrB,aAAa,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAA"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Options for `reformProofPlugin`. */
|
|
2
|
+
export interface ReformProofPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Module specifier(s) the plugin side-effect-imports into every `*.proof.ts`,
|
|
5
|
+
* before registering its suites. Use to register per-proof-test setup
|
|
6
|
+
* (`setProofTestHook`) that must run ONLY in proof-test workers — e.g. an app's
|
|
7
|
+
* headless React-hooks dispatcher. Imported only into `*.proof.ts`, so regular
|
|
8
|
+
* `*.test.ts` files are never affected.
|
|
9
|
+
*/
|
|
10
|
+
readonly setup?: string | ReadonlyArray<string>;
|
|
11
|
+
}
|
|
12
|
+
/** The minimal vite plugin shape this adapter needs — structurally a `Plugin`,
|
|
13
|
+
* declared locally so the package need not depend on vite's types. */
|
|
14
|
+
export interface ReformProofPlugin {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly enforce: 'post';
|
|
17
|
+
transform(code: string, id: string): Promise<{
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly map: null;
|
|
20
|
+
} | null>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The plugin. Runs `post` (after TS→JS), so it lexes plain JS exports reliably.
|
|
24
|
+
* Only `*.proof.ts` modules are touched; everything else passes through.
|
|
25
|
+
*/
|
|
26
|
+
export declare const reformProofPlugin: (options?: ReformProofPluginOptions) => ReformProofPlugin;
|
|
27
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,uCAAuC;AACvC,MAAM,WAAW,wBAAwB;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;CAChD;AAED;uEACuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CACjE;AAOD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,wBAAwB,KAAG,iBAwBtE,CAAA"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { init, parse } from 'es-module-lexer';
|
|
2
|
+
// reform-proof vitest plugin — a vite/vitest plugin that auto-registers proof
|
|
3
|
+
// suites. For every `*.proof.ts` file vitest collects, it lexes the module's
|
|
4
|
+
// export names and appends a `registerSuites([...exports])` call, so each exported
|
|
5
|
+
// `ProofSuite` becomes native vitest tests. This is what lets a feature ship a
|
|
6
|
+
// `*.proof.ts` with NO hand-written `*.proof.test.ts` wrapper: add this plugin and
|
|
7
|
+
// the glob `**/*.proof.ts` to the vitest config, and the suites run themselves.
|
|
8
|
+
const PROOF_RE = /\.proof\.ts$/;
|
|
9
|
+
const sourcePath = (id) => id.split('?')[0] ?? id;
|
|
10
|
+
const setupList = (setup) => setup === undefined ? [] : typeof setup === 'string' ? [setup] : setup;
|
|
11
|
+
/**
|
|
12
|
+
* The plugin. Runs `post` (after TS→JS), so it lexes plain JS exports reliably.
|
|
13
|
+
* Only `*.proof.ts` modules are touched; everything else passes through.
|
|
14
|
+
*/
|
|
15
|
+
export const reformProofPlugin = (options) => {
|
|
16
|
+
const setupImports = setupList(options?.setup)
|
|
17
|
+
.map((spec) => `import '${spec}'`)
|
|
18
|
+
.join('\n');
|
|
19
|
+
return {
|
|
20
|
+
name: 'reform-proof-vitest',
|
|
21
|
+
enforce: 'post',
|
|
22
|
+
async transform(code, id) {
|
|
23
|
+
if (!PROOF_RE.test(sourcePath(id)))
|
|
24
|
+
return null;
|
|
25
|
+
await init;
|
|
26
|
+
const [, exports] = parse(code);
|
|
27
|
+
// Reference each export's LOCAL binding (in scope after the module body); a
|
|
28
|
+
// re-export-from has no local name (`ln` undefined) and is skipped.
|
|
29
|
+
const names = exports
|
|
30
|
+
.map((exportSpec) => exportSpec.ln)
|
|
31
|
+
.filter((local) => typeof local === 'string' && local.length > 0);
|
|
32
|
+
if (names.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const epilogue = `\n${setupImports}\n` +
|
|
35
|
+
`import { registerSuites as __registerReformProofSuites } from '@playfast/reform-proof-vitest'\n` +
|
|
36
|
+
`__registerReformProofSuites([${names.join(', ')}])\n`;
|
|
37
|
+
return { code: code + epilogue, map: null };
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAE7C,8EAA8E;AAC9E,6EAA6E;AAC7E,mFAAmF;AACnF,+EAA+E;AAC/E,mFAAmF;AACnF,gFAAgF;AAEhF,MAAM,QAAQ,GAAG,cAAc,CAAA;AAyB/B,MAAM,UAAU,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAEjE,MAAM,SAAS,GAAG,CAAC,KAAwC,EAAyB,EAAE,CACpF,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAExE;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAkC,EAAqB,EAAE;IACzF,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC;SAC3C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,IAAI,GAAG,CAAC;SACjC,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,MAAM;QACf,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE;YACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAA;YAC/C,MAAM,IAAI,CAAA;YACV,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;YAC/B,4EAA4E;YAC5E,oEAAoE;YACpE,MAAM,KAAK,GAAG,OAAO;iBAClB,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;iBAClC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YACpF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;YACnC,MAAM,QAAQ,GACZ,KAAK,YAAY,IAAI;gBACrB,iGAAiG;gBACjG,gCAAgC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;YACxD,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QAC7C,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@playfast/reform-proof-vitest",
|
|
3
|
+
"playbook": "./playbook",
|
|
4
|
+
"version": "0.0.2",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Vitest adapter for reform-proof — a vite plugin that auto-registers every *.proof.ts suite as native vitest tests, run through the proof engine.",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"reform",
|
|
9
|
+
"effect",
|
|
10
|
+
"testing",
|
|
11
|
+
"proof",
|
|
12
|
+
"vitest"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/playfast/reform.git",
|
|
18
|
+
"directory": "packages/reform-proof-vitest"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/playfast/reform/issues"
|
|
22
|
+
},
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"exports": {
|
|
25
|
+
"./package.json": "./package.json",
|
|
26
|
+
".": "./src/index.ts",
|
|
27
|
+
"./*": "./src/*.ts"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"clean": "rm -rf dist .tsbuildinfo",
|
|
35
|
+
"check": "tsc --noEmit",
|
|
36
|
+
"build": "tsc -p tsconfig.build.json",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"lint": "oxlint src",
|
|
40
|
+
"lint:fix": "oxlint --fix src"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"es-module-lexer": "^1.5.4"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"vitest": "*",
|
|
47
|
+
"@playfast/reform-proof": "*"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@playfast/reform-proof": "*"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|