@rotorsoft/act-tck 0.2.0 → 0.4.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 +56 -59
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +394 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +395 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
# @rotorsoft/act-tck
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@rotorsoft/act-tck)
|
|
4
|
+
[](https://www.npmjs.com/package/@rotorsoft/act-tck)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
_Test Compatibility Kit for the `Store`, `Cache`, and `Logger` ports of [@rotorsoft/act](https://www.npmjs.com/package/@rotorsoft/act). Lane conformance suite (claim filter, subscribe UPSERT, ack/block round-trip) added in v0.4.0 ([ACT-1103](https://github.com/Rotorsoft/act-root/issues/733))._
|
|
6
8
|
|
|
7
|
-
## Why
|
|
9
|
+
## Why this package
|
|
8
10
|
|
|
9
|
-
A port without an executable contract is undefined behavior.
|
|
11
|
+
A port without an executable contract is undefined behavior. Act has three pluggable ports (event store, snapshot cache, logger), each with multiple in-tree adapters and an open door for third-party implementations. Before this package, every adapter's test file independently re-stated what the contract was — tribal knowledge, not a spec.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
`act-tck` turns the contract into a runnable spec. Drop it into your adapter's test file, point it at your implementation, and vitest will execute the same conformance suite the in-tree adapters pass. New port methods land here first; adapters add capability flags and opt in.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add -D @rotorsoft/act-tck
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The kit is a dev dependency — it ships test code, not runtime code.
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
12
24
|
|
|
13
25
|
```ts
|
|
14
26
|
// libs/act-mysql/test/store-tck.spec.ts
|
|
@@ -22,29 +34,15 @@ runStoreTck({
|
|
|
22
34
|
});
|
|
23
35
|
```
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
// libs/act-redis/test/cache-tck.spec.ts
|
|
27
|
-
import { runCacheTck } from "@rotorsoft/act-tck";
|
|
28
|
-
import { RedisCache } from "../src/index.js";
|
|
29
|
-
|
|
30
|
-
runCacheTck({
|
|
31
|
-
name: "RedisCache",
|
|
32
|
-
factory: () => new RedisCache({ url: process.env.REDIS_URL! }),
|
|
33
|
-
});
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
// libs/act-winston/test/logger-tck.spec.ts
|
|
38
|
-
import { runLoggerTck } from "@rotorsoft/act-tck";
|
|
39
|
-
import { WinstonLogger } from "../src/index.js";
|
|
37
|
+
That's the whole integration. `run*Tck` calls vitest's `describe`/`it` internally; your test runner drives execution. A fixed Counter-style fixture domain keeps tests deterministic and self-contained.
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
name: "WinstonLogger",
|
|
43
|
-
factory: () => new WinstonLogger({ level: "trace" }),
|
|
44
|
-
});
|
|
45
|
-
```
|
|
39
|
+
## API
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
- **`runStoreTck(options)`** — every `Store` method, capability-gated where optional.
|
|
42
|
+
- **`runCacheTck(options)`** — every `Cache` method, cross-stream isolation, dispose idempotency.
|
|
43
|
+
- **`runLoggerTck(options)`** — structural smoke test of the `Logger` contract.
|
|
44
|
+
- **`StoreCapabilities`** / **`CacheCapabilities`** / **`LoggerCapabilities`** — flag types for opting into optional surface (e.g., `Store.notify`).
|
|
45
|
+
- Fixture helpers re-exported from `@rotorsoft/act-tck/fixtures` for adapter-specific tests that want the same Counter domain.
|
|
48
46
|
|
|
49
47
|
## What's covered
|
|
50
48
|
|
|
@@ -61,63 +59,62 @@ Every method on the `Store` interface in [`libs/act/src/types/ports.ts`](https:/
|
|
|
61
59
|
- `prioritize` — bulk priority updates by filter
|
|
62
60
|
- `truncate` — snapshot vs tombstone seeding, empty inputs, missing streams
|
|
63
61
|
- `query_streams` — filters, exact-match, pagination, blocked
|
|
62
|
+
- `query_stats` — array + filter forms, opt-in count/tail/names, exclude + before, snapshot count via `names`
|
|
64
63
|
- `notify` (capability-gated) — subscribe + dispose smoke test
|
|
65
64
|
|
|
66
65
|
### `runCacheTck`
|
|
67
66
|
|
|
68
|
-
Every method on the `Cache` interface:
|
|
69
|
-
|
|
70
|
-
- `get` on unset stream returns `undefined`
|
|
71
|
-
- `set` then `get` round-trip
|
|
72
|
-
- `set` overwrites a prior entry
|
|
73
|
-
- `invalidate` removes one stream, leaves others
|
|
74
|
-
- `invalidate` / `clear` no-op on absent state
|
|
75
|
-
- `clear` empties every stream
|
|
76
|
-
- Cross-stream isolation
|
|
77
|
-
- `dispose` idempotency
|
|
67
|
+
Every method on the `Cache` interface: `get` on unset stream returns `undefined`; `set` then `get` round-trip; `set` overwrites; `invalidate` removes one stream, leaves others; `invalidate`/`clear` no-op on absent state; `clear` empties every stream; cross-stream isolation; `dispose` idempotency.
|
|
78
68
|
|
|
79
69
|
### `runLoggerTck`
|
|
80
70
|
|
|
81
|
-
Structural smoke test of the `Logger` interface:
|
|
71
|
+
Structural smoke test of the `Logger` interface: `level` is a non-empty string; every level method callable with both overload signatures; `null` and cyclic payloads don't throw; `child(bindings)` returns a Logger satisfying the same contract; `dispose` is idempotent and awaitable.
|
|
82
72
|
|
|
83
|
-
|
|
84
|
-
- Every level method (`fatal`/`error`/`warn`/`info`/`debug`/`trace`) callable with both overload signatures
|
|
85
|
-
- `null` and cyclic payloads don't throw
|
|
86
|
-
- `child(bindings)` returns a Logger satisfying the same contract; child loggers can themselves spawn children
|
|
87
|
-
- `dispose` is idempotent and awaitable
|
|
73
|
+
## Common patterns
|
|
88
74
|
|
|
89
|
-
|
|
75
|
+
### Capability flags for optional methods
|
|
90
76
|
|
|
91
|
-
Optional methods
|
|
77
|
+
Optional methods are gated so adapters can opt out of features they don't implement:
|
|
92
78
|
|
|
93
79
|
```ts
|
|
94
80
|
runStoreTck({
|
|
95
81
|
name: "MysqlStore",
|
|
96
82
|
factory: () => new MysqlStore({ /* … */ }),
|
|
97
|
-
capabilities: {
|
|
98
|
-
notify: true, // adapter implements Store.notify
|
|
99
|
-
},
|
|
83
|
+
capabilities: { notify: true }, // adapter implements Store.notify
|
|
100
84
|
});
|
|
101
85
|
```
|
|
102
86
|
|
|
103
|
-
|
|
87
|
+
### Adding adapter-specific tests alongside the TCK
|
|
88
|
+
|
|
89
|
+
The TCK validates the contract; adapter-specific edge cases (defensive `rowCount ?? 0` branches, dialect-specific SQL paths) belong in the adapter's own test file. See `libs/act-pg/test/store.error.spec.ts` and `libs/act-sqlite/test/store.error.spec.ts` for the fault-injection patterns the in-tree adapters use to round out the 100% coverage gate.
|
|
90
|
+
|
|
91
|
+
### When the port interface changes
|
|
92
|
+
|
|
93
|
+
New / changed methods on `Store`, `Cache`, or `Logger` are added to `libs/act-tck/src/` in lockstep. Optional methods land behind a `Capabilities` flag so existing adapters keep passing until they opt in.
|
|
94
|
+
|
|
95
|
+
## Compatibility
|
|
96
|
+
|
|
97
|
+
- **Node**: >=22.18.0
|
|
98
|
+
- **Peer**: `@rotorsoft/act` (workspace version), `vitest` >=3.0.9, `zod` ^4.4.3
|
|
99
|
+
- **Runtime deps**: none — pure test code
|
|
100
|
+
|
|
101
|
+
## Stability
|
|
104
102
|
|
|
105
|
-
|
|
103
|
+
This package stays at **0.x** while `@rotorsoft/act` ships **1.0**. The Store/Cache/Logger contracts the TCK validates are covered by the [Act Stability Charter](../../STABILITY.md) and are stable at 1.0. The TCK's own surface (the `run*Tck` functions, the `Capabilities` types, the fixture helpers) may still evolve in 0.x as third-party adapter authors report what they need. The TCK joins the 1.x line once that surface settles.
|
|
106
104
|
|
|
107
|
-
##
|
|
105
|
+
## Related packages
|
|
108
106
|
|
|
109
|
-
|
|
107
|
+
- **[@rotorsoft/act](https://www.npmjs.com/package/@rotorsoft/act)** — the framework defining the ports this kit validates.
|
|
108
|
+
- **[@rotorsoft/act-pg](https://www.npmjs.com/package/@rotorsoft/act-pg)** / **[@rotorsoft/act-sqlite](https://www.npmjs.com/package/@rotorsoft/act-sqlite)** — reference `Store` adapters; both pass `runStoreTck`.
|
|
109
|
+
- **[@rotorsoft/act-pino](https://www.npmjs.com/package/@rotorsoft/act-pino)** — reference `Logger` adapter; passes `runLoggerTck`.
|
|
110
110
|
|
|
111
|
-
-
|
|
112
|
-
- [`@rotorsoft/act-pg`](https://www.npmjs.com/package/@rotorsoft/act-pg)
|
|
113
|
-
- [`@rotorsoft/act-sqlite`](https://www.npmjs.com/package/@rotorsoft/act-sqlite)
|
|
114
|
-
- [`@rotorsoft/act-pino`](https://www.npmjs.com/package/@rotorsoft/act-pino)
|
|
111
|
+
The in-tree InMemoryStore / InMemoryCache / ConsoleLogger (bundled with `@rotorsoft/act`) are the first customers — they prove the TCK works before any external adapter ships.
|
|
115
112
|
|
|
116
|
-
##
|
|
113
|
+
## Documentation
|
|
117
114
|
|
|
118
|
-
- [Writing a custom Store adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-store.md)
|
|
119
|
-
- [Writing a custom Cache adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-cache.md)
|
|
120
|
-
- [Writing a custom Logger adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-logger.md)
|
|
115
|
+
- **[Writing a custom Store adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-store.md)** — full walkthrough, with `runStoreTck` as the acceptance harness.
|
|
116
|
+
- **[Writing a custom Cache adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-cache.md)**.
|
|
117
|
+
- **[Writing a custom Logger adapter](https://github.com/Rotorsoft/act-root/blob/master/docs/docs/guides/writing-a-logger.md)**.
|
|
121
118
|
|
|
122
119
|
## License
|
|
123
120
|
|