diff --git a/internal/assertions/assertions.go b/internal/assertions/assertions.go index fb9b7e1..9e625f6 100644 --- a/internal/assertions/assertions.go +++ b/internal/assertions/assertions.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "io/fs" "os" "path/filepath" @@ -1044,6 +1045,15 @@ func FilePathValid(path string) (s string) { return } +func Close(c io.Closer) (s string) { + err := c.Close() + if err != nil { + s = "calling Close failed\n" + s += bullet("error: %v\n", err) + } + return +} + func StrEqFold(exp, val string) (s string) { if !strings.EqualFold(exp, val) { s = "expected strings to be equal ignoring case\n" diff --git a/must/must.go b/must/must.go index 7719734..c957614 100644 --- a/must/must.go +++ b/must/must.go @@ -3,6 +3,7 @@ package must import ( + "io" "io/fs" "os" "path/filepath" @@ -599,6 +600,12 @@ func FilePathValid(t T, path string, settings ...Setting) { invoke(t, assertions.FilePathValid(path), settings...) } +// Close asserts c.Close does not cause an error. +func Close(t T, c io.Closer) { + t.Helper() + invoke(t, assertions.Close(c)) +} + // StrEqFold asserts exp and val are equivalent, ignoring case. func StrEqFold(t T, exp, val string, settings ...Setting) { t.Helper() diff --git a/must/must_test.go b/must/must_test.go index 1bf01e7..ac343ec 100644 --- a/must/must_test.go +++ b/must/must_test.go @@ -1401,6 +1401,22 @@ func TestFilePathValid(t *testing.T) { FilePathValid(tc, "foo/../bar") } +type closer struct { + err error +} + +func (c *closer) Close() error { + return c.err +} + +func TestClose(t *testing.T) { + tc := newCase(t, `calling Close failed`) + t.Cleanup(tc.assert) + + c := &closer{err: errors.New("oops")} + Close(tc, c) +} + func TestStrEqFold(t *testing.T) { tc := newCase(t, `expected strings to be equal ignoring case`) t.Cleanup(tc.assert) diff --git a/test.go b/test.go index b5e943a..8af85f9 100644 --- a/test.go +++ b/test.go @@ -1,6 +1,7 @@ package test import ( + "io" "io/fs" "os" "path/filepath" @@ -597,6 +598,12 @@ func FilePathValid(t T, path string, settings ...Setting) { invoke(t, assertions.FilePathValid(path), settings...) } +// Close asserts c.Close does not cause an error. +func Close(t T, c io.Closer) { + t.Helper() + invoke(t, assertions.Close(c)) +} + // StrEqFold asserts exp and val are equivalent, ignoring case. func StrEqFold(t T, exp, val string, settings ...Setting) { t.Helper() diff --git a/test_test.go b/test_test.go index aff875f..0d60c68 100644 --- a/test_test.go +++ b/test_test.go @@ -1399,6 +1399,22 @@ func TestFilePathValid(t *testing.T) { FilePathValid(tc, "foo/../bar") } +type closer struct { + err error +} + +func (c *closer) Close() error { + return c.err +} + +func TestClose(t *testing.T) { + tc := newCase(t, `calling Close failed`) + t.Cleanup(tc.assert) + + c := &closer{err: errors.New("oops")} + Close(tc, c) +} + func TestStrEqFold(t *testing.T) { tc := newCase(t, `expected strings to be equal ignoring case`) t.Cleanup(tc.assert)