package assets import ( "path/filepath" "testing" ) // 测试指向仓库根下的真实素材包(用户已放入 resourcepacks/)。 // go test 的工作目录为 internal/assets,因此向上两级。 var ( testPackDir = filepath.Join("..", "..", "resourcepacks") testEmbedded = filepath.Join("..", "..", "assets") ) // newTestManager 构造加载了真实素材包的资源管理器。 func newTestManager(t *testing.T) *Manager { t.Helper() m := New() if err := m.Load(testEmbedded, testPackDir); err != nil { t.Fatalf("加载内容包失败: %v", err) } return m } // TestDiscover 验证原生 pack.mcmeta 素材包被发现并解析元数据。 func TestDiscover(t *testing.T) { m := newTestManager(t) if len(m.Packs()) == 0 { t.Fatal("未发现任何内容包") } p := m.Packs()[0] if p.Type != PackResource { t.Fatalf("期望素材包类型,实际 %v", p.Type) } if p.Meta == nil || p.Meta.Pack.PackFormat != 34 { t.Fatalf("pack.mcmeta 解析异常: %+v", p.Meta) } } // TestResolveTexture 验证纹理解析命中素材包(原版命名空间)。 func TestResolveTexture(t *testing.T) { m := newTestManager(t) path, ok := m.ResolveTexture("block/stone") if !ok { t.Fatal("block/stone 未解析到纹理") } if !fileExists(path) { t.Fatalf("纹理路径不存在: %s", path) } } // TestExpandAtlas 验证图集源展开:blocks 含 block/stone,gui 递归子目录含 widget/button。 func TestExpandAtlas(t *testing.T) { m := newTestManager(t) blocks, err := m.ExpandAtlas("blocks") if err != nil { t.Fatalf("展开 blocks 图集失败: %v", err) } found := false for _, k := range blocks { if k == "block/stone" { found = true } } if !found { t.Fatalf("blocks 图集缺少 block/stone(共 %d 键)", len(blocks)) } gui, err := m.ExpandAtlas("gui") if err != nil { t.Fatalf("展开 gui 图集失败: %v", err) } for _, k := range gui { if k == "widget/button" { return // 命中即通过 } } t.Fatalf("gui 图集缺少 widget/button(共 %d 键)", len(gui)) } // TestLoadLang 验证语言表加载与缺键回退。 func TestLoadLang(t *testing.T) { m := newTestManager(t) lang, err := m.LoadLang("en_us") if err != nil { t.Fatalf("加载语言失败: %v", err) } if v := lang.Get("block.minecraft.stone"); v == "" || v == "block.minecraft.stone" { t.Fatalf("block.minecraft.stone 翻译缺失: %q", v) } // 缺键回退键名本身 if v := lang.Get("this.key.does.not.exist"); v != "this.key.does.not.exist" { t.Fatalf("缺键应回退键名,实际 %q", v) } } // TestLoadFont 验证字体 provider 展开与 ASCII 字形命中。 func TestLoadFont(t *testing.T) { m := newTestManager(t) f, err := m.LoadFont("default") if err != nil { t.Fatalf("加载字体失败: %v", err) } if len(f.Providers) == 0 { t.Fatal("字体 providers 为空") } if _, ok := f.Glyph('A'); !ok { t.Fatal("字体缺少 'A' 字形") } } // TestLoadModel 验证模型 parent 继承链展开与纹理变量解析。 func TestLoadModel(t *testing.T) { m := newTestManager(t) mod, err := m.LoadModel("block/stone") if err != nil { t.Fatalf("加载模型失败: %v", err) } if tex := mod.ResolvedTexture("all"); tex != "block/stone" { t.Fatalf("stone 模型纹理 all 期望 block/stone,实际 %q", tex) } if len(mod.Elements) == 0 { t.Fatal("stone 模型元素为空(parent 链未展开)") } } // TestLoadBlockState 验证方块状态解析与缺省变体。 func TestLoadBlockState(t *testing.T) { m := newTestManager(t) bs, err := m.LoadBlockState("stone") if err != nil { t.Fatalf("加载方块状态失败: %v", err) } if len(bs.VariantsOf(nil)) == 0 { t.Fatal("stone 默认变体为空") } }