Main reverted G's half merge (#189, reverted by8afc3ebin #191) and then took the reader release's S1-S5, which copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's headf30dee54only by those and the release's two tests (objects cap option, seat states and stream kinds). Builds: design 47 G (the milestone's sdk part, as atf30dee54) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
54 lines
2.0 KiB
Go
54 lines
2.0 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
func strSliceEqual(a, b []string) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i := range a {
|
|
if a[i] != b[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Design 47 G A-115, A-127: `serves` is a field of the process beside its bus; inside the bus it is refused.
|
|
func TestProcessServesIsReadBesideTheBusAndRefusedInsideIt(t *testing.T) {
|
|
if err := json.Unmarshal([]byte(`{"serves":["seat:mesh-broker.list"]}`), &ProcessBus{}); err == nil {
|
|
t.Error("a serves inside bus was accepted")
|
|
}
|
|
if err := json.Unmarshal([]byte(`{"holds":["x"]}`), &ProcessBus{}); err == nil {
|
|
t.Error("an unknown key was accepted")
|
|
}
|
|
// Design 47 G A-340: a process's bus names the events it hears under `consumes`.
|
|
var heard ProcessBus
|
|
if err := json.Unmarshal([]byte(`{"consumes":["mesh-conditions.findings-asked"]}`), &heard); err != nil ||
|
|
!strSliceEqual(heard.Consumes, []string{"mesh-conditions.findings-asked"}) {
|
|
t.Errorf("a bus's consumes read as %v (%v)", heard.Consumes, err)
|
|
}
|
|
m := Manifest{Module: "nats", Resources: []map[string]any{
|
|
{"id": "keeper", "type": "process", "serves": []any{"seat:mesh-broker.snapshot-get", "seat:mesh-broker.list"},
|
|
"bus": map[string]any{"keeps": true}},
|
|
{"id": "plain", "type": "process", "serves": []any{"seat:mesh-broker.snapshot-remove"}},
|
|
{"id": "mute", "type": "process"},
|
|
}}
|
|
got := m.ProcessServes()
|
|
if !strSliceEqual(got["keeper"], []string{"seat:mesh-broker.snapshot-get", "seat:mesh-broker.list"}) ||
|
|
!strSliceEqual(got["plain"], []string{"seat:mesh-broker.snapshot-remove"}) || len(got) != 2 {
|
|
t.Errorf("process serves = %v", got)
|
|
}
|
|
accounts := m.BusAccounts()
|
|
if len(accounts) != 1 || !strSliceEqual(accounts[0].Serves, got["keeper"]) {
|
|
t.Errorf("the bus account's serves = %+v", accounts)
|
|
}
|
|
bad := Manifest{Resources: []map[string]any{{"id": "x", "type": "process", "serves": "seat:a.b"}}}
|
|
if _, err := ProcessServesOf(bad.Resources[0]); err == nil {
|
|
t.Error("a serves that is not a list was accepted")
|
|
}
|
|
}
|