@playfast/reform-proof-vitest 0.1.0 → 1.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/package.json +1 -1
- package/src/index.ts +2 -25
- package/src/plugin.ts +1 -23
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playfast/reform-proof-vitest",
|
|
3
3
|
"playbook": "./playbook",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"type": "module",
|
|
6
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
7
|
"keywords": [
|
package/src/index.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { isProofSuite, type ProofSuite, withProofRunner } from '@playfast/reform-proof'
|
|
2
2
|
import { describe, expect, test } from 'vitest'
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
// vitest tests (a `describe` per product, a `test` per requirement), each run
|
|
6
|
-
// through the proof engine via the `ProofRunner` layer. Pair it with
|
|
7
|
-
// `reformProofPlugin` (./plugin), which appends a `registerSuites(...)` call to
|
|
8
|
-
// every `*.proof.ts` so suites become tests with no per-feature wrapper file.
|
|
9
|
-
|
|
10
|
-
// A suite registers exactly once even if several modules import it (its own test
|
|
11
|
-
// entry plus any flow test that pulls it in). Identity-keyed, so a suite value is
|
|
12
|
-
// never double-registered within a worker.
|
|
4
|
+
// Identity-keyed: a suite registers once even if several modules import it.
|
|
13
5
|
const registered = new WeakSet<ProofSuite>()
|
|
14
6
|
|
|
15
|
-
//
|
|
16
|
-
// `setup` option imports into each `*.proof.ts`) to run app-specific preparation
|
|
17
|
-
// right before each proof renders — e.g. installing a render-free React-hooks
|
|
18
|
-
// dispatcher for view bodies that reach for hooks. The adapter stays view-agnostic:
|
|
19
|
-
// it just runs whatever the app registered, only inside proof-test bodies, so a
|
|
20
|
-
// `*.test.ts` that controls global state is never disturbed.
|
|
7
|
+
// App setup hooks (via plugin `setup`) run only inside proof-test bodies.
|
|
21
8
|
const setupHooks = new Set<() => void>()
|
|
22
9
|
|
|
23
|
-
/**
|
|
24
|
-
* Register a function to run immediately before every proof test. Idempotent by
|
|
25
|
-
* reference; intended to be called from a side-effect module the plugin imports
|
|
26
|
-
* into `*.proof.ts` files only.
|
|
27
|
-
*/
|
|
28
10
|
export const setProofTestHook = (hook: () => void): void => {
|
|
29
11
|
setupHooks.add(hook)
|
|
30
12
|
}
|
|
@@ -46,11 +28,6 @@ const registerSuite = (suite: ProofSuite): void => {
|
|
|
46
28
|
})
|
|
47
29
|
}
|
|
48
30
|
|
|
49
|
-
/**
|
|
50
|
-
* Register every `ProofSuite` among the given values as vitest tests. Non-suite
|
|
51
|
-
* values are ignored, so a whole module's exports can be passed verbatim — which
|
|
52
|
-
* is exactly what `reformProofPlugin` does.
|
|
53
|
-
*/
|
|
54
31
|
export const registerSuites = (candidates: ReadonlyArray<unknown>): void => {
|
|
55
32
|
candidates.forEach((candidate) => {
|
|
56
33
|
if (!isProofSuite(candidate) || registered.has(candidate)) {
|
package/src/plugin.ts
CHANGED
|
@@ -1,28 +1,11 @@
|
|
|
1
1
|
import { init, parse } from 'es-module-lexer'
|
|
2
2
|
|
|
3
|
-
// reform-proof vitest plugin — a vite/vitest plugin that auto-registers proof
|
|
4
|
-
// suites. For every `*.proof.ts` file vitest collects, it lexes the module's
|
|
5
|
-
// export names and appends a `registerSuites([...exports])` call, so each exported
|
|
6
|
-
// `ProofSuite` becomes native vitest tests. This is what lets a feature ship a
|
|
7
|
-
// `*.proof.ts` with NO hand-written `*.proof.test.ts` wrapper: add this plugin and
|
|
8
|
-
// the glob `**/*.proof.ts` to the vitest config, and the suites run themselves.
|
|
9
|
-
|
|
10
3
|
const PROOF_RE = /\.proof\.ts$/
|
|
11
4
|
|
|
12
|
-
/** Options for `reformProofPlugin`. ExternalApi: vite-plugin config boundary. */
|
|
13
5
|
export interface ReformProofPluginOptionsExternalApi {
|
|
14
|
-
/**
|
|
15
|
-
* Module specifier(s) the plugin side-effect-imports into every `*.proof.ts`,
|
|
16
|
-
* before registering its suites. Use to register per-proof-test setup
|
|
17
|
-
* (`setProofTestHook`) that must run ONLY in proof-test workers — e.g. an app's
|
|
18
|
-
* headless React-hooks dispatcher. Imported only into `*.proof.ts`, so regular
|
|
19
|
-
* `*.test.ts` files are never affected.
|
|
20
|
-
*/
|
|
21
6
|
readonly setup?: string | ReadonlyArray<string>
|
|
22
7
|
}
|
|
23
8
|
|
|
24
|
-
/** The minimal vite plugin shape this adapter needs — structurally a `Plugin`,
|
|
25
|
-
* declared locally so the package need not depend on vite's types. */
|
|
26
9
|
export interface ReformProofPluginExternalApi {
|
|
27
10
|
readonly name: string
|
|
28
11
|
readonly enforce: 'post'
|
|
@@ -39,10 +22,6 @@ const setupList = (
|
|
|
39
22
|
): ReadonlyArray<string> =>
|
|
40
23
|
setup === undefined ? [] : typeof setup === 'string' ? [setup] : setup
|
|
41
24
|
|
|
42
|
-
/**
|
|
43
|
-
* The plugin. Runs `post` (after TS→JS), so it lexes plain JS exports reliably.
|
|
44
|
-
* Only `*.proof.ts` modules are touched; everything else passes through.
|
|
45
|
-
*/
|
|
46
25
|
export const reformProofPlugin = (
|
|
47
26
|
options?: ReformProofPluginOptionsExternalApi,
|
|
48
27
|
): ReformProofPluginExternalApi => {
|
|
@@ -58,8 +37,7 @@ export const reformProofPlugin = (
|
|
|
58
37
|
}
|
|
59
38
|
await init
|
|
60
39
|
const [, exports] = parse(code)
|
|
61
|
-
//
|
|
62
|
-
// re-export-from has no local name (`ln` undefined) and is skipped.
|
|
40
|
+
// Use local binding names; re-export-from has no `ln` and is skipped.
|
|
63
41
|
const names = exports
|
|
64
42
|
.map((exportSpec) => exportSpec.ln)
|
|
65
43
|
.filter((local): local is string => typeof local === 'string' && local.length > 0)
|