Files
errorx/error_test.go
T
2026-07-22 00:05:37 +08:00

161 lines
3.8 KiB
Go

package errorx_test
import (
"context"
"testing"
"github.com/yuninks/errorx"
"github.com/yuninks/langx"
)
func init() {
langx.InitLangx(
langx.SetDefaultCode(0),
langx.SetDefaultLanguage("zh"),
)
langx.RegisterCode(map[string]int{
"login_success": 200,
"error": 400,
"username": 201,
"password": 202,
})
langx.RegisterTrans("zh", map[string]string{
"login_success": "登录成功",
"error": "错误",
"username": "你好 #name#",
"password": "密码错误: #reason#",
})
langx.RegisterTrans("en", map[string]string{
"login_success": "Login success",
"error": "Error",
"username": "Hello #name#",
"password": "Password error: #reason#",
})
}
func TestNewError_Basic(t *testing.T) {
ctx := context.Background()
err := errorx.NewError(ctx, "error")
t.Log(err.Error()) // 输出:错误
if code := err.Code(); code != 400 {
t.Fatalf("expected code 400, got %d", code)
}
}
func TestNewErrorf_Placeholder(t *testing.T) {
ctx := context.Background()
err := errorx.NewErrorf(ctx, "username", map[string]string{
"name": "yuninks",
})
t.Log(err.Error()) // 输出:你好 yuninks
// 不可变:WithLang 返回新实例,原实例不变
errEn := err.WithLang("en")
t.Log(err.Error()) // 仍然是中文
t.Log(errEn.Error()) // 输出:Hello yuninks
}
func TestErrorCode_Predefined(t *testing.T) {
ctx := context.Background()
// 使用预定义 ErrorCode 创建运行时错误
err := errorx.Error.New(ctx)
t.Log(err.Error()) // 输出:操作失败
if code := err.Code(); code != 400 {
t.Fatalf("expected code 400, got %d", code)
}
}
func TestErrorCode_Newf(t *testing.T) {
ctx := context.Background()
err := errorx.ErrWithMsg.Newf(ctx, map[string]string{"msg": "参数校验失败"})
t.Log(err.Error()) // 输出:操作失败: 参数校验失败
}
func TestErrorCode_Msg(t *testing.T) {
ctx := context.Background()
msg := errorx.Success.Msg(ctx)
t.Log(msg) // 输出:操作成功
if msg != "操作成功" {
t.Fatalf("expected '操作成功', got '%s'", msg)
}
// 验证中文环境
if code := errorx.Success.Code(); code != 200 {
t.Fatalf("expected code 200, got %d", code)
}
}
func TestHelper_As(t *testing.T) {
ctx := context.Background()
err := errorx.NewError(ctx, "username")
e, ok := errorx.As(err)
if !ok {
t.Fatal("expected errorx.As to succeed")
}
t.Log(e.Key()) // username
t.Log(e.Code()) // 201
}
func TestHelper_CodeFrom(t *testing.T) {
ctx := context.Background()
err := errorx.NewError(ctx, "error")
if code := errorx.CodeFrom(err); code != 400 {
t.Fatalf("expected 400, got %d", code)
}
// 非 langError 返回 -1
if code := errorx.CodeFrom(context.Canceled); code != -1 {
t.Fatalf("expected -1 for non-langError, got %d", code)
}
}
func TestHelper_KeyFrom(t *testing.T) {
err := errorx.NewError(context.Background(), "login_success")
if key := errorx.KeyFrom(err); key != "login_success" {
t.Fatalf("expected 'login_success', got '%s'", key)
}
}
func TestImmutability_CreateChain(t *testing.T) {
// 演示不可变链式调用
ctx := context.Background()
base := errorx.Error.New(ctx)
zh := base.WithKV("msg", "中文错误")
en := zh.WithLang("en").WithKV("msg", "English error")
t.Log(base.Error()) // 操作失败
t.Log(zh.Error()) // 操作失败: 中文错误
t.Log(en.Error()) // 操作失败: English error
// 各自独立,互不影响
zh2 := zh.WithKV("extra", "additional")
t.Log(zh.Error()) // 仍然只有 msg
t.Log(zh2.Error()) // msg + extra 都有了
}
func TestConcurrency_Safety(t *testing.T) {
// 多个 goroutine 共享同一个 ErrorCode,各自派生独立实例
ctx := context.Background()
done := make(chan bool, 10)
for range 10 {
go func() {
_ = errorx.Error.New(ctx).WithKV("msg", "go routine")
done <- true
}()
}
for range 10 {
<-done
}
// 无竞态即为通过
}