github.com/philpearl/plenc@v0.0.15/plenccodec/binary_test.go (about)

     1  package plenccodec_test
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/philpearl/plenc"
    11  )
    12  
    13  func TestBinaryCompatibility(t *testing.T) {
    14  	anInt32 := int32(1234)
    15  	// These tests ensure the wire format of the library does not change. We
    16  	// encode data and check the encoding matches golden values we've stored.
    17  	tests := []struct {
    18  		name     string
    19  		toEncode any
    20  	}{
    21  		{
    22  			name:     "string",
    23  			toEncode: "hats",
    24  		},
    25  		{
    26  			name:     "string_array",
    27  			toEncode: []string{"hats", "coats"},
    28  		},
    29  		{
    30  			name:     "bytes",
    31  			toEncode: []byte{1, 2, 3, 4},
    32  		},
    33  		{
    34  			name:     "int16",
    35  			toEncode: int16(1234),
    36  		},
    37  		{
    38  			name:     "int32",
    39  			toEncode: int32(1234),
    40  		},
    41  		{
    42  			name:     "int64",
    43  			toEncode: int64(12343453453),
    44  		},
    45  		{
    46  			name:     "uint16",
    47  			toEncode: uint16(1234),
    48  		},
    49  		{
    50  			name:     "uint32",
    51  			toEncode: uint32(1234),
    52  		},
    53  		{
    54  			name:     "uint64",
    55  			toEncode: uint64(12343453453),
    56  		},
    57  		{
    58  			name:     "int_array",
    59  			toEncode: []int{1, 2, 1337, 98, -100},
    60  		},
    61  		{
    62  			name:     "float32",
    63  			toEncode: float32(1234.5678),
    64  		},
    65  		{
    66  			name:     "float64",
    67  			toEncode: float64(1234.5678),
    68  		},
    69  		{
    70  			name:     "float_array",
    71  			toEncode: []float64{1.2, 3.4, 5.6},
    72  		},
    73  		{
    74  			name:     "bool",
    75  			toEncode: true,
    76  		},
    77  		{
    78  			name:     "bool_array",
    79  			toEncode: []bool{true, false, true},
    80  		},
    81  
    82  		{
    83  			name: "struct",
    84  			toEncode: struct {
    85  				Name string   `plenc:"1"`
    86  				Age  int      `plenc:"2,flat"`
    87  				F32  float32  `plenc:"3"`
    88  				F64  float64  `plenc:"4"`
    89  				I    int      `plenc:"5"`
    90  				J    []uint32 `plenc:"6"`
    91  				K    []string `plenc:"7"`
    92  				L    *int     `plenc:"8"`
    93  				M    *int32   `plenc:"9"`
    94  				// TODO: add more types
    95  			}{
    96  				Name: "Phil",
    97  				Age:  1337,
    98  				F32:  1234.5678,
    99  				F64:  1234.5678,
   100  				I:    -234332,
   101  				J:    []uint32{747439, 2223, 3344},
   102  				K:    []string{"hats", "coats"},
   103  				L:    nil,
   104  				M:    &anInt32,
   105  			},
   106  		},
   107  		{
   108  			name: "struct_array",
   109  			toEncode: []struct {
   110  				Name string `plenc:"1"`
   111  				Age  int    `plenc:"2"`
   112  			}{{Name: "Phil", Age: 1337}, {Name: "Bob", Age: 42}},
   113  		},
   114  		{
   115  			// Sigh. The binary representation of a map is not stable as the
   116  			// iteration order of the map is random. We'll test with one entry
   117  			// for now.
   118  			name: "map",
   119  			toEncode: map[string]int{
   120  				"Phil": 1337,
   121  			},
   122  		},
   123  		{
   124  			name:     "time",
   125  			toEncode: time.Date(1970, 3, 15, 13, 37, 42, 0, time.UTC),
   126  		},
   127  	}
   128  
   129  	for _, test := range tests {
   130  		t.Run(test.name, func(t *testing.T) {
   131  			// Encode the data.
   132  			encoded, err := plenc.Marshal(nil, test.toEncode)
   133  			if err != nil {
   134  				t.Fatalf("failed to encode: %v", err)
   135  			}
   136  
   137  			golden, err := os.ReadFile(filepath.Join("testdata", test.name+".golden"))
   138  			if err != nil {
   139  				if errors.Is(err, os.ErrNotExist) {
   140  					if err := os.WriteFile(filepath.Join("testdata", test.name+".golden"), encoded, 0o644); err != nil {
   141  						t.Fatal(err)
   142  					}
   143  					return
   144  				}
   145  				t.Fatalf("failed to read golden file: %v", err)
   146  			}
   147  
   148  			if string(encoded) != string(golden) {
   149  				t.Fatalf("encoded data does not match golden file")
   150  			}
   151  		})
   152  	}
   153  }