1717package  types_test
1818
1919import  (
20+ 	"encoding/json" 
2021	"errors" 
22+ 	"fmt" 
2123	"io" 
2224	"testing" 
2325
@@ -31,19 +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
51+ func  (hh  * stubHeaderHooks ) MarshalJSON (h  * Header ) ([]byte , error ) { //nolint:govet 
52+ 	return  fakeHeaderJSON (h , hh .suffix ), hh .errMarshal 
53+ }
54+ 
55+ func  (hh  * stubHeaderHooks ) UnmarshalJSON (h  * Header , b  []byte ) error  { //nolint:govet 
56+ 	hh .gotRawJSONToUnmarshal  =  b 
57+ 	* h  =  hh .setHeaderToOnUnmarshalOrDecode 
58+ 	return  hh .errUnmarshal 
59+ }
60+ 
4561func  (hh  * stubHeaderHooks ) EncodeRLP (h  * Header , w  io.Writer ) error  {
46- 	if  _ , err  :=  w .Write (fakeHeaderRLP (h , hh .rlpSuffix )); err  !=  nil  {
62+ 	if  _ , err  :=  w .Write (fakeHeaderRLP (h , hh .suffix )); err  !=  nil  {
4763		return  err 
4864	}
4965	return  hh .errEncode 
@@ -55,7 +71,7 @@ func (hh *stubHeaderHooks) DecodeRLP(h *Header, s *rlp.Stream) error {
5571		return  err 
5672	}
5773	hh .gotRawRLPToDecode  =  r 
58- 	* h  =  hh .setHeaderToOnDecode 
74+ 	* h  =  hh .setHeaderToOnUnmarshalOrDecode 
5975	return  hh .errDecode 
6076}
6177
@@ -66,14 +82,36 @@ func TestHeaderHooks(t *testing.T) {
6682	extras  :=  RegisterExtras [stubHeaderHooks , * stubHeaderHooks , struct {}]()
6783	rng  :=  ethtest .NewPseudoRand (13579 )
6884
69- 	t .Run ("EncodeRLP" , func (t  * testing.T ) {
70- 		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 ... )
90+ 
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+ 	})
7196
72- 		hdr  :=  & Header {
73- 			ParentHash : rng .Hash (),
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+ 			},
74103		}
75- 		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()" )
76109
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+ 	})
113+ 
114+ 	t .Run ("EncodeRLP" , func (t  * testing.T ) {
77115		got , err  :=  rlp .EncodeToBytes (hdr )
78116		require .NoError (t , err , "rlp.EncodeToBytes(%T)" , hdr )
79117		assert .Equal (t , fakeHeaderRLP (hdr , suffix ), got )
@@ -85,7 +123,7 @@ func TestHeaderHooks(t *testing.T) {
85123
86124		hdr  :=  new (Header )
87125		stub  :=  & stubHeaderHooks {
88- 			setHeaderToOnDecode : Header {
126+ 			setHeaderToOnUnmarshalOrDecode : Header {
89127				Extra : []byte ("arr4n was here" ),
90128			},
91129		}
@@ -94,20 +132,46 @@ func TestHeaderHooks(t *testing.T) {
94132		require .NoErrorf (t , err , "rlp.DecodeBytes(%#x)" , input )
95133
96134		assert .Equal (t , input , stub .gotRawRLPToDecode , "raw RLP received by hooks" )
97- 		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 )
98136	})
99137
100138	t .Run ("error_propagation" , func (t  * testing.T ) {
139+ 		errMarshal  :=  errors .New ("whoops" )
140+ 		errUnmarshal  :=  errors .New ("is it broken?" )
101141		errEncode  :=  errors .New ("uh oh" )
102142		errDecode  :=  errors .New ("something bad happened" )
103143
104144		hdr  :=  new (Header )
105- 		extras .Header .Set (hdr , & stubHeaderHooks {
106- 			errEncode : errEncode ,
107- 			errDecode : errDecode ,
108- 		})
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+ 		// The { } blocks are defensive, avoiding accidentally having the wrong 
156+ 		// error checked in a future refactor. The verbosity is acceptable for 
157+ 		// clarity in tests. 
158+ 		{
159+ 			_ , err  :=  json .Marshal (hdr )
160+ 			assert .ErrorIs (t , err , errMarshal , "via json.Marshal()" ) //nolint:testifylint // require is inappropriate here as we wish to keep going 
161+ 		}
162+ 		{
163+ 			err  :=  json .Unmarshal ([]byte ("{}" ), hdr )
164+ 			assert .Equal (t , errUnmarshal , err , "via json.Unmarshal()" )
165+ 		}
109166
110- 		assert .Equal (t , errEncode , rlp .Encode (io .Discard , hdr ), "via rlp.Encode()" )
111- 		assert .Equal (t , errDecode , rlp .DecodeBytes ([]byte {0 }, hdr ), "via rlp.DecodeBytes()" )
167+ 		setStub () // [stubHeaderHooks] completely overrides the Header 
168+ 		{
169+ 			err  :=  rlp .Encode (io .Discard , hdr )
170+ 			assert .Equal (t , errEncode , err , "via rlp.Encode()" )
171+ 		}
172+ 		{
173+ 			err  :=  rlp .DecodeBytes ([]byte {0 }, hdr )
174+ 			assert .Equal (t , errDecode , err , "via rlp.DecodeBytes()" )
175+ 		}
112176	})
113177}
0 commit comments