Files
geniusrun/backend/internal/log/log_test.go
Christophe Vila 10cdc4176a refactor(log): split location into package/file/class/method, auto-derived
Per the log schema: 'package' is the Go package (absent on
Python-emitted lines), 'file' the Go/Python source basename, 'class' the
Go receiver or Python class (omitted when there is none -- free
functions no longer masquerade under a package-as-class), 'method' the
emitting function. applog.App() now takes no arguments and derives all
of it from runtime.Caller, so labels can never drift from the code; the
manual http/wrapper emitters and forwarded wrapper.py lines (file=
wrapper.py, no package) carry the same fields.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:59:48 +02:00

79 lines
2.2 KiB
Go

package applog
import (
"bytes"
"encoding/json"
"log/slog"
"strings"
"testing"
)
func TestNewLogger_FiltersBelowConfiguredLevel(t *testing.T) {
var buf bytes.Buffer
logger := NewLogger("warn", &buf)
logger.Info("should be dropped")
if buf.Len() != 0 {
t.Fatalf("expected no output for an Info message under a warn-level logger, got %q", buf.String())
}
logger.Warn("should appear")
if !strings.Contains(buf.String(), "should appear") {
t.Fatalf("expected the Warn message in output, got %q", buf.String())
}
}
func TestNewLogger_WritesValidJSON(t *testing.T) {
var buf bytes.Buffer
logger := NewLogger("info", &buf)
logger.Info("hello", "key", "value")
var decoded map[string]any
if err := json.Unmarshal(buf.Bytes(), &decoded); err != nil {
t.Fatalf("output is not valid JSON: %v (%q)", err, buf.String())
}
if decoded["msg"] != "hello" || decoded["key"] != "value" {
t.Errorf("decoded = %+v, want msg=hello key=value", decoded)
}
}
func TestNewLogger_OmitsEmptyMsg(t *testing.T) {
var buf bytes.Buffer
logger := NewLogger("info", &buf)
logger.Info("", "type", "http", "status", 200)
var decoded map[string]any
if err := json.Unmarshal(buf.Bytes(), &decoded); err != nil {
t.Fatalf("output not JSON: %v (%q)", err, buf.String())
}
if _, present := decoded["msg"]; present {
t.Errorf("empty msg should be omitted, got %+v", decoded)
}
if decoded["type"] != "http" {
t.Errorf("attrs lost alongside dropped msg: %+v", decoded)
}
}
func TestApp_TagsMandatoryFields(t *testing.T) {
var buf bytes.Buffer
prev := slog.Default()
slog.SetDefault(NewLogger("info", &buf))
defer slog.SetDefault(prev)
App().Info("did it", "extra", 1)
var decoded map[string]any
if err := json.Unmarshal(buf.Bytes(), &decoded); err != nil {
t.Fatalf("output not JSON: %v", err)
}
if decoded["type"] != "app" || decoded["package"] != "log" || decoded["file"] != "log_test.go" {
t.Errorf("fields = %+v, want type=app package=log (import-path element) file=log_test.go", decoded)
}
if decoded["method"] != "TestApp_TagsMandatoryFields" {
t.Errorf("method = %v, want the emitting function name", decoded["method"])
}
if _, hasClass := decoded["class"]; hasClass {
t.Errorf("class should be omitted for a free function, got %v", decoded["class"])
}
}