github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/datacodec/varchar_test.go (about) 1 // Copyright 2021 DataStax 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 datacodec 16 17 import ( 18 "fmt" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 23 "github.com/datastax/go-cassandra-native-protocol/datatype" 24 "github.com/datastax/go-cassandra-native-protocol/primitive" 25 ) 26 27 var ( 28 abcBytes = []byte("abc") 29 greekBytes = []byte("Μιλάτε αγγλικά;") 30 abcRunes = []rune("abc") 31 greekRunes = []rune("Μιλάτε αγγλικά;") 32 ) 33 34 func Test_stringCodec_DataType(t *testing.T) { 35 assert.Equal(t, datatype.Varchar, Varchar.DataType()) 36 assert.Equal(t, datatype.Ascii, Ascii.DataType()) 37 } 38 39 func Test_stringCodec_Encode(t *testing.T) { 40 codecs := []Codec{Varchar, Ascii} 41 for _, codec := range codecs { 42 t.Run(codec.DataType().AsCql(), func(t *testing.T) { 43 for _, version := range primitive.SupportedProtocolVersions() { 44 t.Run(version.String(), func(t *testing.T) { 45 tests := []struct { 46 name string 47 source interface{} 48 expected []byte 49 err string 50 }{ 51 {"nil", nil, nil, ""}, 52 {"nil pointer", stringNilPtr(), nil, ""}, 53 {"empty", "", []byte{}, ""}, 54 {"non nil", "abc", abcBytes, ""}, 55 {"conversion failed", 123, nil, fmt.Sprintf("cannot encode int as CQL %v with %v: cannot convert from int to []uint8: conversion not supported", codec.DataType(), version)}, 56 } 57 for _, tt := range tests { 58 t.Run(tt.name, func(t *testing.T) { 59 actual, err := codec.Encode(tt.source, version) 60 assert.Equal(t, tt.expected, actual) 61 assertErrorMessage(t, tt.err, err) 62 }) 63 } 64 }) 65 } 66 }) 67 } 68 } 69 70 func Test_stringCodec_Decode(t *testing.T) { 71 codecs := []Codec{Varchar, Ascii} 72 for _, codec := range codecs { 73 t.Run(codec.DataType().AsCql(), func(t *testing.T) { 74 for _, version := range primitive.SupportedProtocolVersions() { 75 t.Run(version.String(), func(t *testing.T) { 76 tests := []struct { 77 name string 78 source []byte 79 dest interface{} 80 expected interface{} 81 wasNull bool 82 err string 83 }{ 84 {"null", nil, new(string), new(string), true, ""}, 85 {"non null", abcBytes, new(string), stringPtr("abc"), false, ""}, 86 {"non null interface", abcBytes, new(interface{}), interfacePtr("abc"), false, ""}, 87 {"conversion failed", abcBytes, new(float64), new(float64), false, fmt.Sprintf("cannot decode CQL %v as *float64 with %v: cannot convert from []uint8 to *float64: conversion not supported", codec.DataType(), version)}, 88 } 89 for _, tt := range tests { 90 t.Run(tt.name, func(t *testing.T) { 91 wasNull, err := codec.Decode(tt.source, tt.dest, version) 92 assert.Equal(t, tt.expected, tt.dest) 93 assert.Equal(t, tt.wasNull, wasNull) 94 assertErrorMessage(t, tt.err, err) 95 }) 96 } 97 }) 98 } 99 }) 100 } 101 } 102 103 func Test_convertToStringBytes(t *testing.T) { 104 tests := []struct { 105 name string 106 source interface{} 107 wantDest []byte 108 wantErr string 109 }{ 110 {"from []byte", abcBytes, abcBytes, ""}, 111 {"from *[]byte", &greekBytes, greekBytes, ""}, 112 {"from *[]byte nil", byteSliceNilPtr(), nil, ""}, 113 {"from []rune", abcRunes, abcBytes, ""}, 114 {"from *[]rune", &greekRunes, greekBytes, ""}, 115 {"from *[]rune nil", runeSliceNilPtr(), nil, ""}, 116 {"from string", "abc", abcBytes, ""}, 117 {"from *string", stringPtr("abc"), abcBytes, ""}, 118 {"from *string nil", stringNilPtr(), nil, ""}, 119 {"from untyped nil", nil, nil, ""}, 120 {"from unsupported value type", 42.0, nil, "cannot convert from float64 to []uint8: conversion not supported"}, 121 {"from unsupported pointer type", float64Ptr(42.0), nil, "cannot convert from *float64 to []uint8: conversion not supported"}, 122 } 123 for _, tt := range tests { 124 t.Run(tt.name, func(t *testing.T) { 125 gotDest, gotErr := convertToStringBytes(tt.source) 126 assert.Equal(t, tt.wantDest, gotDest) 127 assertErrorMessage(t, tt.wantErr, gotErr) 128 }) 129 } 130 } 131 132 func Test_convertFromStringBytes(t *testing.T) { 133 tests := []struct { 134 name string 135 val []byte 136 wasNull bool 137 dest interface{} 138 expected interface{} 139 err string 140 }{ 141 {"to *interface{} nil dest", []byte{1}, false, interfaceNilPtr(), interfaceNilPtr(), "cannot convert from []uint8 to *interface {}: destination is nil"}, 142 {"to *interface{} nil source", nil, true, new(interface{}), new(interface{}), ""}, 143 {"to *interface{} non nil", abcBytes, false, new(interface{}), interfacePtr("abc"), ""}, 144 {"to *byte[] nil dest", []byte{1}, false, byteSliceNilPtr(), byteSliceNilPtr(), "cannot convert from []uint8 to *[]uint8: destination is nil"}, 145 {"to *byte[] nil source", nil, true, new([]byte), new([]byte), ""}, 146 {"to *byte[] empty source", []byte{}, false, new([]byte), &[]byte{}, ""}, 147 {"to *byte[] non nil", abcBytes, false, new([]byte), &abcBytes, ""}, 148 {"to *rune[] nil dest", []byte{1}, false, runeSliceNilPtr(), runeSliceNilPtr(), "cannot convert from []uint8 to *[]int32: destination is nil"}, 149 {"to *rune[] nil source", nil, true, new([]rune), new([]rune), ""}, 150 {"to *rune[] empty source", []byte{}, false, new([]rune), &[]rune{}, ""}, 151 {"to *rune[] non nil", abcBytes, false, new([]rune), &abcRunes, ""}, 152 {"to *string nil dest", []byte{1}, false, stringNilPtr(), stringNilPtr(), "cannot convert from []uint8 to *string: destination is nil"}, 153 {"to *string nil source", nil, true, new(string), new(string), ""}, 154 {"to *string empty source", []byte{}, false, new(string), new(string), ""}, 155 {"to *string non nil", abcBytes, false, new(string), stringPtr("abc"), ""}, 156 {"to untyped nil", []byte{1}, false, nil, nil, "cannot convert from []uint8 to <nil>: destination is nil"}, 157 {"to non pointer", []byte{1}, false, []byte{}, []byte{}, "cannot convert from []uint8 to []uint8: destination is not pointer"}, 158 {"to unsupported pointer type", []byte{1}, false, new(float64), new(float64), "cannot convert from []uint8 to *float64: conversion not supported"}, 159 } 160 for _, tt := range tests { 161 t.Run(tt.name, func(t *testing.T) { 162 gotWasNull, gotErr := convertFromStringBytes(tt.val, tt.dest) 163 assert.Equal(t, tt.expected, tt.dest) 164 assert.Equal(t, tt.wasNull, gotWasNull) 165 assertErrorMessage(t, tt.err, gotErr) 166 }) 167 } 168 }