From 52b6cecd647a39ff8b52acb3f7fb708dad693c87 Mon Sep 17 00:00:00 2001 From: hypercross Date: Mon, 20 Apr 2026 13:01:11 +0800 Subject: [PATCH] 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. --- .../combat/effects.test.ts | 2 +- .../combat/triggers.test.ts | 2 +- .../slay-the-spire-like/deck/factory.test.ts | 382 +++++++++--------- 3 files changed, 203 insertions(+), 183 deletions(-) diff --git a/tests/samples/slay-the-spire-like/combat/effects.test.ts b/tests/samples/slay-the-spire-like/combat/effects.test.ts index 9b4e7ae..485d8ea 100644 --- a/tests/samples/slay-the-spire-like/combat/effects.test.ts +++ b/tests/samples/slay-the-spire-like/combat/effects.test.ts @@ -30,7 +30,7 @@ import type { GridInventory, InventoryItem, } 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 { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision"; diff --git a/tests/samples/slay-the-spire-like/combat/triggers.test.ts b/tests/samples/slay-the-spire-like/combat/triggers.test.ts index 54a4b22..ee83acc 100644 --- a/tests/samples/slay-the-spire-like/combat/triggers.test.ts +++ b/tests/samples/slay-the-spire-like/combat/triggers.test.ts @@ -26,7 +26,7 @@ import { GridInventory, InventoryItem, } 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 { Transform2D } from "@/samples/slay-the-spire-like/system/utils/shape-collision"; import { diff --git a/tests/samples/slay-the-spire-like/deck/factory.test.ts b/tests/samples/slay-the-spire-like/deck/factory.test.ts index bff46e6..19b2552 100644 --- a/tests/samples/slay-the-spire-like/deck/factory.test.ts +++ b/tests/samples/slay-the-spire-like/deck/factory.test.ts @@ -1,224 +1,244 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from "vitest"; import { - generateDeckFromInventory, - createCard, - createDeckRegions, - createPlayerDeck, - generateCardId, -} from '@/samples/slay-the-spire-like/system/deck/factory'; -import { createGridInventory, placeItem } from '@/samples/slay-the-spire-like/system/grid-inventory'; -import type { GridInventory, InventoryItem } from '@/samples/slay-the-spire-like/system/grid-inventory'; -import type { GameItemMeta } from '@/samples/slay-the-spire-like/system/progress/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'; + generateDeckFromInventory, + createCard, + createDeckRegions, + createPlayerDeck, + generateCardId, +} from "@/samples/slay-the-spire-like/system/deck/factory"; +import { + createGridInventory, + placeItem, +} from "@/samples/slay-the-spire-like/system/grid-inventory"; +import type { + 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. */ function createTestCardData(id: string, name: string, desc: string): CardData { - return { - id, - name, - desc, - type: 'item', - costType: 'energy', - costCount: 1, - targetType: 'single', - effects: [], - }; + 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, - }; +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 minimal GameItemMeta for testing. */ -function createTestMeta(name: string, desc: string, shapeStr: string): GameItemMeta { - const shape = parseShapeString(shapeStr); - const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc); - return { - itemData, - shape, - }; +function createTestMeta( + name: string, + desc: string, + shapeStr: string, +): GameItemMeta { + const shape = parseShapeString(shapeStr); + const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc); + return { + itemData, + shape, + }; } /** * Helper: create a test inventory with some items. */ function createTestInventory(): GridInventory { - const inv = createGridInventory(6, 4); + const inv = createGridInventory(6, 4); - // Item "短刀" with shape "oe" (2 cells) - const meta1 = createTestMeta('短刀', '【攻击3】【攻击3】', 'oe'); - const item1: InventoryItem = { - id: 'dagger-1', - shape: meta1.shape, - transform: { ...IDENTITY_TRANSFORM, offset: { x: 0, y: 0 } }, - meta: meta1, - }; - placeItem(inv, item1); + // Item "短刀" with shape "oe" (2 cells) + const meta1 = createTestMeta("短刀", "【攻击3】【攻击3】", "oe"); + const item1: InventoryItem = { + id: "dagger-1", + shape: meta1.shape, + transform: { ...IDENTITY_TRANSFORM, offset: { x: 0, y: 0 } }, + meta: meta1, + }; + placeItem(inv, item1); - // Item "盾" with shape "oesw" (4 cells) - const meta2 = createTestMeta('盾', '【防御3】', 'oesw'); - const item2: InventoryItem = { - id: 'shield-1', - shape: meta2.shape, - transform: { ...IDENTITY_TRANSFORM, offset: { x: 3, y: 0 } }, - meta: meta2, - }; - placeItem(inv, item2); + // Item "盾" with shape "oesw" (4 cells) + const meta2 = createTestMeta("盾", "【防御3】", "oesw"); + const item2: InventoryItem = { + id: "shield-1", + shape: meta2.shape, + transform: { ...IDENTITY_TRANSFORM, offset: { x: 3, y: 0 } }, + meta: meta2, + }; + placeItem(inv, item2); - return inv; + return inv; } -describe('deck/factory', () => { - describe('generateCardId', () => { - it('should generate deterministic unique IDs', () => { - expect(generateCardId('item-1', 0)).toBe('card-item-1-0'); - expect(generateCardId('item-1', 1)).toBe('card-item-1-1'); - expect(generateCardId('item-2', 0)).toBe('card-item-2-0'); - }); +describe("deck/factory", () => { + describe("generateCardId", () => { + it("should generate deterministic unique IDs", () => { + expect(generateCardId("item-1", 0)).toBe("card-item-1-0"); + expect(generateCardId("item-1", 1)).toBe("card-item-1-1"); + expect(generateCardId("item-2", 0)).toBe("card-item-2-0"); + }); + }); + + describe("createCard", () => { + it("should create a card with itemId and cardData", () => { + const cardData = createTestCardData("wound", "伤口", "无法被弃牌"); + const card = createCard("wound-1", cardData, 0); + + expect(card.id).toBe("card-wound-1-0"); + expect(card.itemId).toBe("wound-1"); + expect(card.cardData).toBe(cardData); + expect(card.regionId).toBe(""); + expect(card.position).toEqual([]); + }); + }); + + describe("generateDeckFromInventory", () => { + it("should generate correct number of cards based on shape cell counts", () => { + const inv = createTestInventory(); + + // "短刀" has 2 cells, "盾" has 4 cells = 6 total + const deck = generateDeckFromInventory(inv); + + expect(Object.keys(deck.cards).length).toBe(6); + expect(deck.regions.drawPile.childIds.length).toBe(6); + expect(deck.regions.hand.childIds).toEqual([]); + expect(deck.regions.discardPile.childIds).toEqual([]); + expect(deck.regions.exhaustPile.childIds).toEqual([]); }); - describe('createCard', () => { - it('should create a card with itemId and cardData', () => { - const cardData = createTestCardData('wound', '伤口', '无法被弃牌'); - const card = createCard('wound-1', cardData, 0); + it("should link cards to their source items", () => { + const inv = createTestInventory(); + const deck = generateDeckFromInventory(inv); - expect(card.id).toBe('card-wound-1-0'); - expect(card.itemId).toBe('wound-1'); - expect(card.cardData).toBe(cardData); - expect(card.regionId).toBe(''); - expect(card.position).toEqual([]); - }); + const daggerCards = Object.values(deck.cards).filter( + (c) => c.itemId === "dagger-1", + ); + const shieldCards = Object.values(deck.cards).filter( + (c) => c.itemId === "shield-1", + ); + + expect(daggerCards.length).toBe(2); + expect(shieldCards.length).toBe(4); + + // Verify card data + expect(daggerCards[0].cardData.name).toBe("短刀"); + expect(shieldCards[0].cardData.name).toBe("盾"); }); - describe('generateDeckFromInventory', () => { - it('should generate correct number of cards based on shape cell counts', () => { - const inv = createTestInventory(); + it("should set displayName and description from item data", () => { + const inv = createTestInventory(); + const deck = generateDeckFromInventory(inv); - // "短刀" has 2 cells, "盾" has 4 cells = 6 total - const deck = generateDeckFromInventory(inv); + for (const card of Object.values(deck.cards)) { + expect(card.cardData.name).toBeTruthy(); + expect(card.cardData.desc).toBeTruthy(); + } - expect(Object.keys(deck.cards).length).toBe(6); - expect(deck.regions.drawPile.childIds.length).toBe(6); - expect(deck.regions.hand.childIds).toEqual([]); - expect(deck.regions.discardPile.childIds).toEqual([]); - expect(deck.regions.exhaustPile.childIds).toEqual([]); - }); - - it('should link cards to their source items', () => { - const inv = createTestInventory(); - const deck = generateDeckFromInventory(inv); - - const daggerCards = Object.values(deck.cards).filter( - c => c.itemId === 'dagger-1' - ); - const shieldCards = Object.values(deck.cards).filter( - c => c.itemId === 'shield-1' - ); - - expect(daggerCards.length).toBe(2); - expect(shieldCards.length).toBe(4); - - // Verify card data - expect(daggerCards[0].cardData.name).toBe('短刀'); - expect(shieldCards[0].cardData.name).toBe('盾'); - }); - - it('should set displayName and description from item data', () => { - const inv = createTestInventory(); - const deck = generateDeckFromInventory(inv); - - for (const card of Object.values(deck.cards)) { - expect(card.cardData.name).toBeTruthy(); - expect(card.cardData.desc).toBeTruthy(); - } - - const daggerCard = Object.values(deck.cards).find( - c => c.cardData.name === '短刀' - ); - expect(daggerCard?.cardData.name).toBe('短刀'); - expect(daggerCard?.cardData.desc).toBe('【攻击3】【攻击3】'); - }); - - it('should assign unique IDs to each card from same item', () => { - const inv = createTestInventory(); - const deck = generateDeckFromInventory(inv); - - const daggerCards = Object.values(deck.cards).filter( - c => c.itemId === 'dagger-1' - ); - - const ids = daggerCards.map(c => c.id); - const uniqueIds = new Set(ids); - expect(uniqueIds.size).toBe(ids.length); - }); - - it('should handle empty inventory', () => { - const inv = createGridInventory(6, 4); - const deck = generateDeckFromInventory(inv); - - expect(Object.keys(deck.cards).length).toBe(0); - expect(deck.regions.drawPile.childIds).toEqual([]); - }); - - it('should place all cards in draw pile initially', () => { - const inv = createTestInventory(); - const deck = generateDeckFromInventory(inv); - - for (const cardId of deck.regions.drawPile.childIds) { - expect(deck.cards[cardId]).toBeDefined(); - } - - // All cards are in draw pile - expect(new Set(deck.regions.drawPile.childIds).size).toBe(Object.keys(deck.cards).length); - }); + const daggerCard = Object.values(deck.cards).find( + (c) => c.cardData.name === "短刀", + ); + expect(daggerCard?.cardData.name).toBe("短刀"); + expect(daggerCard?.cardData.desc).toBe("【攻击3】【攻击3】"); }); - describe('createDeckRegions', () => { - it('should create regions for all deck zones', () => { - const regions = createDeckRegions(); + it("should assign unique IDs to each card from same item", () => { + const inv = createTestInventory(); + const deck = generateDeckFromInventory(inv); - expect(regions.drawPile.id).toBe('drawPile'); - expect(regions.hand.id).toBe('hand'); - expect(regions.discardPile.id).toBe('discardPile'); - expect(regions.exhaustPile.id).toBe('exhaustPile'); - }); + const daggerCards = Object.values(deck.cards).filter( + (c) => c.itemId === "dagger-1", + ); - it('should have empty childIds initially', () => { - const regions = createDeckRegions(); - - expect(regions.drawPile.childIds).toEqual([]); - expect(regions.hand.childIds).toEqual([]); - expect(regions.discardPile.childIds).toEqual([]); - expect(regions.exhaustPile.childIds).toEqual([]); - }); + const ids = daggerCards.map((c) => c.id); + const uniqueIds = new Set(ids); + expect(uniqueIds.size).toBe(ids.length); }); - describe('createPlayerDeck', () => { - it('should create an empty deck structure', () => { - const deck = createPlayerDeck(); + it("should handle empty inventory", () => { + const inv = createGridInventory(6, 4); + const deck = generateDeckFromInventory(inv); - expect(deck.cards).toEqual({}); - expect(deck.regions.drawPile.childIds).toEqual([]); - expect(deck.regions.hand.childIds).toEqual([]); - expect(deck.regions.discardPile.childIds).toEqual([]); - expect(deck.regions.exhaustPile.childIds).toEqual([]); - }); + expect(Object.keys(deck.cards).length).toBe(0); + expect(deck.regions.drawPile.childIds).toEqual([]); }); + + it("should place all cards in draw pile initially", () => { + const inv = createTestInventory(); + const deck = generateDeckFromInventory(inv); + + for (const cardId of deck.regions.drawPile.childIds) { + expect(deck.cards[cardId]).toBeDefined(); + } + + // All cards are in draw pile + expect(new Set(deck.regions.drawPile.childIds).size).toBe( + Object.keys(deck.cards).length, + ); + }); + }); + + describe("createDeckRegions", () => { + it("should create regions for all deck zones", () => { + const regions = createDeckRegions(); + + expect(regions.drawPile.id).toBe("drawPile"); + expect(regions.hand.id).toBe("hand"); + expect(regions.discardPile.id).toBe("discardPile"); + expect(regions.exhaustPile.id).toBe("exhaustPile"); + }); + + it("should have empty childIds initially", () => { + const regions = createDeckRegions(); + + expect(regions.drawPile.childIds).toEqual([]); + expect(regions.hand.childIds).toEqual([]); + expect(regions.discardPile.childIds).toEqual([]); + expect(regions.exhaustPile.childIds).toEqual([]); + }); + }); + + describe("createPlayerDeck", () => { + it("should create an empty deck structure", () => { + const deck = createPlayerDeck(); + + expect(deck.cards).toEqual({}); + expect(deck.regions.drawPile.childIds).toEqual([]); + expect(deck.regions.hand.childIds).toEqual([]); + expect(deck.regions.discardPile.childIds).toEqual([]); + expect(deck.regions.exhaustPile.childIds).toEqual([]); + }); + }); });