The delivery repository's contracts and SDK live under modules/ as mesh-delivery-contracts and mesh-delivery-sdk, their Go module paths renamed to match the folders (the TypeScript names already did), and every importer in mesh-delivery, mesh-catalog, mesh-host, mesh-tools and mesh-sdk follows in the same group: a design as it should be, one path per module, checked by the group's check building every importer. Builds: design 47 G §427, §88 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
165 lines
29 KiB
Go
165 lines
29 KiB
Go
// Code generated by seatgen from the seat definitions; DO NOT EDIT.
|
|
|
|
package git
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"regexp"
|
|
"testing"
|
|
)
|
|
|
|
// TestFixtures reads every fixture of seats/git/fixtures: each decodes into its type, a field the type does not
|
|
// know is dropped (ADR 0608 §6), and it reads back as its wire says; each subject named is the contract's.
|
|
func TestFixtures(t *testing.T) {
|
|
cases := []struct {
|
|
name, subject, given, wire string
|
|
decode func([]byte) (any, error)
|
|
subjectIs *regexp.Regexp
|
|
}{
|
|
{name: "pull.updated is said", subject: "mesh.seat.git.event.pull-updated", given: "{\"author\":\"jochen\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}", wire: "{\"author\":\"jochen\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}",
|
|
decode: func(b []byte) (any, error) { var v PullUpdatedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-updated$")},
|
|
{name: "pull.merged is said", subject: "mesh.seat.git.event.pull-merged", given: "{\"base\":\"main\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"head-checks\":{\"mesh/check\":\"success\"},\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"base\":\"main\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"head-checks\":{\"mesh/check\":\"success\"},\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v PullMergedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-merged$")},
|
|
{name: "pull.closed is said", subject: "mesh.seat.git.event.pull-closed", given: "{\"base\":\"main\",\"branch\":\"fix/x\",\"head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"number\":179,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"base\":\"main\",\"branch\":\"fix/x\",\"head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"number\":179,\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v PullClosedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-closed$")},
|
|
{name: "forge.pull is said", subject: "mesh.seat.git.event.forge-pull", given: "{\"action\":\"synchronized\",\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}", wire: "{\"action\":\"synchronized\",\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}",
|
|
decode: func(b []byte) (any, error) { var v ForgePullEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-pull$")},
|
|
{name: "forge.status is said", subject: "mesh.seat.git.event.forge-status", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"failed\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"mesh-delivery-checker\",\"state\":\"failure\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"failed\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"mesh-delivery-checker\",\"state\":\"failure\"}",
|
|
decode: func(b []byte) (any, error) { var v ForgeStatusEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-status$")},
|
|
{name: "forge.delete is said", subject: "mesh.seat.git.event.forge-delete", given: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}", wire: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}",
|
|
decode: func(b []byte) (any, error) { var v ForgeDeleteEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-delete$")},
|
|
{name: "repo.writable is said", subject: "mesh.seat.git.event.repo-writable", given: "{\"account\":\"mesh-delivery\",\"repository\":\"jochen/notes\"}", wire: "{\"account\":\"mesh-delivery\",\"repository\":\"jochen/notes\"}",
|
|
decode: func(b []byte) (any, error) { var v RepoWritableEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.repo-writable$")},
|
|
{name: "a branch moved by a merge", subject: "mesh.seat.git.event.branch-moved", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"head\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-catalog\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"head\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-catalog\"}",
|
|
decode: func(b []byte) (any, error) { var v BranchMovedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.branch-moved$")},
|
|
{name: "a failed required step kept", subject: "", given: "{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"commits\":[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"run\":\"main.12.nats\",\"said\":\"TestTheBusWhole failed\",\"step\":\"unit\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"commits\":[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"run\":\"main.12.nats\",\"said\":\"TestTheBusWhole failed\",\"step\":\"unit\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v FailedStepsByModuleFingerprintStepValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "pull asks", subject: "", given: "{\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v PullInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "pull answers", subject: "", given: "{\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}", wire: "{\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}",
|
|
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "pull answers an open one with what the forge would merge now", subject: "", given: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}", wire: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}",
|
|
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "pull answers an error, never none", subject: "", given: "{\"error\":\"the forge holds no pull request novox/mesh-sdk#999\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge holds no pull request novox/mesh-sdk#999\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "open-pulls asks", subject: "", given: "{}", wire: "{}",
|
|
decode: func(b []byte) (any, error) { var v OpenPullsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "open-pulls answers", subject: "", given: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}", wire: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}",
|
|
decode: func(b []byte) (any, error) { var v OpenPullsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "open-pulls answers none open as an empty list", subject: "", given: "{\"pulls\":[]}", wire: "{\"pulls\":[]}",
|
|
decode: func(b []byte) (any, error) { var v OpenPullsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "open-pulls answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\",\"pulls\":[]}", wire: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\",\"pulls\":[]}",
|
|
decode: func(b []byte) (any, error) { var v OpenPullsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tags asks", subject: "", given: "{\"page\":1,\"prefix\":\"go/v\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"page\":1,\"prefix\":\"go/v\",\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v TagsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tags answers", subject: "", given: "{\"bound\":50,\"more\":true,\"page\":1,\"repository\":\"novox/mesh-sdk\",\"tags\":[\"go/v0.1.15\",\"go/v0.1.14\"]}", wire: "{\"bound\":50,\"more\":true,\"page\":1,\"repository\":\"novox/mesh-sdk\",\"tags\":[\"go/v0.1.15\",\"go/v0.1.14\"]}",
|
|
decode: func(b []byte) (any, error) { var v TagsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tags answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 404 for novox/nothing\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge answered 404 for novox/nothing\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v TagsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "trees asks", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"files\":[\"contracts\"],\"paths\":{\"\":[\"go.work\"]},\"repository\":\"novox/mesh-delivery\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"files\":[\"contracts\"],\"paths\":{\"\":[\"go.work\"]},\"repository\":\"novox/mesh-delivery\"}",
|
|
decode: func(b []byte) (any, error) { var v TreesInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "trees answers", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"files\":{\"contracts\":{\"module.json\":\"ffffffffffffffffffffffffffffffffffffffff\"}},\"paths\":{\"\":{\"go.work\":\"1111111111111111111111111111111111111111\"}},\"root\":\"dddddddddddddddddddddddddddddddddddddddd\",\"trees\":{\"\":\"dddddddddddddddddddddddddddddddddddddddd\",\"contracts\":\"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\"}}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"files\":{\"contracts\":{\"module.json\":\"ffffffffffffffffffffffffffffffffffffffff\"}},\"paths\":{\"\":{\"go.work\":\"1111111111111111111111111111111111111111\"}},\"root\":\"dddddddddddddddddddddddddddddddddddddddd\",\"trees\":{\"\":\"dddddddddddddddddddddddddddddddddddddddd\",\"contracts\":\"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\"}}",
|
|
decode: func(b []byte) (any, error) { var v TreesAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "trees answers an error, never none", subject: "", given: "{\"error\":\"the forge's tree listing of novox/mesh-delivery at aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa was cut; no trees are answered from a part\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge's tree listing of novox/mesh-delivery at aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa was cut; no trees are answered from a part\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v TreesAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "file asks", subject: "", given: "{\"path\":\"seats/index.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"repository\":\"novox/mesh-contracts\"}", wire: "{\"path\":\"seats/index.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"repository\":\"novox/mesh-contracts\"}",
|
|
decode: func(b []byte) (any, error) { var v FileInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "file answers", subject: "", given: "{\"blob\":\"2222222222222222222222222222222222222222\",\"content\":\"{\\\"format\\\":1,\\\"seats\\\":[\\\"mesh-broker\\\"]}\",\"path\":\"seats/index.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"size\":31}", wire: "{\"blob\":\"2222222222222222222222222222222222222222\",\"content\":\"{\\\"format\\\":1,\\\"seats\\\":[\\\"mesh-broker\\\"]}\",\"path\":\"seats/index.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"size\":31}",
|
|
decode: func(b []byte) (any, error) { var v FileAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "file answers", subject: "", given: "{\"absent\":true,\"path\":\"seats/gone.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}", wire: "{\"absent\":true,\"path\":\"seats/gone.json\",\"ref\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}",
|
|
decode: func(b []byte) (any, error) { var v FileAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "file answers an error, never none", subject: "", given: "{\"error\":\"seats/big.json is over 512 KiB\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"seats/big.json is over 512 KiB\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v FileAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "contains asks", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"in\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"in\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v ContainsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "contains answers", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"contains\":true,\"in\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"contains\":true,\"in\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"}",
|
|
decode: func(b []byte) (any, error) { var v ContainsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "contains answers an error, never none", subject: "", given: "{\"error\":\"the forge cannot compare bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge cannot compare bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v ContainsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "contains answers a commit the forge does not have as not-found", subject: "", given: "{\"error\":\"the forge has no commit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"error-kind\":\"not-found\"}", wire: "{\"error\":\"the forge has no commit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"error-kind\":\"not-found\"}",
|
|
decode: func(b []byte) (any, error) { var v ContainsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "statuses asks", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v StatusesInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "statuses answers", subject: "", given: "{\"combined\":\"success\",\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"statuses\":[{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}]}", wire: "{\"combined\":\"success\",\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"statuses\":[{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}]}",
|
|
decode: func(b []byte) (any, error) { var v StatusesAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "statuses answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 500\",\"error-kind\":\"failed\"}", wire: "{\"error\":\"the forge answered 500\",\"error-kind\":\"failed\"}",
|
|
decode: func(b []byte) (any, error) { var v StatusesAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "status asks", subject: "", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"checking\",\"id\":\"owed-1\",\"repository\":\"novox/mesh-sdk\",\"state\":\"pending\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"checking\",\"id\":\"owed-1\",\"repository\":\"novox/mesh-sdk\",\"state\":\"pending\"}",
|
|
decode: func(b []byte) (any, error) { var v StatusInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "status answers", subject: "", given: "{\"id\":\"owed-1\",\"performed\":true}", wire: "{\"id\":\"owed-1\",\"performed\":true}",
|
|
decode: func(b []byte) (any, error) { var v StatusAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "status answers an error, never none", subject: "", given: "{\"error\":\"the forge account cannot write novox/mesh-sdk\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge account cannot write novox/mesh-sdk\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v StatusAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "comment asks", subject: "", given: "{\"id\":\"owed-2\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"text\":\"the delivery reached every node\"}", wire: "{\"id\":\"owed-2\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"text\":\"the delivery reached every node\"}",
|
|
decode: func(b []byte) (any, error) { var v CommentInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "comment answers", subject: "", given: "{\"held\":true,\"id\":\"owed-2\"}", wire: "{\"held\":true,\"id\":\"owed-2\"}",
|
|
decode: func(b []byte) (any, error) { var v CommentAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "comment answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 403\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge answered 403\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v CommentAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "view asks", subject: "", given: "{\"id\":\"owed-3\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"text\":\"## Delivery\"}", wire: "{\"id\":\"owed-3\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"text\":\"## Delivery\"}",
|
|
decode: func(b []byte) (any, error) { var v ViewInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "view answers", subject: "", given: "{\"id\":\"owed-3\",\"performed\":true}", wire: "{\"id\":\"owed-3\",\"performed\":true}",
|
|
decode: func(b []byte) (any, error) { var v ViewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "view answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}", wire: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}",
|
|
decode: func(b []byte) (any, error) { var v ViewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "note asks", subject: "", given: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to ace\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to ace\",\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v NoteInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "note answers", subject: "", given: "{\"id\":\"owed-4\",\"performed\":true}", wire: "{\"id\":\"owed-4\",\"performed\":true}",
|
|
decode: func(b []byte) (any, error) { var v NoteAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "note answers an error, never none", subject: "", given: "{\"error\":\"the note ref could not be pushed\",\"error-kind\":\"failed\"}", wire: "{\"error\":\"the note ref could not be pushed\",\"error-kind\":\"failed\"}",
|
|
decode: func(b []byte) (any, error) { var v NoteAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "merge-pull asks", subject: "", given: "{\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"id\":\"owed-5\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"id\":\"owed-5\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}",
|
|
decode: func(b []byte) (any, error) { var v MergePullInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "merge-pull answers", subject: "", given: "{\"id\":\"owed-5\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"performed\":true}", wire: "{\"id\":\"owed-5\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"performed\":true}",
|
|
decode: func(b []byte) (any, error) { var v MergePullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "merge-pull answers", subject: "", given: "{\"id\":\"owed-5\",\"refused\":\"the head moved: cccccccccccccccccccccccccccccccccccccccc, not the named aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"refused-kind\":\"head-moved\"}", wire: "{\"id\":\"owed-5\",\"refused\":\"the head moved: cccccccccccccccccccccccccccccccccccccccc, not the named aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"refused-kind\":\"head-moved\"}",
|
|
decode: func(b []byte) (any, error) { var v MergePullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "merge-pull answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}", wire: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}",
|
|
decode: func(b []byte) (any, error) { var v MergePullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "merge-pull refuses a failed required step, naming the run, the module and the step", subject: "", given: "{\"id\":\"merge-7\",\"module\":\"nats\",\"refused\":\"unit of nats:program failed at fp-0123 in main.12.nats\",\"refused-kind\":\"policy-failed\",\"run\":\"main.12.nats\",\"step\":\"unit\"}", wire: "{\"id\":\"merge-7\",\"module\":\"nats\",\"refused\":\"unit of nats:program failed at fp-0123 in main.12.nats\",\"refused-kind\":\"policy-failed\",\"run\":\"main.12.nats\",\"step\":\"unit\"}",
|
|
decode: func(b []byte) (any, error) { var v MergePullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "branch asks a branch", subject: "", given: "{\"branch\":\"main\",\"repository\":\"novox/mesh-catalog\"}", wire: "{\"branch\":\"main\",\"repository\":\"novox/mesh-catalog\"}",
|
|
decode: func(b []byte) (any, error) { var v BranchInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "branch answers its head and protection", subject: "", given: "{\"branch\":\"main\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"protected\":true,\"repository\":\"novox/mesh-catalog\"}", wire: "{\"branch\":\"main\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"protected\":true,\"repository\":\"novox/mesh-catalog\"}",
|
|
decode: func(b []byte) (any, error) { var v BranchAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "branch answers a branch the forge does not hold", subject: "", given: "{\"error\":\"no branch beta in novox/mesh-catalog\",\"error-kind\":\"not-found\"}", wire: "{\"error\":\"no branch beta in novox/mesh-catalog\",\"error-kind\":\"not-found\"}",
|
|
decode: func(b []byte) (any, error) { var v BranchAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tag asks", subject: "", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\",\"tag\":\"go/v0.1.15\"}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\",\"tag\":\"go/v0.1.15\"}",
|
|
decode: func(b []byte) (any, error) { var v TagInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tag answers performed", subject: "", given: "{\"performed\":true,\"tag\":\"go/v0.1.15\"}", wire: "{\"performed\":true,\"tag\":\"go/v0.1.15\"}",
|
|
decode: func(b []byte) (any, error) { var v TagAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "tag answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 403\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge answered 403\",\"error-kind\":\"refused\"}",
|
|
decode: func(b []byte) (any, error) { var v TagAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
}
|
|
for _, c := range cases {
|
|
v, err := c.decode([]byte(c.given))
|
|
if err != nil {
|
|
t.Errorf("%s: does not decode: %v", c.name, err)
|
|
continue
|
|
}
|
|
back, err := json.Marshal(v)
|
|
if err != nil {
|
|
t.Errorf("%s: does not encode: %v", c.name, err)
|
|
continue
|
|
}
|
|
var got, want any
|
|
if err := json.Unmarshal(back, &got); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := json.Unmarshal([]byte(c.wire), &want); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("%s: reads back as %s, want %s", c.name, back, c.wire)
|
|
}
|
|
if c.subjectIs != nil && !c.subjectIs.MatchString(c.subject) {
|
|
t.Errorf("%s: subject %q is not the contract's %s", c.name, c.subject, c.subjectIs)
|
|
}
|
|
}
|
|
}
|