230 lines
4.8 KiB
Go
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")
|
|
}
|