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
45 lines
2.3 KiB
Go
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)
|
|
}
|
|
}
|