Tentacle enhancements.

This commit is contained in:
Storm Dragon committed 2026-11-04 13:44:13 -05:00
1 parent 4f9b89e38b
commit 9e15f8652d
12 files changed
+619 -22

No files matched your search

@@ -0,0 +1,92 @@
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package tentaclewire
import (
"encoding/json"
"os/exec"
"path/filepath"
"strings"
"testing"
)
func TestRemoteSpeechSDKValidation(t *testing.T) {
cases := []struct {
data string
valid bool
}{
{`{"kind":"speak","parts":[{"text":" hello\t世界 ","characters":true,"language":"en_US"},{"end":true}]}`, true},
{`{"kind":"cancel"}`, true},
{`{"kind":"pause","paused":false}`, true},
{`{"kind":"pause","paused":true}`, true},
{`{"kind":"speak","priority":2,"parts":[{"text":"x"}]}`, true},
{`{"kind":"speak","priority":3,"parts":[{"text":"x"}]}`, false},
{`{"kind":"speak","priority":true,"parts":[{"text":"x"}]}`, false},
{`{"kind":"speak","parts":[]}`, false},
{`{"kind":"speak","parts":[{}]}`, false},
{`{"kind":"speak","parts":[{"text":null}]}`, false},
{`{"kind":"speak","parts":[{"text":"x","end":true}]}`, false},
{`{"kind":"speak","parts":[{"text":"x","language":"../en"}]}`, false},
{`{"kind":"speak","parts":[{"text":"x","voice":"peer path"}]}`, false},
{`{"kind":"speak","parts":[{"text":"x"}],"paused":false}`, false},
{`{"kind":"cancel","parts":null}`, false},
{`{"kind":"cancel","parts":[{"text":"x"}]}`, false},
{`{"kind":"cancel","paused":false}`, false},
{`{"kind":"pause"}`, false},
{`{"kind":"pause","paused":null}`, false},
{`{"kind":"pause","paused":0}`, false},
{`{"kind":"wave","path":"anything"}`, false},
{`{"kind":"cancel","priority":null}`, false},
{`{"kind":"cancel","extra":1}`, false},
{`{"kind":"speak","parts":[{"text":"` + strings.Repeat("x", MaxRemoteSpeechBytes) + `"}]}`, false},
{`{"kind":"speak","parts":[{"text":"` + strings.Repeat("<", 1100) + `"}]}`, false},
{`{"kind":"speak","parts":[{"text":"` + strings.Repeat("\u2028", 1100) + `"}]}`, false},
}
var pythonCases []any
for _, item := range cases {
var speech RemoteSpeech
valid := DecodeStrict([]byte(item.data), &speech) == nil && ValidRemoteSpeech(speech)
if valid != item.valid {
t.Fatalf("Go validation: %.100s: got %v", item.data, valid)
}
var value any
if err := json.Unmarshal([]byte(item.data), &value); err != nil {
t.Fatal(err)
}
pythonCases = append(pythonCases, map[string]any{"speech": value, "valid": item.valid})
}
path, err := filepath.Abs("../../sdk/python")
if err != nil {
t.Fatal(err)
}
script := `import json, sys
sys.path.insert(0, sys.argv[1])
from cthulhu_tentacle.session import valid_remote_speech
for case in json.load(sys.stdin):
assert valid_remote_speech(case['speech']) == case['valid'], str(case)[:150]
`
data, _ := json.Marshal(pythonCases)
command := exec.Command("python3", "-B", "-c", script, path)
command.Stdin = strings.NewReader(string(data))
if output, err := command.CombinedOutput(); err != nil {
t.Fatalf("Python validation: %v: %s", err, output)
}
}
func TestRemoteSpeechEncodedBoundary(t *testing.T) {
value := RemoteSpeech{Kind: "speak", Parts: []RemoteSpeechPart{{Text: "x"}}}
data, _ := json.Marshal(value)
value.Parts[0].Text = strings.Repeat("x", MaxRemoteSpeechBytes-len(data)+1)
if !ValidRemoteSpeech(value) {
t.Fatal("rejected exact bound")
}
value.Parts[0].Text += "x"
if ValidRemoteSpeech(value) {
t.Fatal("accepted above bound")
}
value.Parts[0].Text = string([]byte{0xff})
if ValidRemoteSpeech(value) {
t.Fatal("accepted invalid UTF-8")
}
}