更新
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
package loggerx_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/yuninks/loggerx"
|
||||
)
|
||||
|
||||
func readOne(t *testing.T, dir, file string) string {
|
||||
t.Helper()
|
||||
files, _ := filepath.Glob(filepath.Join(dir, "*_"+file))
|
||||
if len(files) == 0 {
|
||||
files, _ = filepath.Glob(filepath.Join(dir, file))
|
||||
}
|
||||
if len(files) == 0 {
|
||||
t.Fatalf("没找到 %s", file)
|
||||
}
|
||||
b, err := os.ReadFile(files[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// 默认(不调用 SetFormat)必须是合法 JSON —— 与 readme 的承诺一致
|
||||
func TestDefaultFormatIsJSON(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(), loggerx.SetDir(dir))
|
||||
l.Info(context.Background(), "hello")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
line := strings.TrimSpace(readOne(t, dir, "info.log"))
|
||||
var v map[string]any
|
||||
if err := json.Unmarshal([]byte(line), &v); err != nil {
|
||||
t.Fatalf("默认格式不是合法 JSON: %v\n%s", err, line)
|
||||
}
|
||||
if v["level"] != "info" {
|
||||
t.Errorf("level=%v", v["level"])
|
||||
}
|
||||
}
|
||||
|
||||
// SetFormat(FormatText) 之后输出单行文本,且仍是一行一条
|
||||
func TestTextFormat(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetFormat(loggerx.FormatText),
|
||||
)
|
||||
ctx := context.Background()
|
||||
l.Info(ctx, "hello text")
|
||||
l.Errorf(ctx, "boom %d", 42)
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
info := strings.TrimSpace(readOne(t, dir, "info.log"))
|
||||
if info == "" {
|
||||
t.Fatal("text 格式没有输出")
|
||||
}
|
||||
for _, want := range []string{"level=info", "time=", "file=", "content="} {
|
||||
if !strings.Contains(info, want) {
|
||||
t.Errorf("text 输出缺少 %q: %s", want, info)
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(info, "{") {
|
||||
t.Errorf("SetFormat(text) 之后不应还是 JSON: %s", info)
|
||||
}
|
||||
if strings.Count(info, "\n") != 0 {
|
||||
t.Errorf("一条日志必须占一行: %q", info)
|
||||
}
|
||||
|
||||
errLine := strings.TrimSpace(readOne(t, dir, "error.log"))
|
||||
if !strings.Contains(errLine, "level=error") || !strings.Contains(errLine, "42") {
|
||||
t.Errorf("error 的 text 输出不正确: %s", errLine)
|
||||
}
|
||||
}
|
||||
|
||||
// 内容里有空格/引号时,text 格式用引号包起来,避免歧义
|
||||
func TestTextFormatQuotesAmbiguousValues(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetFormat(loggerx.FormatText),
|
||||
)
|
||||
l.Info(context.Background(), "has space and \"quote\"")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := strings.TrimSpace(readOne(t, dir, "info.log"))
|
||||
if !strings.Contains(line, `content="`) {
|
||||
t.Errorf("含空格/引号的值应当被引号包裹: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
// SetFormat 传非法值时应保持默认,而不是切到一个没实现的格式
|
||||
func TestInvalidFormatKeepsDefault(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetFormat(loggerx.Format("yaml")),
|
||||
)
|
||||
l.Info(context.Background(), "still-json")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := strings.TrimSpace(readOne(t, dir, "info.log"))
|
||||
var v map[string]any
|
||||
if err := json.Unmarshal([]byte(line), &v); err != nil {
|
||||
t.Errorf("非法格式值不该改变默认行为: %v\n%s", err, line)
|
||||
}
|
||||
}
|
||||
|
||||
// SetPrefix 必须真的加上前缀(两种格式都生效)
|
||||
func TestPrefixApplied(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetPrefix("[order-svc] "),
|
||||
)
|
||||
l.Info(context.Background(), "with-prefix")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := readOne(t, dir, "info.log")
|
||||
if !strings.HasPrefix(line, "[order-svc] ") {
|
||||
t.Errorf("前缀未生效: %q", line)
|
||||
}
|
||||
// 前缀之后仍然要是合法 JSON
|
||||
body := strings.TrimSpace(strings.TrimPrefix(line, "[order-svc] "))
|
||||
var v map[string]any
|
||||
if err := json.Unmarshal([]byte(body), &v); err != nil {
|
||||
t.Errorf("前缀后的内容不是合法 JSON: %v\n%s", err, body)
|
||||
}
|
||||
}
|
||||
|
||||
// text 格式 + 前缀 + expandData 组合
|
||||
func TestTextFormatWithPrefixAndExpand(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetFormat(loggerx.FormatText),
|
||||
loggerx.SetPrefix("P|"),
|
||||
loggerx.SetExpandData("app", "order"),
|
||||
)
|
||||
l.Info(context.Background(), "combo")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
line := strings.TrimSpace(readOne(t, dir, "info.log"))
|
||||
if !strings.HasPrefix(line, "P|level=info") {
|
||||
t.Errorf("前缀/格式组合输出不正确: %s", line)
|
||||
}
|
||||
if !strings.Contains(line, "app=order") {
|
||||
t.Errorf("expandData 未出现在 text 输出里: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
// text 格式下不可序列化的内容也不能丢
|
||||
func TestTextFormatUnmarshalableContent(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
l := loggerx.NewLogger(context.Background(),
|
||||
loggerx.SetDir(dir),
|
||||
loggerx.SetFormat(loggerx.FormatText),
|
||||
)
|
||||
l.Info(context.Background(), make(chan int), func() {})
|
||||
l.Info(context.Background(), "after")
|
||||
if err := l.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content := readOne(t, dir, "info.log")
|
||||
lines := strings.Split(strings.TrimSpace(content), "\n")
|
||||
if len(lines) != 2 {
|
||||
t.Fatalf("期望 2 行,实际 %d: %q", len(lines), content)
|
||||
}
|
||||
for i, line := range lines {
|
||||
if !strings.Contains(line, "content=") {
|
||||
t.Errorf("第 %d 行缺少 content: %s", i+1, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user