Improve L2 market parsing and data handling
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { access, readdir, readFile } from "node:fs/promises";
|
||||
|
||||
const dataUrl = new URL("../data/", import.meta.url);
|
||||
|
||||
async function loadManifest() {
|
||||
return JSON.parse(await readFile(new URL("fixtures.json", dataUrl), "utf8"));
|
||||
}
|
||||
|
||||
test("fixture manifest covers every screenshot exactly once", async () => {
|
||||
const manifest = await loadManifest();
|
||||
const files = (await readdir(dataUrl)).filter((file) => file.toLowerCase().endsWith(".jpg")).sort();
|
||||
const declared = manifest.cases.map((fixture) => fixture.file).sort();
|
||||
|
||||
assert.equal(manifest.version, 1);
|
||||
assert.deepEqual(manifest.frame, { width: 1560, height: 1360 });
|
||||
assert.equal(new Set(manifest.cases.map((fixture) => fixture.id)).size, manifest.cases.length);
|
||||
assert.deepEqual(declared, files);
|
||||
});
|
||||
|
||||
test("fixture groups have deterministic order and reviewed slot transitions", async () => {
|
||||
const { cases } = await loadManifest();
|
||||
const groups = new Map();
|
||||
cases.forEach((fixture) => {
|
||||
const group = groups.get(fixture.groupId) || [];
|
||||
group.push(fixture);
|
||||
groups.set(fixture.groupId, group);
|
||||
});
|
||||
|
||||
for (const fixtures of groups.values()) {
|
||||
const orders = fixtures.map((fixture) => fixture.order).sort((left, right) => left - right);
|
||||
assert.deepEqual(orders, [...Array(fixtures.length).keys()]);
|
||||
|
||||
for (const fixture of fixtures) {
|
||||
const expected = fixture.expected;
|
||||
const occupied = expected.occupiedSlots;
|
||||
const classified = [...expected.pendingSlots, ...expected.foundSlots].sort((a, b) => a - b);
|
||||
assert.deepEqual(classified, occupied);
|
||||
assert.equal(new Set(classified).size, classified.length);
|
||||
assert.ok(classified.every((slot) => Number.isInteger(slot) && slot >= 0 && slot < 18));
|
||||
if (expected.item) {
|
||||
assert.ok(fixture.catalogAssetId);
|
||||
assert.ok(expected.foundSlots.includes(expected.hoveredSlot));
|
||||
assert.ok(expected.item.name && expected.item.displayName);
|
||||
assert.ok(Number.isSafeInteger(expected.item.quantity) && expected.item.quantity >= 0);
|
||||
assert.ok(Number.isSafeInteger(expected.item.priceAdena) && expected.item.priceAdena > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("contextual tooltip fixtures own their initial shop state", async () => {
|
||||
const { cases } = await loadManifest();
|
||||
const contextual = cases.filter((fixture) => fixture.mode === "contextual");
|
||||
assert.ok(contextual.length > 0);
|
||||
contextual.forEach((fixture) => {
|
||||
assert.equal(fixture.initialState.side, fixture.expected.side);
|
||||
assert.equal(fixture.initialState.merchant, fixture.expected.merchant);
|
||||
assert.ok(fixture.initialState.activeShopKey);
|
||||
});
|
||||
});
|
||||
|
||||
test("fixture calibration and every declared catalog asset are committed", async () => {
|
||||
const manifest = await loadManifest();
|
||||
const calibration = JSON.parse(await readFile(new URL(manifest.calibration, dataUrl), "utf8"));
|
||||
const catalog = JSON.parse(
|
||||
await readFile(new URL("fixture-assets/catalog.json", dataUrl), "utf8"),
|
||||
);
|
||||
|
||||
assert.deepEqual(calibration.frame, manifest.frame);
|
||||
for (const field of [
|
||||
"saleAnchor",
|
||||
"storeHeaderRegion",
|
||||
"tooltipSearchRegion",
|
||||
"tooltipAnchor",
|
||||
"itemNameRegion",
|
||||
"itemPriceRegion",
|
||||
"sellItemGridRegion",
|
||||
"buyItemGridRegion",
|
||||
]) {
|
||||
assert.ok(calibration[field], `missing fixture calibration field: ${field}`);
|
||||
}
|
||||
await access(new URL(calibration.saleAnchor.image, dataUrl));
|
||||
await access(new URL(calibration.tooltipAnchor.image, dataUrl));
|
||||
|
||||
for (const fixture of manifest.cases.filter((entry) => entry.catalogAssetId)) {
|
||||
const item = catalog.items[fixture.catalogAssetId];
|
||||
assert.ok(item, `missing catalog fixture: ${fixture.catalogAssetId}`);
|
||||
await access(new URL(item.iconUrl.replace(/^\//, "../"), dataUrl));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user