Files
ngzz-mc/internal/block/registry_test.go
2026-09-19 14:21:08 +08:00

144 lines
4.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package block
import (
"path/filepath"
"testing"
)
// blocksPath 指向仓库 assets/config/blocks.json(测试运行目录为 internal/block)。
var blocksPath = filepath.Join("..", "..", "assets", "config", "blocks.json")
// TestLoad 验证注册表加载与 ID 解析。
func TestLoad(t *testing.T) {
r, err := Load(blocksPath)
if err != nil {
t.Fatalf("加载注册表失败: %v", err)
}
id, ok := r.ID("stone")
if !ok || id != 1 {
t.Fatalf("stone ID 期望 1,实际 %d (ok=%v)", id, ok)
}
if r.Name(1) != "stone" {
t.Fatalf("ID 1 名称期望 stone,实际 %q", r.Name(1))
}
}
// TestStates 验证状态打包/解包与判定表(单一来源)。
func TestStates(t *testing.T) {
r, err := Load(blocksPath)
if err != nil {
t.Fatalf("加载注册表失败: %v", err)
}
torch, _ := r.ID("torch")
water, _ := r.ID("water")
stone, _ := r.ID("stone")
s := NewState(torch, 3)
if s.ID() != torch || s.Meta() != 3 {
t.Fatalf("状态打包/解包异常: %+v", s)
}
if r.Light(s) != 14 {
t.Fatalf("火把亮度期望 14,实际 %d", r.Light(s))
}
if r.IsOpaque(s) {
t.Fatal("火把不应完全遮光")
}
if !r.IsOpaque(NewState(stone, 0)) {
t.Fatal("石头应完全遮光")
}
if r.IsSolid(NewState(water, 0)) {
t.Fatal("水不应为实体碰撞方块")
}
if !r.IsFluid(NewState(water, 0)) {
t.Fatal("水应为液体")
}
if Air.ID() != 0 {
t.Fatalf("空气 ID 期望 0")
}
}
// TestTexture 验证纹理键解析(all 面回退)。
func TestTexture(t *testing.T) {
r, err := Load(blocksPath)
if err != nil {
t.Fatalf("加载注册表失败: %v", err)
}
grass, _ := r.ID("grass_block")
if tex := r.Texture(NewState(grass, 0), "up"); tex != "block/grass_block_top" {
t.Fatalf("草方块顶面纹理期望 block/grass_block_top,实际 %q", tex)
}
if tex := r.Texture(NewState(grass, 0), "down"); tex != "block/dirt" {
t.Fatalf("草方块底面纹理期望 block/dirt,实际 %q", tex)
}
}
func TestTintTextureKeysSkipDirt(t *testing.T) {
r, err := Load(blocksPath)
if err != nil {
t.Fatalf("加载注册表失败: %v", err)
}
tinted := r.TintTextureKeys()
for _, keys := range tinted {
for _, k := range keys {
if k == "block/dirt" || k == "block/grass_block_side" {
t.Fatalf("不应染色共享/侧面纹理 %s,实际表=%v", k, tinted)
}
}
}
grass := tinted["grass"]
found := false
for _, k := range grass {
if k == "block/grass_block_top" {
found = true
}
}
if !found {
t.Fatalf("草顶应染色,实际 %v", grass)
}
}
func TestRollDropsVanilla(t *testing.T) {
r, err := Load(blocksPath)
if err != nil {
t.Fatalf("加载注册表失败: %v", err)
}
stone := r.Get(mustID(t, r, "stone"))
if got := stone.RollDrops("", 0, func() float64 { return 0 }); len(got) != 0 {
t.Fatalf("空手挖石头应无掉落,实际 %+v", got)
}
if got := stone.RollDrops("pickaxe", 1, func() float64 { return 0 }); len(got) != 1 || got[0].Item != "cobblestone" {
t.Fatalf("镐挖石头应掉圆石,实际 %+v", got)
}
grass := r.Get(mustID(t, r, "grass_block"))
if got := grass.RollDrops("", 0, func() float64 { return 0 }); len(got) != 1 || got[0].Item != "dirt" {
t.Fatalf("草应掉泥土,实际 %+v", got)
}
iron := r.Get(mustID(t, r, "iron_ore"))
if got := iron.RollDrops("pickaxe", 1, func() float64 { return 0 }); len(got) != 0 {
t.Fatalf("木镐挖铁矿应无掉落,实际 %+v", got)
}
if got := iron.RollDrops("pickaxe", 2, func() float64 { return 0 }); len(got) != 1 || got[0].Item != "raw_iron" {
t.Fatalf("石镐挖铁矿应掉粗铁,实际 %+v", got)
}
glass := r.Get(mustID(t, r, "glass"))
if got := glass.RollDrops("pickaxe", 4, func() float64 { return 0 }); len(got) != 0 {
t.Fatalf("玻璃不应掉落,实际 %+v", got)
}
gravel := r.Get(mustID(t, r, "gravel"))
if got := gravel.RollDrops("", 0, func() float64 { return 0.05 }); len(got) != 1 || got[0].Item != "flint" {
t.Fatalf("沙砾低随机应掉燧石,实际 %+v", got)
}
if got := gravel.RollDrops("", 0, func() float64 { return 0.5 }); len(got) != 1 || got[0].Item != "gravel" {
t.Fatalf("沙砾高随机应掉沙砾,实际 %+v", got)
}
}
func mustID(t *testing.T, r *Registry, name string) uint16 {
t.Helper()
id, ok := r.ID(name)
if !ok {
t.Fatalf("方块 %s 未注册", name)
}
return id
}