package main import ( "bytes" "testing" intrgb "netdome.biz/paul/qmk-rgb/internal/rgb" ) // README.md: "Without a zone the profile is applied to every channel it names." // A profile key names a channel, so a load applies only the keys that resolve to // a selected channel. The keys themselves are resolved by resolveZoneName, which // channels_test.go covers; what matters here is that a key is never applied to a // channel it does not name. func TestLoadAppliesOnlyTheKeysTheSelectionNames(t *testing.T) { t.Cleanup(vendoredDefinitions(t)) dir := t.TempDir() profile := Profile{ Name: "three", Version: 1, Zones: map[string]*ZoneSettings{ "logo": {Enabled: true, Effect: "light", Brightness: 100, Speed: 1, Color: "00ff"}, "backlight": {Enabled: true, Effect: "solid_color", Brightness: 100, Speed: 1, Color: "00ff"}, "side": {Enabled: true, Effect: "wave", Brightness: 100, Speed: 1, Color: "00ff"}, }, } originalDir := profilesDirOverride t.Cleanup(func() { profilesDirOverride = originalDir }) profilesDirOverride = dir if err := profile.Save(); err != nil { t.Fatalf("save profile: %v", err) } tests := []struct { name string zoneFlag string wantApplied int }{ {"no flag applies all three", "", 3}, {"logo applies one", "logo", 1}, {"backlight applies one", "backlight", 1}, {"side applies one", "side", 1}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { proto := &verifyingProtocol{} restore := stubTargetForProfileTest(t, proto, tt.zoneFlag, impact80Display()) defer restore() cmd := NewProfileLoadCmd() cmd.SetOut(&bytes.Buffer{}) cmd.SetErr(&bytes.Buffer{}) cmd.SetArgs([]string{"three"}) if err := cmd.Execute(); err != nil { t.Fatalf("load returned error: %v", err) } if got := effectWrites(proto); got != tt.wantApplied { t.Errorf("effect writes = %d, want %d", got, tt.wantApplied) } }) } } // effectWrites counts the effect writes, one per applied channel. func effectWrites(proto *verifyingProtocol) int { count := 0 for _, r := range proto.reports { if r.param == uint8(intrgb.EffectID) { count++ } } return count } // A key the selection leaves out is the user's own choice, and saying the // keyboard lacks it is false. Only a key that resolves to a channel the // keyboard does not have is reported. func TestLoadIsQuietAboutAKeyTheSelectionExcludes(t *testing.T) { t.Cleanup(vendoredDefinitions(t)) dir := t.TempDir() originalDir := profilesDirOverride t.Cleanup(func() { profilesDirOverride = originalDir }) profilesDirOverride = dir profile := Profile{ Name: "three", Version: 1, Zones: map[string]*ZoneSettings{ "logo": {Enabled: true, Effect: "light", Brightness: 100, Speed: 1, Color: "00ff"}, "backlight": {Enabled: true, Effect: "solid_color", Brightness: 100, Speed: 1, Color: "00ff"}, }, } if err := profile.Save(); err != nil { t.Fatalf("save profile: %v", err) } proto := &verifyingProtocol{} t.Cleanup(stubTargetForProfileTest(t, proto, "logo", impact80Display())) var stderr bytes.Buffer cmd := NewProfileLoadCmd() cmd.SetOut(&bytes.Buffer{}) cmd.SetErr(&stderr) cmd.SetArgs([]string{"three"}) if err := cmd.Execute(); err != nil { t.Fatalf("load returned error: %v", err) } if stderr.Len() != 0 { t.Errorf("stderr = %q, want nothing for a channel the selection excluded", stderr.String()) } if got := effectWrites(proto); got != 1 { t.Errorf("effect writes = %d, want 1", got) } }