github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/datacodec/boolean_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 "time" 21 22 "github.com/stretchr/testify/assert" 23 24 "github.com/datastax/go-cassandra-native-protocol/datatype" 25 "github.com/datastax/go-cassandra-native-protocol/primitive" 26 ) 27 28 func Test_booleanCodec_DataType(t *testing.T) { 29 assert.Equal(t, datatype.Boolean, Boolean.DataType()) 30 } 31 32 func Test_booleanCodec_Encode(t *testing.T) { 33 for _, version := range primitive.SupportedProtocolVersions() { 34 t.Run(version.String(), func(t *testing.T) { 35 tests := []struct { 36 name string 37 source interface{} 38 expected []byte 39 err string 40 }{ 41 {"nil", nil, nil, ""}, 42 {"nil pointer", boolNilPtr(), nil, ""}, 43 {"true", true, []byte{1}, ""}, 44 {"false", false, []byte{0}, ""}, 45 {"conversion failed", time.Nanosecond, nil, fmt.Sprintf("cannot encode time.Duration as CQL boolean with %v: cannot convert from time.Duration to bool: conversion not supported", version)}, 46 } 47 for _, tt := range tests { 48 t.Run(tt.name, func(t *testing.T) { 49 actual, err := Boolean.Encode(tt.source, version) 50 assert.Equal(t, tt.expected, actual) 51 assertErrorMessage(t, tt.err, err) 52 }) 53 } 54 }) 55 } 56 } 57 58 func Test_booleanCodec_Decode(t *testing.T) { 59 for _, version := range primitive.SupportedProtocolVersions() { 60 t.Run(version.String(), func(t *testing.T) { 61 tests := []struct { 62 name string 63 source []byte 64 dest interface{} 65 expected interface{} 66 wasNull bool 67 err string 68 }{ 69 {"null", nil, new(bool), new(bool), true, ""}, 70 {"true", []byte{1}, new(bool), boolPtr(true), false, ""}, 71 {"true 255", []byte{255}, new(bool), boolPtr(true), false, ""}, 72 {"false", []byte{0}, new(bool), boolPtr(false), false, ""}, 73 {"non null interface", []byte{1}, new(interface{}), interfacePtr(true), false, ""}, 74 {"read failed", []byte{1, 2, 3}, new(bool), new(bool), false, fmt.Sprintf("cannot decode CQL boolean as *bool with %v: cannot read bool: expected 1 bytes but got: 3", version)}, 75 {"conversion failed", []byte{1}, new(float64), new(float64), false, fmt.Sprintf("cannot decode CQL boolean as *float64 with %v: cannot convert from bool to *float64: conversion not supported", version)}, 76 } 77 for _, tt := range tests { 78 t.Run(tt.name, func(t *testing.T) { 79 wasNull, err := Boolean.Decode(tt.source, tt.dest, version) 80 assert.Equal(t, tt.expected, tt.dest) 81 assert.Equal(t, tt.wasNull, wasNull) 82 assertErrorMessage(t, tt.err, err) 83 }) 84 } 85 }) 86 } 87 } 88 89 func Test_convertToBoolean(t *testing.T) { 90 tests := []struct { 91 name string 92 source interface{} 93 wantDest bool 94 wantWasNil bool 95 wantErr string 96 }{ 97 {"from bool", true, true, false, ""}, 98 {"from *bool non nil", boolPtr(true), true, false, ""}, 99 {"from *bool nil", boolNilPtr(), false, true, ""}, 100 {"from int", int(1), true, false, ""}, 101 {"from *int non nil", intPtr(1), true, false, ""}, 102 {"from *int nil", intNilPtr(), false, true, ""}, 103 {"from int64", int64(1), true, false, ""}, 104 {"from *int64 non nil", int64Ptr(1), true, false, ""}, 105 {"from *int64 nil", int64NilPtr(), false, true, ""}, 106 {"from int32", int32(1), true, false, ""}, 107 {"from *int32 non nil", int32Ptr(1), true, false, ""}, 108 {"from *int32 nil", int32NilPtr(), false, true, ""}, 109 {"from int16", int16(1), true, false, ""}, 110 {"from *int16 non nil", int16Ptr(1), true, false, ""}, 111 {"from *int16 nil", int16NilPtr(), false, true, ""}, 112 {"from int8", int8(1), true, false, ""}, 113 {"from *int8 non nil", int8Ptr(1), true, false, ""}, 114 {"from *int8 nil", int8NilPtr(), false, true, ""}, 115 {"from uint", uint(1), true, false, ""}, 116 {"from *uint non nil", uintPtr(1), true, false, ""}, 117 {"from *uint nil", uintNilPtr(), false, true, ""}, 118 {"from uint64", uint64(1), true, false, ""}, 119 {"from *uint64 non nil", uint64Ptr(1), true, false, ""}, 120 {"from *uint64 nil", uint64NilPtr(), false, true, ""}, 121 {"from uint32", uint32(1), true, false, ""}, 122 {"from *uint32 non nil", uint32Ptr(1), true, false, ""}, 123 {"from *uint32 nil", uint32NilPtr(), false, true, ""}, 124 {"from uint16", uint16(1), true, false, ""}, 125 {"from *uint16 non nil", uint16Ptr(1), true, false, ""}, 126 {"from *uint16 nil", uint16NilPtr(), false, true, ""}, 127 {"from uint8", uint8(1), true, false, ""}, 128 {"from *uint8 non nil", uint8Ptr(1), true, false, ""}, 129 {"from *uint8 nil", uint8NilPtr(), false, true, ""}, 130 {"from untyped nil", nil, false, true, ""}, 131 {"from unsupported pointer type", float64Ptr(42.0), false, false, "cannot convert from *float64 to bool: conversion not supported"}} 132 for _, tt := range tests { 133 t.Run(tt.name, func(t *testing.T) { 134 gotDest, gotWasNil, gotErr := convertToBoolean(tt.source) 135 assert.Equal(t, tt.wantDest, gotDest) 136 assert.Equal(t, tt.wantWasNil, gotWasNil) 137 assertErrorMessage(t, tt.wantErr, gotErr) 138 }) 139 } 140 } 141 142 func Test_convertFromBoolean(t *testing.T) { 143 tests := []struct { 144 name string 145 val bool 146 wasNull bool 147 dest interface{} 148 expected interface{} 149 err string 150 }{ 151 {"to *interface{} nil dest", true, false, interfaceNilPtr(), interfaceNilPtr(), "cannot convert from bool to *interface {}: destination is nil"}, 152 {"to *interface{} nil source", false, true, new(interface{}), new(interface{}), ""}, 153 {"to *interface{} non nil", true, false, new(interface{}), interfacePtr(true), ""}, 154 {"to *bool nil dest", true, false, boolNilPtr(), boolNilPtr(), "cannot convert from bool to *bool: destination is nil"}, 155 {"to *bool nil source", false, true, new(bool), boolPtr(false), ""}, 156 {"to *bool non nil", true, false, new(bool), boolPtr(true), ""}, 157 {"to *int nil dest", true, false, intNilPtr(), intNilPtr(), "cannot convert from bool to *int: destination is nil"}, 158 {"to *int nil source", false, true, new(int), intPtr(0), ""}, 159 {"to *int non nil", true, false, new(int), intPtr(1), ""}, 160 {"to *int64 nil dest", true, false, int64NilPtr(), int64NilPtr(), "cannot convert from bool to *int64: destination is nil"}, 161 {"to *int64 nil source", false, true, new(int64), int64Ptr(0), ""}, 162 {"to *int64 non nil", true, false, new(int64), int64Ptr(1), ""}, 163 {"to *int32 nil dest", true, false, int32NilPtr(), int32NilPtr(), "cannot convert from bool to *int32: destination is nil"}, 164 {"to *int32 nil source", false, true, new(int32), int32Ptr(0), ""}, 165 {"to *int32 non nil", true, false, new(int32), int32Ptr(1), ""}, 166 {"to *int16 nil dest", true, false, int16NilPtr(), int16NilPtr(), "cannot convert from bool to *int16: destination is nil"}, 167 {"to *int16 nil source", false, true, new(int16), int16Ptr(0), ""}, 168 {"to *int16 non nil", true, false, new(int16), int16Ptr(1), ""}, 169 {"to *int8 nil dest", true, false, int8NilPtr(), int8NilPtr(), "cannot convert from bool to *int8: destination is nil"}, 170 {"to *int8 nil source", false, true, new(int8), int8Ptr(0), ""}, 171 {"to *int8 non nil", true, false, new(int8), int8Ptr(1), ""}, 172 {"to *uint nil dest", true, false, uintNilPtr(), uintNilPtr(), "cannot convert from bool to *uint: destination is nil"}, 173 {"to *uint nil source", false, true, new(uint), uintPtr(0), ""}, 174 {"to *uint non nil", true, false, new(uint), uintPtr(1), ""}, 175 {"to *uint64 nil dest", true, false, uint64NilPtr(), uint64NilPtr(), "cannot convert from bool to *uint64: destination is nil"}, 176 {"to *uint64 nil source", false, true, new(uint64), uint64Ptr(0), ""}, 177 {"to *uint64 non nil", true, false, new(uint64), uint64Ptr(1), ""}, 178 {"to *uint32 nil dest", true, false, uint32NilPtr(), uint32NilPtr(), "cannot convert from bool to *uint32: destination is nil"}, 179 {"to *uint32 nil source", false, true, new(uint32), uint32Ptr(0), ""}, 180 {"to *uint32 non nil", true, false, new(uint32), uint32Ptr(1), ""}, 181 {"to *uint16 nil dest", true, false, uint16NilPtr(), uint16NilPtr(), "cannot convert from bool to *uint16: destination is nil"}, 182 {"to *uint16 nil source", false, true, new(uint16), uint16Ptr(0), ""}, 183 {"to *uint16 non nil", true, false, new(uint16), uint16Ptr(1), ""}, 184 {"to *uint8 nil dest", true, false, uint8NilPtr(), uint8NilPtr(), "cannot convert from bool to *uint8: destination is nil"}, 185 {"to *uint8 nil source", false, true, new(uint8), uint8Ptr(0), ""}, 186 {"to *uint8 non nil", true, false, new(uint8), uint8Ptr(1), ""}, 187 {"to untyped nil", true, false, nil, nil, "cannot convert from bool to <nil>: destination is nil"}, 188 {"to non pointer", true, false, int64(0), int64(0), "cannot convert from bool to int64: destination is not pointer"}, 189 {"to unsupported pointer type", true, false, new(float64), new(float64), "cannot convert from bool to *float64: conversion not supported"}} 190 for _, tt := range tests { 191 t.Run(tt.name, func(t *testing.T) { 192 gotErr := convertFromBoolean(tt.val, tt.wasNull, tt.dest) 193 assert.Equal(t, tt.expected, tt.dest) 194 assertErrorMessage(t, tt.err, gotErr) 195 }) 196 } 197 } 198 199 func Test_writeBoolean(t *testing.T) { 200 tests := []struct { 201 name string 202 val bool 203 expected []byte 204 }{ 205 {"false", false, []byte{0}}, 206 {"true", true, []byte{1}}, 207 } 208 for _, tt := range tests { 209 t.Run(tt.name, func(t *testing.T) { 210 actual := writeBool(tt.val) 211 assert.Equal(t, tt.expected, actual) 212 }) 213 } 214 } 215 216 func Test_readBoolean(t *testing.T) { 217 tests := []struct { 218 name string 219 source []byte 220 expected bool 221 wasNull bool 222 err string 223 }{ 224 {"nil", nil, false, true, ""}, 225 {"empty", []byte{}, false, true, ""}, 226 {"wrong length", []byte{1, 2}, false, false, "cannot read bool: expected 1 bytes but got: 2"}, 227 {"false", []byte{0}, false, false, ""}, 228 {"true", []byte{1}, true, false, ""}, 229 {"true 255", []byte{255}, true, false, ""}, 230 } 231 for _, tt := range tests { 232 t.Run(tt.name, func(t *testing.T) { 233 actual, wasNull, err := readBool(tt.source) 234 assert.Equal(t, tt.expected, actual) 235 assert.Equal(t, tt.wasNull, wasNull) 236 assertErrorMessage(t, tt.err, err) 237 }) 238 } 239 }