feat(capability): 转码能力包(vendor 纯 Go AMR-NB 解码器 + 黄金向量逐样本对照 + 8 哨兵 + 注册面)
This commit is contained in:
1 parent
89715d1813
commit
4a2d276881
100 files changed
+11319
No files matched your search
@@ -0,0 +1,67 @@
|
||||
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")
|
||||
Reference in new issue
Block a user