com um clique
test-analyzer
analyzes test files and generates slice.json specifications for drift detection
Menu
analyzes test files and generates slice.json specifications for drift detection
builds an automation slice from an event model
builds a state-view slice from an event model
Generate a sample configuration for slices
builds a state-change slice from an event model
Step-by-step guide for getting started with event-driven development
| name | test-analyzer |
| description | analyzes test files and generates slice.json specifications for drift detection |
Analyzes test files (*.test.ts) to generate code-slice.json specification files. These capture behavioral contracts in given/when/then form, enabling drift detection between tests and slice.json design documentation.
CRITICAL: This skill NEVER touches existing slice.json files. It only creates/deletes code-slice.json files.
code-slice.json files matching the format of slice.json in .slices/ directorycode-slice.json (what tests say) with slice.json (design documentation)slice.json files - only work with code-slice.jsonActivateShift.test.ts or OnlineReservationStatus.test.ts)DeciderSpecification.for() for state-change slicesPostgreSQLProjectionSpec.for() for state-view slicesFile: .slices/<Context>/<folder>/code-slice.json (same directory as slice.json)
Contains:
{
"id": "<slice-id-from-slice.json>",
"title": "<slice-title-from-slice.json>",
"specifications": [...]
}
id and title fields copied from the corresponding slice.json fileInclude ALL test cases that are:
specifications array of existing slice.jsonIMPORTANT: Even if a command/event is defined in slice.json's commands/events arrays, if the test specification is NOT in the specifications array, it MUST be included in code-slice.json
Each specification includes:
vertical: falseid: unique generated IDsliceName: slice titletype: COMMAND, EVENT, READMODEL or SPEC_ERROR'title: spec description from testgiven: array of event objects (preconditions)
when: command object OR empty array
[] (events are in given for projections)then: array of event/error/readmodel objects
comments: empty arraylinkedId: MUST be the same as the specification's id field (self-reference)Uses DeciderSpecification.for() with decide/evolve pattern.
const given = DeciderSpecification.for({
decide,
evolve,
initialState: ...
});
it('spec: description', () => {
given([...events])
.when(command)
.then([...events])
});
Uses PostgreSQLProjectionSpec.for() for projections/read models.
given = PostgreSQLProjectionSpec.for({
projection: SomeProjection,
connectionString,
});
it('spec: description', () => {
await given([...events]) // Events are in given() for projections
.when([]) // when() is always empty for projections
.then(assertReadModel);
});
IMPORTANT for STATE_VIEW:
given array (the events to project)when is always empty array (no command in projections)then contains readmodel assertionsDeciderSpecification.for() → STATE_CHANGEPostgreSQLProjectionSpec.for() → STATE_VIEWFor each it('spec: ...', ...) test:
slice.json specifications arraywhen() calls with fields and typesgiven() and then() calls with fields and typesgiven() calls (events to be projected)when() is always empty for STATE_VIEW slicesthen()slice.json specifications arraySee specification-format.md for complete format details.
Slice Name:
<SliceName>.test.ts → <SliceName>ActivateShift.test.ts → "ActivateShift"Context:
restaurantId or locationId → "Restaurant Management"Using .slices/index.json for lookup:
.slices/index.json to find correct folderfolder and context from matching entry.slices/<context>/<folder>/slice.jsonWhen invoked with a test file path:
Read and parse the test file
Extract slice metadata
Check for existing files
slice.json location via .slices/index.jsonslice.json if found for comparisonid and title fields from slice.json (required for code-slice.json)Analyze test cases
it('spec: ...') test casesslice.jsonBuild specifications array
slice.json specifications arraywhen: Find matching command in slice.json → commands array by titlegiven/then:
slice.json → events array by titlereadmodels → dependencies array (INBOUND events)id field from the matched element/dependency as the linkedIdthen: Find matching readmodel in slice.json → readmodels array by titlenull (indicates new element not in design documentation)linkedId field (errors don't exist in slice.json)Decision: Generate, Update, or Remove code-slice.json
slice.json specifications arrayslice.json specifications: Remove/don't create code-slice.json (no drift)slice.json specifications: Generate/update code-slice.json with:
.slices/<Context>/<folder>/code-slice.json (same directory as slice.json)id field copied from slice.jsontitle field copied from slice.jsonspecifications array with missing specificationsslice.json - it's read-only design documentationValidate output
Infer TypeScript/JSON types from test data:
"String""UUID""Date" or "DateTime""Decimal""Integer""Boolean""List" with element typeCRITICAL: LinkedId Fields Must Use Real IDs from slice.json
linkedId in given/when/then elements: MUST use the actual element IDs from slice.json
slice.json → commands array → id fieldslice.json → events array → id field
events array if they're from other slicesreadmodels → dependencies array for entries with type: "INBOUND" and elementType: "EVENT"id field from the dependency entryslice.json → readmodels array → id fieldnull (will be identified as drift)Other ID fields: Generate unique IDs for specification containers
id: Generate unique ID (e.g., "GENERATED-SPEC-<counter>")id: Generate unique ID for each given/when/then elementExample from slice.json:
{
"commands": [
{
"id": "3458764657124632223", // ← Use THIS for linkedId
"title": "Activate Shift",
...
}
],
"events": [
{
"id": "3458764657005669318", // ← Use THIS for linkedId
"title": "Shift activated",
...
}
]
}
Example in code-slice.json:
{
"id": "GENERATED-SPEC-001", // ← Specification ID
"linkedId": "GENERATED-SPEC-001", // ← MUST match specification id
"when": [
{
"title": "Activate Shift",
"id": "GENERATED-SPEC-CMD-1", // ← Generated wrapper ID
"linkedId": "3458764657124632223" // ← MUST be real command ID from slice.json
}
]
}
Summary of linkedId usage:
specification.linkedId = specification.id (self-reference)element.linkedId = real ID from slice.json → commands arrayelement.linkedId = real ID from slice.json → events array OR readmodels → dependencies (for STATE_VIEW)element.linkedId = real ID from slice.json → readmodels arraylinkedId field (errors don't exist in slice.json)Invoke with any test file path:
State-change slices:
/test-analyzer src/slices/ActivateShift/ActivateShift.test.ts
/test-analyzer src/slices/PlanVacation/PlanVacation.test.ts
State-view slices (projections):
/test-analyzer src/slices/ActivatedOnlineReservations/OnlineReservationStatus.test.ts
/test-analyzer src/slices/ActiveShifts/ActiveShifts.test.ts
The skill automatically:
.slices/ documentationcode-slice.json in same directory as test fileslice.json specifications arrayslice.json specifications array:
code-slice.json:
slice.json specifications → Remove/don't create code-slice.json (no drift)slice.json specifications → Generate/update code-slice.jsonslice.json found → Generate code-slice.json with all test specificationsKey Principle:
slice.json = design documentation (source of truth, READ ONLY)code-slice.json = test-derived specifications (generated/deleted by this skill)src/slices/<SliceName>/<SliceName>.test.ts.slices/<Context>/<folder>/code-slice.json (same directory as slice.json).slices/index.json (find matching slice by title).slices/<Context>/<folder>/slice.json (READ ONLY, from index.json)slice.json specifications arraycode-slice.json if no drift detected (all test specs are in slice.json specifications) - keeps codebase cleanslice.json files - they are read-only design documentation