diff --git a/go/seatdef/seatdef.go b/go/seatdef/seatdef.go index 50f0da4..f1336f3 100644 --- a/go/seatdef/seatdef.go +++ b/go/seatdef/seatdef.go @@ -389,8 +389,16 @@ func (d Definition) check() Problems { if !eventName.MatchString(e.Name) { ps = append(ps, Problem{where + ".name", "missing, or not lower-case words joined by dots"}) } - if e.Subject == "" { + // A holder's event is published under the holder's own module subjects, or, when it is kept in a stream of the + // holder's own module (its family), under that stream's (buscompose.ModuleStreamSubject). + own, stream := "mesh.mod..event."+e.Name, "mesh.stream..event."+e.Name + switch { + case e.Subject == "": ps = append(ps, Problem{where + ".subject", "missing"}) + case e.Subject == stream && e.Family == "": + ps = append(ps, Problem{where + ".subject", "a subject of the holder's own stream, and no family names that stream"}) + case e.Subject != own && e.Subject != stream: + ps = append(ps, Problem{where + ".subject", fmt.Sprintf("not %s, nor %s for an event kept in the holder's own stream", own, stream)}) } } for i, r := range d.Records { diff --git a/go/seatdef/seatdef_test.go b/go/seatdef/seatdef_test.go index 7f27a8f..e51f316 100644 --- a/go/seatdef/seatdef_test.go +++ b/go/seatdef/seatdef_test.go @@ -41,6 +41,12 @@ func TestADefinitionIsReadStrictlyNamingWhatIsWrong(t *testing.T) { `"max-age-days":30`, 1), "family.max-age-days: missing, or not 7"}, {"a family with a cap of its own", strings.Replace(whole, `"max-age-days":7`, `"max-age-days":7,"max-mib":256`, 1), "max-mib: a field the format does not know"}, + {"a holder's event on its own stream", strings.Replace(whole, `"family":`, `"holder-events":[{"name":"verdict",`+ + `"subject":"mesh.stream..event.verdict","family":"checker.asks"}],"family":`, 1), ""}, + {"a holder's event on its own stream with no family", strings.Replace(whole, `"family":`, `"holder-events":[{"name":"verdict",`+ + `"subject":"mesh.stream..event.verdict"}],"family":`, 1), "no family names that stream"}, + {"a holder's event on a subject of no module", strings.Replace(whole, `"family":`, `"holder-events":[{"name":"verdict",`+ + `"subject":"mesh.event.verdict"}],"family":`, 1), "holder-events[0].subject: not mesh.mod..event.verdict"}, {"a verb twice", strings.Replace(listGrain, `]}`, `,{"name":"add"}]}`, 1), `"add" twice`}, {"records at the seat list's grain", strings.Replace(listGrain, `"decision":"ADR 1",`, `"decision":"ADR 1","records":[{"name":"asks"}],`, 1), "grain: seat-list holds"},