]> git.localhorst.tv Git - alttp.git/commitdiff
base logic test cases
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 31 Mar 2024 09:40:40 +0000 (11:40 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 31 Mar 2024 09:40:40 +0000 (11:40 +0200)
resources/js/helpers/logic.js
resources/js/helpers/tracker.js
resources/js/hooks/tracker.js
tests/js/helpers/logic/inverted.test.js [new file with mode: 0644]
tests/js/helpers/logic/open.test.js [new file with mode: 0644]
tests/js/helpers/tracker.test.js [new file with mode: 0644]

index 59757e2415dd7f3a426b67e45afd22cb21fb46f6..de4da81cbb039fa99f3852e9abcf7c32014bd732 100644 (file)
@@ -262,7 +262,7 @@ const westLightWorld = eastLightWorld;
 const southLightWorld = eastLightWorld;
 
 const eastDarkWorld = when(isInverted,
-       or(canFly, canSwim, hasHammer, and(hasMoonpearl, eastLightWorld)),
+       or(canFly, canSwim, hasHammer, and(hasMirror, eastLightWorld)),
        and(
                hasMoonpearl,
                or(
index 6a927bc056b9680a9e7ec5acf9e6377c2d2256b6..33338692bd155bf8a4e3be35d553b44774001725 100644 (file)
@@ -1576,6 +1576,26 @@ export const UNDERWORLD_LOCATIONS = [
 export const getConfigValue = (config, name, fallback) =>
        Object.prototype.hasOwnProperty.call(config, name) ? config[name] : fallback;
 
+export const configureDungeons = config => DUNGEONS.map(dungeon => {
+       const newDungeon = JSON.parse(JSON.stringify(dungeon));
+       if (config.wildMap && dungeon.map) {
+               ++newDungeon.items;
+       }
+       if (config.wildCompass && dungeon.compass) {
+               ++newDungeon.items;
+       }
+       if (config.wildSmall) {
+               newDungeon.items += dungeon.sk;
+       }
+       if (config.wildBig && dungeon.bk && !dungeon.dropBk) {
+               ++newDungeon.items;
+       }
+       if (dungeon.boss) {
+               newDungeon.bosses = config.bossShuffle ? BOSSES : [dungeon.boss];
+       }
+       return newDungeon;
+});
+
 export const applyLogic = (config, dungeons, state) => {
        const logic = Logic[config.worldState];
        const map = {};
@@ -1859,18 +1879,6 @@ const collectUnderworld = (state, data) => {
        });
 };
 
-export const computeState = (config, data, prizeMap) => {
-       const state = {};
-       collectInventory(state, data.slice(SRAM_ADDR.INV_START), prizeMap);
-       collectOverworld(state, data);
-       collectUnderworld(state, data.slice(SRAM_ADDR.ROOM_DATA_START));
-       const amounts = getDungeonAmounts(config, state);
-       DUNGEONS.forEach(dungeon => {
-               state[`${dungeon.id}-checks`] = amounts[dungeon.id];
-       });
-       return state;
-};
-
 const getDungeonAmounts = (config, state) => {
        const amounts = {};
        DUNGEONS.forEach(dungeon => {
@@ -1902,6 +1910,18 @@ const getDungeonAmounts = (config, state) => {
        return amounts;
 };
 
+export const computeState = (config, data, prizeMap) => {
+       const state = {};
+       collectInventory(state, data.slice(SRAM_ADDR.INV_START), prizeMap);
+       collectOverworld(state, data);
+       collectUnderworld(state, data.slice(SRAM_ADDR.ROOM_DATA_START));
+       const amounts = getDungeonAmounts(config, state);
+       DUNGEONS.forEach(dungeon => {
+               state[`${dungeon.id}-checks`] = amounts[dungeon.id];
+       });
+       return state;
+};
+
 export const mergeStates = (autoState, manualState) => {
        const next = { ...autoState };
        BOOLEAN_STATES.forEach(name => {
index ec1e8ce25c2a6725c5ebbd726377eb6a890755ad..ce01c4b94079dd646e17f9263882a85544bc3153 100644 (file)
@@ -2,10 +2,10 @@ import PropTypes from 'prop-types';
 import React from 'react';
 
 import {
-       BOSSES,
        CONFIG,
        DUNGEONS,
        applyLogic,
+       configureDungeons,
        makeEmptyState,
        mergeStates,
 } from '../helpers/tracker';
@@ -38,25 +38,7 @@ export const TrackerProvider = ({ children }) => {
        }, []);
 
        React.useEffect(() => {
-               const newDungeons = DUNGEONS.map(dungeon => {
-                       const newDungeon = JSON.parse(JSON.stringify(dungeon));
-                       if (config.wildMap && dungeon.map) {
-                               ++newDungeon.items;
-                       }
-                       if (config.wildCompass && dungeon.compass) {
-                               ++newDungeon.items;
-                       }
-                       if (config.wildSmall) {
-                               newDungeon.items += dungeon.sk;
-                       }
-                       if (config.wildBig && dungeon.bk && !dungeon.dropBk) {
-                               ++newDungeon.items;
-                       }
-                       if (dungeon.boss) {
-                               newDungeon.bosses = config.bossShuffle ? BOSSES : [dungeon.boss];
-                       }
-                       return newDungeon;
-               });
+               const newDungeons = configureDungeons(config);
                setDungeons(newDungeons);
        }, [config]);
 
diff --git a/tests/js/helpers/logic/inverted.test.js b/tests/js/helpers/logic/inverted.test.js
new file mode 100644 (file)
index 0000000..5bb9ca3
--- /dev/null
@@ -0,0 +1,146 @@
+import {
+       CONFIG,
+       applyLogic,
+       configureDungeons,
+       getLocationStatus,
+       makeEmptyState,
+} from 'helpers/tracker';
+
+describe('base reachability', () => {
+       const config = {
+               ...CONFIG,
+               worldState: 'inverted',
+       };
+       const dungeons = configureDungeons(config);
+       const state = makeEmptyState();
+       const logic = applyLogic(config, dungeons, state);
+
+       test('Dungeon Entrances', () => {
+               expect(getLocationStatus('hc', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('ct', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('gt', logic, state)).toBe('unavailable');
+
+               expect(getLocationStatus('ep', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('dp', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('th', logic, state)).toBe('unavailable');
+
+               expect(getLocationStatus('pd', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sp', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sw', logic, state)).toBe('available');
+               expect(getLocationStatus('tt', logic, state)).toBe('available');
+               expect(getLocationStatus('ip', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mm', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('tr', logic, state)).toBe('unavailable');
+       });
+
+       test('East Light World', () => {
+               expect(getLocationStatus('potion-shop', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha-mid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('secret-passage', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('uncle', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('waterfall-fairy-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('waterfall-fairy-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('zora', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('zora-ledge', logic, state)).toBe('unavailable');
+       });
+
+       test('West Light World', () => {
+               expect(getLocationStatus('blinds-hut-far-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('blinds-hut-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('blinds-hut-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('blinds-hut-far-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('blinds-hut-top', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('bonk-rocks', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('bottle-vendor', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('chicken-house', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('graveyard-ledge', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-bottom', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-mid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-top', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kings-tomb', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('lost-woods-hideout', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('lumberjack', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('magic-bat', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pedestal', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sick-kid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('tavern', logic, state)).toBe('unavailable');
+       });
+
+       test('South Light World', () => {
+               expect(getLocationStatus('aginah', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('checkerboard', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('desert-ledge', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('flooded-chest', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hobo', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('ice-rod-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('lake-hylia-island', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('library', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mini-moldorm-far-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mini-moldorm-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mini-moldorm-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mini-moldorm-far-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mini-moldorm-npc', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('race-game', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sunken-treasure', logic, state)).toBe('unavailable');
+       });
+
+       test('Death Mountain', () => {
+               expect(getLocationStatus('ether-tablet', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('floating-island', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mimic-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('old-man', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-far-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-mid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-far-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-upper-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-upper-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spec-rock', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spec-rock-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spiral-cave', logic, state)).toBe('unavailable');
+       });
+
+       test('East Dark World', () => {
+               expect(getLocationStatus('brewery', logic, state)).toBe('available');
+               expect(getLocationStatus('bumper-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('c-house', logic, state)).toBe('available');
+               expect(getLocationStatus('chest-game', logic, state)).toBe('available');
+               expect(getLocationStatus('hammer-pegs', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('purple-chest', logic, state)).toBe('unavailable');
+       });
+
+       test('West Dark World', () => {
+               expect(getLocationStatus('catfish', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid-fairy-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid-fairy-right', logic, state)).toBe('unavailable');
+       });
+
+       test('South Dark World', () => {
+               expect(getLocationStatus('blacksmith', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('digging-game', logic, state)).toBe('available');
+               expect(getLocationStatus('hype-cave-top', logic, state)).toBe('available');
+               expect(getLocationStatus('hype-cave-left', logic, state)).toBe('available');
+               expect(getLocationStatus('hype-cave-right', logic, state)).toBe('available');
+               expect(getLocationStatus('hype-cave-bottom', logic, state)).toBe('available');
+               expect(getLocationStatus('hype-cave-npc', logic, state)).toBe('available');
+               expect(getLocationStatus('links-house', logic, state)).toBe('available');
+               expect(getLocationStatus('stumpy', logic, state)).toBe('available');
+       });
+
+       test('Dark Death Mountain', () => {
+               expect(getLocationStatus('hookshot-cave-tl', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-tr', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-bl', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-br', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spike-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('super-bunny-top', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('super-bunny-bottom', logic, state)).toBe('unavailable');
+       });
+});
diff --git a/tests/js/helpers/logic/open.test.js b/tests/js/helpers/logic/open.test.js
new file mode 100644 (file)
index 0000000..615c385
--- /dev/null
@@ -0,0 +1,143 @@
+import {
+       CONFIG,
+       applyLogic,
+       configureDungeons,
+       getLocationStatus,
+       makeEmptyState,
+} from 'helpers/tracker';
+
+describe('base reachability', () => {
+       const config = { ...CONFIG };
+       const dungeons = configureDungeons(config);
+       const state = makeEmptyState();
+       const logic = applyLogic(config, dungeons, state);
+
+       test('Dungeon Entrances', () => {
+               expect(getLocationStatus('hc', logic, state)).toBe('available');
+               expect(getLocationStatus('ct', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('gt', logic, state)).toBe('unavailable');
+
+               expect(getLocationStatus('ep', logic, state)).toBe('available');
+               expect(getLocationStatus('dp', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('th', logic, state)).toBe('unavailable');
+
+               expect(getLocationStatus('pd', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sp', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sw', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('tt', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('ip', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mm', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('tr', logic, state)).toBe('unavailable');
+       });
+
+       test('East Light World', () => {
+               expect(getLocationStatus('potion-shop', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('saha-left', logic, state)).toBe('available');
+               expect(getLocationStatus('saha-mid', logic, state)).toBe('available');
+               expect(getLocationStatus('saha-right', logic, state)).toBe('available');
+               expect(getLocationStatus('secret-passage', logic, state)).toBe('available');
+               expect(getLocationStatus('uncle', logic, state)).toBe('available');
+               expect(getLocationStatus('waterfall-fairy-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('waterfall-fairy-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('zora', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('zora-ledge', logic, state)).toBe('unavailable');
+       });
+
+       test('West Light World', () => {
+               expect(getLocationStatus('blinds-hut-far-left', logic, state)).toBe('available');
+               expect(getLocationStatus('blinds-hut-left', logic, state)).toBe('available');
+               expect(getLocationStatus('blinds-hut-right', logic, state)).toBe('available');
+               expect(getLocationStatus('blinds-hut-far-right', logic, state)).toBe('available');
+               expect(getLocationStatus('blinds-hut-top', logic, state)).toBe('available');
+               expect(getLocationStatus('bonk-rocks', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('bottle-vendor', logic, state)).toBe('available');
+               expect(getLocationStatus('chicken-house', logic, state)).toBe('available');
+               expect(getLocationStatus('graveyard-ledge', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('kak-well-bottom', logic, state)).toBe('available');
+               expect(getLocationStatus('kak-well-left', logic, state)).toBe('available');
+               expect(getLocationStatus('kak-well-right', logic, state)).toBe('available');
+               expect(getLocationStatus('kak-well-mid', logic, state)).toBe('available');
+               expect(getLocationStatus('kak-well-top', logic, state)).toBe('available');
+               expect(getLocationStatus('kings-tomb', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('lost-woods-hideout', logic, state)).toBe('available');
+               expect(getLocationStatus('lumberjack', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('magic-bat', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pedestal', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('sick-kid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('tavern', logic, state)).toBe('available');
+       });
+
+       test('South Light World', () => {
+               expect(getLocationStatus('aginah', logic, state)).toBe('available');
+               expect(getLocationStatus('checkerboard', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('desert-ledge', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('flooded-chest', logic, state)).toBe('available');
+               expect(getLocationStatus('hobo', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('ice-rod-cave', logic, state)).toBe('available');
+               expect(getLocationStatus('lake-hylia-island', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('library', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('links-house', logic, state)).toBe('available');
+               expect(getLocationStatus('mini-moldorm-far-left', logic, state)).toBe('available');
+               expect(getLocationStatus('mini-moldorm-left', logic, state)).toBe('available');
+               expect(getLocationStatus('mini-moldorm-right', logic, state)).toBe('available');
+               expect(getLocationStatus('mini-moldorm-far-right', logic, state)).toBe('available');
+               expect(getLocationStatus('mini-moldorm-npc', logic, state)).toBe('available');
+               expect(getLocationStatus('race-game', logic, state)).toBe('available');
+               expect(getLocationStatus('sunken-treasure', logic, state)).toBe('available');
+       });
+
+       test('Death Mountain', () => {
+               expect(getLocationStatus('ether-tablet', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('floating-island', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('mimic-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('old-man', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-far-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-mid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-lower-far-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-upper-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('paradox-upper-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spec-rock', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spec-rock-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spiral-cave', logic, state)).toBe('unavailable');
+       });
+
+       test('East Dark World', () => {
+               expect(getLocationStatus('brewery', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('bumper-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('c-house', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('chest-game', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hammer-pegs', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('purple-chest', logic, state)).toBe('unavailable');
+       });
+
+       test('West Dark World', () => {
+               expect(getLocationStatus('catfish', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid-fairy-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('pyramid-fairy-right', logic, state)).toBe('unavailable');
+       });
+
+       test('South Dark World', () => {
+               expect(getLocationStatus('blacksmith', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('digging-game', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hype-cave-top', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hype-cave-left', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hype-cave-right', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hype-cave-bottom', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hype-cave-npc', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('stumpy', logic, state)).toBe('unavailable');
+       });
+
+       test('Dark Death Mountain', () => {
+               expect(getLocationStatus('hookshot-cave-tl', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-tr', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-bl', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('hookshot-cave-br', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('spike-cave', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('super-bunny-top', logic, state)).toBe('unavailable');
+               expect(getLocationStatus('super-bunny-bottom', logic, state)).toBe('unavailable');
+       });
+});
diff --git a/tests/js/helpers/tracker.test.js b/tests/js/helpers/tracker.test.js
new file mode 100644 (file)
index 0000000..ceaaacc
--- /dev/null
@@ -0,0 +1,204 @@
+import {
+       CONFIG,
+       configureDungeons,
+       getDungeonBoss,
+       getDungeonRemainingItems,
+       makeEmptyState,
+} from 'helpers/tracker';
+
+describe('default dungeon configuration', () => {
+       const dungeons = configureDungeons(CONFIG);
+       const state = makeEmptyState();
+
+       test('HC', () => {
+               const dungeon = dungeons.find(d => d.id === 'hc');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(6);
+       });
+
+       test('CT', () => {
+               const dungeon = dungeons.find(d => d.id === 'ct');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('aga');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(0);
+       });
+
+       test('GT', () => {
+               const dungeon = dungeons.find(d => d.id === 'gt');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('aga');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(20);
+       });
+
+       test('EP', () => {
+               const dungeon = dungeons.find(d => d.id === 'ep');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('armos');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(3);
+       });
+
+       test('DP', () => {
+               const dungeon = dungeons.find(d => d.id === 'dp');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('lanmolas');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(2);
+       });
+
+       test('TH', () => {
+               const dungeon = dungeons.find(d => d.id === 'th');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('moldorm');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(2);
+       });
+
+       test('PD', () => {
+               const dungeon = dungeons.find(d => d.id === 'pd');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('helma');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(5);
+       });
+
+       test('SP', () => {
+               const dungeon = dungeons.find(d => d.id === 'sp');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('arrghus');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(6);
+       });
+
+       test('SW', () => {
+               const dungeon = dungeons.find(d => d.id === 'sw');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('mothula');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(2);
+       });
+
+       test('TT', () => {
+               const dungeon = dungeons.find(d => d.id === 'tt');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('blind');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(4);
+       });
+
+       test('IP', () => {
+               const dungeon = dungeons.find(d => d.id === 'ip');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('kholdstare');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(3);
+       });
+
+       test('MM', () => {
+               const dungeon = dungeons.find(d => d.id === 'mm');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('vitreous');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(2);
+       });
+
+       test('TR', () => {
+               const dungeon = dungeons.find(d => d.id === 'tr');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('trinexx');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(5);
+       });
+});
+
+describe('keysanity dungeon configuration', () => {
+       const config = {
+               ...CONFIG,
+               wildMap: true,
+               wildCompass: true,
+               wildSmall: true,
+               wildBig: true,
+       };
+       const dungeons = configureDungeons(config);
+       const state = makeEmptyState();
+
+       test('HC', () => {
+               const dungeon = dungeons.find(d => d.id === 'hc');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(8);
+       });
+
+       test('CT', () => {
+               const dungeon = dungeons.find(d => d.id === 'ct');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('aga');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(2);
+       });
+
+       test('GT', () => {
+               const dungeon = dungeons.find(d => d.id === 'gt');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('aga');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(27);
+       });
+
+       test('EP', () => {
+               const dungeon = dungeons.find(d => d.id === 'ep');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('armos');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(6);
+       });
+
+       test('DP', () => {
+               const dungeon = dungeons.find(d => d.id === 'dp');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('lanmolas');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(6);
+       });
+
+       test('TH', () => {
+               const dungeon = dungeons.find(d => d.id === 'th');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('moldorm');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(6);
+       });
+
+       test('PD', () => {
+               const dungeon = dungeons.find(d => d.id === 'pd');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('helma');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(14);
+       });
+
+       test('SP', () => {
+               const dungeon = dungeons.find(d => d.id === 'sp');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('arrghus');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(10);
+       });
+
+       test('SW', () => {
+               const dungeon = dungeons.find(d => d.id === 'sw');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('mothula');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(8);
+       });
+
+       test('TT', () => {
+               const dungeon = dungeons.find(d => d.id === 'tt');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('blind');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(8);
+       });
+
+       test('IP', () => {
+               const dungeon = dungeons.find(d => d.id === 'ip');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('kholdstare');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(8);
+       });
+
+       test('MM', () => {
+               const dungeon = dungeons.find(d => d.id === 'mm');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('vitreous');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(8);
+       });
+
+       test('TR', () => {
+               const dungeon = dungeons.find(d => d.id === 'tr');
+               expect(dungeon).not.toBeNull();
+               expect(getDungeonBoss(state, dungeon)).toBe('trinexx');
+               expect(getDungeonRemainingItems(state, dungeon)).toBe(12);
+       });
+});