Files
Maven/internal/phraser/query_lines_test.go
T
claude 765ed36340 phraser: the query answers as review rewrote them (V-521)
The owner's wording, taken from the PR 111 review, with one correction from the
PR 113 review folded in: {temp} {word} rather than {temp}°, because the degree
sign reads as nothing through piper.

What the wording changes: query_unknown drops "не знаю.", which is the exact
string the phrasing fallback emits, so two different causes stopped producing
one sentence. weather_nolocation stops reading voice.weather.default_location
out loud and just asks which city. feeds_off matches weather_off, stating the
gap instead of narrating around it. The passive doubles and the near-identical
pairs go.

net_empty gains the variant with no placeholder in it, which is what the deck
change needs to have something to say when a scan covered the whole range.

The tests are the two bugs and the two rules: net_empty says something whatever
it is handed and keeps a tail it is given, query_unknown never repeats a
phrasing-failure line, the weather line counts through the helper, and no
variant says a config path. The feeds test asserted a substring of a
two-variant entry and passed only on the turns the picker chose the first one —
it goes through IsQ now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGTGCWX33aX8SMBSRz9VmS
2026-08-04 15:38:16 +04:00

108 lines
3.3 KiB
Go

package phraser
import (
"math/rand"
"strings"
"testing"
)
func TestQueriesLoad(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
for _, k := range queryKeys {
if got := q.Say(k, nil); got == "" {
t.Errorf("%s says nothing", k)
}
}
}
// The bug: net_empty carried {tail} in every variant, and a scan that finished
// the whole range has no caveat to put there. Whatever the file says, an answer
// he can hear has to come out — never braces, never nothing.
func TestNetEmptySaysSomethingWithNoTail(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
for _, vars := range []map[string]string{nil, {"tail": ""}} {
for i := 0; i < 20; i++ {
got := q.Say(QueryNetEmpty, vars)
if got == "" || strings.ContainsAny(got, "{}") {
t.Fatalf("net_empty with vars %v said %q", vars, got)
}
}
}
}
// The other half: a caveat he was given is not dropped for a shorter wording.
func TestNetEmptyKeepsTheTailItIsGiven(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
const tail = ", но успела посмотреть не всю сеть"
for i := 0; i < 20; i++ {
if got := q.Say(QueryNetEmpty, map[string]string{"tail": tail}); !strings.Contains(got, tail) {
t.Fatalf("net_empty dropped the tail: %q", got)
}
}
}
// query_unknown means she looked and found nothing. The phraser's fallback
// means she failed to phrase an answer she had. Two causes, two sentences, or
// the distinction the two files exist for is unobservable from the outside.
func TestQueryUnknownNeverRepeatsAPhrasingFallback(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
f, err := LoadFallbacks(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadFallbacks: %v", err)
}
failures := map[string]bool{}
for _, v := range f.Variants() {
failures[v] = true
}
for _, v := range q.d.file.Entries[QueryUnknown].Variants {
if failures[v] {
t.Errorf("query_unknown variant %q is also a phrasing failure line", v)
}
}
}
// The weather line splits the count into a number and a noun, so a variant that
// says the temperature without {word} is the hardcoded "градусов" coming back.
func TestWeatherLineCountsWithTheHelper(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
for _, v := range q.d.file.Entries[QueryWeatherNow].Variants {
if strings.Contains(v, "градус") {
t.Errorf("weather_now variant %q spells the noun out instead of using {word}", v)
}
}
got := q.Say(QueryWeatherNow, map[string]string{
"location": "Москва", "temp": "1", "word": Degrees(1), "condition": "ясно",
})
if !strings.Contains(got, "1 градус,") {
t.Errorf("weather_now said %q, want the singular noun", got)
}
}
// No line spoken to him names a config key. She asks instead.
func TestNoQueryLineRecitesAConfigPath(t *testing.T) {
q, err := LoadQueries(rand.NewSource(1))
if err != nil {
t.Fatalf("LoadQueries: %v", err)
}
for _, v := range q.Variants() {
if strings.Contains(v, "voice.") || strings.Contains(v, "_location") {
t.Errorf("variant %q says a config path out loud", v)
}
}
}