diff --git a/pkg/models/balance_marshal_test.go b/pkg/models/balance_marshal_test.go new file mode 100644 index 0000000..8386847 --- /dev/null +++ b/pkg/models/balance_marshal_test.go @@ -0,0 +1,129 @@ +package models + +import ( + "encoding/xml" + "strings" + "testing" +) + +func TestBalanceMarshalXML(t *testing.T) { + balance := Balance{ + DeviceID: "1234567890AB", + TargetBalance: -25, + ActualBalance: -25, + } + + var buf strings.Builder + encoder := xml.NewEncoder(&buf) + err := balance.MarshalXML(encoder, xml.StartElement{Name: xml.Name{Local: "balance"}}) + if err != nil { + t.Fatalf("MarshalXML failed: %v", err) + } + encoder.Flush() + + // Convert to string for easier testing + xmlStr := buf.String() + + // Check that XML contains expected elements + expectedElements := []string{ + `deviceID="1234567890AB"`, + `-25`, + `-25`, + } + + for _, expected := range expectedElements { + if !strings.Contains(xmlStr, expected) { + t.Errorf("MarshalXML result %q does not contain expected element %q", xmlStr, expected) + } + } +} + +func TestBalanceMarshalXML_PositiveValue(t *testing.T) { + balance := Balance{ + DeviceID: "ABCDEF123456", + TargetBalance: 30, + ActualBalance: 30, + } + + var buf strings.Builder + encoder := xml.NewEncoder(&buf) + err := balance.MarshalXML(encoder, xml.StartElement{Name: xml.Name{Local: "balance"}}) + if err != nil { + t.Fatalf("MarshalXML failed: %v", err) + } + encoder.Flush() + + xmlStr := buf.String() + + expectedElements := []string{ + `deviceID="ABCDEF123456"`, + `30`, + `30`, + } + + for _, expected := range expectedElements { + if !strings.Contains(xmlStr, expected) { + t.Errorf("MarshalXML result %q does not contain expected element %q", xmlStr, expected) + } + } +} + +func TestBalanceMarshalXML_ZeroValue(t *testing.T) { + balance := Balance{ + DeviceID: "ZERO0000TEST", + TargetBalance: 0, + ActualBalance: 0, + } + + var buf strings.Builder + encoder := xml.NewEncoder(&buf) + err := balance.MarshalXML(encoder, xml.StartElement{Name: xml.Name{Local: "balance"}}) + if err != nil { + t.Fatalf("MarshalXML failed: %v", err) + } + encoder.Flush() + + xmlStr := buf.String() + + expectedElements := []string{ + `deviceID="ZERO0000TEST"`, + `0`, + `0`, + } + + for _, expected := range expectedElements { + if !strings.Contains(xmlStr, expected) { + t.Errorf("MarshalXML result %q does not contain expected element %q", xmlStr, expected) + } + } +} + +func TestBalanceMarshalXML_ExtremeValues(t *testing.T) { + balance := Balance{ + DeviceID: "EXTREME_TEST", + TargetBalance: -50, // Min value + ActualBalance: 50, // Max value + } + + var buf strings.Builder + encoder := xml.NewEncoder(&buf) + err := balance.MarshalXML(encoder, xml.StartElement{Name: xml.Name{Local: "balance"}}) + if err != nil { + t.Fatalf("MarshalXML failed: %v", err) + } + encoder.Flush() + + xmlStr := buf.String() + + expectedElements := []string{ + `deviceID="EXTREME_TEST"`, + `-50`, + `50`, + } + + for _, expected := range expectedElements { + if !strings.Contains(xmlStr, expected) { + t.Errorf("MarshalXML result %q does not contain expected element %q", xmlStr, expected) + } + } +} diff --git a/pkg/models/bass_utilities_test.go b/pkg/models/bass_utilities_test.go new file mode 100644 index 0000000..23e4e3b --- /dev/null +++ b/pkg/models/bass_utilities_test.go @@ -0,0 +1,247 @@ +package models + +import ( + "encoding/xml" + "strings" + "testing" +) + +func TestBassCapabilities_UtilityMethods(t *testing.T) { + t.Run("IsBassSupported", func(t *testing.T) { + tests := []struct { + name string + caps BassCapabilities + expected bool + }{ + { + name: "Bass supported device", + caps: BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + }, + expected: true, + }, + { + name: "Bass not supported device", + caps: BassCapabilities{ + DeviceID: "5678", + BassMin: 0, + BassMax: 0, + BassDefault: 0, + BassAvailable: false, + }, + expected: false, + }, + { + name: "Bass not available", + caps: BassCapabilities{ + DeviceID: "9999", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: false, + }, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.caps.IsBassSupported() + if result != tt.expected { + t.Errorf("IsBassSupported() = %v, expected %v", result, tt.expected) + } + }) + } + }) + + t.Run("GetMinLevel", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + result := caps.GetMinLevel() + expected := -9 + + if result != expected { + t.Errorf("GetMinLevel() = %d, expected %d", result, expected) + } + }) + + t.Run("GetMaxLevel", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + result := caps.GetMaxLevel() + expected := 9 + + if result != expected { + t.Errorf("GetMaxLevel() = %d, expected %d", result, expected) + } + }) + + t.Run("GetDefaultLevel", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + result := caps.GetDefaultLevel() + expected := 0 + + if result != expected { + t.Errorf("GetDefaultLevel() = %d, expected %d", result, expected) + } + }) + + t.Run("ValidateLevel", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + tests := []struct { + name string + level int + expected bool + }{ + {"Valid min level", -9, true}, + {"Valid max level", 9, true}, + {"Valid middle level", 0, true}, + {"Valid positive level", 3, true}, + {"Valid negative level", -5, true}, + {"Invalid too low", -10, false}, + {"Invalid too high", 10, false}, + {"Invalid way too high", 100, false}, + {"Invalid way too low", -100, false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := caps.ValidateLevel(tt.level) + if result != tt.expected { + t.Errorf("ValidateLevel(%d) = %v, expected %v", tt.level, result, tt.expected) + } + }) + } + }) + + t.Run("ClampLevel", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "1234", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + tests := []struct { + name string + level int + expected int + }{ + {"Valid level unchanged", 5, 5}, + {"Valid min level unchanged", -9, -9}, + {"Valid max level unchanged", 9, 9}, + {"Too low clamped to min", -15, -9}, + {"Too high clamped to max", 15, 9}, + {"Way too low clamped", -100, -9}, + {"Way too high clamped", 100, 9}, + {"Zero unchanged", 0, 0}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := caps.ClampLevel(tt.level) + if result != tt.expected { + t.Errorf("ClampLevel(%d) = %d, expected %d", tt.level, result, tt.expected) + } + }) + } + }) + + t.Run("String", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "TEST123", + BassMin: -9, + BassMax: 9, + BassDefault: 0, + BassAvailable: true, + } + + result := caps.String() + + // Check that the string contains expected information + expected := "Bass: -9 to 9 (default: 0)" + if result != expected { + t.Errorf("String() = %q, expected %q", result, expected) + } + }) + + t.Run("String for unsupported device", func(t *testing.T) { + caps := BassCapabilities{ + DeviceID: "TEST456", + BassMin: 0, + BassMax: 0, + BassDefault: 0, + BassAvailable: false, + } + + result := caps.String() + expected := "Bass control not supported" + + if result != expected { + t.Errorf("String() for unsupported device = %q, expected %q", result, expected) + } + }) +} + +func TestBassMarshalXML(t *testing.T) { + bass := Bass{ + DeviceID: "1234567890AB", + TargetBass: 5, + ActualBass: 5, + } + + var buf strings.Builder + encoder := xml.NewEncoder(&buf) + err := bass.MarshalXML(encoder, xml.StartElement{Name: xml.Name{Local: "bass"}}) + if err != nil { + t.Fatalf("MarshalXML failed: %v", err) + } + encoder.Flush() + + // Convert to string for easier testing + xmlStr := buf.String() + + // Check that XML contains expected elements + expectedElements := []string{ + `deviceID="1234567890AB"`, + `5`, + `5`, + } + + for _, expected := range expectedElements { + if !strings.Contains(xmlStr, expected) { + t.Errorf("MarshalXML result %q does not contain expected element %q", xmlStr, expected) + } + } +}