Refactor append_test to use standalone test functions

- Remove testify/suite dependency
- Use t.ArtifactDir() and t.Cleanup() for test isolation
- Add proper cleanup for config overrides in each test
- Update Go version to 1.26.0
This commit is contained in:
Dan Jones 2026-02-13 11:25:45 -06:00
commit 79f58b3e6c
2 changed files with 115 additions and 92 deletions

View file

@ -8,32 +8,42 @@ import (
"codeberg.org/danjones000/my-log/config" "codeberg.org/danjones000/my-log/config"
"codeberg.org/danjones000/my-log/models" "codeberg.org/danjones000/my-log/models"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestAppend(t *testing.T) { func TestAppend(tt *testing.T) {
suite.Run(t, new(AppendTestSuite)) tt.Run("success", func(t *testing.T) {
t.Run("single", appendTestSingle)
t.Run("two", appendTestTwoEntries)
t.Run("new_line", appendTestAddNewLine)
t.Run("no-new-line", appendTestDontAddNewLine)
t.Run("dot-folder", appendTestDotFolder)
t.Run("no-dot-folder", appendTestDotFolderNo)
t.Run("no-ext", appendTestNoExt)
})
tt.Run("failure", func(t *testing.T) {
t.Run("badEntry", appendTestBadEntry)
t.Run("load-err", appendTestConfLoadErr)
t.Run("mkdir-err", appendTestMkdirErr)
t.Run("append-log-err", appendTestOpenErr)
})
} }
type AppendTestSuite struct { func setupAppendTest(t *testing.T) string {
suite.Suite t.Helper()
dir string dir := t.ArtifactDir()
} config.Overrides["input.path"] = dir
func (s *AppendTestSuite) SetupSuite() {
s.dir, _ = os.MkdirTemp("", "append-test")
config.Overrides["input.path"] = s.dir
config.Overrides["input.ext"] = "log" config.Overrides["input.ext"] = "log"
} t.Cleanup(func() {
func (s *AppendTestSuite) TearDownSuite() {
os.RemoveAll(s.dir)
delete(config.Overrides, "input.path") delete(config.Overrides, "input.path")
delete(config.Overrides, "input.ext") delete(config.Overrides, "input.ext")
})
return dir
} }
func (s *AppendTestSuite) TestSuccess() { func appendTestSingle(t *testing.T) {
defer os.Remove(s.dir + "/test.log") dir := setupAppendTest(t)
when := time.Now().Local() when := time.Now().Local()
e := models.Entry{ e := models.Entry{
Title: "Jimmy", Title: "Jimmy",
@ -48,18 +58,18 @@ func (s *AppendTestSuite) TestSuccess() {
Entries: []models.Entry{e}, Entries: []models.Entry{e},
} }
err := Append(l) err := Append(l)
s.Require().NoError(err) require.NoError(t, err)
s.Require().FileExists(s.dir + "/test.log") require.FileExists(t, dir+"/test.log")
by, err := os.ReadFile(s.dir + "/test.log") by, err := os.ReadFile(dir + "/test.log")
st := string(by) st := string(by)
s.Require().NoError(err) require.NoError(t, err)
s.Assert().Contains(st, "Jimmy\n") assert.Contains(t, st, "Jimmy\n")
s.Assert().Contains(st, "\n@foo 42") assert.Contains(t, st, "\n@foo 42")
s.Assert().Contains(st, "\n@bar true") assert.Contains(t, st, "\n@bar true")
} }
func (s *AppendTestSuite) TestTwoEntries() { func appendTestTwoEntries(t *testing.T) {
defer os.Remove(s.dir + "/test.log") dir := setupAppendTest(t)
when := time.Now().Local() when := time.Now().Local()
whens := when.Format(models.DateFormat) whens := when.Format(models.DateFormat)
e := []models.Entry{ e := []models.Entry{
@ -71,17 +81,17 @@ func (s *AppendTestSuite) TestTwoEntries() {
Entries: e, Entries: e,
} }
err := Append(l) err := Append(l)
s.Assert().NoError(err) assert.NoError(t, err)
s.Require().FileExists(s.dir + "/test.log") require.FileExists(t, dir+"/test.log")
by, _ := os.ReadFile(s.dir + "/test.log") by, _ := os.ReadFile(dir + "/test.log")
st := string(by) st := string(by)
s.Assert().Contains(st, fmt.Sprintf("@begin %s - one", whens)) assert.Contains(t, st, fmt.Sprintf("@begin %s - one", whens))
s.Assert().Contains(st, fmt.Sprintf("@begin %s - two", whens)) assert.Contains(t, st, fmt.Sprintf("@begin %s - two", whens))
} }
func (s *AppendTestSuite) TestAddNewLine() { func appendTestAddNewLine(t *testing.T) {
defer os.Remove(s.dir + "/test.log") dir := setupAppendTest(t)
os.WriteFile(s.dir+"/test.log", []byte("foo"), 0644) os.WriteFile(dir+"/test.log", []byte("foo"), 0644)
when := time.Now().Local() when := time.Now().Local()
whens := when.Format(models.DateFormat) whens := when.Format(models.DateFormat)
e := []models.Entry{ e := []models.Entry{
@ -92,16 +102,16 @@ func (s *AppendTestSuite) TestAddNewLine() {
Entries: e, Entries: e,
} }
err := Append(l) err := Append(l)
s.Assert().NoError(err) assert.NoError(t, err)
s.Require().FileExists(s.dir + "/test.log") require.FileExists(t, dir+"/test.log")
by, _ := os.ReadFile(s.dir + "/test.log") by, _ := os.ReadFile(dir + "/test.log")
exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens) exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens)
s.Assert().Equal(exp, string(by)) assert.Equal(t, exp, string(by))
} }
func (s *AppendTestSuite) TestDontAddNewLine() { func appendTestDontAddNewLine(t *testing.T) {
defer os.Remove(s.dir + "/test.log") dir := setupAppendTest(t)
os.WriteFile(s.dir+"/test.log", []byte("foo\n"), 0644) os.WriteFile(dir+"/test.log", []byte("foo\n"), 0644)
when := time.Now().Local() when := time.Now().Local()
whens := when.Format(models.DateFormat) whens := when.Format(models.DateFormat)
e := []models.Entry{ e := []models.Entry{
@ -112,15 +122,15 @@ func (s *AppendTestSuite) TestDontAddNewLine() {
Entries: e, Entries: e,
} }
err := Append(l) err := Append(l)
s.Assert().NoError(err) assert.NoError(t, err)
s.Require().FileExists(s.dir + "/test.log") require.FileExists(t, dir+"/test.log")
by, _ := os.ReadFile(s.dir + "/test.log") by, _ := os.ReadFile(dir + "/test.log")
exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens) exp := fmt.Sprintf("foo\n@begin %s - one\n@id jimmy @end\n", whens)
s.Assert().Equal(exp, string(by)) assert.Equal(t, exp, string(by))
} }
func (s *AppendTestSuite) TestFailEntry() { func appendTestBadEntry(t *testing.T) {
defer os.Remove(s.dir + "/test.log") dir := setupAppendTest(t)
e := models.Entry{ e := models.Entry{
Title: "Jimmy", Title: "Jimmy",
} }
@ -129,14 +139,19 @@ func (s *AppendTestSuite) TestFailEntry() {
Entries: []models.Entry{e}, Entries: []models.Entry{e},
} }
err := Append(l) err := Append(l)
s.Assert().NoError(err) assert.NoError(t, err)
s.Require().FileExists(s.dir + "/test.log") require.FileExists(t, dir+"/test.log")
by, _ := os.ReadFile(s.dir + "/test.log") by, _ := os.ReadFile(dir + "/test.log")
s.Assert().Equal([]byte{}, by) assert.Equal(t, []byte{}, by)
} }
func (s *AppendTestSuite) TestDotFolder() { func appendTestDotFolder(t *testing.T) {
config.Overrides["input.dotFolder"] = "true" config.Overrides["input.dotFolder"] = "true"
t.Cleanup(func() {
delete(config.Overrides, "input.dotFolder")
})
dir := setupAppendTest(t)
e := models.Entry{ e := models.Entry{
Title: "something", Title: "something",
Date: time.Now(), Date: time.Now(),
@ -146,16 +161,21 @@ func (s *AppendTestSuite) TestDotFolder() {
Entries: []models.Entry{e}, Entries: []models.Entry{e},
} }
err := Append(l) err := Append(l)
s.Require().NoError(err) require.NoError(t, err)
s.Require().FileExists(s.dir + "/sub/test.log") require.FileExists(t, dir+"/sub/test.log")
by, err := os.ReadFile(s.dir + "/sub/test.log") by, err := os.ReadFile(dir + "/sub/test.log")
st := string(by) st := string(by)
s.Require().NoError(err) require.NoError(t, err)
s.Assert().Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title)) assert.Contains(t, st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))
} }
func (s *AppendTestSuite) TestDotFolderNo() { func appendTestDotFolderNo(t *testing.T) {
config.Overrides["input.dotFolder"] = "false" config.Overrides["input.dotFolder"] = "false"
t.Cleanup(func() {
delete(config.Overrides, "input.dotFolder")
})
dir := setupAppendTest(t)
e := models.Entry{ e := models.Entry{
Title: "another", Title: "another",
Date: time.Now(), Date: time.Now(),
@ -165,19 +185,21 @@ func (s *AppendTestSuite) TestDotFolderNo() {
Entries: []models.Entry{e}, Entries: []models.Entry{e},
} }
err := Append(l) err := Append(l)
s.Require().NoError(err) require.NoError(t, err)
s.Require().FileExists(s.dir + "/sub.test.log") require.FileExists(t, dir+"/sub.test.log")
by, err := os.ReadFile(s.dir + "/sub.test.log") by, err := os.ReadFile(dir + "/sub.test.log")
st := string(by) st := string(by)
s.Require().NoError(err) require.NoError(t, err)
s.Assert().Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title)) assert.Contains(t, st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))
} }
func (s *AppendTestSuite) TestNoExt() { func appendTestNoExt(t *testing.T) {
dir := setupAppendTest(t)
config.Overrides["input.ext"] = "" config.Overrides["input.ext"] = ""
defer func() { t.Cleanup(func() {
config.Overrides["input.ext"] = "log" config.Overrides["input.ext"] = "log"
}() })
e := models.Entry{ e := models.Entry{
Title: "baz", Title: "baz",
Date: time.Now(), Date: time.Now(),
@ -187,48 +209,49 @@ func (s *AppendTestSuite) TestNoExt() {
Entries: []models.Entry{e}, Entries: []models.Entry{e},
} }
err := Append(l) err := Append(l)
s.Require().NoError(err) require.NoError(t, err)
s.Require().FileExists(s.dir + "/foobar") require.FileExists(t, dir+"/foobar")
by, err := os.ReadFile(s.dir + "/foobar") by, err := os.ReadFile(dir + "/foobar")
st := string(by) st := string(by)
s.Require().NoError(err) require.NoError(t, err)
s.Assert().Contains(st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title)) assert.Contains(t, st, fmt.Sprintf("@begin %s - %s", e.Date.Format(models.DateFormat), e.Title))
} }
func (s *AppendTestSuite) TestConfLoadErr() { func appendTestConfLoadErr(t *testing.T) {
dir := t.ArtifactDir()
currConf := config.ConfigPath currConf := config.ConfigPath
tmp, _ := os.CreateTemp("", "app-conf-*.toml") tmp, _ := os.CreateTemp(dir, "app-conf-*.toml")
fname := tmp.Name() fname := tmp.Name()
defer tmp.Close() t.Cleanup(func() { tmp.Close() })
defer os.Remove(fname) t.Cleanup(func() { os.Remove(fname) })
fmt.Fprintln(tmp, `{"not":"toml"}`) fmt.Fprintln(tmp, `{"not":"toml"}`)
config.ConfigPath = fname config.ConfigPath = fname
defer func(path string) { t.Cleanup(func() { config.ConfigPath = currConf })
config.ConfigPath = path
}(currConf)
err := Append(models.Log{}) err := Append(models.Log{})
s.Assert().ErrorContains(err, "toml") assert.ErrorContains(t, err, "toml")
} }
func (s *AppendTestSuite) TestMkdirErr() { func appendTestMkdirErr(t *testing.T) {
// Don't run this test as root // Don't run this test as root
config.Overrides["input.path"] = "/var/my-logs-test" config.Overrides["input.path"] = "/var/my-logs-test"
defer func(path string) { t.Cleanup(func() { delete(config.Overrides, "input.path") })
config.Overrides["input.path"] = path
}(s.dir)
err := Append(models.Log{}) err := Append(models.Log{})
s.Assert().ErrorContains(err, "permission denied") assert.ErrorContains(t, err, "permission denied")
} }
func (s *AppendTestSuite) TestOpenErr() { func appendTestOpenErr(t *testing.T) {
dir := setupAppendTest(t)
l := models.Log{ l := models.Log{
Name: "test-open-err", Name: "test-open-err",
} }
fname := s.dir + "/test-open-err.log" fname := dir + "/test-open-err.log"
os.MkdirAll(s.dir, 0750) os.MkdirAll(dir, 0750)
f, _ := os.Create(fname) f, _ := os.Create(fname)
f.Close() f.Close()
os.Chmod(fname, 0400) // read only os.Chmod(fname, 0400)
err := Append(l) err := Append(l)
s.Assert().ErrorContains(err, "permission denied") assert.ErrorContains(t, err, "permission denied")
} }

2
go.mod
View file

@ -1,6 +1,6 @@
module codeberg.org/danjones000/my-log module codeberg.org/danjones000/my-log
go 1.21.5 go 1.26.0
require ( require (
github.com/BurntSushi/toml v1.3.2 github.com/BurntSushi/toml v1.3.2