The first version filled the whole row at 24%, and in a real log that meant every row was painted: nearly every contact has SOME QSL state, so colour was present everywhere and stopped being information — a striped background with the data behind it. The default is now a 3px stripe down the left edge. Same signal, nothing lost to read it. A filled row is still offered, with a strength slider, for operators who want the block — and the rule cards in Settings preview whichever is chosen, so the decision is made by looking rather than by imagining. Drawn as an inset shadow rather than a border: a border would shift the cells three pixels on coloured rows only, and the columns would stop lining up. Style and strength are normalised rather than rejected — a value out of range is a slider that got away, not a reason to reset the operator's colours.
78 lines
2.8 KiB
Go
78 lines
2.8 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
// The colour is interpolated into a CSS color-mix() by the grid, so anything
|
|
// that is not plainly a hex colour has to be refused rather than passed on.
|
|
func TestRowColorsRefuseAnythingButHex(t *testing.T) {
|
|
in := RowColorSettings{Enabled: true, Rules: []RowColorRule{
|
|
{ID: "confirmed_lotw", Color: "#123abc", Enabled: true},
|
|
{ID: "sent_waiting", Color: "red; background:url(x)", Enabled: true},
|
|
{ID: "to_send", Color: "", Enabled: true},
|
|
}}
|
|
got := normRowColors(in)
|
|
|
|
byID := map[string]RowColorRule{}
|
|
for _, r := range got.Rules {
|
|
byID[r.ID] = r
|
|
}
|
|
if byID["confirmed_lotw"].Color != "#123abc" {
|
|
t.Errorf("a valid colour was rewritten: %q", byID["confirmed_lotw"].Color)
|
|
}
|
|
if byID["sent_waiting"].Color != rowColorDefaults["sent_waiting"] {
|
|
t.Errorf("an injection attempt survived: %q", byID["sent_waiting"].Color)
|
|
}
|
|
if byID["to_send"].Color != rowColorDefaults["to_send"] {
|
|
t.Errorf("an empty colour was kept: %q", byID["to_send"].Color)
|
|
}
|
|
}
|
|
|
|
// Priority lives in the data, not in a chain of ifs: a contact confirmed on
|
|
// LoTW AND by card is confirmed, not "sent, awaiting reply". The panel shows
|
|
// the rules in the order they apply, so that order must survive a round trip.
|
|
func TestRowColorsKeepPriorityOrder(t *testing.T) {
|
|
// Saved in a jumbled order, as a hand-edited settings row could be.
|
|
got := normRowColors(RowColorSettings{Rules: []RowColorRule{
|
|
{ID: "to_send", Color: "#111111"},
|
|
{ID: "confirmed_lotw", Color: "#222222"},
|
|
}})
|
|
if len(got.Rules) != len(rowColorOrder) {
|
|
t.Fatalf("got %d rules, want every one present", len(got.Rules))
|
|
}
|
|
for i, id := range rowColorOrder {
|
|
if got.Rules[i].ID != id {
|
|
t.Errorf("rule %d is %q, want %q", i, got.Rules[i].ID, id)
|
|
}
|
|
}
|
|
// The saved colours survived the reordering.
|
|
if got.Rules[0].Color != "#222222" {
|
|
t.Errorf("confirmed_lotw lost its colour: %q", got.Rules[0].Color)
|
|
}
|
|
}
|
|
|
|
// Style and strength are normalised, not rejected: they only shape a colour, and
|
|
// a value that got away is a slider, not a fault worth resetting the operator's
|
|
// whole choice for.
|
|
func TestRowColorsNormaliseStyleAndIntensity(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
inStyle string
|
|
inPct int
|
|
wantStyle string
|
|
wantPct int
|
|
}{
|
|
{"bar", 12, "bar", 12},
|
|
{"tint", 30, "tint", 30},
|
|
{"both", 45, "both", 45},
|
|
{"", 0, "bar", 12}, // never configured
|
|
{"wallpaper", 12, "bar", 12}, // not a style we draw
|
|
{"tint", 900, "tint", 45}, // clamped, not reset
|
|
{"tint", -5, "tint", 12},
|
|
} {
|
|
got := normRowColors(RowColorSettings{Style: tc.inStyle, Intensity: tc.inPct})
|
|
if got.Style != tc.wantStyle || got.Intensity != tc.wantPct {
|
|
t.Errorf("(%q,%d) -> (%q,%d), want (%q,%d)",
|
|
tc.inStyle, tc.inPct, got.Style, got.Intensity, tc.wantStyle, tc.wantPct)
|
|
}
|
|
}
|
|
}
|