Files
mesh-delivery/modules/mesh-delivery-teller/cmd/mesh-delivery-teller-tools/main_test.go
T
jschoubben 0f4a33ce48 TL5: the teller carries the assigner's asks only, follows the view's answers and says its own on views.answers
The merge-ask path goes whole with the Approve per merge: the reads of
mesh-delivery-gate.asks and mesh-delivery-view.answers, OnAsk, OnAskGone, the
gate branches of Answer and the room list, and the merge words. The teller
follows the view's answers through view_read_answers and views.answers, says
its state answers as views.answers from its state teller-marks, and serves the
read tool teller_read_answers. The room list stays for the assigner's asks
(the lead's answer). viewstate gains the names the view's own commit gives it
(the same hunk, so the two merge cleanly).

Builds: design 47 G §653, §431, §512; lead answers A-172, A-175, A-178

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

102 lines
3.4 KiB
Go

package main
import (
"encoding/json"
"fmt"
"testing"
"time"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/views"
)
type fakeAnswers map[string]string
func (f fakeAnswers) Get(key string) (*stdio.StateEntry, error) {
v, ok := f[key]
if !ok {
return nil, nil
}
return &stdio.StateEntry{Key: key, Value: json.RawMessage(v)}, nil
}
func (f fakeAnswers) Keys() ([]string, error) {
var out []string
for k := range f {
out = append(out, k)
}
return out, nil
}
// teller_answers reads the teller's answers: one by the ask's key, an ask with none said as not found, every answer when no key
// is named (ADR 0596 §3: the gate asks this tool, never the bucket).
func TestTellerAnswersReadsOneAnswerOrEveryAnswer(t *testing.T) {
tool := AnswerTools(fakeAnswers{"k1": `{"option":"approve"}`, "k2": `{"option":"decline"}`})[0]
if tool.Name != "teller_answers" {
t.Fatalf("the tool is %s", tool.Name)
}
out, err := tool.Run(map[string]any{"key": "k1"})
if err != nil || fmt.Sprint(out) != `map[answer:{"option":"approve"} found:true key:k1]` {
t.Errorf("one answer: %v, %v", out, err)
}
out, err = tool.Run(map[string]any{"key": "gone"})
if err != nil || fmt.Sprint(out) != `map[found:false key:gone]` {
t.Errorf("no answer: %v, %v", out, err)
}
out, err = tool.Run(map[string]any{})
raw, _ := json.Marshal(out)
if err != nil || string(raw) != `{"answers":[{"answer":{"option":"approve"},"key":"k1"},{"answer":{"option":"decline"},"key":"k2"}]}` {
t.Errorf("every answer: %s, %v", raw, err)
}
}
// teller_widens_said reads the state widens-said: the commit last said for one module and branch, or every one.
func TestTellerWidensSaidReadsOneKeyOrEveryKey(t *testing.T) {
tool := WidensSaidTools(fakeAnswers{"nats.main": `"c1"`, "nats.next": `"c2"`})[0]
if tool.Name != "teller_widens_said" {
t.Fatalf("the tool is %s", tool.Name)
}
out, err := tool.Run(map[string]any{"key": "nats.main"})
if err != nil || fmt.Sprint(out) != `map[commit:"c1" found:true key:nats.main]` {
t.Errorf("one key: %v, %v", out, err)
}
out, err = tool.Run(map[string]any{})
raw, _ := json.Marshal(out)
if err != nil || string(raw) != `{"said":[{"commit":"c1","key":"nats.main"},{"commit":"c2","key":"nats.next"}]}` {
t.Errorf("every key: %s, %v", raw, err)
}
}
// teller_read_answers is the teller's ordinary read tool of its state answers (A-175, A-178): the key's value and revision, the
// keys, over the answers state and the marks state teller-marks.
type entries map[string]views.Entry
func (e entries) Keys() ([]string, error) {
var out []string
for k := range e {
out = append(out, k)
}
return out, nil
}
func (e entries) Get(key string) (*views.Entry, bool, error) {
v, ok := e[key]
return &v, ok, nil
}
func TestTellerReadAnswersIsTheViewsReadToolOfTheAnswersState(t *testing.T) {
values := entries{"hold.k1": {Value: json.RawMessage(`{"option":"keep"}`), Revision: 3}}
tool := ReadAnswersTools(values, entries{}, time.Now)[0]
if tool.Name != "teller_read_answers" {
t.Fatalf("the tool is %s", tool.Name)
}
out, err := tool.Run(map[string]any{"key": "hold.k1"})
raw, _ := json.Marshal(out)
if err != nil || string(raw) != `{"owner":"mesh-delivery-teller","state":"answers","key":"hold.k1","found":true,"value":{"option":"keep"},"revision":3}` {
t.Errorf("one key: %s, %v", raw, err)
}
if marksState != "teller-marks" {
t.Errorf("the marks state is %s", marksState)
}
}