package buffer import ( "bytes" "encoding" "fmt" "io" "reflect" "testing" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" ) // TestInterface is a testing interface for byte encoding and decoding. type TestInterface interface { io.WriterTo io.ReaderFrom encoding.BinaryMarshaler encoding.BinaryUnmarshaler } // TestInterfaceWriteAndRead tests that: // - input and output implement TestInterface // - input.WriteTo(io.Writer) writes a number of bytes on the writer equal to the number of bytes generated by input.MarshalBinary() // - input.WriteTo buffered bytes are equal to the bytes generated by input.MarshalBinary() // - output.ReadFrom(io.Reader) reads a number of bytes on the reader equal to the number of bytes writen using input.WriteTo(io.Writer) // - applies require.Equalf between the original and reconstructed object for // - all the above WriteTo, ReadFrom, MarhsalBinary and UnmarshalBinary do not return an error func TestInterfaceWriteAndRead(t *testing.T, input TestInterface) { // Allocates a new object of the underlying type of input output := reflect.New(reflect.TypeOf(input).Elem()).Elem().Addr().Interface().(TestInterface) data := []byte{} buf := bytes.NewBuffer(data) // Compliant to io.Writer and io.Reader // Check io.Writer bytesWriten, err := input.WriteTo(buf) require.NoError(t, err) // Check encoding.BinaryMarshaler data2, err := input.MarshalBinary() require.NoError(t, err) // Check that #bytes written with io.Writer = #bytes generates by encoding.BinaryMarshaler require.Equal(t, int(bytesWriten), len(data2), fmt.Errorf("invalid size: %T.WriteTo #bytes writen != %T.MarshalBinary #bytes generates", input, input)) // Check that bytes written with io.Writer = bytes generates by encoding.BinaryMarshaler require.True(t, bytes.Equal(buf.Bytes(), data2), fmt.Errorf("invalid encoding: %T.WriteTo buffer != %T.MarshalBinary bytes generates", input, input)) // Check io.Reader //fmt.Println(buf.Bytes()) bytesRead, err := output.ReadFrom(buf) require.NoError(t, err) // Check that #bytes read with io.Reader = #bytes writen with io.Writer require.Equal(t, bytesRead, bytesWriten, fmt.Errorf("invalid encoding: %T.ReadFrom #bytes read != %T.WriteTo #bytes writen", input, input)) // Deep equal output = input require.True(t, cmp.Equal(input, output)) // Check encoding.BinaryUnmarshaler output = reflect.New(reflect.TypeOf(input).Elem()).Elem().Addr().Interface().(TestInterface) require.NoError(t, output.UnmarshalBinary(data2)) // Deep equal output = input require.True(t, cmp.Equal(input, output)) }