github.com/vc42/parquet-go@v0.0.0-20240320194221-1a9adb5f23f5/encoding/test/test_go18.go (about)

     1  //go:build go1.18
     2  
     3  package test
     4  
     5  import (
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/vc42/parquet-go/encoding"
    10  	"github.com/vc42/parquet-go/internal/unsafecast"
    11  )
    12  
    13  func EncodeInt32(t *testing.T, enc encoding.Encoding, min, max int, bitWidth uint) {
    14  	t.Helper()
    15  	encode(t, enc, min, max,
    16  		encoding.Encoding.EncodeInt32,
    17  		encoding.Encoding.DecodeInt32,
    18  		func(i int) int32 {
    19  			value := int32(i)
    20  			mask := int32((1 << bitWidth) - 1)
    21  			if (i % 2) != 0 {
    22  				value = -value
    23  			}
    24  			return value & mask
    25  		},
    26  	)
    27  }
    28  
    29  func EncodeInt64(t *testing.T, enc encoding.Encoding, min, max int, bitWidth uint) {
    30  	t.Helper()
    31  	encode(t, enc, min, max,
    32  		encoding.Encoding.EncodeInt64,
    33  		encoding.Encoding.DecodeInt64,
    34  		func(i int) int64 {
    35  			value := int64(i)
    36  			mask := int64((1 << bitWidth) - 1)
    37  			if (i % 2) != 0 {
    38  				value = -value
    39  			}
    40  			return value & mask
    41  		},
    42  	)
    43  }
    44  
    45  func EncodeFloat(t *testing.T, enc encoding.Encoding, min, max int) {
    46  	t.Helper()
    47  	encode(t, enc, min, max,
    48  		encoding.Encoding.EncodeFloat,
    49  		encoding.Encoding.DecodeFloat,
    50  		func(i int) float32 { return float32(i) },
    51  	)
    52  }
    53  
    54  func EncodeDouble(t *testing.T, enc encoding.Encoding, min, max int) {
    55  	t.Helper()
    56  	encode(t, enc, min, max,
    57  		encoding.Encoding.EncodeDouble,
    58  		encoding.Encoding.DecodeDouble,
    59  		func(i int) float64 { return float64(i) },
    60  	)
    61  }
    62  
    63  type encodingMethod func(encoding.Encoding, []byte, []byte) ([]byte, error)
    64  
    65  func encode[T comparable](t *testing.T, enc encoding.Encoding, min, max int, encode, decode encodingMethod, valueOf func(int) T) {
    66  	t.Helper()
    67  
    68  	for k := min; k <= max; k++ {
    69  		t.Run(fmt.Sprintf("N=%d", k), func(t *testing.T) {
    70  			src := make([]T, k)
    71  			for i := range src {
    72  				src[i] = valueOf(i)
    73  			}
    74  
    75  			buf, err := encode(enc, nil, unsafecast.Slice[byte](src))
    76  			if err != nil {
    77  				t.Fatalf("encoding %d values: %v", k, err)
    78  			}
    79  
    80  			res, err := decode(enc, nil, buf)
    81  			if err != nil {
    82  				t.Fatalf("decoding %d values: %v", k, err)
    83  			}
    84  
    85  			if err := assertEqual(src, unsafecast.Slice[T](res)); err != nil {
    86  				t.Fatalf("testing %d values: %v", k, err)
    87  			}
    88  		})
    89  	}
    90  }
    91  
    92  func assertEqual[T comparable](want, got []T) error {
    93  	if len(want) != len(got) {
    94  		return fmt.Errorf("number of values mismatch: want=%d got=%d", len(want), len(got))
    95  	}
    96  
    97  	for i := range want {
    98  		if want[i] != got[i] {
    99  			return fmt.Errorf("values at index %d/%d mismatch: want=%+v got=%+v", i, len(want), want[i], got[i])
   100  		}
   101  	}
   102  
   103  	return nil
   104  }