github.com/yandex/pandora@v0.5.32/core/config/hooks_test.go (about) 1 package config 2 3 import ( 4 "net" 5 "net/url" 6 "strconv" 7 "testing" 8 9 "github.com/c2h5oh/datasize" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestStringToURLPtrHook(t *testing.T) { 15 const ( 16 validURL = "http://yandex.ru" 17 invalidURL = "http://yandex.ru%%@#$%^&*()%%)(#U@%U)U)##(" 18 ) 19 var data struct { 20 URLPtr *url.URL `validate:"required"` 21 } 22 err := DecodeAndValidate(M{"urlptr": validURL}, &data) 23 require.NoError(t, err) 24 expectedURL, err := url.Parse(validURL) 25 require.NoError(t, err) 26 assert.Equal(t, data.URLPtr, expectedURL) 27 28 err = DecodeAndValidate(M{"urlptr": invalidURL}, &data) 29 assert.Error(t, err) 30 } 31 32 func TestStringToURLHook(t *testing.T) { 33 const ( 34 validURL = "http://yandex.ru" 35 invalidURL = "http://yandex.ru%%@#$%^&*()%%)(#U@%U)U)##(" 36 ) 37 var data struct { 38 URL url.URL `validate:"required,url"` 39 } 40 err := DecodeAndValidate(M{"url": validURL}, &data) 41 require.NoError(t, err) 42 expectedURL, err := url.Parse(validURL) 43 require.NoError(t, err) 44 assert.Equal(t, data.URL, *expectedURL) 45 46 err = DecodeAndValidate(M{"url": invalidURL}, &data) 47 assert.Error(t, err) 48 } 49 50 func TestStringToIPHook(t *testing.T) { 51 const ( 52 validIPv4 = "192.168.0.1" 53 validIPv6 = "FF80::1" 54 invalidIP = "that is not ip" 55 ) 56 var data struct { 57 IP net.IP `validate:"required"` 58 } 59 60 err := DecodeAndValidate(M{"ip": validIPv4}, &data) 61 require.NoError(t, err) 62 expectedIP := net.ParseIP(validIPv4) 63 require.NoError(t, err) 64 assert.Equal(t, data.IP, expectedIP) 65 66 err = DecodeAndValidate(M{"ip": validIPv6}, &data) 67 require.NoError(t, err) 68 expectedIP = net.ParseIP(validIPv6) 69 require.NoError(t, err) 70 assert.Equal(t, data.IP, expectedIP) 71 72 err = DecodeAndValidate(M{"ip": invalidIP}, &data) 73 assert.Error(t, err) 74 } 75 76 func TestStringToDataSizeHook(t *testing.T) { 77 var data struct { 78 Size datasize.ByteSize `validate:"min-size=128b"` 79 } 80 81 err := Decode(M{"size": "0"}, &data) 82 assert.NoError(t, err) 83 assert.Error(t, Validate(data)) 84 assert.EqualValues(t, 0, data.Size) 85 86 err = Decode(M{"size": "128"}, &data) 87 assert.NoError(t, err) 88 assert.NoError(t, Validate(data)) 89 assert.EqualValues(t, 128, data.Size) 90 91 err = Decode(M{"size": "5mb"}, &data) 92 assert.NoError(t, err) 93 assert.EqualValues(t, 5*datasize.MB, data.Size) 94 95 err = Decode(M{"size": "127KB"}, &data) 96 assert.NoError(t, err) 97 assert.EqualValues(t, 127*datasize.KB, data.Size) 98 99 err = Decode(M{"size": "Bullshit"}, &data) 100 assert.Error(t, err) 101 } 102 103 type ptrUnmarshaller int64 104 105 func (i *ptrUnmarshaller) UnmarshalText(text []byte) error { 106 val, err := strconv.ParseInt(string(text), 10, 64) 107 if err != nil { 108 return err 109 } 110 *i = ptrUnmarshaller(val) 111 return nil 112 } 113 114 type valueUnmarshaller struct{ Value *int64 } 115 116 var valueUnmarshallerSink int64 117 118 func (v valueUnmarshaller) UnmarshalText(text []byte) error { 119 val, err := strconv.ParseInt(string(text), 10, 64) 120 if err != nil { 121 return err 122 } 123 valueUnmarshallerSink = val 124 return nil 125 } 126 127 func TestTextUnmarshallerHookImplementsByValue(t *testing.T) { 128 var data struct { 129 Val valueUnmarshaller 130 } 131 data.Val.Value = new(int64) 132 133 err := Decode(M{"val": "0"}, &data) 134 assert.NoError(t, err) 135 assert.EqualValues(t, 0, valueUnmarshallerSink) 136 137 err = Decode(M{"val": "128"}, &data) 138 assert.NoError(t, err) 139 assert.EqualValues(t, 128, valueUnmarshallerSink) 140 141 }