mlpcardgame/src/tests/unit/draft.spec.ts

132 lines
4.3 KiB
TypeScript

import { setupIDBShim, EventHook } from "@/testing";
import { initDB, loadSets, Database, Card } from "@/mlpccg";
import {
PackBuilder,
spanByRarity,
Cube,
Session,
DraftOptions
} from "@/mlpccg/draft";
setupIDBShim();
const testSessionOptions: DraftOptions = {
type: "booster-draft",
source: "set",
set: "FF",
packs: 2,
players: 4,
spacing: "evenly"
};
describe("mlpccg/draft", () => {
beforeAll(async () => {
jest.setTimeout(15000);
await initDB();
await loadSets();
});
test("Set booster packs are generated correctly", async () => {
expect(Database).toBeTruthy();
const builder = await PackBuilder.fromSet("FF");
const pack = builder.buildPack();
// Check pack size
expect(pack).toHaveLength(12);
const rarities = spanByRarity(pack);
// Check pack distribution
expect(rarities["R"]).toHaveLength(1);
expect(rarities["U"]).toHaveLength(3);
});
test("Cube can load a newline separated card list", async () => {
expect(Database).toBeTruthy();
const cubeCards = ["ff10", "ff11", "ff12", "ff13", "ff14", "ff15"];
const cubeList = cubeCards.join("\n");
const cube = await Cube.fromList(cubeList);
const builder = new PackBuilder(cube.schema());
const pack = builder.buildPack();
// Pack size should only be 6, since there are not enough cards for a 12 cards pack
expect(pack).toHaveLength(6);
// Make sure pack has ALL the cards from the pool, no duplicates
const sortedPack = pack.map(c => c.ID).sort();
expect(sortedPack).toEqual(cubeCards);
});
test("A session can be initialized", async () => {
expect(Database).toBeTruthy();
const session = await Session.create(testSessionOptions);
const hook = new EventHook();
hook.hookEmitter(session, "start", "session-start");
session.assign(["test1", "test2"], () => {
// Do nothing
});
session.start();
await hook.expect("session-start");
});
test("Players receive pick events and can pick cards", async () => {
expect(Database).toBeTruthy();
const session = await Session.create(testSessionOptions);
const hook = new EventHook();
hook.hookEmitter(session, "start", "session-start");
hook.hookEmitter(session, "next-pack", "session-new-pack");
hook.hookEmitter(session, "next-pick", "session-new-pick");
hook.hookEmitter(session, "player-pick", "session-picked");
hook.hookEmitter(session, "draft-over", "session-done");
session.assign(["test1", "test2"], (name, player) => {
player.on("available-picks", cards => {
// setTimeout hack to avoid handlers being called before the rest of the code
setTimeout(() => player.pick(cards[0].ID), 0);
});
});
session.start();
await hook.expect("session-start");
for (let i = 0; i < testSessionOptions.packs; i++) {
await hook.expect("session-new-pack");
for (let j = 0; j < 12; j++) {
for (let p = 0; p < testSessionOptions.players; p++) {
await hook.expect("session-picked");
}
if (i < testSessionOptions.packs - 1) {
await hook.expect("session-new-pick");
}
}
}
await hook.expect("session-done");
});
test("Sessions can load and draft I8PCube files", async () => {
expect(Database).toBeTruthy();
const session = await Session.create({
type: "booster-draft",
source: "i8pcube",
url: "https://mcg.zyg.ovh/cubes/hamchacube.json",
packs: 4,
players: 4,
spacing: "evenly"
});
const hook = new EventHook();
hook.hookEmitter(session, "start", "session-start");
session.assign(["test1"], (_, player) => {
hook.hookEmitter(player, "available-picks", "got-cards");
});
session.start();
await hook.expect("session-start");
await hook.expect("got-cards", 1000, (cards: Card[]) => {
expect(cards).toHaveLength(12);
// Check for 2 or more multicolor cards
const multicolor = cards.filter(
c =>
c.Element.length > 1 ||
(c.Requirement && Object.keys(c.Requirement).length > 1)
);
expect(multicolor.length).toBeGreaterThanOrEqual(2);
// Check for 2 or more entry cards
const entry = cards.filter(
c => !c.Requirement || c.Requirement.length < 1
);
expect(entry.length).toBeGreaterThanOrEqual(2);
});
});
});