@rotorsoft/act-tck 0.3.0 → 1.0.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 CHANGED
@@ -1,14 +1,26 @@
1
1
  # @rotorsoft/act-tck
2
2
 
3
- Test Compatibility Kit for the `Store`, `Cache`, and `Logger` ports of [`@rotorsoft/act`](https://www.npmjs.com/package/@rotorsoft/act).
3
+ [![NPM Version](https://img.shields.io/npm/v/@rotorsoft/act-tck.svg)](https://www.npmjs.com/package/@rotorsoft/act-tck)
4
+ [![NPM Downloads](https://img.shields.io/npm/dm/@rotorsoft/act-tck.svg)](https://www.npmjs.com/package/@rotorsoft/act-tck)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
6
 
5
- > **Stability:** 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.
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 it exists
9
+ ## Why this package
8
10
 
9
- A port without an executable contract is undefined behavior. The three pluggable ports in `@rotorsoft/act` (event store, snapshot cache, logger) each have multiple in-tree adapters and an open door for third-party implementations. Before this package, each adapter's test file independently re-stated what the contract was — that's tribal knowledge, not a spec. This package turns the contract into a runnable spec a third party can validate themselves against.
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
- ## Usage
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
- ```ts
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
- runLoggerTck({
42
- name: "WinstonLogger",
43
- factory: () => new WinstonLogger({ level: "trace" }),
44
- });
45
- ```
39
+ ## API
46
40
 
47
- Each `run*Tck` is a function that calls vitest's `describe` and `it` internally. Vitest is a peer dependency — your test runner drives execution. The TCK ships a fixed Counter-style fixture domain so tests are deterministic and self-contained.
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
- - `level` is a non-empty string
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
- ## Capabilities flags
75
+ ### Capability flags for optional methods
90
76
 
91
- Optional methods (currently just `Store.notify`) are gated by capability flags so adapters can opt out of features they don't implement:
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
- ## When the port interface changes
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
- When a method is added, removed, or changed on `Store`, `Cache`, or `Logger`, the matching cases in `libs/act-tck/src/` are updated in lockstep. New optional methods land behind a `Capabilities` flag so existing adapters keep passing until they opt in.
103
+ Public API governed by the [Act Stability Charter](../../STABILITY.md). The TCK's published surface — `runStoreTck`, `runCacheTck`, `runLoggerTck`, the `Capabilities` types, and the fixture helpers is now covered by SemVer alongside the `Store`/`Cache`/`Logger` contracts it validates. Charter is **in effect as of 1.0.0**; the milestone tracker is [milestone 1.0](https://github.com/Rotorsoft/act-root/milestone/1).
106
104
 
107
- ## Reference adapters
105
+ ## Related packages
108
106
 
109
- The in-tree adapters are the first customers of this kit. They prove the TCK works before any external adapter ships:
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
- - [`InMemoryStore`](https://github.com/Rotorsoft/act-root/blob/master/libs/act/src/adapters/in-memory-store.ts), [`InMemoryCache`](https://github.com/Rotorsoft/act-root/blob/master/libs/act/src/adapters/in-memory-cache.ts), [`ConsoleLogger`](https://github.com/Rotorsoft/act-root/blob/master/libs/act/src/adapters/console-logger.ts)
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
- ## See also
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