package builtins import ( "net" "testing" ) func TestCompileCIDR(t *testing.T) { tests := []struct { name string input string wantErr bool wantStr string }{ {"valid ipv4", "192.168.0.0/24", false, "192.168.0.0/24"}, {"valid ipv6", "2001:db8::/32", false, "2001:db8::/32"}, {"valid host ipv4", "10.0.0.1/32", false, "10.0.0.1/32"}, {"valid host ipv6", "::1/128", false, "::1/128"}, {"invalid no mask", "192.168.0.0", true, ""}, {"invalid bad ip", "not-an-ip/24", true, ""}, {"invalid empty", "", true, ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := CompileCIDR(tt.input) if tt.wantErr { if err == nil { t.Errorf("CompileCIDR(%q) expected error, got nil", tt.input) } return } if err != nil { t.Fatalf("CompileCIDR(%q) unexpected error: %v", tt.input, err) } if got.String() != tt.wantStr { t.Errorf("CompileCIDR(%q) = %q, want %q", tt.input, got.String(), tt.wantStr) } }) } } func TestMatchCIDR(t *testing.T) { cidr := mustCompileCIDR(t, "192.168.0.0/24") tests := []struct { name string ip string want bool }{ {"inside", "192.168.0.1", true}, {"boundary low", "192.168.0.0", true}, {"boundary high", "192.168.0.255", true}, {"outside", "192.168.1.1", false}, {"different network", "10.0.0.1", false}, {"invalid ip", "not-an-ip", false}, {"empty", "", false}, {"ipv6 in ipv4", "::1", false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := MatchCIDR(tt.ip, cidr) if got != tt.want { t.Errorf("MatchCIDR(%q, %q) = %v, want %v", tt.ip, cidr, got, tt.want) } }) } } func TestMatchCIDR_IPv6(t *testing.T) { cidr := mustCompileCIDR(t, "2001:db8::/32") inside := "2001:db8::1" if !MatchCIDR(inside, cidr) { t.Errorf("MatchCIDR(%q) should be true", inside) } outside := "2001:db9::1" if MatchCIDR(outside, cidr) { t.Errorf("MatchCIDR(%q) should be false", outside) } } func TestMatchCIDR_NullResult(t *testing.T) { if MatchCIDR("10.0.0.1", &net.IPNet{}) { t.Error("MatchCIDR with empty IPNet should return false") } } func mustCompileCIDR(t *testing.T, cidr string) *net.IPNet { t.Helper() _, ipNet, err := net.ParseCIDR(cidr) if err != nil { t.Fatalf("failed to parse CIDR %q: %v", cidr, err) } return ipNet }