github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/string_test.go (about) 1 // Copyright 2020-2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "fmt" 19 "math" 20 "testing" 21 "time" 22 23 "github.com/stretchr/testify/require" 24 25 "github.com/dolthub/go-mysql-server/sql" 26 "github.com/dolthub/go-mysql-server/sql/expression" 27 "github.com/dolthub/go-mysql-server/sql/types" 28 ) 29 30 func TestAsciiFunc(t *testing.T) { 31 f := sql.Function1{Name: "ascii", Fn: NewAscii} 32 tf := NewTestFactory(f.Fn) 33 tf.AddSucceeding(nil, nil) 34 tf.AddSucceeding(uint8(0), "") 35 tf.AddSucceeding(uint8(115), "string") 36 tf.AddSucceeding(uint8(49), true) 37 tf.AddSucceeding(uint8(50), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) 38 tf.AddSignedVariations(uint8(48), 0) 39 tf.AddUnsignedVariations(uint8(48), 0) 40 tf.AddFloatVariations(uint8(54), 6.0) 41 tf.Test(t, nil, nil) 42 } 43 44 func TestOrdFunc(t *testing.T) { 45 f := sql.Function1{Name: "ord", Fn: NewOrd} 46 tf := NewTestFactory(f.Fn) 47 tf.AddSucceeding(nil, nil) 48 tf.AddSucceeding(int64(0), "") 49 tf.AddSucceeding(int64(115), "string") 50 tf.AddSucceeding(int64(49826), "¢") 51 tf.AddSucceeding(int64(49838), "®®") 52 tf.AddSucceeding(int64(49), true) 53 tf.AddSucceeding(int64(50), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) 54 tf.AddSignedVariations(int64(48), 0) 55 tf.AddUnsignedVariations(int64(48), 0) 56 tf.AddFloatVariations(int64(54), 6.0) 57 tf.Test(t, nil, nil) 58 } 59 60 func TestHexFunc(t *testing.T) { 61 f := sql.Function1{Name: "hex", Fn: NewHex} 62 tf := NewTestFactory(f.Fn) 63 tf.AddSucceeding(nil, nil) 64 tf.AddSucceeding("8F", []byte("\x8f")) 65 tf.AddSignedVariations("FFFFFFFFFFFFFFFF", -1) 66 tf.AddUnsignedVariations("5", 5) 67 tf.AddFloatVariations("5", 4.5) 68 tf.AddFloatVariations("5", 5.4) 69 tf.AddSucceeding("FFFFFFFFFFFFFFFF", uint64(math.MaxUint64)) 70 tf.AddSucceeding("74657374", "test") 71 tf.AddSignedVariations("FFFFFFFFFFFFFFF0", -16) 72 tf.AddSignedVariations("FFFFFFFFFFFFFF00", -256) 73 tf.AddSignedVariations("FFFFFFFFFFFFFE00", -512) 74 tf.AddFloatVariations("FFFFFFFFFFFFFFFF", -0.5) 75 tf.AddFloatVariations("FFFFFFFFFFFFFFFF", -1.4) 76 tf.AddSucceeding("323032302D30322D30342031343A31303A33322E35", time.Date(2020, 2, 4, 14, 10, 32, 500000000, time.UTC)) 77 tf.AddSucceeding("323032302D30322D30342031343A31303A33322E30303035", time.Date(2020, 2, 4, 14, 10, 32, 500000, time.UTC)) 78 tf.AddSucceeding("323032302D30322D30342031343A31303A33322E303030303035", time.Date(2020, 2, 4, 14, 10, 32, 5000, time.UTC)) 79 tf.AddSucceeding("323032302D30322D30342031343A31303A3332", time.Date(2020, 2, 4, 14, 10, 32, 500, time.UTC)) 80 81 tf.Test(t, nil, nil) 82 } 83 84 func TestUnhexFunc(t *testing.T) { 85 f := sql.Function1{Name: "unhex", Fn: NewUnhex} 86 tf := NewTestFactory(f.Fn) 87 tf.AddSucceeding(nil, nil) 88 tf.AddSucceeding([]byte("MySQL"), "4D7953514C") 89 tf.AddSucceeding([]byte{0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, "0123456789abcdef") 90 tf.AddSucceeding([]byte{0x8f}, "8F") 91 tf.AddSucceeding([]byte{0x8f}, "8f") 92 tf.AddSucceeding([]byte{0x0b}, "B") 93 tf.AddSucceeding(nil, "gh") 94 tf.AddSignedVariations([]byte{0x35}, 35) 95 tf.AddSignedVariations([]byte{0x01}, 1) 96 tf.AddSignedVariations(nil, -1) 97 tf.AddUnsignedVariations([]byte{0x35}, 35) 98 tf.AddFloatVariations(nil, 35.5) 99 tf.AddSucceeding(nil, time.Now()) 100 101 tf.Test(t, nil, nil) 102 } 103 104 func TestHexRoundTrip(t *testing.T) { 105 tests := []struct { 106 val interface{} 107 typ sql.Type 108 out string 109 }{ 110 {"1B", types.Text, "1B"}, 111 {"C", types.Text, "0C"}, 112 {"8F", types.Text, "8F"}, 113 {"ABCD", types.Text, "ABCD"}, 114 {int64(1), types.Int64, "01"}, 115 {int8(11), types.Int64, "11"}, 116 {uint16(375), types.Int64, "0375"}, 117 } 118 119 for _, test := range tests { 120 t.Run(fmt.Sprintf("%v %s", test.val, test.typ.String()), func(t *testing.T) { 121 lit := expression.NewLiteral(test.val, test.typ) 122 f := NewHex(NewUnhex(lit)) 123 res, err := f.Eval(sql.NewEmptyContext(), nil) 124 require.NoError(t, err) 125 require.Equal(t, test.out, res) 126 }) 127 } 128 } 129 130 func TestBinFunc(t *testing.T) { 131 f := sql.Function1{Name: "bin", Fn: NewBin} 132 tf := NewTestFactory(f.Fn) 133 tf.AddSucceeding(nil, nil) 134 tf.AddSucceeding("1100", "12") 135 tf.AddSucceeding("0", "TEST") 136 tf.AddSucceeding("11111100100", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) 137 tf.AddSignedVariations("1100", 12) 138 tf.AddUnsignedVariations("1100", 12) 139 tf.AddFloatVariations("1100", 12.5) 140 tf.AddSignedVariations("1111111111111111111111111111111111111111111111111111111111110100", -12) 141 tf.AddFloatVariations("1111111111111111111111111111111111111111111111111111111111110100", -12.5) 142 tf.Test(t, nil, nil) 143 } 144 145 func TestBitLength(t *testing.T) { 146 f := sql.Function1{Name: "bin", Fn: NewBitlength} 147 tf := NewTestFactory(f.Fn) 148 tf.AddSucceeding(nil, nil) 149 tf.AddSucceeding(32, "test") 150 tf.AddSucceeding(8, true) 151 tf.AddSucceeding(8, int8(0)) 152 tf.AddSucceeding(8, uint8(0)) 153 tf.AddSucceeding(16, int16(0)) 154 tf.AddSucceeding(16, uint16(0)) 155 tf.AddSucceeding(32, uint32(0)) 156 tf.AddSucceeding(32, int32(0)) 157 tf.AddSucceeding(32, uint(0)) 158 tf.AddSucceeding(32, 0) 159 tf.AddSucceeding(64, uint64(0)) 160 tf.AddSucceeding(64, int64(0)) 161 tf.AddSucceeding(64, float64(0)) 162 tf.AddSucceeding(32, float32(0)) 163 tf.AddSucceeding(128, time.Now()) 164 tf.Test(t, nil, nil) 165 }