Files
mesh-delivery/modules/mesh-grants/internal/grants/defined_test.go
T
jschoubben 9cd38f59ff A-181: the assigner reads the builder's build ends from their stream, kept last per subject, and reads no builder bucket
The builder's `build.ended` stream declares last-per-subject; the grants part composes it one message per subject and its readers read
whole; the assigner reads it whole at its start then follows it (consumes `build.ended.**`), so what was built and a failed build's error
survive its restart. world.built, buildNeeds, manifestOf and the put verbs read the ends; the manifest reads no builder bucket;
assigner_put's fingerprint-prefix form goes.

Builds: design 47 G A-181, A-162, §556, §703

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:53:02 +01:00

45 lines
2.3 KiB
Go

package grants
import (
"slices"
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// Design 47 G §386, §474, §644: a `*` emitter before one of mesh-sdk's finding events reaches each declaring module's own
// stream, with no seat list read; one before an event no definition names stays the shared stream's.
func TestAStarEmitterBeforeAFindingEventReachesEachDeclaringStream(t *testing.T) {
shelf := map[string]catalogue.Manifest{
"a": {Module: "a", Streams: []catalogue.StreamDeclaration{{Name: "a-findings", Events: []string{"finding-written"}}}},
"b": {Module: "b", Streams: []catalogue.StreamDeclaration{{Name: "b-usage", Events: []string{"usage"}}}},
}
none := func(string, string) []any { return nil }
defined := func(e string) bool { return definedEventsOf(nil)[e] }
keeper := catalogue.Manifest{Module: "keeper", Consumes: []string{"*.finding-written", "*.usage"}}
hears, touches, onEvents := hearsOf(keeper, shelf, "ace", none, keeper.Consumes, defined)
if !touches || len(hears) != 1 || hears[0].Emitter != "a" || !slices.Equal(onEvents, []string{"*.finding-written", "*.usage"}) {
t.Fatalf("heard %+v (touches %v, on EVENTS %v)", hears, touches, onEvents)
}
if hears, _, _ := hearsOf(keeper, shelf, "ace", none, keeper.Consumes, nil); len(hears) != 0 {
t.Fatalf("with no event defined, heard %+v", hears)
}
}
// Design 47 G §703, §556, A-181: a stream a manifest declares kept last per subject is asked of the bus so (one message per subject),
// and what hears it is composed to read it whole.
func TestAStreamKeptLastPerSubjectIsComposedAndHeardSo(t *testing.T) {
shelf := map[string]catalogue.Manifest{
"builder": {Module: "builder", Streams: []catalogue.StreamDeclaration{{Name: "builder-builds", Events: []string{"build.ended.**"}, LastPerSubject: true}}},
}
none := func(string, string) []any { return nil }
reader := catalogue.Manifest{Module: "reader", Consumes: []string{"builder.build.ended.**"}}
hears, _, _ := hearsOf(reader, shelf, "ace", none, reader.Consumes, nil)
if len(hears) != 1 || !hears[0].LastPerSubject {
t.Fatalf("heard %+v, want one stream read whole", hears)
}
if got := streamsOf(shelf["builder"]); len(got) != 1 || got[0].Stream().MaxMsgsPerSubject != 1 {
t.Fatalf("composed %+v, want one message per subject", got)
}
}