evcc-io/meter/danfoss_test.go

85 lines
2.8 KiB
Go

package meter
import (
"testing"
comlynx "github.com/PanterSoft/comlynx-go"
"github.com/evcc-io/evcc/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestDanfossTLXInterfaceCompliance verifies interface compliance at compile
// time. No network or hardware access needed.
func TestDanfossTLXInterfaceCompliance(t *testing.T) {
var _ api.Meter = (*DanfossTLX)(nil)
}
// TestDanfossTLXConfigRejectsNonPV ensures the factory rejects usage modes
// other than "pv" before touching any I/O.
func TestDanfossTLXConfigRejectsNonPV(t *testing.T) {
_, err := NewDanfossTLXFromConfig(t.Context(), map[string]any{
"usage": "grid",
"device": "/dev/null",
})
assert.ErrorContains(t, err, "pv", "non-pv usage must be rejected")
_, err = NewDanfossTLXFromConfig(t.Context(), map[string]any{
"usage": "battery",
"device": "/dev/null",
})
assert.ErrorContains(t, err, "pv", "non-pv usage must be rejected")
}
// TestDanfossTLXConfigRejectsDeviceAndURI verifies that supplying both device
// and uri is rejected before any I/O.
func TestDanfossTLXConfigRejectsDeviceAndURI(t *testing.T) {
_, err := NewDanfossTLXFromConfig(t.Context(), map[string]any{
"usage": "pv",
"device": "/dev/null",
"uri": "host:4196",
})
assert.ErrorContains(t, err, "mutually exclusive")
}
// TestDanfossTLXConfigRejectsNoTransport verifies that omitting both device
// and uri returns a clear error.
func TestDanfossTLXConfigRejectsNoTransport(t *testing.T) {
_, err := NewDanfossTLXFromConfig(t.Context(), map[string]any{
"usage": "pv",
})
assert.ErrorContains(t, err, "device")
}
func TestParseComlynxNodeAddress(t *testing.T) {
tests := []struct {
name string
input string
want comlynx.Address
wantErr string
}{
{"valid", "c-6-b1", comlynx.NewAddress(0x0c, 0x06, 0xb1), ""},
{"valid lowercase", "a-f-ff", comlynx.NewAddress(0x0a, 0x0f, 0xff), ""},
{"valid uppercase", "A-F-FF", comlynx.NewAddress(0x0a, 0x0f, 0xff), ""},
{"valid zeros", "0-0-00", comlynx.NewAddress(0x00, 0x00, 0x00), ""},
{"network out of range", "10-0-00", comlynx.Address{}, "network component"},
{"subnet out of range", "0-10-00", comlynx.Address{}, "subnet component"},
{"node out of range", "0-0-100", comlynx.Address{}, "node component"},
{"invalid format missing parts", "c-6", comlynx.Address{}, "expected format"},
{"invalid format no dashes", "c6b1", comlynx.Address{}, "expected format"},
{"invalid hex chars", "g-0-00", comlynx.Address{}, "expected format"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got, err := parseComlynxNodeAddress(tc.input)
if tc.wantErr != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), tc.wantErr)
return
}
require.NoError(t, err)
assert.Equal(t, tc.want, got)
})
}
}