github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/datacodec/blob_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 func Test_blobCodec_DataType(t *testing.T) { 28 assert.Equal(t, datatype.Blob, Blob.DataType()) 29 assert.Equal(t, datatype.Blob, PassThrough.DataType()) 30 customType := datatype.NewCustom("com.example.Type") 31 assert.Equal(t, customType, NewCustom(customType).DataType()) 32 } 33 34 func Test_blobCodec_Encode(t *testing.T) { 35 for _, version := range primitive.SupportedProtocolVersions() { 36 t.Run(version.String(), func(t *testing.T) { 37 tests := []struct { 38 name string 39 source interface{} 40 expected []byte 41 err string 42 }{ 43 {"nil", nil, nil, ""}, 44 {"nil pointer", byteSliceNilPtr(), nil, ""}, 45 {"empty", []byte{}, []byte{}, ""}, 46 {"non nil", []byte{1, 2, 3}, []byte{1, 2, 3}, ""}, 47 {"conversion failed", 123, nil, fmt.Sprintf("cannot encode int as CQL blob with %v: cannot convert from int to []uint8: conversion not supported", version)}, 48 } 49 for _, tt := range tests { 50 t.Run(tt.name, func(t *testing.T) { 51 actual, err := Blob.Encode(tt.source, version) 52 assert.Equal(t, tt.expected, actual) 53 assertErrorMessage(t, tt.err, err) 54 }) 55 } 56 }) 57 } 58 } 59 60 func Test_blobCodec_Decode(t *testing.T) { 61 for _, version := range primitive.SupportedProtocolVersions() { 62 t.Run(version.String(), func(t *testing.T) { 63 tests := []struct { 64 name string 65 source []byte 66 dest interface{} 67 expected interface{} 68 wasNull bool 69 err string 70 }{ 71 {"null", nil, new([]byte), new([]byte), true, ""}, 72 {"non null", []byte{1, 2, 3}, new([]byte), &[]byte{1, 2, 3}, false, ""}, 73 {"non null interface", []byte{1, 2, 3}, new(interface{}), interfacePtr([]byte{1, 2, 3}), false, ""}, 74 {"conversion failed", []byte{1, 2, 3}, new(float64), new(float64), false, fmt.Sprintf("cannot decode CQL blob as *float64 with %v: cannot convert from []uint8 to *float64: conversion not supported", version)}, 75 } 76 for _, tt := range tests { 77 t.Run(tt.name, func(t *testing.T) { 78 wasNull, err := Blob.Decode(tt.source, tt.dest, version) 79 assert.Equal(t, tt.expected, tt.dest) 80 assert.Equal(t, tt.wasNull, wasNull) 81 assertErrorMessage(t, tt.err, err) 82 }) 83 } 84 }) 85 } 86 } 87 88 func Test_convertToBytes(t *testing.T) { 89 tests := []struct { 90 name string 91 source interface{} 92 wantDest []byte 93 wantErr string 94 }{ 95 {"from byte", []byte{a, b, c}, []byte{a, b, c}, ""}, 96 {"from *byte", &[]byte{a, b, c}, []byte{a, b, c}, ""}, 97 {"from *byte nil", byteSliceNilPtr(), nil, ""}, 98 {"from string", "abc", []byte{a, b, c}, ""}, 99 {"from *string", stringPtr("abc"), []byte{a, b, c}, ""}, 100 {"from *string nil", stringNilPtr(), nil, ""}, 101 {"from untyped nil", nil, nil, ""}, 102 {"from unsupported value type", 42.0, nil, "cannot convert from float64 to []uint8: conversion not supported"}, 103 {"from unsupported pointer type", float64Ptr(42.0), nil, "cannot convert from *float64 to []uint8: conversion not supported"}, 104 } 105 for _, tt := range tests { 106 t.Run(tt.name, func(t *testing.T) { 107 gotDest, gotErr := convertToBytes(tt.source) 108 assert.Equal(t, tt.wantDest, gotDest) 109 assertErrorMessage(t, tt.wantErr, gotErr) 110 }) 111 } 112 } 113 114 func Test_convertFromBytes(t *testing.T) { 115 tests := []struct { 116 name string 117 val []byte 118 wasNull bool 119 dest interface{} 120 expected interface{} 121 err string 122 }{ 123 {"to *interface{} nil dest", []byte{1}, false, interfaceNilPtr(), interfaceNilPtr(), "cannot convert from []uint8 to *interface {}: destination is nil"}, 124 {"to *interface{} nil source", nil, true, new(interface{}), new(interface{}), ""}, 125 {"to *interface{} non nil", []byte{1}, false, new(interface{}), interfacePtr([]byte{1}), ""}, 126 {"to *byte[] nil dest", []byte{1}, false, byteSliceNilPtr(), byteSliceNilPtr(), "cannot convert from []uint8 to *[]uint8: destination is nil"}, 127 {"to *byte[] nil source", nil, true, new([]byte), new([]byte), ""}, 128 {"to *byte[] empty source", []byte{}, false, new([]byte), &[]byte{}, ""}, 129 {"to *byte[] non nil", []byte{a, b, c}, false, new([]byte), &[]byte{a, b, c}, ""}, 130 {"to *string nil dest", []byte{1}, false, stringNilPtr(), stringNilPtr(), "cannot convert from []uint8 to *string: destination is nil"}, 131 {"to *string nil source", nil, true, new(string), new(string), ""}, 132 {"to *string empty source", []byte{}, false, new(string), new(string), ""}, 133 {"to *string non nil", []byte{a, b, c}, false, new(string), stringPtr("abc"), ""}, 134 {"to untyped nil", []byte{1}, false, nil, nil, "cannot convert from []uint8 to <nil>: destination is nil"}, 135 {"to non pointer", []byte{1}, false, []byte{}, []byte{}, "cannot convert from []uint8 to []uint8: destination is not pointer"}, 136 {"to unsupported pointer type", []byte{1}, false, new(float64), new(float64), "cannot convert from []uint8 to *float64: conversion not supported"}, 137 } 138 for _, tt := range tests { 139 t.Run(tt.name, func(t *testing.T) { 140 gotWasNull, gotErr := convertFromBytes(tt.val, tt.dest) 141 assert.Equal(t, tt.expected, tt.dest) 142 assert.Equal(t, tt.wasNull, gotWasNull) 143 assertErrorMessage(t, tt.err, gotErr) 144 }) 145 } 146 }