68 lines
2.3 KiB
Go
68 lines
2.3 KiB
Go
package transcode
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestSentinelInventoryMatchesDesign 把 design/25 §2.4 的**八个**哨兵钉在测试里:
|
|
// 少一个、多一个、或者文案离开 `transcode: ` 前缀都会红。它是「清单型断言」——
|
|
// 与只测边界逻辑互补(design/25 §6.3 的同一手法)。
|
|
func TestSentinelInventoryMatchesDesign(t *testing.T) {
|
|
designSentinels := []struct {
|
|
name string
|
|
err error
|
|
}{
|
|
{"ErrUnsupportedFormat", ErrUnsupportedFormat},
|
|
{"ErrInputTooLarge", ErrInputTooLarge},
|
|
{"ErrOutputTooLarge", ErrOutputTooLarge},
|
|
{"ErrDecodeFailed", ErrDecodeFailed},
|
|
{"ErrEncodeFailed", ErrEncodeFailed},
|
|
{"ErrTimeout", ErrTimeout},
|
|
{"ErrBusy", ErrBusy},
|
|
{"ErrNoBackend", ErrNoBackend},
|
|
}
|
|
if len(designSentinels) != 8 {
|
|
t.Fatalf("design/25 §2.4 是八个哨兵,这里列了 %d 个", len(designSentinels))
|
|
}
|
|
const prefix = "transcode: "
|
|
for _, s := range designSentinels {
|
|
if s.err == nil {
|
|
t.Fatalf("%s is nil", s.name)
|
|
}
|
|
if !strings.HasPrefix(s.err.Error(), prefix) {
|
|
t.Errorf("%s = %q, want the %q prefix", s.name, s.err.Error(), prefix)
|
|
}
|
|
if !isSentinelError(s.err) {
|
|
t.Errorf("%s is missing from knownErrors", s.name)
|
|
}
|
|
}
|
|
// 两两不同(防止复制粘贴出的同一个值被当成两个哨兵)。
|
|
for i := range designSentinels {
|
|
for j := i + 1; j < len(designSentinels); j++ {
|
|
if errors.Is(designSentinels[i].err, designSentinels[j].err) {
|
|
t.Errorf("%s and %s are the same error", designSentinels[i].name, designSentinels[j].name)
|
|
}
|
|
}
|
|
}
|
|
// 包内自有的构造期/入参错误也必须可见(它们不是 §2.4 的八个)。
|
|
for _, s := range []error{ErrDuplicate, ErrInvalidCodec, ErrBadArgs} {
|
|
if !isSentinelError(s) {
|
|
t.Errorf("%q is missing from knownErrors", s)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestTimeoutErrorKeepsBothCauses 断言超时错误同时能被判为 ErrTimeout、也保留
|
|
// 原始 ctx 原因(%w 链):调用方既能走哨兵分支,也能看到「为什么」。
|
|
func TestTimeoutErrorKeepsBothCauses(t *testing.T) {
|
|
err := timeoutError(errTimeoutCause)
|
|
if !errors.Is(err, ErrTimeout) || !errors.Is(err, errTimeoutCause) {
|
|
t.Fatalf("err = %v, want both ErrTimeout and the cause", err)
|
|
}
|
|
}
|
|
|
|
// errTimeoutCause 是超时链里的原始原因桩。
|
|
var errTimeoutCause = errors.New("stub deadline")
|