> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sightmap.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Sightmap Conformance Fixtures: The Language-Agnostic Test Suite

> The fixture catalog, how the assertions run, and how to contribute a new fixture.

The conformance fixtures define language-independent test cases for Sightmap implementations. Each implementation is expected to pass them. The fixtures live under [`spec/conformance/`](https://github.com/sightmap/sightmap/tree/main/spec/conformance).

## Layout

Each fixture is a directory named `NNN-{slug}.fixture/` with:

* `sightmap/`: input YAML files that simulate a `.sightmap/` directory
* `expected.json`: an object whose `cases` array contains `{ command, args, expected }` entries

The runner checks that each key in `expected` exists in the actual output and matches deeply. The actual output may contain additional keys. For an array in `expected`, the actual array must be at least as long and have the same prefix. [`spec/conformance/README.md`](https://github.com/sightmap/sightmap/blob/main/spec/conformance/README.md) defines the case shape.

<Note>
  The `command` values in `expected.json` (`match`, `explain`, `fmt`, `validate`, `lint`) are fixture-runner operations, not `sightmap` CLI commands. The CLI has no `match`, `explain`, or `fmt` command; only `validate` and `lint` share names with CLI commands. Each implementation supplies its own runner.
</Note>

## Runtime-semantics fixtures (`0NN`)

The `0NN` series covers loading, route matching, and diagnostics:

| #   | Name                       | Exercises                                                                                   |
| --- | -------------------------- | ------------------------------------------------------------------------------------------- |
| 001 | `minimal`                  | Smallest valid sightmap; basic matching                                                     |
| 002 | `multi-file-merge`         | Same view name across two files → `merge-collision-view` warning                            |
| 003 | `route-precedence`         | Most-specific-wins for views: literal > `:param` > `*` > `**`; declaration order tie-breaks |
| 004 | `param-normalization`      | Express-style `:param` normalizes to `*`                                                    |
| 005 | `selector-array`           | `selector` accepts an array                                                                 |
| 006 | `view-scoped-vs-global`    | Global components match everywhere; scoped only on their view                               |
| 007 | `request-method-filter`    | Request matching filters by HTTP method                                                     |
| 008 | `dependencies-binding`     | `dependencies[]` glob binding and diagnostics (SEP-0001)                                    |
| 010 | `component-ref`            | `$ref` expansion, view attestation, global+view dedup (SEP-0002)                            |
| 011 | `component-ref-unresolved` | `$ref` to an unknown component → `ref-unresolved` error                                     |
| 012 | `component-ref-circular`   | Self-referential `$ref` chain → `ref-circular` error                                        |

## Canonical-format fixtures (`1NN`)

The `1NN` series covers the byte-level YAML format defined by [`spec/v1/canonical-format.md`](https://github.com/sightmap/sightmap/blob/main/spec/v1/canonical-format.md). Tools that write `.sightmap/*.yaml` must produce this format. Fixtures that test rewritten output store the expected YAML under `sightmap/.expected/`.

| #   | Name                         | Exercises                                                    |
| --- | ---------------------------- | ------------------------------------------------------------ |
| 100 | `fmt-quoting`                | Quoting preference: plain → single-quoted → double-quoted    |
| 101 | `fmt-key-order`              | Canonical key order per entry type                           |
| 102 | `fmt-list-sort`              | Top-level views sorted by `name`                             |
| 103 | `fmt-comment-preservation`   | Canonical input with component comments passes `fmt --check` |
| 104 | `fmt-header-preservation`    | Leading `#`-comment blocks preserved verbatim                |
| 105 | `fmt-idempotent`             | Canonicalizing canonical input is a no-op                    |
| 106 | `fmt-invalid-untouched`      | Schema-invalid input is rejected without changes             |
| 108 | `fmt-dependencies-canonical` | `dependencies` arrays sorted and deduplicated                |

<Note>
  These fixtures define canonical output; the CLI does not include a formatter command. An implementation that writes Sightmap YAML can check its output against this series.
</Note>

## Running locally

The monorepo checker validates fixture inputs expected to be valid and canonical outputs. It skips inputs that the fixture marks with a `fmt.schema-invalid` or `fmt.parse-error` diagnostic.

```bash from a checkout of sightmap/sightmap theme={null}
cd spec
npm ci
node scripts/validate-sightmap.mjs conformance
```

The checker above validates YAML; it does not execute the `{ command, args, expected }` cases. Each implementation needs a fixture runner that loads the `sightmap/` directory, executes each `command` with its `args`, and checks the result against `expected`.

## Contributing a new fixture

<Steps>
  <Step title="Claim the next number">
    Create the next-numbered `NNN-{slug}.fixture/` directory under `spec/conformance/` (see [`CONVENTIONS.md`](https://github.com/sightmap/sightmap/blob/main/spec/CONVENTIONS.md)). Check open SEP and fixture PRs first because they reserve associated fixture numbers.
  </Step>

  <Step title="Author the fixture">
    Write `sightmap/*.yaml` and `expected.json`. Keep each fixture focused on one behavior.
  </Step>

  <Step title="Verify and open a PR">
    Run the schema checker and the fixture runner for the implementation you are changing, then open a PR. Sign off your commits with `-s` per the [Contributing guide](/reference/contributing).
  </Step>
</Steps>
