package blockentity import ( "path/filepath" "testing" "mc/internal/item" ) // loadItemRegBE 加载物品注册表。 func loadItemRegBE(t *testing.T) *item.Registry { t.Helper() r, err := item.Load(filepath.Join("..", "..", "assets", "config", "items.json")) if err != nil { t.Fatalf("加载物品注册表失败: %v", err) } return r } // TestFurnaceSmelt 熔炉烧炼闭环(物品与背包.md §6):煤+铁矿石 → 铁锭。 func TestFurnaceSmelt(t *testing.T) { reg := loadItemRegBE(t) f := NewFurnace(0, 64, 0) // 放燃料与输入 if rem := f.Insert(SlotFuel, item.Stack{Name: "coal", Count: 1}, reg); !rem.Empty() { t.Fatal("燃料应放入") } if rem := f.Insert(SlotInput, item.Stack{Name: "iron_ore", Count: 2}, reg); !rem.Empty() { t.Fatal("输入应放入") } // 烧炼 2 炉 produced := 0 for i := 0; i < 2000; i++ { if _, ok := f.Tick(); ok { produced++ } } if produced != 2 { t.Fatalf("产出期望 2,实际 %d", produced) } if f.Slots[SlotInput].Count != 0 { t.Fatalf("输入应耗尽,剩余 %d", f.Slots[SlotInput].Count) } } // TestFurnaceFuelExhaust 燃料耗尽自动停炉。 func TestFurnaceFuelExhaust(t *testing.T) { reg := loadItemRegBE(t) f := NewFurnace(0, 64, 0) f.Insert(SlotFuel, item.Stack{Name: "coal", Count: 1}, reg) f.Insert(SlotInput, item.Stack{Name: "iron_ore", Count: 64}, reg) // 一块煤 1600 tick,最多产出 8 个(1600/200) produced := 0 for i := 0; i < 4000; i++ { if _, ok := f.Tick(); ok { produced++ } } if produced != 8 { t.Fatalf("产出期望 8(一块煤),实际 %d", produced) } } // TestChestStore 箱子存取(物品与背包.md §6 容器)。 func TestChestStore(t *testing.T) { reg := loadItemRegBE(t) c := NewChest(1, 64, 1) if rem := c.Insert(0, item.Stack{Name: "diamond", Count: 32}, reg); !rem.Empty() { t.Fatal("应全部放入") } if rem := c.Insert(0, item.Stack{Name: "diamond", Count: 32}, reg); !rem.Empty() { t.Fatal("应合并到 64") } got := c.Remove(0, 10) if got.Count != 10 || got.Name != "diamond" { t.Fatalf("取出异常: %+v", got) } if c.Slots[0].Count != 54 { t.Fatalf("剩余期望 54,实际 %d", c.Slots[0].Count) } } // TestFurnaceSlotRules 熔炉槽位规则(燃料槽只收燃料)。 func TestFurnaceSlotRules(t *testing.T) { reg := loadItemRegBE(t) f := NewFurnace(0, 64, 0) if f.CanInsert(SlotFuel, item.Stack{Name: "diamond", Count: 1}, reg) { t.Fatal("燃料槽不应接受钻石") } if !f.CanInsert(SlotFuel, item.Stack{Name: "coal", Count: 1}, reg) { t.Fatal("燃料槽应接受煤炭") } if !f.CanInsert(SlotFuel, item.Stack{Name: "oak_planks", Count: 1}, reg) { t.Fatal("燃料槽应接受木板") } if f.CanInsert(SlotOutput, item.Stack{Name: "iron_ingot", Count: 1}, reg) { t.Fatal("输出格不应放入") } } func TestSerializeRoundtrip(t *testing.T) { e := NewChest(1, 2, 3) e.Slots[0] = item.Stack{Name: "stick", Count: 7} got := Deserialize(e.Serialize()) if got.Kind != KindChest || got.Slots[0].Count != 7 { t.Fatalf("箱子快照往返失败: %+v", got) } }