1package pgtype_test
2
3import (
4	"net"
5	"reflect"
6	"testing"
7
8	"github.com/jackc/pgtype"
9	"github.com/jackc/pgtype/testutil"
10)
11
12func TestInetTranscode(t *testing.T) {
13	for _, pgTypeName := range []string{"inet", "cidr"} {
14		testutil.TestSuccessfulTranscode(t, pgTypeName, []interface{}{
15			&pgtype.Inet{IPNet: mustParseCIDR(t, "0.0.0.0/32"), Status: pgtype.Present},
16			&pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
17			&pgtype.Inet{IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present},
18			&pgtype.Inet{IPNet: mustParseCIDR(t, "192.168.1.0/24"), Status: pgtype.Present},
19			&pgtype.Inet{IPNet: mustParseCIDR(t, "255.0.0.0/8"), Status: pgtype.Present},
20			&pgtype.Inet{IPNet: mustParseCIDR(t, "255.255.255.255/32"), Status: pgtype.Present},
21			&pgtype.Inet{IPNet: mustParseCIDR(t, "::/128"), Status: pgtype.Present},
22			&pgtype.Inet{IPNet: mustParseCIDR(t, "::/0"), Status: pgtype.Present},
23			&pgtype.Inet{IPNet: mustParseCIDR(t, "::1/128"), Status: pgtype.Present},
24			&pgtype.Inet{IPNet: mustParseCIDR(t, "2607:f8b0:4009:80b::200e/128"), Status: pgtype.Present},
25			&pgtype.Inet{Status: pgtype.Null},
26		})
27	}
28}
29
30func TestInetSet(t *testing.T) {
31	successfulTests := []struct {
32		source interface{}
33		result pgtype.Inet
34	}{
35		{source: mustParseCIDR(t, "127.0.0.1/32"), result: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
36		{source: mustParseCIDR(t, "127.0.0.1/32").IP, result: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
37		{source: "127.0.0.1/32", result: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
38	}
39
40	for i, tt := range successfulTests {
41		var r pgtype.Inet
42		err := r.Set(tt.source)
43		if err != nil {
44			t.Errorf("%d: %v", i, err)
45		}
46
47		if !reflect.DeepEqual(r, tt.result) {
48			t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
49		}
50	}
51}
52
53func TestInetAssignTo(t *testing.T) {
54	var ipnet net.IPNet
55	var pipnet *net.IPNet
56	var ip net.IP
57	var pip *net.IP
58
59	simpleTests := []struct {
60		src      pgtype.Inet
61		dst      interface{}
62		expected interface{}
63	}{
64		{src: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}, dst: &ipnet, expected: *mustParseCIDR(t, "127.0.0.1/32")},
65		{src: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}, dst: &ip, expected: mustParseCIDR(t, "127.0.0.1/32").IP},
66		{src: pgtype.Inet{Status: pgtype.Null}, dst: &pipnet, expected: ((*net.IPNet)(nil))},
67		{src: pgtype.Inet{Status: pgtype.Null}, dst: &pip, expected: ((*net.IP)(nil))},
68	}
69
70	for i, tt := range simpleTests {
71		err := tt.src.AssignTo(tt.dst)
72		if err != nil {
73			t.Errorf("%d: %v", i, err)
74		}
75
76		if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
77			t.Errorf("%d: expected %v to assign %#v, but result was %#v", i, tt.src, tt.expected, dst)
78		}
79	}
80
81	pointerAllocTests := []struct {
82		src      pgtype.Inet
83		dst      interface{}
84		expected interface{}
85	}{
86		{src: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}, dst: &pipnet, expected: *mustParseCIDR(t, "127.0.0.1/32")},
87		{src: pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}, dst: &pip, expected: mustParseCIDR(t, "127.0.0.1/32").IP},
88	}
89
90	for i, tt := range pointerAllocTests {
91		err := tt.src.AssignTo(tt.dst)
92		if err != nil {
93			t.Errorf("%d: %v", i, err)
94		}
95
96		if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
97			t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
98		}
99	}
100
101	errorTests := []struct {
102		src pgtype.Inet
103		dst interface{}
104	}{
105		{src: pgtype.Inet{IPNet: mustParseCIDR(t, "192.168.0.0/16"), Status: pgtype.Present}, dst: &ip},
106		{src: pgtype.Inet{Status: pgtype.Null}, dst: &ipnet},
107	}
108
109	for i, tt := range errorTests {
110		err := tt.src.AssignTo(tt.dst)
111		if err == nil {
112			t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
113		}
114	}
115}
116