test: add createItemIn tests for grid-inventory

This commit is contained in:
hypercross 2026-04-20 16:28:14 +08:00
parent ca9912a5f5
commit 140b7aed86
1 changed files with 119 additions and 0 deletions

View File

@ -15,6 +15,48 @@ import {
type GridInventory,
type InventoryItem,
} from "@/samples/slay-the-spire-like/system/grid-inventory";
import { createItemIn } from "@/samples/slay-the-spire-like/system/grid-inventory/factory";
import type { GameItemMeta } from "@/samples/slay-the-spire-like/system/grid-inventory/types";
import type {
CardData,
ItemData,
} from "@/samples/slay-the-spire-like/system/types";
/**
* Helper: create a minimal CardData for testing.
*/
function createTestCardData(id: string, name: string, desc: string): CardData {
return {
id,
name,
desc,
type: "item",
costType: "energy",
costCount: 1,
targetType: "single",
effects: [],
};
}
/**
* Helper: create a minimal ItemData for testing.
*/
function createTestItemData(
id: string,
name: string,
shapeStr: string,
desc: string,
): ItemData {
return {
id,
type: "weapon",
name,
shape: shapeStr,
card: createTestCardData(id, name, desc),
price: 10,
description: desc,
};
}
/**
* Helper: create a test inventory item.
@ -535,4 +577,81 @@ describe("grid-inventory", () => {
expect(adjShield.has("sword")).toBe(true);
});
});
describe("createItemIn", () => {
it("should place item at first valid position", () => {
const inv = createGridInventory<GameItemMeta>(6, 4);
const itemData = createTestItemData("sword", "长剑", "oee", "攻击");
const result = createItemIn(inv, "sword-1", itemData);
expect(result).toEqual({ success: true });
expect(inv.items.size).toBe(1);
expect(inv.occupiedCells.size).toBe(3); // shape "oee" has 3 cells
expect(inv.items.get("sword-1")?.meta?.itemData.id).toBe("sword");
});
it("should skip occupied cells and find next valid position", () => {
const inv = createGridInventory<GameItemMeta>(6, 4);
// Place first item manually at origin
const firstItem = createTestItem("existing", "oee");
placeItem(inv, firstItem);
const itemData = createTestItemData("shield", "盾牌", "o", "防御");
const result = createItemIn(inv, "shield-1", itemData);
expect(result).toEqual({ success: true });
// Shield should be at x=3, y=0 (first available spot after "oee" at x=0-2)
const placedItem = inv.items.get("shield-1");
expect(placedItem?.transform.offset).toEqual({ x: 3, y: 0 });
});
it("should return error when no valid placement exists", () => {
const inv = createGridInventory<GameItemMeta>(3, 3);
// Fill the grid completely with 1x1 items
for (let i = 0; i < 9; i++) {
const itemData = createTestItemData(`item${i}`, `物品${i}`, "o", "");
createItemIn(inv, `item-${i}`, itemData);
}
// Try to place one more item
const itemData = createTestItemData("overflow", "溢出", "oee", "");
const result = createItemIn(inv, "overflow-1", itemData);
expect(result).toEqual({ success: false, reason: "无可用位置" });
});
it("should handle multi-cell items correctly", () => {
const inv = createGridInventory<GameItemMeta>(4, 4);
const itemData = createTestItemData("lshape", "L形", "oes", "特殊");
const result = createItemIn(inv, "lshape-1", itemData);
expect(result).toEqual({ success: true });
expect(inv.items.size).toBe(1);
// Shape "oes" has 3 cells
expect(inv.occupiedCells.size).toBe(3);
});
it("should not place item when inventory is completely full", () => {
const inv = createGridInventory<GameItemMeta>(2, 2);
// Fill with 1x1 items
const itemData = createTestItemData("small", "小物品", "o", "");
createItemIn(inv, "small-1", itemData);
createItemIn(inv, "small-2", itemData);
createItemIn(inv, "small-3", itemData);
createItemIn(inv, "small-4", itemData);
// Grid is now full
const overflowItem = createTestItemData("overflow", "溢出", "o", "");
const result = createItemIn(inv, "overflow-5", overflowItem);
expect(result).toEqual({ success: false, reason: "无可用位置" });
expect(inv.items.size).toBe(4);
});
});
});