From 1863c403c28da848871ed0cf8474fdee3c9914e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 16:57:18 +0000 Subject: [PATCH 1/4] Add tests for logger fallback init helper functions Add direct unit tests for four package-private helpers in internal/logger/global_helpers.go that had no direct test coverage: - logFallbackWarnings: verify two WARNING lines are printed with the expected error message and fallback description - fallbackLoggerOnInitError: verify warnings are emitted and the fallback value is returned with nil error; covers pointer types - silentFallbackLoggerOnInitError: verify the fallback is returned with nil error and no log output is produced; covers nil pointers - strictLoggerOnInitError: verify the original error is propagated and the zero value is returned; covers pointer and scalar types All tests are table-driven or scenario-based, use captureStdLog for stderr capture, and follow the testify patterns established by the rest of the logger package. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- internal/logger/fallback_init_helpers_test.go | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 internal/logger/fallback_init_helpers_test.go diff --git a/internal/logger/fallback_init_helpers_test.go b/internal/logger/fallback_init_helpers_test.go new file mode 100644 index 00000000..4334f0a8 --- /dev/null +++ b/internal/logger/fallback_init_helpers_test.go @@ -0,0 +1,162 @@ +package logger + +import ( + "errors" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestLogFallbackWarnings verifies that logFallbackWarnings prints two WARNING +// lines to the standard log output: one with the error message and one with the +// fallback description. +func TestLogFallbackWarnings(t *testing.T) { + sentinel := errors.New("disk full") + + output := captureStdLog(t, func() { + logFallbackWarnings(sentinel, "Failed to open log file", "Falling back to stderr") + }) + + assert.Contains(t, output, "WARNING:") + assert.Contains(t, output, "Failed to open log file") + assert.Contains(t, output, "disk full") + assert.Contains(t, output, "Falling back to stderr") + + // Two WARNING lines must appear. + assert.Equal(t, 2, strings.Count(output, "WARNING:"), "expected exactly two WARNING lines") +} + +// TestLogFallbackWarnings_ErrorMessageInFirstLine verifies the ordering of lines: +// error message appears in the first WARNING line, fallback message in the second. +func TestLogFallbackWarnings_ErrorMessageInFirstLine(t *testing.T) { + sentinel := errors.New("connection refused") + + output := captureStdLog(t, func() { + logFallbackWarnings(sentinel, "Cannot reach endpoint", "Using local stub") + }) + + lines := strings.Split(strings.TrimSpace(output), "\n") + require.GreaterOrEqual(t, len(lines), 2, "expected at least two log lines") + + // The error string and errMsg belong to the first WARNING line. + assert.Contains(t, lines[0], "Cannot reach endpoint") + assert.Contains(t, lines[0], "connection refused") + + // The fallback description belongs to the second WARNING line. + assert.Contains(t, lines[1], "Using local stub") +} + +// TestFallbackLoggerOnInitError_ReturnsProvidedFallback verifies that the +// function returns the fallback value with no error, regardless of the wrapped +// error severity. +func TestFallbackLoggerOnInitError_ReturnsProvidedFallback(t *testing.T) { + fallback := "stub-logger" + sentinel := errors.New("init failed") + + var got string + var err error + _ = captureStdLog(t, func() { + got, err = fallbackLoggerOnInitError(sentinel, "Component init failed", "Using stub", fallback) + }) + + require.NoError(t, err, "fallbackLoggerOnInitError must swallow the original error") + assert.Equal(t, fallback, got, "must return the provided fallback value unchanged") +} + +// TestFallbackLoggerOnInitError_LogsWarnings verifies that the two WARNING +// lines are emitted to the standard logger when a fallback is used. +func TestFallbackLoggerOnInitError_LogsWarnings(t *testing.T) { + sentinel := errors.New("timeout") + + output := captureStdLog(t, func() { + _, _ = fallbackLoggerOnInitError(sentinel, "Connection timed out", "Retrying with default", 42) + }) + + assert.Contains(t, output, "Connection timed out") + assert.Contains(t, output, "timeout") + assert.Contains(t, output, "Retrying with default") +} + +// TestFallbackLoggerOnInitError_PointerType verifies the generic behaviour with +// a pointer fallback type, matching the real usage in file_logger.go. +func TestFallbackLoggerOnInitError_PointerType(t *testing.T) { + type myLogger struct{ name string } + fallback := &myLogger{name: "fallback"} + sentinel := errors.New("cannot open file") + + var got *myLogger + _ = captureStdLog(t, func() { + var err error + got, err = fallbackLoggerOnInitError(sentinel, "Open failed", "Using fallback logger", fallback) + require.NoError(t, err) + }) + + require.NotNil(t, got) + assert.Equal(t, "fallback", got.name) +} + +// TestSilentFallbackLoggerOnInitError_ReturnsProvidedFallback verifies that the +// function returns the fallback value and nil error without any log output. +func TestSilentFallbackLoggerOnInitError_ReturnsProvidedFallback(t *testing.T) { + fallback := "silent-stub" + + output := captureStdLog(t, func() { + got, err := silentFallbackLoggerOnInitError(fallback) + require.NoError(t, err, "silentFallbackLoggerOnInitError must return nil error") + assert.Equal(t, fallback, got, "must return the provided fallback value unchanged") + }) + + assert.Empty(t, output, "silentFallbackLoggerOnInitError must not emit any log output") +} + +// TestSilentFallbackLoggerOnInitError_NilPointer verifies behaviour with a nil +// pointer fallback, matching the real usage with *MarkdownLogger. +func TestSilentFallbackLoggerOnInitError_NilPointer(t *testing.T) { + type placeholder struct{} + var fallback *placeholder // nil pointer + + output := captureStdLog(t, func() { + got, err := silentFallbackLoggerOnInitError(fallback) + require.NoError(t, err) + assert.Nil(t, got) + }) + + assert.Empty(t, output, "must remain silent even for nil fallback") +} + +// TestStrictLoggerOnInitError_PropagatesError verifies that the original error +// is returned unchanged and the zero value is returned for the type parameter. +func TestStrictLoggerOnInitError_PropagatesError(t *testing.T) { + sentinel := errors.New("fatal init error") + + got, err := strictLoggerOnInitError[string](sentinel) + + require.Error(t, err) + assert.Equal(t, sentinel, err, "must return the original error unchanged") + assert.Equal(t, "", got, "must return the zero value for the type parameter") +} + +// TestStrictLoggerOnInitError_NilErrorStillReturnsZero verifies that passing a +// nil error still returns the zero value; callers should check errors before +// relying on the returned value. +func TestStrictLoggerOnInitError_NilErrorStillReturnsZero(t *testing.T) { + got, err := strictLoggerOnInitError[int](nil) + + assert.NoError(t, err) + assert.Equal(t, 0, got) +} + +// TestStrictLoggerOnInitError_PointerType verifies behaviour with a pointer +// type parameter, matching the real usage with *JSONLLogger. +func TestStrictLoggerOnInitError_PointerType(t *testing.T) { + type myLogger struct{} + sentinel := errors.New("jsonl init failed") + + got, err := strictLoggerOnInitError[*myLogger](sentinel) + + require.Error(t, err) + assert.Equal(t, sentinel, err) + assert.Nil(t, got, "zero value for a pointer type must be nil") +} From fa866725c2acea57af9813d19dda94f79ba587c6 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Sun, 26 Jul 2026 14:14:50 -0700 Subject: [PATCH 2/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/logger/fallback_init_helpers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/logger/fallback_init_helpers_test.go b/internal/logger/fallback_init_helpers_test.go index 4334f0a8..5b6a8efd 100644 --- a/internal/logger/fallback_init_helpers_test.go +++ b/internal/logger/fallback_init_helpers_test.go @@ -134,7 +134,7 @@ func TestStrictLoggerOnInitError_PropagatesError(t *testing.T) { got, err := strictLoggerOnInitError[string](sentinel) require.Error(t, err) - assert.Equal(t, sentinel, err, "must return the original error unchanged") +assert.Same(t, sentinel, err, "must return the original error unchanged") assert.Equal(t, "", got, "must return the zero value for the type parameter") } From 57a9e20b26ed2446632d3d227bbbffd8b6ffb832 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Sun, 26 Jul 2026 14:15:06 -0700 Subject: [PATCH 3/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/logger/fallback_init_helpers_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/logger/fallback_init_helpers_test.go b/internal/logger/fallback_init_helpers_test.go index 5b6a8efd..e76236f4 100644 --- a/internal/logger/fallback_init_helpers_test.go +++ b/internal/logger/fallback_init_helpers_test.go @@ -111,8 +111,8 @@ func TestSilentFallbackLoggerOnInitError_ReturnsProvidedFallback(t *testing.T) { assert.Empty(t, output, "silentFallbackLoggerOnInitError must not emit any log output") } -// TestSilentFallbackLoggerOnInitError_NilPointer verifies behaviour with a nil -// pointer fallback, matching the real usage with *MarkdownLogger. +// TestSilentFallbackLoggerOnInitError_NilPointer verifies that a nil pointer +// fallback remains nil without producing an error or log output. func TestSilentFallbackLoggerOnInitError_NilPointer(t *testing.T) { type placeholder struct{} var fallback *placeholder // nil pointer From 8e02e9ae061d4840193cceff648064a1c5d4d19f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Jul 2026 21:30:30 +0000 Subject: [PATCH 4/4] fix: correct indentation on assert.Same line in fallback_init_helpers_test.go --- internal/logger/fallback_init_helpers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/logger/fallback_init_helpers_test.go b/internal/logger/fallback_init_helpers_test.go index e76236f4..e317974d 100644 --- a/internal/logger/fallback_init_helpers_test.go +++ b/internal/logger/fallback_init_helpers_test.go @@ -134,7 +134,7 @@ func TestStrictLoggerOnInitError_PropagatesError(t *testing.T) { got, err := strictLoggerOnInitError[string](sentinel) require.Error(t, err) -assert.Same(t, sentinel, err, "must return the original error unchanged") + assert.Same(t, sentinel, err, "must return the original error unchanged") assert.Equal(t, "", got, "must return the zero value for the type parameter") }