156 lines
4.2 KiB
Go
156 lines
4.2 KiB
Go
package inventory
|
||
|
||
import (
|
||
"path/filepath"
|
||
"testing"
|
||
|
||
"mc/internal/item"
|
||
)
|
||
|
||
// loadItemReg 加载物品注册表。
|
||
func loadItemReg(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
|
||
}
|
||
|
||
// TestMerge 验证合并规则(物品与背包.md §3 规则表)。
|
||
func TestMerge(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
|
||
// 放入 30 个木板 → 合并到 34 个
|
||
rem := inv.Add(item.Stack{Name: "oak_planks", Count: 30})
|
||
if !rem.Empty() {
|
||
t.Fatal("30 个木板应全部放入")
|
||
}
|
||
rem = inv.Add(item.Stack{Name: "oak_planks", Count: 34})
|
||
if !rem.Empty() {
|
||
t.Fatal("34 个木板应合并入同一槽")
|
||
}
|
||
// 64 上限:再放 10 应进入新槽(槽 0 已满 64)
|
||
rem = inv.Add(item.Stack{Name: "oak_planks", Count: 10})
|
||
if !rem.Empty() {
|
||
t.Fatalf("剩余期望空,实际 %d", rem.Count)
|
||
}
|
||
if inv.Slots[1].Name != "oak_planks" || inv.Slots[1].Count != 10 {
|
||
t.Fatalf("槽 1 期望 10 个木板,实际 %+v", inv.Slots[1])
|
||
}
|
||
}
|
||
|
||
// TestRemove 验证取出物品。
|
||
func TestRemove(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
inv.Add(item.Stack{Name: "stick", Count: 16})
|
||
if !inv.Remove("stick", 5) {
|
||
t.Fatal("应能取出 5 个")
|
||
}
|
||
if inv.Remove("stick", 20) {
|
||
t.Fatal("不足 20 个不应成功")
|
||
}
|
||
if !inv.Remove("stick", 11) {
|
||
t.Fatal("应能取出剩余 11 个")
|
||
}
|
||
}
|
||
|
||
// TestSelected 验证选中槽。
|
||
func TestSelected(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
inv.Slots[3] = item.Stack{Name: "torch", Count: 8}
|
||
inv.Selected = 3
|
||
if s := inv.SelectedStack(); s.Name != "torch" || s.Count != 8 {
|
||
t.Fatalf("选中槽异常: %+v", s)
|
||
}
|
||
}
|
||
|
||
func TestCanPlaceArmor(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
planks := item.Stack{Name: "oak_planks", Count: 1}
|
||
helm := item.Stack{Name: "iron_helmet", Count: 1}
|
||
if CanPlace(reg, SlotHelmet, planks) {
|
||
t.Fatal("盔甲槽应拒收木板")
|
||
}
|
||
if !CanPlace(reg, SlotHelmet, helm) {
|
||
t.Fatal("头盔槽应接收铁头盔")
|
||
}
|
||
if CanPlace(reg, SlotChest, helm) {
|
||
t.Fatal("胸甲槽应拒收头盔")
|
||
}
|
||
if !CanPlace(reg, SlotOffhand, item.Stack{Name: "shield", Count: 1}) {
|
||
t.Fatal("副手应接收盾")
|
||
}
|
||
if CanPlace(reg, SlotOffhand, planks) {
|
||
t.Fatal("副手应拒收木板")
|
||
}
|
||
}
|
||
|
||
func TestClickRightHalf(t *testing.T) {
|
||
slot := item.Stack{Name: "oak_planks", Count: 5}
|
||
ns, nh := ClickRight(slot, item.Stack{}, 64, true)
|
||
if nh.Count != 3 || ns.Count != 2 {
|
||
t.Fatalf("空手右键应拿一半向上取整:槽=%d 手=%d", ns.Count, nh.Count)
|
||
}
|
||
ns, nh = ClickRight(item.Stack{}, nh, 64, true)
|
||
if ns.Count != 1 || nh.Count != 2 {
|
||
t.Fatalf("手持右键应放 1 个:槽=%d 手=%d", ns.Count, nh.Count)
|
||
}
|
||
}
|
||
|
||
func TestShiftHotbarMain(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
inv.Slots[0] = item.Stack{Name: "stick", Count: 8}
|
||
if !inv.ShiftFromInv(0) {
|
||
t.Fatal("热键栏 Shift 应移到主区")
|
||
}
|
||
if !inv.Slots[0].Empty() || inv.Slots[9].Name != "stick" || inv.Slots[9].Count != 8 {
|
||
t.Fatalf("应进入主区槽 9,实际 hot=%+v main=%+v", inv.Slots[0], inv.Slots[9])
|
||
}
|
||
}
|
||
|
||
func TestAddSkipsArmor(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
for i := 0; i < StorageSize; i++ {
|
||
inv.Slots[i] = item.Stack{Name: "dirt", Count: 64}
|
||
}
|
||
rem := inv.Add(item.Stack{Name: "oak_planks", Count: 1})
|
||
if rem.Empty() {
|
||
t.Fatal("存储满时不应写入盔甲槽")
|
||
}
|
||
if !inv.Slots[SlotHelmet].Empty() {
|
||
t.Fatal("盔甲槽应保持空")
|
||
}
|
||
}
|
||
|
||
func TestSpreadEven(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
slots := []item.Stack{{}, {}, {}, {}, {}}
|
||
ptrs := []*item.Stack{&slots[0], &slots[1], &slots[2], &slots[3], &slots[4]}
|
||
held := SpreadEven(reg, item.Stack{Name: "oak_planks", Count: 5}, ptrs)
|
||
if !held.Empty() {
|
||
t.Fatalf("5 个应均分完,剩余 %+v", held)
|
||
}
|
||
for i, st := range slots {
|
||
if st.Count != 1 {
|
||
t.Fatalf("槽 %d 应各 1,实际 %+v", i, st)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestGather(t *testing.T) {
|
||
reg := loadItemReg(t)
|
||
inv := New(reg)
|
||
inv.Slots[0] = item.Stack{Name: "stick", Count: 10}
|
||
inv.Slots[9] = item.Stack{Name: "stick", Count: 20}
|
||
held := inv.GatherStorage(item.Stack{}, "stick")
|
||
if held.Count != 30 {
|
||
t.Fatalf("应聚 30 棍,实际 %d", held.Count)
|
||
}
|
||
}
|