From 9885721d55ed696ecb187a85ac9f3b3bffba0367 Mon Sep 17 00:00:00 2001 From: ad044 Date: Mon, 25 Jul 2022 16:36:47 +0400 Subject: [PATCH] added tests --- __tests__/core/handleEvent.test.ts | 12 +++ __tests__/utils/boot.test.ts | 29 +++++++ __tests__/utils/node.test.ts | 125 +++++++++++++++++++++++++++++ __tests__/utils/save.test.ts | 98 ++++++++++++++++++++++ __tests__/utils/site.test.ts | 55 +++++++++++++ 5 files changed, 319 insertions(+) create mode 100644 __tests__/core/handleEvent.test.ts create mode 100644 __tests__/utils/boot.test.ts create mode 100644 __tests__/utils/node.test.ts create mode 100644 __tests__/utils/save.test.ts create mode 100644 __tests__/utils/site.test.ts diff --git a/__tests__/core/handleEvent.test.ts b/__tests__/core/handleEvent.test.ts new file mode 100644 index 0000000..c0a05aa --- /dev/null +++ b/__tests__/core/handleEvent.test.ts @@ -0,0 +1,12 @@ +import { enterSsknScene } from "@/core/events"; +import handleEvent from "@/core/handleEvent"; +import { useStore } from "@/store"; +import { GameScene } from "@/types"; + +it("Checks whether handleEvent applies mutations correctly", () => { + const initialState = useStore.getState(); + handleEvent(enterSsknScene); + const newState = useStore.getState(); + expect(newState.scene).toEqual(GameScene.Sskn); + expect(newState.prev.scene).toEqual(initialState.scene); +}); diff --git a/__tests__/utils/boot.test.ts b/__tests__/utils/boot.test.ts new file mode 100644 index 0000000..65ebcc8 --- /dev/null +++ b/__tests__/utils/boot.test.ts @@ -0,0 +1,29 @@ +import { addCharacter } from "@/utils/boot"; + +it("Handles the logic for Japanese characters", () => { + // cant be first character check + expect(addCharacter("", "ン")).toEqual(""); + // if its not first, then fine + expect(addCharacter("キ", "ン")).toEqual("キン"); + //「ー」 cannot be added to 「ッ」 and 「ン」or itself + expect(addCharacter("キッ", "ー")).toEqual("キッ"); + expect(addCharacter("キン", "ー")).toEqual("キン"); + expect(addCharacter("キー", "ー")).toEqual("キー"); + // characters that can be followed by the lowercase characters + expect(addCharacter("キ", "ャ")).toEqual("キャ"); + // cant be followed by lowercase character + expect(addCharacter("ー", "ャ")).toEqual("ー"); + // for 「ッ」, it can added to any character except itself + expect(addCharacter("ャ", "ッ")).toEqual("ャッ"); + // cant be added + expect(addCharacter("ッ", "ッ")).toEqual("ッ"); + // dakuten + expect(addCharacter("カ", "゛")).toEqual("ガ"); + // cant be appended + expect(addCharacter("ガ", "゛")).toEqual("ガ"); + // handakuten + expect(addCharacter("ハ", "゜")).toEqual("パ"); + // cant be appended + expect(addCharacter("キ", "゜")).toEqual("キ"); + expect(addCharacter("パ", "゜")).toEqual("パ"); +}); diff --git a/__tests__/utils/node.test.ts b/__tests__/utils/node.test.ts new file mode 100644 index 0000000..116ed38 --- /dev/null +++ b/__tests__/utils/node.test.ts @@ -0,0 +1,125 @@ +import { Direction, GameSite } from "@/types"; +import { + findNode, + findNodeFromWord, + getNode, + isNodeVisible, +} from "@/utils/node"; +import gameProgressJson from "@/json/initial_progress.json"; +import { useStore } from "@/store"; + +it("Finds nodes from words properly", () => { + expect(findNodeFromWord("father", getNode("0606b")).name).toEqual("Lda151"); + expect(findNodeFromWord("father", getNode("0105b")).name).toEqual("Lda155"); + expect(findNodeFromWord("father", getNode("0123b")).name).toEqual("Lda164"); + expect(findNodeFromWord("father", getNode("0502b")).name).toEqual("Lda200"); + expect(findNodeFromWord("father", getNode("1118b")).name).toEqual("Cou041"); + expect(findNodeFromWord("father", getNode("0606b")).name).toEqual("Lda151"); + expect(findNodeFromWord("chaos", getNode("0115b")).name).toEqual("Tda056"); + expect(findNodeFromWord("chaos", getNode("0311b")).name).toEqual("Tda059"); + expect(findNodeFromWord("prompt", getNode("0115b")).name).toEqual("Tda072"); + expect(findNodeFromWord("abuse", getNode("1622a")).name).toEqual("Lda005"); + expect(findNodeFromWord("abuse", getNode("0718a")).name).toEqual("Dc1012"); +}); + +it("Finds node by it's id", () => { + expect(getNode("0422a").name).toEqual("Tda028"); + expect(getNode("0000a").name).toEqual("Env001"); + expect(getNode("0616a").name).toEqual("Cou015"); + expect(getNode("0100b").name).toEqual("SSkn04#"); + expect(getNode("0101b").name).toEqual("Dc1025"); +}); + +it("Checks if the node is visible", () => { + const oneViewCount = { ...gameProgressJson, final_video_viewcount: 1 }; + const twoViewCount = { ...gameProgressJson, final_video_viewcount: 2 }; + const threeViewCount = { ...gameProgressJson, final_video_viewcount: 3 }; + const fourViewCount = { ...gameProgressJson, final_video_viewcount: 4 }; + + expect(isNodeVisible(getNode("0422a"), gameProgressJson)).toEqual(true); + expect(isNodeVisible(getNode("0413a"), gameProgressJson)).toEqual(true); + expect(isNodeVisible(getNode("0406a"), gameProgressJson)).toEqual(false); + expect(isNodeVisible(getNode("0410a"), gameProgressJson)).toEqual(false); + expect(isNodeVisible(getNode("0406a"), oneViewCount)).toEqual(true); + expect(isNodeVisible(getNode("0612a"), gameProgressJson)).toEqual(false); + expect(isNodeVisible(getNode("0612a"), oneViewCount)).toEqual(true); + expect(isNodeVisible(getNode("0612a"), twoViewCount)).toEqual(true); + expect(isNodeVisible(getNode("0801a"), fourViewCount)).toEqual(true); + expect(isNodeVisible(getNode("0801a"), threeViewCount)).toEqual(false); +}); + +/* + visual representation of the state we're working with + [null, "0517", null, null], + [null, null, "0510", "0513"], + ["0506", null, null, null], + | +[null, null, null, "0422"], ["0422", "0417", null, null], [null, "0416", "0417", "0420"], +[null, null, null, "0414"], - ["0414", null, null, "0413"], - ["0413", null, null, null], +[null, null, null, null], [null, null, null, "0405"], ["0405", null, null, null], + | +[null, null, null, null] [null, null, null, null], [null, null, null, null], +[null, null, null, null], [null, null, null, null], [null, null, null, null], +[null, null, null, null], [null, null, null, null], [null, null, null, null], +*/ + +it("Finds which node to go to", () => { + const state0414 = useStore.getState(); + + // from 0414 left + expect(findNode(state0414, Direction.Left, true)).toEqual({ + node: getNode("0414a"), + nodeMatrixIndex: { row: 1, col: 3 }, + siteSegment: 7, + level: 4, + didMove: true, + }); + + // from 0414 down + expect(findNode(state0414, Direction.Down, true)).toEqual({ + node: getNode("0405a"), + nodeMatrixIndex: { row: 2, col: 3 }, + siteSegment: 6, + level: 4, + didMove: false, + }); + + const state0405 = { + ...state0414, + node: getNode("0405a"), + nodeMatrixIndex: { row: 2, col: 3 }, + }; + // from 0405 down + expect(findNode(state0405, Direction.Down, true)).toEqual({ + node: null, + nodeMatrixIndex: { row: 2, col: 3 }, + siteSegment: 6, + level: 3, + didMove: true, + }); + + // from 0405 left + expect(findNode(state0405, Direction.Left, true)).toEqual({ + node: getNode("0417a"), + nodeMatrixIndex: { row: 0, col: 1 }, + siteSegment: 6, + level: 4, + didMove: false, + }); + + const state0506 = { + ...state0414, + node: getNode("0506a"), + nodeMatrixIndex: { row: 3, col: 0 }, + level: 5, + }; + + // from 0506 down + expect(findNode(state0506, Direction.Down, true)).toEqual({ + node: getNode("0422a"), + nodeMatrixIndex: { row: 0, col: 0 }, + siteSegment: 6, + level: 4, + didMove: true, + }); +}); diff --git a/__tests__/utils/save.test.ts b/__tests__/utils/save.test.ts new file mode 100644 index 0000000..6549209 --- /dev/null +++ b/__tests__/utils/save.test.ts @@ -0,0 +1,98 @@ +import { upgradeLegacySave } from "@/utils/save"; +import legacySaveJson from "@/json/legacy/save.json"; +import { GameSite, LegacySaveState } from "@/types"; + +it("Checks whether legacy saves get updated correctly", () => { + const res = upgradeLegacySave(legacySaveJson as LegacySaveState); + + const siteASaveState = res.siteSaveState[GameSite.A]; + expect(siteASaveState.level).toEqual(10); + expect(siteASaveState.siteSegment).toEqual(0); + expect(siteASaveState.nodeMatrixIndex.row).toEqual(1); + expect(siteASaveState.nodeMatrixIndex.col).toEqual(0); + expect(siteASaveState.node?.id).toEqual("1008a"); + expect(siteASaveState.node?.image_table_indices).toEqual([18, null, null]); + expect(siteASaveState.node?.media_file).toEqual("LAIN09.XA[6]"); + expect(siteASaveState.node?.name).toEqual("Tda040"); + expect(siteASaveState.node?.protocol_lines).toEqual([ + "authorized_il", + "decoded file:t", + "ftp/tl.S_server", + ]); + expect(siteASaveState.node?.required_final_video_viewcount).toEqual(0); + expect(siteASaveState.node?.site).toEqual(GameSite.A); + expect(siteASaveState.node?.title).toEqual("TOUKO's DIARY"); + expect(siteASaveState.node?.triggers_final_video).toEqual(0); + expect(siteASaveState.node?.type).toEqual(2); + expect(siteASaveState.node?.unlocked_by).toEqual(null); + expect(siteASaveState.node?.upgrade_requirement).toEqual(0); + expect(siteASaveState.node?.words).toEqual([ + "telephone", + "takeshi", + "simplicity", + ]); + + const siteBSaveState = res.siteSaveState[GameSite.B]; + expect(siteBSaveState.level).toEqual(13); + expect(siteBSaveState.siteSegment).toEqual(4); + expect(siteBSaveState.nodeMatrixIndex.row).toEqual(0); + expect(siteBSaveState.nodeMatrixIndex.col).toEqual(0); + expect(siteBSaveState.node?.id).toEqual("1320b"); + expect(siteBSaveState.node?.image_table_indices).toEqual([556, 557, null]); + expect(siteBSaveState.node?.media_file).toEqual("LAIN18.XA[7]"); + expect(siteBSaveState.node?.name).toEqual("Lda237"); + expect(siteBSaveState.node?.protocol_lines).toEqual([ + "anonymous_user", + "active_file:", + "ftp/tl.L_server", + ]); + expect(siteBSaveState.node?.required_final_video_viewcount).toEqual(0); + expect(siteBSaveState.node?.site).toEqual(GameSite.B); + expect(siteBSaveState.node?.title).toEqual("lain's DIARY"); + expect(siteBSaveState.node?.triggers_final_video).toEqual(1); + expect(siteBSaveState.node?.type).toEqual(0); + expect(siteBSaveState.node?.unlocked_by).toEqual("1300b"); + expect(siteBSaveState.node?.upgrade_requirement).toEqual(5); + expect(siteBSaveState.node?.words).toEqual([ + "evolution", + "thought", + "will&existence", + ]); + + expect(res.site).toEqual(GameSite.B); + expect(res.level).toEqual(1); + expect(res.playerName).toEqual("\u30b1\u30ea\u30b9"); + expect(res.siteSegment).toEqual(7); + expect(res.nodeMatrixIndex.row).toEqual(0); + expect(res.nodeMatrixIndex.col).toEqual(0); + + const node = res.node; + expect(node?.id).toEqual("0123b"); + expect(node?.image_table_indices).toEqual([512, 96, 366]); + expect(node?.media_file).toEqual("LAIN15.XA[21]"); + expect(node?.name).toEqual("Lda155"); + expect(node?.protocol_lines).toEqual([ + "anonymous_user", + "active_file:", + "ftp/tl.L_server", + ]); + expect(node?.required_final_video_viewcount).toEqual(0); + expect(node?.site).toEqual(GameSite.B); + expect(node?.title).toEqual("lain's DIARY"); + expect(node?.triggers_final_video).toEqual(0); + expect(node?.type).toEqual(0); + expect(node?.unlocked_by).toEqual(null); + expect(node?.upgrade_requirement).toEqual(3); + expect(node?.words).toEqual(["whereabouts", "father", "proof"]); + + const gameProgress = res.gameProgress; + expect(gameProgress.sskn_level).toEqual(7); + expect(gameProgress.gate_level).toEqual(4); + expect(gameProgress.final_video_viewcount).toEqual(4); + expect( + Object.values(gameProgress.polytan_unlocked_parts).every((v) => v) + ).toEqual(true); + expect( + Object.values(gameProgress.nodes).every((v) => v.is_viewed === true) + ).toEqual(true); +}); diff --git a/__tests__/utils/site.test.ts b/__tests__/utils/site.test.ts new file mode 100644 index 0000000..9ad052c --- /dev/null +++ b/__tests__/utils/site.test.ts @@ -0,0 +1,55 @@ +import { Direction } from "@/types"; +import { getRotationForSegment } from "@/utils/site"; + +const doCircles = ( + segment: number, + count: number, + direction: Direction.Left | Direction.Right, + startRotation?: number +): [number, number] => { + let currentCount = 0; + let rotation = startRotation ?? getRotationForSegment(segment); + let prevRotation = rotation; + while (currentCount < count) { + if (direction === Direction.Left) { + segment -= 1; + } + + if (direction === Direction.Right) { + segment += 1; + } + + if (segment > 7) { + currentCount += 1; + segment = 0; + } + + if (segment < 0) { + currentCount += 1; + segment = 7; + } + + prevRotation = rotation; + rotation = getRotationForSegment(segment, prevRotation); + if (direction === Direction.Left) { + expect(rotation).toBeCloseTo(prevRotation - Math.PI / 4, 6); + } + + if (direction === Direction.Right) { + expect(rotation).toBeCloseTo(prevRotation + Math.PI / 4, 6); + } + } + + return [segment, rotation]; +}; + +it("Checks if rotation calculator works", () => { + // site is initially positioned like this + doCircles(6, 3, Direction.Left); + doCircles(6, 3, Direction.Right); + doCircles(4, 6, Direction.Left); + doCircles(0, 6, Direction.Left); + // move to right then move to left based on last coordinates + let [segment, rotation] = doCircles(7, 6, Direction.Right); + doCircles(segment, 6, Direction.Left, rotation); +});