Filter dialog: only offer options that yield results

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 20:48:57 +02:00
co-authored by Claude Sonnet 5.5
parent ac1c2ebce2
commit 8a357f7418
7 changed files with 215 additions and 81 deletions
+53
View File
@@ -1,6 +1,7 @@
package ui
import (
"slices"
"strings"
"testing"
@@ -156,3 +157,55 @@ func TestMovieItemAttrs(t *testing.T) {
t.Error("series with files must fetch its attributes")
}
}
func TestListedValues(t *testing.T) {
uhd := arr.FileAttrs{Resolution: 2160, Codec: arr.CodecX265, HDR: true, Audio: []string{"Atmos"}, Languages: []string{"English"}}
hd := arr.FileAttrs{Resolution: 1080, Codec: arr.CodecX264, Audio: []string{"DD"}, Languages: []string{"German"}}
pool := filterPool{files: [][]arr.FileAttrs{{uhd}, {hd}, nil}}
byLabel := func(label string) facet {
for _, f := range facetDefs {
if f.label == label {
return f
}
}
t.Fatalf("no facet %q", label)
return facet{}
}
list := func(label string, state attrFilter, p filterPool) []string {
return listedValues(byLabel(label), state, p)
}
// Without other criteria only options present in the pool are offered.
if got := list("Quality", attrFilter{}, pool); !slices.Equal(got, []string{"", "2160p", "1080p"}) {
t.Errorf("quality = %v", got)
}
if got := list("Audio", attrFilter{}, pool); !slices.Equal(got, []string{"", "Atmos", "DD"}) {
t.Errorf("audio = %v", got)
}
if got := list("Language", attrFilter{}, pool); !slices.Equal(got, []string{"", "English", "German"}) {
t.Errorf("language = %v", got)
}
// Other criteria narrow the options: nothing in 2160p is x264.
if got := list("Codec", attrFilter{res: "2160p"}, pool); !slices.Equal(got, []string{"", "x265"}) {
t.Errorf("codec given 2160p = %v", got)
}
// A facet is not narrowed by its own choice.
if got := list("Quality", attrFilter{res: "2160p"}, pool); !slices.Equal(got, []string{"", "2160p", "1080p"}) {
t.Errorf("quality given 2160p = %v", got)
}
// The current choice stays listed even when it matches nothing.
if got := list("Audio", attrFilter{res: "1080p", audio: "Atmos"}, pool); !slices.Equal(got, []string{"", "Atmos", "DD"}) {
t.Errorf("audio = %v", got)
}
if got := list("Language", attrFilter{lang: "Swahili"}, pool); got[1] != "Swahili" {
t.Errorf("a language not in the pool must stay listed: %v", got)
}
// While files are unknown nothing is ruled out.
if got := list("Quality", attrFilter{}, filterPool{unknown: true}); len(got) != 1+len(resOptions) {
t.Errorf("unknown pool: %v", got)
}
// An empty pool offers nothing but "any".
if got := list("Codec", attrFilter{}, filterPool{}); !slices.Equal(got, []string{""}) {
t.Errorf("empty pool: %v", got)
}
}