Files
mesh-host/internal/compose/resolution/seat_data_test.go
T
jschoubben d68e241724 Take the catalogue's composition rules into the node-engine
ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk
carries no composition rule. The catalogue functions only the
node-engine's composition reaches (Resolve, Resolution's Compose,
Declaration, DataItems, LeftOut, Rules and the rest, the settings,
placeholder and template refusals, the rendering helpers) are copied
with their tests into internal/compose/resolution; a method of a
mesh-sdk shape becomes a function taking it first. The composition
calls its own copies, and the captured catalogue its tests read lives
here now, shared by mesh-compose's tests.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 19:15:55 +01:00

109 lines
3.8 KiB
Go

package resolution
import (
"encoding/json"
"strings"
"testing"
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
)
const barTemplate = `{{if eq .shows "battery"}}[[block]]
block = "battery"
{{with .options}}{{with .device}}device = {{quote .}}
{{end}}{{end}}{{else if eq .shows "command"}}[[block]]
block = "custom"
command = {{quote .options.command}}
interval = {{.options.interval}}
{{else if eq .shows "state"}}[[block]]
block = "custom"
command = {{quote (printf "show %s %s" .options.state (or .options.key .machine))}}
{{end}}`
func barHolder() mcat.Manifest {
place := func(bar string) string {
return "own-first\n${contribution:node-bar:block:bar=" + bar + ",place=resources}" +
"own-middle\n${contribution:node-bar:block:bar=" + bar + ",place=status}own-last\n"
}
return mcat.Manifest{Module: "a-bar", Claims: []mcat.Claim{{Name: mcat.BarSeat, Renders: map[string]string{mcat.BarKindBlock: barTemplate}}},
Resources: []map[string]any{
{"id": "bottom", "type": "file", "path": "/b", "content": place("bottom")},
{"id": "top", "type": "file", "path": "/t", "content": place("top")},
}}
}
func block(data string) mcat.SeatContribution {
var d map[string]any
if err := json.Unmarshal([]byte(data), &d); err != nil {
panic(err)
}
return mcat.SeatContribution{Seat: mcat.BarSeat, Kind: mcat.BarKindBlock, Data: d}
}
func composedFile(t *testing.T, r mcat.Resolution, id string) string {
t.Helper()
out, err := Declaration(r, mcat.Rendering{})
if err != nil {
t.Fatal(err)
}
for _, res := range out {
if res["id"] == id {
return res["content"].(string)
}
}
t.Fatalf("%s was not composed", id)
return ""
}
func TestResolveCarriesTheMachinesCapabilities(t *testing.T) {
node := workstation()
node.Capabilities["battery"] = true
r, err := Resolve(shelf(mcat.Manifest{Module: "a"}), []string{"a"}, node, mcat.World{})
if err != nil {
t.Fatal(err)
}
if !r.Capabilities["battery"] || !r.Capabilities["seat"] {
t.Fatalf("the resolution carries %v, not the node's %v", r.Capabilities, node.Capabilities)
}
}
func TestAPieceTheHolderCannotRenderIsLeftOutAndNamedNotTheMachine(t *testing.T) {
// A shows the shape gained after the holder's template was written: built here, past the check.
power := mcat.Manifest{Module: "power", Contributions: []mcat.SeatContribution{
block(`{"bar":"bottom","place":"status","shows":"gpu"}`),
block(`{"bar":"bottom","place":"status","shows":"battery"}`),
}}
r := mcat.Resolution{Node: "n", Account: "op", Modules: []mcat.Manifest{barHolder(), power}}
c, err := Compose(r, mcat.Rendering{})
if err != nil {
t.Fatalf("one piece failed the whole machine: %v", err)
}
if len(c.Unplaced) != 1 || !strings.Contains(c.Unplaced[0], "power's node-bar:block") ||
!strings.Contains(c.Unplaced[0], "shows=gpu") || !strings.Contains(c.Unplaced[0], "renders nothing") {
t.Fatalf("unplaced: %v", c.Unplaced)
}
for _, res := range c.Resources {
if res["id"] == "a-bar.bottom" && !strings.Contains(res["content"].(string), `block = "battery"`) {
t.Fatalf("the piece beside it was lost too: %s", res["content"])
}
}
}
func TestAnOfferedBlockMakesNoDependencyOnTheBar(t *testing.T) {
power := mcat.Manifest{Module: "power", Contributions: []mcat.SeatContribution{
block(`{"bar":"bottom","place":"status","shows":"battery"}`),
{Seat: mcat.HotkeysSeat, Kind: "trigger", Content: "x"},
}}
for _, seat := range DependsOn(nil, power) {
if seat == mcat.BarSeat {
t.Fatalf("a block made the power module depend on the bar: %v", DependsOn(nil, power))
}
}
// And on a machine with no bar it is placed nowhere, and nothing fails.
r := mcat.Resolution{Node: "server", Account: "op", Capabilities: map[string]bool{"battery": true},
Modules: []mcat.Manifest{hotkeysHolder(), power}}
if _, err := Declaration(r, mcat.Rendering{}); err != nil {
t.Fatal(err)
}
}