refactor(slay-the-spire-like): update GameItemMeta import path and

reformat tests

Update imports for `GameItemMeta` from `progress/types` to
`encounter/types`
in combat and deck tests. Reformat `deck/factory.test.ts` to use double
quotes and consistent indentation.
This commit is contained in:
hypercross 2026-04-20 13:01:11 +08:00
parent f336a989e2
commit 52b6cecd64
3 changed files with 203 additions and 183 deletions

View File

@ -30,7 +30,7 @@ import type {
GridInventory, GridInventory,
InventoryItem, InventoryItem,
} from "@/samples/slay-the-spire-like/system/grid-inventory/types"; } from "@/samples/slay-the-spire-like/system/grid-inventory/types";
import type { GameItemMeta } from "@/samples/slay-the-spire-like/system/progress/types"; import type { GameItemMeta } from "@/samples/slay-the-spire-like/system/grid-inventory/types";
import type { ParsedShape } from "@/samples/slay-the-spire-like/system/utils/parse-shape"; import type { ParsedShape } from "@/samples/slay-the-spire-like/system/utils/parse-shape";
import type { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision"; import type { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision";

View File

@ -26,7 +26,7 @@ import {
GridInventory, GridInventory,
InventoryItem, InventoryItem,
} from "@/samples/slay-the-spire-like/system/grid-inventory/types"; } from "@/samples/slay-the-spire-like/system/grid-inventory/types";
import { GameItemMeta } from "@/samples/slay-the-spire-like/system/progress/types"; import { GameItemMeta } from "@/samples/slay-the-spire-like/system/grid-inventory/types";
import { ParsedShape } from "@/samples/slay-the-spire-like/system/utils/parse-shape"; import { ParsedShape } from "@/samples/slay-the-spire-like/system/utils/parse-shape";
import { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision"; import { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision";
import { import {

View File

@ -1,17 +1,26 @@
import { describe, it, expect } from 'vitest'; import { describe, it, expect } from "vitest";
import { import {
generateDeckFromInventory, generateDeckFromInventory,
createCard, createCard,
createDeckRegions, createDeckRegions,
createPlayerDeck, createPlayerDeck,
generateCardId, generateCardId,
} from '@/samples/slay-the-spire-like/system/deck/factory'; } from "@/samples/slay-the-spire-like/system/deck/factory";
import { createGridInventory, placeItem } from '@/samples/slay-the-spire-like/system/grid-inventory'; import {
import type { GridInventory, InventoryItem } from '@/samples/slay-the-spire-like/system/grid-inventory'; createGridInventory,
import type { GameItemMeta } from '@/samples/slay-the-spire-like/system/progress/types'; placeItem,
import { IDENTITY_TRANSFORM } from '@/samples/slay-the-spire-like/system/utils/shape-collision'; } from "@/samples/slay-the-spire-like/system/grid-inventory";
import { parseShapeString } from '@/samples/slay-the-spire-like/system/utils/parse-shape'; import type {
import type { CardData, ItemData } from '@/samples/slay-the-spire-like/system/types'; GridInventory,
InventoryItem,
} from "@/samples/slay-the-spire-like/system/grid-inventory";
import type { GameItemMeta } from "@/samples/slay-the-spire-like/system/encounter/types";
import { IDENTITY_TRANSFORM } from "@/samples/slay-the-spire-like/system/utils/shape-collision";
import { parseShapeString } from "@/samples/slay-the-spire-like/system/utils/parse-shape";
import type {
CardData,
ItemData,
} from "@/samples/slay-the-spire-like/system/types";
/** /**
* Helper: create a minimal CardData for testing. * Helper: create a minimal CardData for testing.
@ -21,10 +30,10 @@ function createTestCardData(id: string, name: string, desc: string): CardData {
id, id,
name, name,
desc, desc,
type: 'item', type: "item",
costType: 'energy', costType: "energy",
costCount: 1, costCount: 1,
targetType: 'single', targetType: "single",
effects: [], effects: [],
}; };
} }
@ -32,10 +41,15 @@ function createTestCardData(id: string, name: string, desc: string): CardData {
/** /**
* Helper: create a minimal ItemData for testing. * Helper: create a minimal ItemData for testing.
*/ */
function createTestItemData(id: string, name: string, shapeStr: string, desc: string): ItemData { function createTestItemData(
id: string,
name: string,
shapeStr: string,
desc: string,
): ItemData {
return { return {
id, id,
type: 'weapon', type: "weapon",
name, name,
shape: shapeStr, shape: shapeStr,
card: createTestCardData(id, name, desc), card: createTestCardData(id, name, desc),
@ -47,7 +61,11 @@ function createTestItemData(id: string, name: string, shapeStr: string, desc: st
/** /**
* Helper: create a minimal GameItemMeta for testing. * Helper: create a minimal GameItemMeta for testing.
*/ */
function createTestMeta(name: string, desc: string, shapeStr: string): GameItemMeta { function createTestMeta(
name: string,
desc: string,
shapeStr: string,
): GameItemMeta {
const shape = parseShapeString(shapeStr); const shape = parseShapeString(shapeStr);
const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc); const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc);
return { return {
@ -63,9 +81,9 @@ function createTestInventory(): GridInventory<GameItemMeta> {
const inv = createGridInventory<GameItemMeta>(6, 4); const inv = createGridInventory<GameItemMeta>(6, 4);
// Item "短刀" with shape "oe" (2 cells) // Item "短刀" with shape "oe" (2 cells)
const meta1 = createTestMeta('短刀', '【攻击3】【攻击3】', 'oe'); const meta1 = createTestMeta("短刀", "【攻击3】【攻击3】", "oe");
const item1: InventoryItem<GameItemMeta> = { const item1: InventoryItem<GameItemMeta> = {
id: 'dagger-1', id: "dagger-1",
shape: meta1.shape, shape: meta1.shape,
transform: { ...IDENTITY_TRANSFORM, offset: { x: 0, y: 0 } }, transform: { ...IDENTITY_TRANSFORM, offset: { x: 0, y: 0 } },
meta: meta1, meta: meta1,
@ -73,9 +91,9 @@ function createTestInventory(): GridInventory<GameItemMeta> {
placeItem(inv, item1); placeItem(inv, item1);
// Item "盾" with shape "oesw" (4 cells) // Item "盾" with shape "oesw" (4 cells)
const meta2 = createTestMeta('盾', '【防御3】', 'oesw'); const meta2 = createTestMeta("盾", "【防御3】", "oesw");
const item2: InventoryItem<GameItemMeta> = { const item2: InventoryItem<GameItemMeta> = {
id: 'shield-1', id: "shield-1",
shape: meta2.shape, shape: meta2.shape,
transform: { ...IDENTITY_TRANSFORM, offset: { x: 3, y: 0 } }, transform: { ...IDENTITY_TRANSFORM, offset: { x: 3, y: 0 } },
meta: meta2, meta: meta2,
@ -85,30 +103,30 @@ function createTestInventory(): GridInventory<GameItemMeta> {
return inv; return inv;
} }
describe('deck/factory', () => { describe("deck/factory", () => {
describe('generateCardId', () => { describe("generateCardId", () => {
it('should generate deterministic unique IDs', () => { it("should generate deterministic unique IDs", () => {
expect(generateCardId('item-1', 0)).toBe('card-item-1-0'); expect(generateCardId("item-1", 0)).toBe("card-item-1-0");
expect(generateCardId('item-1', 1)).toBe('card-item-1-1'); expect(generateCardId("item-1", 1)).toBe("card-item-1-1");
expect(generateCardId('item-2', 0)).toBe('card-item-2-0'); expect(generateCardId("item-2", 0)).toBe("card-item-2-0");
}); });
}); });
describe('createCard', () => { describe("createCard", () => {
it('should create a card with itemId and cardData', () => { it("should create a card with itemId and cardData", () => {
const cardData = createTestCardData('wound', '伤口', '无法被弃牌'); const cardData = createTestCardData("wound", "伤口", "无法被弃牌");
const card = createCard('wound-1', cardData, 0); const card = createCard("wound-1", cardData, 0);
expect(card.id).toBe('card-wound-1-0'); expect(card.id).toBe("card-wound-1-0");
expect(card.itemId).toBe('wound-1'); expect(card.itemId).toBe("wound-1");
expect(card.cardData).toBe(cardData); expect(card.cardData).toBe(cardData);
expect(card.regionId).toBe(''); expect(card.regionId).toBe("");
expect(card.position).toEqual([]); expect(card.position).toEqual([]);
}); });
}); });
describe('generateDeckFromInventory', () => { describe("generateDeckFromInventory", () => {
it('should generate correct number of cards based on shape cell counts', () => { it("should generate correct number of cards based on shape cell counts", () => {
const inv = createTestInventory(); const inv = createTestInventory();
// "短刀" has 2 cells, "盾" has 4 cells = 6 total // "短刀" has 2 cells, "盾" has 4 cells = 6 total
@ -121,26 +139,26 @@ describe('deck/factory', () => {
expect(deck.regions.exhaustPile.childIds).toEqual([]); expect(deck.regions.exhaustPile.childIds).toEqual([]);
}); });
it('should link cards to their source items', () => { it("should link cards to their source items", () => {
const inv = createTestInventory(); const inv = createTestInventory();
const deck = generateDeckFromInventory(inv); const deck = generateDeckFromInventory(inv);
const daggerCards = Object.values(deck.cards).filter( const daggerCards = Object.values(deck.cards).filter(
c => c.itemId === 'dagger-1' (c) => c.itemId === "dagger-1",
); );
const shieldCards = Object.values(deck.cards).filter( const shieldCards = Object.values(deck.cards).filter(
c => c.itemId === 'shield-1' (c) => c.itemId === "shield-1",
); );
expect(daggerCards.length).toBe(2); expect(daggerCards.length).toBe(2);
expect(shieldCards.length).toBe(4); expect(shieldCards.length).toBe(4);
// Verify card data // Verify card data
expect(daggerCards[0].cardData.name).toBe('短刀'); expect(daggerCards[0].cardData.name).toBe("短刀");
expect(shieldCards[0].cardData.name).toBe('盾'); expect(shieldCards[0].cardData.name).toBe("盾");
}); });
it('should set displayName and description from item data', () => { it("should set displayName and description from item data", () => {
const inv = createTestInventory(); const inv = createTestInventory();
const deck = generateDeckFromInventory(inv); const deck = generateDeckFromInventory(inv);
@ -150,26 +168,26 @@ describe('deck/factory', () => {
} }
const daggerCard = Object.values(deck.cards).find( const daggerCard = Object.values(deck.cards).find(
c => c.cardData.name === '短刀' (c) => c.cardData.name === "短刀",
); );
expect(daggerCard?.cardData.name).toBe('短刀'); expect(daggerCard?.cardData.name).toBe("短刀");
expect(daggerCard?.cardData.desc).toBe('【攻击3】【攻击3】'); expect(daggerCard?.cardData.desc).toBe("【攻击3】【攻击3】");
}); });
it('should assign unique IDs to each card from same item', () => { it("should assign unique IDs to each card from same item", () => {
const inv = createTestInventory(); const inv = createTestInventory();
const deck = generateDeckFromInventory(inv); const deck = generateDeckFromInventory(inv);
const daggerCards = Object.values(deck.cards).filter( const daggerCards = Object.values(deck.cards).filter(
c => c.itemId === 'dagger-1' (c) => c.itemId === "dagger-1",
); );
const ids = daggerCards.map(c => c.id); const ids = daggerCards.map((c) => c.id);
const uniqueIds = new Set(ids); const uniqueIds = new Set(ids);
expect(uniqueIds.size).toBe(ids.length); expect(uniqueIds.size).toBe(ids.length);
}); });
it('should handle empty inventory', () => { it("should handle empty inventory", () => {
const inv = createGridInventory<GameItemMeta>(6, 4); const inv = createGridInventory<GameItemMeta>(6, 4);
const deck = generateDeckFromInventory(inv); const deck = generateDeckFromInventory(inv);
@ -177,7 +195,7 @@ describe('deck/factory', () => {
expect(deck.regions.drawPile.childIds).toEqual([]); expect(deck.regions.drawPile.childIds).toEqual([]);
}); });
it('should place all cards in draw pile initially', () => { it("should place all cards in draw pile initially", () => {
const inv = createTestInventory(); const inv = createTestInventory();
const deck = generateDeckFromInventory(inv); const deck = generateDeckFromInventory(inv);
@ -186,21 +204,23 @@ describe('deck/factory', () => {
} }
// All cards are in draw pile // All cards are in draw pile
expect(new Set(deck.regions.drawPile.childIds).size).toBe(Object.keys(deck.cards).length); expect(new Set(deck.regions.drawPile.childIds).size).toBe(
Object.keys(deck.cards).length,
);
}); });
}); });
describe('createDeckRegions', () => { describe("createDeckRegions", () => {
it('should create regions for all deck zones', () => { it("should create regions for all deck zones", () => {
const regions = createDeckRegions(); const regions = createDeckRegions();
expect(regions.drawPile.id).toBe('drawPile'); expect(regions.drawPile.id).toBe("drawPile");
expect(regions.hand.id).toBe('hand'); expect(regions.hand.id).toBe("hand");
expect(regions.discardPile.id).toBe('discardPile'); expect(regions.discardPile.id).toBe("discardPile");
expect(regions.exhaustPile.id).toBe('exhaustPile'); expect(regions.exhaustPile.id).toBe("exhaustPile");
}); });
it('should have empty childIds initially', () => { it("should have empty childIds initially", () => {
const regions = createDeckRegions(); const regions = createDeckRegions();
expect(regions.drawPile.childIds).toEqual([]); expect(regions.drawPile.childIds).toEqual([]);
@ -210,8 +230,8 @@ describe('deck/factory', () => {
}); });
}); });
describe('createPlayerDeck', () => { describe("createPlayerDeck", () => {
it('should create an empty deck structure', () => { it("should create an empty deck structure", () => {
const deck = createPlayerDeck(); const deck = createPlayerDeck();
expect(deck.cards).toEqual({}); expect(deck.cards).toEqual({});