git.lukeshu.com/go/lowmemjson@v0.3.9-0.20230723050957-72f6d13f6fb2/roundtrip_test.go (about)

     1  // Copyright (C) 2022-2023  Luke Shumaker <lukeshu@lukeshu.com>
     2  //
     3  // SPDX-License-Identifier: GPL-2.0-or-later
     4  
     5  package lowmemjson_test
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/json"
    10  	"os"
    11  	"path/filepath"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"git.lukeshu.com/go/lowmemjson"
    17  )
    18  
    19  type ScanDevicesResult map[uint64]ScanOneDeviceResult
    20  
    21  type ScanOneDeviceResult struct {
    22  	FoundExtentCSums []SysExtentCSum
    23  }
    24  
    25  type SysExtentCSum struct {
    26  	Generation int64
    27  	Sums       SumRun
    28  }
    29  
    30  type Optional[T any] struct {
    31  	OK  bool
    32  	Val T
    33  }
    34  
    35  var (
    36  	_ json.Marshaler   = Optional[bool]{}
    37  	_ json.Unmarshaler = (*Optional[bool])(nil)
    38  )
    39  
    40  func (o Optional[T]) MarshalJSON() ([]byte, error) {
    41  	if o.OK {
    42  		return json.Marshal(o.Val)
    43  	} else {
    44  		return []byte("null"), nil
    45  	}
    46  }
    47  
    48  func (o *Optional[T]) UnmarshalJSON(dat []byte) error {
    49  	if string(dat) == "null" {
    50  		*o = Optional[T]{}
    51  		return nil
    52  	}
    53  	o.OK = true
    54  	return json.Unmarshal(dat, &o.Val)
    55  }
    56  
    57  type QualifiedPhysicalAddr struct {
    58  	Dev  uint64
    59  	Addr int64
    60  }
    61  
    62  type Mapping struct {
    63  	LAddr      int64
    64  	PAddr      QualifiedPhysicalAddr
    65  	Size       int64
    66  	SizeLocked bool             `json:",omitempty"`
    67  	Flags      Optional[uint64] `json:",omitempty"`
    68  }
    69  
    70  func TestRoundTrip(t *testing.T) {
    71  	t.Parallel()
    72  
    73  	type testcase struct {
    74  		ObjPtr any
    75  		Cfg    lowmemjson.ReEncoderConfig
    76  	}
    77  	testcases := map[string]testcase{
    78  		"scandevices": {
    79  			ObjPtr: new(ScanDevicesResult),
    80  			Cfg: lowmemjson.ReEncoderConfig{
    81  				Indent:                "\t",
    82  				ForceTrailingNewlines: true,
    83  				CompactIfUnder:        16,
    84  			},
    85  		},
    86  		"mappings": {
    87  			ObjPtr: new([]Mapping),
    88  			Cfg: lowmemjson.ReEncoderConfig{
    89  				Indent:                "\t",
    90  				ForceTrailingNewlines: true,
    91  				CompactIfUnder:        120,
    92  			},
    93  		},
    94  	}
    95  
    96  	for tcName, tc := range testcases {
    97  		tcName := tcName
    98  		tc := tc
    99  		t.Run(tcName, func(t *testing.T) {
   100  			t.Parallel()
   101  			inBytes, err := os.ReadFile(filepath.Join("testdata", "roundtrip", tcName+".json")) // #nosec G304
   102  			require.NoError(t, err)
   103  			require.NoError(t, lowmemjson.NewDecoder(bytes.NewReader(inBytes)).DecodeThenEOF(tc.ObjPtr))
   104  			var outBytes bytes.Buffer
   105  			require.NoError(t, lowmemjson.NewEncoder(lowmemjson.NewReEncoder(&outBytes, tc.Cfg)).Encode(tc.ObjPtr))
   106  			require.Equal(t, string(inBytes), outBytes.String())
   107  		})
   108  	}
   109  }