From 4eb9d8a1fa42ea5a1ecdafdb7a2a8fe1f9d8acb0 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Mon, 28 Oct 2024 15:14:43 +0100 Subject: [PATCH] Add tests for Msg.Write and WriteTo error handling Implemented tests for the Msg.Write method and enhanced WriteTo error handling. Also added a failReadWriteSeekCloser type to explicitly simulate IO failures in tests, ensuring comprehensive reliability of error handling mechanisms. --- msg_test.go | 75 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/msg_test.go b/msg_test.go index e5fee38..8d106ed 100644 --- a/msg_test.go +++ b/msg_test.go @@ -5269,6 +5269,24 @@ func TestMsg_WriteTo(t *testing.T) { t.Errorf("expected message buffer to contain Testmail, got: %s", got) } }) + t.Run("WriteTo fails to write", func(t *testing.T) { + message := testMessage(t) + _, err := message.WriteTo(failReadWriteSeekCloser{}) + if err == nil { + t.Fatalf("writing to failReadWriteSeekCloser should fail") + } + if strings.EqualFold(err.Error(), "failed to write message to buffer: intentional write failure") { + t.Fatalf("expected error to be: failed to write message to buffer: intentional write failure, got: %s", + err) + } + }) +} +func TestMsg_Write(t *testing.T) { + message := testMessage(t) + if _, err := message.Write(io.Discard); err != nil { + t.Fatalf("failed to write message to io.Discard: %s", err) + } + t.Log("Write() is just an alias to WriteTo(), which has already been tested.") } func TestMsg_WriteToSkipMiddleware(t *testing.T) { @@ -5355,39 +5373,6 @@ func TestMsg_WriteToSkipMiddleware(t *testing.T) { } } -// TestMsg_WriteToSkipMiddleware tests the WriteTo() method of the Msg - - func TestMsg_WriteToSkipMiddleware(t *testing.T) { - m := NewMsg(WithMiddleware(encodeMiddleware{}), WithMiddleware(uppercaseMiddleware{})) - m.Subject("This is a test") - m.SetBodyString(TypeTextPlain, "Plain") - wbuf := bytes.Buffer{} - n, err := m.WriteToSkipMiddleware(&wbuf, "uppercase") - if err != nil { - t.Errorf("WriteToSkipMiddleware() failed: %s", err) - return - } - if n != int64(wbuf.Len()) { - t.Errorf("WriteToSkipMiddleware() failed: expected written byte length: %d, got: %d", n, wbuf.Len()) - } - if !strings.Contains(wbuf.String(), "Subject: This is @ test") { - t.Errorf("WriteToSkipMiddleware failed. Unable to find encoded subject") - } - - wbuf2 := bytes.Buffer{} - n, err = m.WriteTo(&wbuf2) - if err != nil { - t.Errorf("WriteTo() failed: %s", err) - return - } - if n != int64(wbuf2.Len()) { - t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf2.Len()) - } - if !strings.Contains(wbuf2.String(), "Subject: THIS IS @ TEST") { - t.Errorf("WriteToSkipMiddleware failed. Unable to find encoded and upperchase subject") - } - } - // TestMsg_WriteTo_fails tests the WriteTo() method of the Msg but with a failing body writer function func TestMsg_WriteTo_fails(t *testing.T) { @@ -6764,6 +6749,30 @@ func (mw encodeMiddleware) Type() MiddlewareType { return "encode" } +// failReadWriteSeekCloser is a type that always returns an error. It satisfies the io.Reader, io.Writer +// io.Closer, io.Seeker, io.WriteSeeker, io.ReadSeeker, io.ReadCloser and io.WriteCloser interfaces +type failReadWriteSeekCloser struct{} + +// Write satisfies the io.Writer interface for the failReadWriteSeekCloser type +func (failReadWriteSeekCloser) Write([]byte) (int, error) { + return 0, errors.New("intentional write failure") +} + +// Read satisfies the io.Reader interface for the failReadWriteSeekCloser type +func (failReadWriteSeekCloser) Read([]byte) (int, error) { + return 0, errors.New("intentional read failure") +} + +// Seek satisfies the io.Seeker interface for the failReadWriteSeekCloser type +func (failReadWriteSeekCloser) Seek(int64, int) (int64, error) { + return 0, errors.New("intentional seek failure") +} + +// Close satisfies the io.Closer interface for the failReadWriteSeekCloser type +func (failReadWriteSeekCloser) Close() error { + return errors.New("intentional close failure") +} + // checkAddrHeader verifies the correctness of an AddrHeader in a Msg based on the provided criteria. // It checks whether the AddrHeader contains the correct address, name, and number of fields. func checkAddrHeader(t *testing.T, message *Msg, header AddrHeader, fn string, field, wantFields int,