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  }