From ffc086e75f6a9d8b4873a3c882fd5b301cd69914 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Thu, 8 Sep 2022 11:47:11 +0200 Subject: [PATCH] #42: Better test coverage for b64linebreaker.go. Also we return errors now --- b64linebreaker.go | 18 +++++++++++++----- b64linebreaker_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/b64linebreaker.go b/b64linebreaker.go index ff99696..ecad47d 100644 --- a/b64linebreaker.go +++ b/b64linebreaker.go @@ -4,7 +4,12 @@ package mail -import "io" +import ( + "fmt" + "io" +) + +const ErrNoOutWriter = "no io.Writer set for Base64LineBreaker" // Base64LineBreaker is a io.WriteCloser that writes Base64 encoded data streams // with line breaks at a given line length @@ -19,6 +24,9 @@ var nl = []byte(SingleNewLine) // Write writes the data stream and inserts a SingleNewLine when the maximum // line length is reached func (l *Base64LineBreaker) Write(b []byte) (n int, err error) { + if l.out == nil { + return 0, fmt.Errorf(ErrNoOutWriter) + } if l.used+len(b) < MaxBodyLength { copy(l.line[l.used:], b) l.used += len(b) @@ -27,19 +35,19 @@ func (l *Base64LineBreaker) Write(b []byte) (n int, err error) { n, err = l.out.Write(l.line[0:l.used]) if err != nil { - return + return 0, err } excess := MaxBodyLength - l.used l.used = 0 n, err = l.out.Write(b[0:excess]) if err != nil { - return + return 0, err } n, err = l.out.Write(nl) if err != nil { - return + return 0, err } return l.Write(b[excess:]) @@ -51,7 +59,7 @@ func (l *Base64LineBreaker) Close() (err error) { if l.used > 0 { _, err = l.out.Write(l.line[0:l.used]) if err != nil { - return + return err } _, err = l.out.Write(nl) } diff --git a/b64linebreaker_test.go b/b64linebreaker_test.go index 05c61c3..f2b3891 100644 --- a/b64linebreaker_test.go +++ b/b64linebreaker_test.go @@ -7,6 +7,7 @@ package mail import ( "bytes" "encoding/base64" + "fmt" "io" "os" "testing" @@ -410,6 +411,31 @@ func TestBase64LineBreaker(t *testing.T) { } } +// TestBase64LineBreakerFailures tests the cases in which the Base64LineBreaker would fail +func TestBase64LineBreakerFailures(t *testing.T) { + stt := []byte("short") + ltt := []byte(logoB64) + + // No output writer defined + lb := Base64LineBreaker{} + if _, err := lb.Write(stt); err == nil { + t.Errorf("writing to Base64LineBreaker with no output io.Writer was supposed to failed, but didn't") + } + if err := lb.Close(); err != nil { + t.Errorf("failed to close Base64LineBreaker: %s", err) + } + + // Closed output writer + wbuf := errorWriter{} + fb := Base64LineBreaker{out: wbuf} + if _, err := fb.Write(ltt); err == nil { + t.Errorf("writing to Base64LineBreaker with errorWriter was supposed to failed, but didn't") + } + if err := fb.Close(); err != nil { + t.Errorf("failed to close Base64LineBreaker: %s", err) + } +} + // removeNewLines removes any newline characters from the given data func removeNewLines(data []byte) []byte { result := make([]byte, len(data)) @@ -425,3 +451,13 @@ func removeNewLines(data []byte) []byte { return result[0:n] } + +type errorWriter struct{} + +func (e errorWriter) Write([]byte) (int, error) { + return 0, fmt.Errorf("supposed to always fail") +} + +func (e errorWriter) Close() error { + return fmt.Errorf("supposed to always fail") +}