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  }