1717package types_test
1818
1919import (
20+ "encoding/json"
2021 "errors"
22+ "fmt"
2123 "io"
2224 "testing"
2325
@@ -31,27 +33,33 @@ import (
3133)
3234
3335type stubHeaderHooks struct {
34- rlpSuffix []byte
35- gotRawRLPToDecode []byte
36- setHeaderToOnDecode Header
36+ suffix []byte
37+ gotRawJSONToUnmarshal , gotRawRLPToDecode []byte
38+ setHeaderToOnUnmarshalOrDecode Header
3739
38- errEncode , errDecode error
40+ errMarshal , errUnmarshal , errEncode , errDecode error
41+ }
42+
43+ func fakeHeaderJSON (h * Header , suffix []byte ) []byte {
44+ return []byte (fmt .Sprintf (`"%#x:%#x"` , h .ParentHash , suffix ))
3945}
4046
4147func fakeHeaderRLP (h * Header , suffix []byte ) []byte {
4248 return append (crypto .Keccak256 (h .ParentHash [:]), suffix ... )
4349}
4450
4551func (hh * stubHeaderHooks ) MarshalJSON (h * Header ) ([]byte , error ) { //nolint:govet
46- return nil , errors . New ( "TODO" )
52+ return fakeHeaderJSON ( h , hh . suffix ), hh . errMarshal
4753}
4854
4955func (hh * stubHeaderHooks ) UnmarshalJSON (h * Header , b []byte ) error { //nolint:govet
50- return errors .New ("TODO" )
56+ hh .gotRawJSONToUnmarshal = b
57+ * h = hh .setHeaderToOnUnmarshalOrDecode
58+ return hh .errUnmarshal
5159}
5260
5361func (hh * stubHeaderHooks ) EncodeRLP (h * Header , w io.Writer ) error {
54- if _ , err := w .Write (fakeHeaderRLP (h , hh .rlpSuffix )); err != nil {
62+ if _ , err := w .Write (fakeHeaderRLP (h , hh .suffix )); err != nil {
5563 return err
5664 }
5765 return hh .errEncode
@@ -63,7 +71,7 @@ func (hh *stubHeaderHooks) DecodeRLP(h *Header, s *rlp.Stream) error {
6371 return err
6472 }
6573 hh .gotRawRLPToDecode = r
66- * h = hh .setHeaderToOnDecode
74+ * h = hh .setHeaderToOnUnmarshalOrDecode
6775 return hh .errDecode
6876}
6977
@@ -74,14 +82,36 @@ func TestHeaderHooks(t *testing.T) {
7482 extras := RegisterExtras [stubHeaderHooks , * stubHeaderHooks , struct {}]()
7583 rng := ethtest .NewPseudoRand (13579 )
7684
77- t .Run ("EncodeRLP" , func (t * testing.T ) {
78- suffix := rng .Bytes (8 )
85+ suffix := rng .Bytes (8 )
86+ hdr := & Header {
87+ ParentHash : rng .Hash (),
88+ }
89+ extras .Header .Get (hdr ).suffix = append ([]byte {}, suffix ... )
7990
80- hdr := & Header {
81- ParentHash : rng .Hash (),
91+ t .Run ("MarshalJSON" , func (t * testing.T ) {
92+ got , err := json .Marshal (hdr )
93+ require .NoError (t , err , "json.Marshal(%T)" , hdr )
94+ assert .Equal (t , fakeHeaderJSON (hdr , suffix ), got )
95+ })
96+
97+ t .Run ("UnmarshalJSON" , func (t * testing.T ) {
98+ hdr := new (Header )
99+ stub := & stubHeaderHooks {
100+ setHeaderToOnUnmarshalOrDecode : Header {
101+ Extra : []byte ("can you solve this puzzle? 0xbda01b6cf56c303bd3f581599c0d5c0b" ),
102+ },
82103 }
83- extras .Header .Get (hdr ).rlpSuffix = append ([]byte {}, suffix ... )
104+ extras .Header .Set (hdr , stub )
105+
106+ input := fmt .Sprintf ("%q" , "hello, JSON world" )
107+ err := json .Unmarshal ([]byte (input ), hdr )
108+ require .NoErrorf (t , err , "json.Unmarshal()" )
109+
110+ assert .Equal (t , input , string (stub .gotRawJSONToUnmarshal ), "raw JSON received by hook" )
111+ assert .Equal (t , & stub .setHeaderToOnUnmarshalOrDecode , hdr , "%T after JSON unmarshalling with hook" , hdr )
112+ })
84113
114+ t .Run ("EncodeRLP" , func (t * testing.T ) {
85115 got , err := rlp .EncodeToBytes (hdr )
86116 require .NoError (t , err , "rlp.EncodeToBytes(%T)" , hdr )
87117 assert .Equal (t , fakeHeaderRLP (hdr , suffix ), got )
@@ -93,7 +123,7 @@ func TestHeaderHooks(t *testing.T) {
93123
94124 hdr := new (Header )
95125 stub := & stubHeaderHooks {
96- setHeaderToOnDecode : Header {
126+ setHeaderToOnUnmarshalOrDecode : Header {
97127 Extra : []byte ("arr4n was here" ),
98128 },
99129 }
@@ -102,19 +132,31 @@ func TestHeaderHooks(t *testing.T) {
102132 require .NoErrorf (t , err , "rlp.DecodeBytes(%#x)" , input )
103133
104134 assert .Equal (t , input , stub .gotRawRLPToDecode , "raw RLP received by hooks" )
105- assert .Equalf (t , & stub .setHeaderToOnDecode , hdr , "%T after RLP decoding with hook" , hdr )
135+ assert .Equalf (t , & stub .setHeaderToOnUnmarshalOrDecode , hdr , "%T after RLP decoding with hook" , hdr )
106136 })
107137
108138 t .Run ("error_propagation" , func (t * testing.T ) {
139+ errMarshal := errors .New ("whoops" )
140+ errUnmarshal := errors .New ("is it broken?" )
109141 errEncode := errors .New ("uh oh" )
110142 errDecode := errors .New ("something bad happened" )
111143
112144 hdr := new (Header )
113- extras .Header .Set (hdr , & stubHeaderHooks {
114- errEncode : errEncode ,
115- errDecode : errDecode ,
116- })
145+ setStub := func () {
146+ extras .Header .Set (hdr , & stubHeaderHooks {
147+ errMarshal : errMarshal ,
148+ errUnmarshal : errUnmarshal ,
149+ errEncode : errEncode ,
150+ errDecode : errDecode ,
151+ })
152+ }
153+
154+ setStub ()
155+ _ , err := json .Marshal (hdr )
156+ assert .ErrorIs (t , err , errMarshal , "via json.Marshal()" )
157+ assert .Equal (t , errUnmarshal , json .Unmarshal ([]byte ("{}" ), hdr ), "via json.Unmarshal()" )
117158
159+ setStub () // [stubHeaderHooks] completely overrides the Header
118160 assert .Equal (t , errEncode , rlp .Encode (io .Discard , hdr ), "via rlp.Encode()" )
119161 assert .Equal (t , errDecode , rlp .DecodeBytes ([]byte {0 }, hdr ), "via rlp.DecodeBytes()" )
120162 })
0 commit comments