package ca import ( "testing" "github.com/uopi/goca/proto" ) // ---- value coercion helpers ------------------------------------------ func TestToFloat64(t *testing.T) { cases := []struct { in any want float64 }{ {float64(1.5), 1.5}, {float32(2.5), 2.5}, {int(3), 3}, {int64(4), 4}, {int32(5), 5}, {int16(6), 6}, {uint64(7), 7}, {uint32(8), 8}, {true, 1}, {false, 0}, } for _, c := range cases { got, err := toFloat64(c.in) if err != nil || got != c.want { t.Errorf("toFloat64(%v) = %v, %v; want %v", c.in, got, err, c.want) } } if _, err := toFloat64("nope"); err == nil { t.Error("toFloat64(string): want error") } } func TestToInt32(t *testing.T) { cases := []struct { in any want int32 }{ {int(3), 3}, {int64(4), 4}, {int32(5), 5}, {int16(6), 6}, {float64(7.9), 7}, {float32(8.9), 8}, {true, 1}, {false, 0}, } for _, c := range cases { got, err := toInt32(c.in) if err != nil || got != c.want { t.Errorf("toInt32(%v) = %v, %v; want %v", c.in, got, err, c.want) } } if _, err := toInt32("nope"); err == nil { t.Error("toInt32(string): want error") } } func TestToString(t *testing.T) { if s, _ := toString("hi"); s != "hi" { t.Errorf("toString(string) = %q", s) } if s, _ := toString([]byte("bytes")); s != "bytes" { t.Errorf("toString([]byte) = %q", s) } if s, _ := toString(42); s != "42" { t.Errorf("toString(int) = %q, want 42", s) } } // ---- ConfigFromEnv --------------------------------------------------- func TestConfigFromEnv(t *testing.T) { t.Setenv("EPICS_CA_ADDR_LIST", "1.2.3.4 5.6.7.8") t.Setenv("EPICS_CA_AUTO_ADDR_LIST", "no") cfg := ConfigFromEnv() if len(cfg.AddrList) != 2 || cfg.AddrList[0] != "1.2.3.4" { t.Errorf("AddrList = %v", cfg.AddrList) } if cfg.AutoAddrList { t.Error("AutoAddrList should be false when env = no") } if cfg.ClientName == "" { t.Error("ClientName should be populated") } t.Setenv("EPICS_CA_ADDR_LIST", "") t.Setenv("EPICS_CA_AUTO_ADDR_LIST", "yes") cfg = ConfigFromEnv() if !cfg.AutoAddrList { t.Error("AutoAddrList should default to true") } if len(cfg.AddrList) != 0 { t.Errorf("AddrList should be empty, got %v", cfg.AddrList) } } // ---- address helpers ------------------------------------------------- func TestResolveAddrs(t *testing.T) { got := resolveAddrs([]string{"host", "host2:9999", ""}, 5064) if len(got) != 2 || got[0] != "host:5064" || got[1] != "host2:9999" { t.Errorf("resolveAddrs = %v", got) } } func TestLocalBroadcastAddrs(t *testing.T) { // Should not panic; the result is environment-dependent. _ = localBroadcastAddrs(5064) } // ---- isAllFF --------------------------------------------------------- func TestIsAllFF(t *testing.T) { if !isAllFF([]byte{0xFF, 0xFF, 0xFF}) { t.Error("all-FF should be true") } if isAllFF([]byte{0xFF, 0x00}) { t.Error("mixed should be false") } } // ---- EncodedSearchPair ----------------------------------------------- func TestEncodedSearchPair(t *testing.T) { pkt := EncodedSearchPair("TEST:PV", 7) // First header must be a VERSION message. h, _, err := proto.DecodeHeader(newBytesReader(pkt)) if err != nil { t.Fatalf("DecodeHeader: %v", err) } if h.Command != proto.CmdVersion { t.Errorf("first command = %d, want CmdVersion", h.Command) } }