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.VariantsOf(QueryUnknown) { 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.VariantsOf(QueryWeatherNow) { 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) } } }