74 lines
2.9 KiB
JavaScript
74 lines
2.9 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
||
import fs from "node:fs";
|
||
import { CHUNK_SIZE, chunkForWorld, chunkName, parseChunkName, threeToWorld, tileForWorld, worldToThree } from "../src/world/coords.js";
|
||
|
||
const NAMES = JSON.parse(fs.readFileSync(new URL("./fixtures/chunk-names.json", import.meta.url), "utf8"));
|
||
|
||
describe("coords", () => {
|
||
it("dreht Y zur three-z-Achse", () => {
|
||
expect(worldToThree(1699, 743)).toEqual({ x: 1699, z: -743 });
|
||
expect(threeToWorld(1699, -743)).toEqual({ X: 1699, Y: 743 });
|
||
});
|
||
|
||
it("findet die Kachel von Vice Beach", () => {
|
||
expect(tileForWorld(1409.4, 2803.2)).toEqual({ row: 53, col: 69 });
|
||
});
|
||
|
||
it("deckt den Ausschnitt mit Spalten 60..71 und Zeilen 54..65 ab", () => {
|
||
expect(tileForWorld(-1000, 2500)).toEqual({ row: 54, col: 60 });
|
||
expect(tileForWorld(1999, -499)).toEqual({ row: 65, col: 71 });
|
||
});
|
||
|
||
it("teilt den Ausschnitt in 250-m-Chunks", () => {
|
||
expect(CHUNK_SIZE).toBe(250);
|
||
expect(chunkForWorld(-1000, 2500)).toEqual({ i: 0, j: 0 });
|
||
expect(chunkForWorld(1999, -499)).toEqual({ i: 11, j: 11 });
|
||
});
|
||
});
|
||
|
||
describe("Chunk-Namen", () => {
|
||
it("benennt Ecken und Beispiel wie in der Spec, in beide Richtungen", () => {
|
||
for (const [name, i, j] of NAMES.pairs) {
|
||
expect(chunkName(i, j)).toBe(name);
|
||
expect(parseChunkName(name)).toEqual({ i, j });
|
||
}
|
||
});
|
||
|
||
it("akzeptiert Kleinschreibung", () => {
|
||
for (const [name, i, j] of NAMES.lowercase) expect(parseChunkName(name)).toEqual({ i, j });
|
||
});
|
||
|
||
it("weist alles außerhalb von A1 bis L12 ab", () => {
|
||
for (const name of NAMES.invalid) expect(parseChunkName(name)).toBeNull();
|
||
});
|
||
|
||
it("liefert null für Indizes außerhalb des Ausschnitts", () => {
|
||
expect(chunkName(12, 0)).toBeNull();
|
||
expect(chunkName(0, 12)).toBeNull();
|
||
expect(chunkName(-1, 3)).toBeNull();
|
||
expect(chunkName(1.5, 3)).toBeNull();
|
||
});
|
||
|
||
it("lehnt ungültige Indextypen ab", () => {
|
||
for (const [i, j] of NAMES.invalidIndices) {
|
||
expect(chunkName(i, j)).toBeNull();
|
||
}
|
||
});
|
||
|
||
it("kommt für alle 144 Chunks hin und zurück", () => {
|
||
for (let i = 0; i < 12; i++) {
|
||
for (let j = 0; j < 12; j++) expect(parseChunkName(chunkName(i, j))).toEqual({ i, j });
|
||
}
|
||
});
|
||
|
||
it("verbindet den Namen mit der Lage: Downtown-Bezugspunkt in B9, höchster Turm in C12", () => {
|
||
// (−511, 254) ist der Bezugspunkt "Downtown" aus tools/extract/data/districts.json, der Mittelpunkt
|
||
// der westlichen Hochhäuser. Die Türme selbst stehen nördlich und südlich davon.
|
||
const { i, j } = chunkForWorld(-511, 254);
|
||
expect({ i, j }).toEqual({ i: 1, j: 8 });
|
||
expect(chunkName(i, j)).toBe("B9");
|
||
const tower = chunkForWorld(-461.31, -460.1); // Southeast Financial Center, 248 m
|
||
expect(chunkName(tower.i, tower.j)).toBe("C12");
|
||
});
|
||
});
|