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 }