Files
gochat/backend/pkg/logger/logger_test.go
T

230 lines
4.8 KiB
Go

package logger
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseLevel_AllLevels(t *testing.T) {
tests := []struct {
input string
expected string // string form for comparison
}{
{"debug", "debug"},
{"info", "info"},
{"warn", "warn"},
{"error", "error"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
level, err := parseLevel(tt.input)
assert.NoError(t, err)
assert.Equal(t, tt.expected, level.String())
})
}
}
func TestParseLevel_UnknownDefaultsToInfo(t *testing.T) {
level, err := parseLevel("nonexistent")
assert.NoError(t, err)
assert.Equal(t, "info", level.String())
}
func TestParseLevel_EmptyString(t *testing.T) {
level, err := parseLevel("")
assert.NoError(t, err)
assert.Equal(t, "info", level.String())
}
func TestGetOutput_Stdout(t *testing.T) {
f, err := getOutput("stdout")
assert.NoError(t, err)
assert.Equal(t, os.Stdout, f)
}
func TestGetOutput_Stderr(t *testing.T) {
f, err := getOutput("stderr")
assert.NoError(t, err)
assert.Equal(t, os.Stderr, f)
}
func TestGetOutput_File(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "test.log")
f, err := getOutput(path)
assert.NoError(t, err)
require.NotNil(t, f)
defer f.Close()
// File should have been created
_, statErr := os.Stat(path)
assert.NoError(t, statErr)
}
func TestGetOutput_InvalidPath(t *testing.T) {
// A path inside a nonexistent directory should fail
_, err := getOutput("/nonexistent/dir/that/does/not/exist/log.txt")
assert.Error(t, err)
}
func TestInit_JSONFormat(t *testing.T) {
cfg := Config{
Level: "info",
Format: "json",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
assert.NoError(t, err)
defer func() { globalLogger = nil }()
// globalLogger should be set
require.NotNil(t, globalLogger)
}
func TestInit_ConsoleFormat(t *testing.T) {
cfg := Config{
Level: "debug",
Format: "console",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
assert.NoError(t, err)
defer func() { globalLogger = nil }()
require.NotNil(t, globalLogger)
}
func TestInit_FileOutput(t *testing.T) {
dir := t.TempDir()
logPath := filepath.Join(dir, "app.log")
errPath := filepath.Join(dir, "err.log")
cfg := Config{
Level: "warn",
Format: "json",
Output: logPath,
ErrorOutput: errPath,
}
err := Init(cfg)
assert.NoError(t, err)
defer func() { globalLogger = nil }()
require.NotNil(t, globalLogger)
// Write a log and sync
L().Info("test message from file output")
Sync()
// The log file should exist
_, statErr := os.Stat(logPath)
assert.NoError(t, statErr)
}
func TestInit_InvalidLevel(t *testing.T) {
// parseLevel never returns an error, so Init should succeed even with an
// unknown level (defaults to info). This test verifies that behavior.
cfg := Config{
Level: "totally-invalid-level",
Format: "json",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
assert.NoError(t, err)
defer func() { globalLogger = nil }()
}
func TestInit_InvalidOutput(t *testing.T) {
cfg := Config{
Level: "info",
Format: "json",
Output: "/nonexistent/dir/that/does/not/exist/log.txt",
ErrorOutput: "stderr",
}
err := Init(cfg)
assert.Error(t, err)
}
func TestInit_InvalidErrorOutput(t *testing.T) {
cfg := Config{
Level: "info",
Format: "json",
Output: "stdout",
ErrorOutput: "/nonexistent/dir/that/does/not/exist/err.txt",
}
err := Init(cfg)
assert.Error(t, err)
}
func TestL_WithoutInit(t *testing.T) {
// Reset globalLogger to nil to test the fallback path
globalLogger = nil
l := L()
assert.NotNil(t, l)
// Should be a usable sugared logger
l.Info("fallback logger works")
}
func TestL_AfterInit(t *testing.T) {
cfg := Config{
Level: "info",
Format: "json",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
require.NoError(t, err)
defer func() { globalLogger = nil }()
l := L()
assert.NotNil(t, l)
}
func TestSync_WithLogger(t *testing.T) {
cfg := Config{
Level: "info",
Format: "json",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
require.NoError(t, err)
defer func() { globalLogger = nil }()
L().Info("message before sync")
Sync()
}
func TestSync_WithoutLogger(t *testing.T) {
globalLogger = nil
// Should not panic
Sync()
}
func TestL_LogsAtVariousLevels(t *testing.T) {
cfg := Config{
Level: "debug",
Format: "json",
Output: "stdout",
ErrorOutput: "stderr",
}
err := Init(cfg)
require.NoError(t, err)
defer func() { globalLogger = nil }()
l := L()
l.Debug("debug message")
l.Info("info message")
l.Warn("warn message")
l.Error("error message")
l.Infof("formatted %s", "info")
l.Errorf("formatted %s", "error")
}