Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions compat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,17 @@ When `compat.Runner.Subcommands` is set, every row above runs once per declared

### Partial-codec exporters: `Runner.SupportedFormats`

§4 requires markdown and json; csv is recommended but optional. Exporters that do not implement csv can use `compat.Runner.SupportedFormats`:
§4 requires markdown and json; csv is recommended but optional. Exporters that do not implement csv can use `compat.Runner.SupportedFormats`. Prefer the exported format constants to string literals so misspelled constant names fail to compile:

```go
formats.RunContract(t, compat.Runner{
Binary: os.Getenv("EXPORT_CLI_BIN"),
SupportedFormats: []string{"markdown", "json"}, // declare what you implement
SupportedFormats: []string{compat.FormatMarkdown, compat.FormatJSON}, // declare what you implement
})
```

`compat.FormatCSV` names the optional CSV codec, and `compat.CanonicalFormats` contains all three canonical names. String literals remain valid; their spelling is not checked by the compiler.

Semantics:

- **Nil (default)** — exporter declares the full §4 surface. Every subtest runs.
Expand Down
18 changes: 15 additions & 3 deletions compat/compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ import (
"time"
)

// Canonical §4 output codec names for Runner.SupportedFormats.
const (
FormatMarkdown = "markdown"
FormatJSON = "json"
FormatCSV = "csv"
)

// CanonicalFormats is the full set of §4 output codecs. Exporters that
// support a subset can populate Runner.SupportedFormats with the constants.
var CanonicalFormats = []string{FormatMarkdown, FormatJSON, FormatCSV}

// Runner invokes a single *-export-cli binary in a controlled environment.
// A zero-value Runner is not usable; Binary must be set to an absolute path.
type Runner struct {
Expand Down Expand Up @@ -65,13 +76,14 @@ type Runner struct {

// SupportedFormats declares which §4 output codecs the exporter
// implements. Used by compat/formats to gate the codec-specific
// data-path subtests.
// data-path subtests. Use FormatMarkdown, FormatJSON, and FormatCSV
// instead of string literals to catch misspelled identifiers at compile time.
//
// Default (nil) means the exporter declares the full §4 surface
// (markdown, json, csv); compat/formats runs every subtest.
//
// Non-nil declares an explicit subset — e.g.
// []string{"markdown", "json"} for a CLI that has not yet added a
// []string{FormatMarkdown, FormatJSON} for a CLI that has not yet added a
// CSV writer. The bundle's JSONIsArray, CSVHasHeader, and
// DefaultIsMarkdown subtests skip via t.Skipf when their codec is
// not in the list, naming the missing codec so the gap is visible
Expand Down Expand Up @@ -253,7 +265,7 @@ func (r Runner) Subcommand() string { return strings.Join(r.subcommandParts, " "
// returns true for any name. When SupportedFormats is non-nil
// (including empty), only names present in the slice return true.
// String comparison is exact: callers pass the canonical CONTRACT.md
// codec names ("markdown", "json", "csv").
// codec names (FormatMarkdown, FormatJSON, and FormatCSV).
//
// Section bundles consult this when deciding whether to skip a
// codec-specific subtest. Integrators normally do not call it
Expand Down
Loading