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:
parent
f336a989e2
commit
52b6cecd64
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -1,224 +1,244 @@
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
function createTestCardData(id: string, name: string, desc: string): CardData {
|
function createTestCardData(id: string, name: string, desc: string): CardData {
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
desc,
|
desc,
|
||||||
type: 'item',
|
type: "item",
|
||||||
costType: 'energy',
|
costType: "energy",
|
||||||
costCount: 1,
|
costCount: 1,
|
||||||
targetType: 'single',
|
targetType: "single",
|
||||||
effects: [],
|
effects: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(
|
||||||
return {
|
id: string,
|
||||||
id,
|
name: string,
|
||||||
type: 'weapon',
|
shapeStr: string,
|
||||||
name,
|
desc: string,
|
||||||
shape: shapeStr,
|
): ItemData {
|
||||||
card: createTestCardData(id, name, desc),
|
return {
|
||||||
price: 10,
|
id,
|
||||||
description: desc,
|
type: "weapon",
|
||||||
};
|
name,
|
||||||
|
shape: shapeStr,
|
||||||
|
card: createTestCardData(id, name, desc),
|
||||||
|
price: 10,
|
||||||
|
description: desc,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(
|
||||||
const shape = parseShapeString(shapeStr);
|
name: string,
|
||||||
const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc);
|
desc: string,
|
||||||
return {
|
shapeStr: string,
|
||||||
itemData,
|
): GameItemMeta {
|
||||||
shape,
|
const shape = parseShapeString(shapeStr);
|
||||||
};
|
const itemData = createTestItemData(name.toLowerCase(), name, shapeStr, desc);
|
||||||
|
return {
|
||||||
|
itemData,
|
||||||
|
shape,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: create a test inventory with some items.
|
* Helper: create a test inventory with some items.
|
||||||
*/
|
*/
|
||||||
function createTestInventory(): GridInventory<GameItemMeta> {
|
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,
|
||||||
};
|
};
|
||||||
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,
|
||||||
};
|
};
|
||||||
placeItem(inv, item2);
|
placeItem(inv, item2);
|
||||||
|
|
||||||
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", () => {
|
||||||
|
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 link cards to their source items", () => {
|
||||||
it('should create a card with itemId and cardData', () => {
|
const inv = createTestInventory();
|
||||||
const cardData = createTestCardData('wound', '伤口', '无法被弃牌');
|
const deck = generateDeckFromInventory(inv);
|
||||||
const card = createCard('wound-1', cardData, 0);
|
|
||||||
|
|
||||||
expect(card.id).toBe('card-wound-1-0');
|
const daggerCards = Object.values(deck.cards).filter(
|
||||||
expect(card.itemId).toBe('wound-1');
|
(c) => c.itemId === "dagger-1",
|
||||||
expect(card.cardData).toBe(cardData);
|
);
|
||||||
expect(card.regionId).toBe('');
|
const shieldCards = Object.values(deck.cards).filter(
|
||||||
expect(card.position).toEqual([]);
|
(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 set displayName and description from item data", () => {
|
||||||
it('should generate correct number of cards based on shape cell counts', () => {
|
const inv = createTestInventory();
|
||||||
const inv = createTestInventory();
|
const deck = generateDeckFromInventory(inv);
|
||||||
|
|
||||||
// "短刀" has 2 cells, "盾" has 4 cells = 6 total
|
for (const card of Object.values(deck.cards)) {
|
||||||
const deck = generateDeckFromInventory(inv);
|
expect(card.cardData.name).toBeTruthy();
|
||||||
|
expect(card.cardData.desc).toBeTruthy();
|
||||||
|
}
|
||||||
|
|
||||||
expect(Object.keys(deck.cards).length).toBe(6);
|
const daggerCard = Object.values(deck.cards).find(
|
||||||
expect(deck.regions.drawPile.childIds.length).toBe(6);
|
(c) => c.cardData.name === "短刀",
|
||||||
expect(deck.regions.hand.childIds).toEqual([]);
|
);
|
||||||
expect(deck.regions.discardPile.childIds).toEqual([]);
|
expect(daggerCard?.cardData.name).toBe("短刀");
|
||||||
expect(deck.regions.exhaustPile.childIds).toEqual([]);
|
expect(daggerCard?.cardData.desc).toBe("【攻击3】【攻击3】");
|
||||||
});
|
|
||||||
|
|
||||||
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<GameItemMeta>(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);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createDeckRegions', () => {
|
it("should assign unique IDs to each card from same item", () => {
|
||||||
it('should create regions for all deck zones', () => {
|
const inv = createTestInventory();
|
||||||
const regions = createDeckRegions();
|
const deck = generateDeckFromInventory(inv);
|
||||||
|
|
||||||
expect(regions.drawPile.id).toBe('drawPile');
|
const daggerCards = Object.values(deck.cards).filter(
|
||||||
expect(regions.hand.id).toBe('hand');
|
(c) => c.itemId === "dagger-1",
|
||||||
expect(regions.discardPile.id).toBe('discardPile');
|
);
|
||||||
expect(regions.exhaustPile.id).toBe('exhaustPile');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have empty childIds initially', () => {
|
const ids = daggerCards.map((c) => c.id);
|
||||||
const regions = createDeckRegions();
|
const uniqueIds = new Set(ids);
|
||||||
|
expect(uniqueIds.size).toBe(ids.length);
|
||||||
expect(regions.drawPile.childIds).toEqual([]);
|
|
||||||
expect(regions.hand.childIds).toEqual([]);
|
|
||||||
expect(regions.discardPile.childIds).toEqual([]);
|
|
||||||
expect(regions.exhaustPile.childIds).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createPlayerDeck', () => {
|
it("should handle empty inventory", () => {
|
||||||
it('should create an empty deck structure', () => {
|
const inv = createGridInventory<GameItemMeta>(6, 4);
|
||||||
const deck = createPlayerDeck();
|
const deck = generateDeckFromInventory(inv);
|
||||||
|
|
||||||
expect(deck.cards).toEqual({});
|
expect(Object.keys(deck.cards).length).toBe(0);
|
||||||
expect(deck.regions.drawPile.childIds).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([]);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue