fix(contract): enums 的 MODES 漂移守卫改按目录收集,抗前端类型拆分
TestModeTableMatchesFrontendModes 原先写死读 frontend/web/src/lib/types.ts;阶段 0 把该 文件拆成 barrel + lib/types/*.ts 后 MODES 住进了 types/chat.ts ⇒ 测试红。 改为读 barrel + 目录下全部 .ts(新增 frontendTypesDir 常量与 readFrontendTypes 辅助): 「MODES 住哪个文件」不再是本测试的耦合点,以后再搬也不用改它;barrel 缺失 (backend-only checkout)仍按 fs.ErrNotExist 跳过。 验证:go test ./internal/contract/enums/ 绿;全树 go test ./... = 58 包 ok / 0 FAIL; gofmt -l 干净。
This commit is contained in:
1 parent
6e0323b446
commit
89434e4f99
1 file changed
+38
-8
@@ -18,6 +18,7 @@ import (
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/contract/enums"
|
||||
@@ -128,23 +129,52 @@ func TestMoodTableMatchesEmotionBuiltins(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// frontendTypesDir 是前端共享类型的目录:barrel(lib/types.ts)+ 按域拆分的
|
||||
// lib/types/*.ts(阶段 0 的结构拆分,方案见 DevDocs/audit/_plan.md)。
|
||||
const frontendTypesDir = "../../../frontend/web/src/lib/types"
|
||||
|
||||
// readFrontendTypes 汇总 barrel 与目录下全部 .ts 的源码。按目录收集而不是写死单个文件,
|
||||
// 是为了让「MODES 数组住在哪个文件」不成为本测试的耦合点——以后再搬一次也不用改它。
|
||||
// barrel 缺失(backend-only checkout)时返回 fs.ErrNotExist,由调用方跳过。
|
||||
func readFrontendTypes() ([]byte, error) {
|
||||
paths := []string{frontendTypesDir + ".ts"}
|
||||
entries, err := os.ReadDir(frontendTypesDir)
|
||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
return nil, err
|
||||
}
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() && strings.HasSuffix(e.Name(), ".ts") {
|
||||
paths = append(paths, frontendTypesDir+"/"+e.Name())
|
||||
}
|
||||
}
|
||||
var all []byte
|
||||
for _, p := range paths {
|
||||
raw, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
all = append(all, raw...)
|
||||
all = append(all, '\n')
|
||||
}
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// TestModeTableMatchesFrontendModes asserts the mode table matches the frontend's
|
||||
// Mode union / MODES array (frontend/web/src/lib/types.ts), the only code-level
|
||||
// definition of the nine modes. This is the cross-language drift guard: adding a
|
||||
// mode on either side without the other fails here.
|
||||
// Mode union / MODES array, the only code-level definition of the nine modes. This
|
||||
// is the cross-language drift guard: adding a mode on either side without the other
|
||||
// fails here.
|
||||
func TestModeTableMatchesFrontendModes(t *testing.T) {
|
||||
t.Parallel()
|
||||
const typesPath = "../../../frontend/web/src/lib/types.ts"
|
||||
raw, err := os.ReadFile(typesPath)
|
||||
raw, err := readFrontendTypes()
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
t.Skipf("%s not present (backend-only checkout)", typesPath)
|
||||
t.Skipf("%s not present (backend-only checkout)", frontendTypesDir)
|
||||
}
|
||||
t.Fatalf("read %s: %v", typesPath, err)
|
||||
t.Fatalf("read frontend types: %v", err)
|
||||
}
|
||||
block := regexp.MustCompile(`(?s)export const MODES\s*:[^=]*=\s*\[(.*?)\]`).FindSubmatch(raw)
|
||||
if block == nil {
|
||||
t.Fatalf("MODES array not found in %s", typesPath)
|
||||
t.Fatalf("MODES array not found under %s", frontendTypesDir)
|
||||
}
|
||||
quoted := regexp.MustCompile(`"([^"]+)"`).FindAllStringSubmatch(string(block[1]), -1)
|
||||
frontend := make([]string, 0, len(quoted))
|
||||
|
||||
Reference in new issue
Block a user