1package json
2
3import (
4	"math"
5	"net"
6	"reflect"
7	"testing"
8)
9
10func TestAppendType(t *testing.T) {
11	w := map[string]func(interface{}) []byte{
12		"AppendInt":     func(v interface{}) []byte { return enc.AppendInt([]byte{}, v.(int)) },
13		"AppendInt8":    func(v interface{}) []byte { return enc.AppendInt8([]byte{}, v.(int8)) },
14		"AppendInt16":   func(v interface{}) []byte { return enc.AppendInt16([]byte{}, v.(int16)) },
15		"AppendInt32":   func(v interface{}) []byte { return enc.AppendInt32([]byte{}, v.(int32)) },
16		"AppendInt64":   func(v interface{}) []byte { return enc.AppendInt64([]byte{}, v.(int64)) },
17		"AppendUint":    func(v interface{}) []byte { return enc.AppendUint([]byte{}, v.(uint)) },
18		"AppendUint8":   func(v interface{}) []byte { return enc.AppendUint8([]byte{}, v.(uint8)) },
19		"AppendUint16":  func(v interface{}) []byte { return enc.AppendUint16([]byte{}, v.(uint16)) },
20		"AppendUint32":  func(v interface{}) []byte { return enc.AppendUint32([]byte{}, v.(uint32)) },
21		"AppendUint64":  func(v interface{}) []byte { return enc.AppendUint64([]byte{}, v.(uint64)) },
22		"AppendFloat32": func(v interface{}) []byte { return enc.AppendFloat32([]byte{}, v.(float32)) },
23		"AppendFloat64": func(v interface{}) []byte { return enc.AppendFloat64([]byte{}, v.(float64)) },
24	}
25	tests := []struct {
26		name  string
27		fn    string
28		input interface{}
29		want  []byte
30	}{
31		{"AppendInt8(math.MaxInt8)", "AppendInt8", int8(math.MaxInt8), []byte("127")},
32		{"AppendInt16(math.MaxInt16)", "AppendInt16", int16(math.MaxInt16), []byte("32767")},
33		{"AppendInt32(math.MaxInt32)", "AppendInt32", int32(math.MaxInt32), []byte("2147483647")},
34		{"AppendInt64(math.MaxInt64)", "AppendInt64", int64(math.MaxInt64), []byte("9223372036854775807")},
35
36		{"AppendUint8(math.MaxUint8)", "AppendUint8", uint8(math.MaxUint8), []byte("255")},
37		{"AppendUint16(math.MaxUint16)", "AppendUint16", uint16(math.MaxUint16), []byte("65535")},
38		{"AppendUint32(math.MaxUint32)", "AppendUint32", uint32(math.MaxUint32), []byte("4294967295")},
39		{"AppendUint64(math.MaxUint64)", "AppendUint64", uint64(math.MaxUint64), []byte("18446744073709551615")},
40
41		{"AppendFloat32(-Inf)", "AppendFloat32", float32(math.Inf(-1)), []byte(`"-Inf"`)},
42		{"AppendFloat32(+Inf)", "AppendFloat32", float32(math.Inf(1)), []byte(`"+Inf"`)},
43		{"AppendFloat32(NaN)", "AppendFloat32", float32(math.NaN()), []byte(`"NaN"`)},
44		{"AppendFloat32(0)", "AppendFloat32", float32(0), []byte(`0`)},
45		{"AppendFloat32(-1.1)", "AppendFloat32", float32(-1.1), []byte(`-1.1`)},
46		{"AppendFloat32(1e20)", "AppendFloat32", float32(1e20), []byte(`100000000000000000000`)},
47		{"AppendFloat32(1e21)", "AppendFloat32", float32(1e21), []byte(`1000000000000000000000`)},
48
49		{"AppendFloat64(-Inf)", "AppendFloat64", float64(math.Inf(-1)), []byte(`"-Inf"`)},
50		{"AppendFloat64(+Inf)", "AppendFloat64", float64(math.Inf(1)), []byte(`"+Inf"`)},
51		{"AppendFloat64(NaN)", "AppendFloat64", float64(math.NaN()), []byte(`"NaN"`)},
52		{"AppendFloat64(0)", "AppendFloat64", float64(0), []byte(`0`)},
53		{"AppendFloat64(-1.1)", "AppendFloat64", float64(-1.1), []byte(`-1.1`)},
54		{"AppendFloat64(1e20)", "AppendFloat64", float64(1e20), []byte(`100000000000000000000`)},
55		{"AppendFloat64(1e21)", "AppendFloat64", float64(1e21), []byte(`1000000000000000000000`)},
56	}
57	for _, tt := range tests {
58		t.Run(tt.name, func(t *testing.T) {
59			if got := w[tt.fn](tt.input); !reflect.DeepEqual(got, tt.want) {
60				t.Errorf("got %s, want %s", got, tt.want)
61			}
62		})
63	}
64}
65
66func Test_appendMAC(t *testing.T) {
67	MACtests := []struct {
68		input string
69		want  []byte
70	}{
71		{"01:23:45:67:89:ab", []byte(`"01:23:45:67:89:ab"`)},
72		{"cd:ef:11:22:33:44", []byte(`"cd:ef:11:22:33:44"`)},
73	}
74	for _, tt := range MACtests {
75		t.Run("MAC", func(t *testing.T) {
76			ha, _ := net.ParseMAC(tt.input)
77			if got := enc.AppendMACAddr([]byte{}, ha); !reflect.DeepEqual(got, tt.want) {
78				t.Errorf("appendMACAddr() = %s, want %s", got, tt.want)
79			}
80		})
81	}
82}
83
84func Test_appendIP(t *testing.T) {
85	IPv4tests := []struct {
86		input net.IP
87		want  []byte
88	}{
89		{net.IP{0, 0, 0, 0}, []byte(`"0.0.0.0"`)},
90		{net.IP{192, 0, 2, 200}, []byte(`"192.0.2.200"`)},
91	}
92
93	for _, tt := range IPv4tests {
94		t.Run("IPv4", func(t *testing.T) {
95			if got := enc.AppendIPAddr([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
96				t.Errorf("appendIPAddr() = %s, want %s", got, tt.want)
97			}
98		})
99	}
100	IPv6tests := []struct {
101		input net.IP
102		want  []byte
103	}{
104		{net.IPv6zero, []byte(`"::"`)},
105		{net.IPv6linklocalallnodes, []byte(`"ff02::1"`)},
106		{net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34}, []byte(`"2001:db8:85a3::8a2e:370:7334"`)},
107	}
108	for _, tt := range IPv6tests {
109		t.Run("IPv6", func(t *testing.T) {
110			if got := enc.AppendIPAddr([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
111				t.Errorf("appendIPAddr() = %s, want %s", got, tt.want)
112			}
113		})
114	}
115}
116
117func Test_appendIPPrefix(t *testing.T) {
118	IPv4Prefixtests := []struct {
119		input net.IPNet
120		want  []byte
121	}{
122		{net.IPNet{IP: net.IP{0, 0, 0, 0}, Mask: net.IPv4Mask(0, 0, 0, 0)}, []byte(`"0.0.0.0/0"`)},
123		{net.IPNet{IP: net.IP{192, 0, 2, 200}, Mask: net.IPv4Mask(255, 255, 255, 0)}, []byte(`"192.0.2.200/24"`)},
124	}
125	for _, tt := range IPv4Prefixtests {
126		t.Run("IPv4", func(t *testing.T) {
127			if got := enc.AppendIPPrefix([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
128				t.Errorf("appendIPPrefix() = %s, want %s", got, tt.want)
129			}
130		})
131	}
132	IPv6Prefixtests := []struct {
133		input net.IPNet
134		want  []byte
135	}{
136		{net.IPNet{IP: net.IPv6zero, Mask: net.CIDRMask(0, 128)}, []byte(`"::/0"`)},
137		{net.IPNet{IP: net.IPv6linklocalallnodes, Mask: net.CIDRMask(128, 128)}, []byte(`"ff02::1/128"`)},
138		{net.IPNet{IP: net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34},
139			Mask: net.CIDRMask(64, 128)},
140			[]byte(`"2001:db8:85a3::8a2e:370:7334/64"`)},
141	}
142	for _, tt := range IPv6Prefixtests {
143		t.Run("IPv6", func(t *testing.T) {
144			if got := enc.AppendIPPrefix([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
145				t.Errorf("appendIPPrefix() = %s, want %s", got, tt.want)
146			}
147		})
148	}
149}
150
151func Test_appendMac(t *testing.T) {
152	MACtests := []struct {
153		input net.HardwareAddr
154		want  []byte
155	}{
156		{net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x90, 0xab}, []byte(`"12:34:56:78:90:ab"`)},
157		{net.HardwareAddr{0x12, 0x34, 0x00, 0x00, 0x90, 0xab}, []byte(`"12:34:00:00:90:ab"`)},
158	}
159
160	for _, tt := range MACtests {
161		t.Run("MAC", func(t *testing.T) {
162			if got := enc.AppendMACAddr([]byte{}, tt.input); !reflect.DeepEqual(got, tt.want) {
163				t.Errorf("appendMAC() = %s, want %s", got, tt.want)
164			}
165		})
166	}
167}
168
169func Test_appendObjectData(t *testing.T) {
170	tests := []struct {
171		dst  []byte
172		obj  []byte
173		want []byte
174	}{
175		{[]byte{}, []byte(`{"foo":"bar"}`), []byte(`"foo":"bar"}`)},
176		{[]byte(`{"qux":"quz"`), []byte(`{"foo":"bar"}`), []byte(`{"qux":"quz","foo":"bar"}`)},
177		{[]byte{}, []byte(`"foo":"bar"`), []byte(`"foo":"bar"`)},
178		{[]byte(`{"qux":"quz"`), []byte(`"foo":"bar"`), []byte(`{"qux":"quz","foo":"bar"`)},
179	}
180	for _, tt := range tests {
181		t.Run("ObjectData", func(t *testing.T) {
182			if got := enc.AppendObjectData(tt.dst, tt.obj); !reflect.DeepEqual(got, tt.want) {
183				t.Errorf("appendObjectData() = %s, want %s", got, tt.want)
184			}
185		})
186	}
187}
188