From 481245efdbf180c22e5372a7062e5c70cf03e472 Mon Sep 17 00:00:00 2001 From: zkldi Date: Fri, 14 May 2021 10:25:48 +0100 Subject: [PATCH] fer converter tests --- server/pnpm-lock.yaml | 6 +- .../ir/fervidex/converter.test.ts | 228 ++++++++++++++++++ .../import-types/ir/fervidex/converter.ts | 10 +- .../import-types/ir/fervidex/types.ts | 4 +- 4 files changed, 238 insertions(+), 10 deletions(-) create mode 100644 server/src/score-import/import-types/ir/fervidex/converter.test.ts diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index a5dfe1cc9..f11902cd7 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -60,7 +60,7 @@ dependencies: express-async-errors: 3.1.1_express@4.17.1 express-session: 1.17.1 fast-json-stable-hash: 1.0.2 - kamaitachi-common: github.com/zkldi/Kamaitachi-common/a5862a276877212d4e4b6b2cb4528d8ef52b729c + kamaitachi-common: github.com/zkldi/Kamaitachi-common/ebb9726e2247e6711ba3fd5b43b675596ebd556c mongodb: 3.6.6 monk: 7.3.4 multer: 1.4.2 @@ -4637,8 +4637,8 @@ packages: '@types/yoga-layout': 1.9.2 dev: true - github.com/zkldi/Kamaitachi-common/a5862a276877212d4e4b6b2cb4528d8ef52b729c: - resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/a5862a276877212d4e4b6b2cb4528d8ef52b729c} + github.com/zkldi/Kamaitachi-common/ebb9726e2247e6711ba3fd5b43b675596ebd556c: + resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/ebb9726e2247e6711ba3fd5b43b675596ebd556c} name: kamaitachi-common version: 0.1.0 dependencies: diff --git a/server/src/score-import/import-types/ir/fervidex/converter.test.ts b/server/src/score-import/import-types/ir/fervidex/converter.test.ts new file mode 100644 index 000000000..6aaedf9ef --- /dev/null +++ b/server/src/score-import/import-types/ir/fervidex/converter.test.ts @@ -0,0 +1,228 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import t from "tap"; +import db, { CloseMongoConnection } from "../../../../db/db"; +import CreateLogCtx from "../../../../logger"; +import ResetDBState from "../../../../test-utils/reset-db-state"; +import { GetKTDataJSON, Testing511Song, Testing511SPA } from "../../../../test-utils/test-data"; +import { InternalFailure } from "../../../framework/score-importing/converter-failures"; +import { + ConverterIRFervidex, + SplitFervidexChartRef, + KtchifyAssist, + KtchifyGauge, + KtchifyRandom, + KtchifyRange, +} from "./converter"; +import { FervidexScore } from "./types"; +import deepmerge from "deepmerge"; + +const logger = CreateLogCtx("converter.test.ts"); + +t.test("#SplitFervidexChartRef", (t) => { + t.strictSame(SplitFervidexChartRef("spb"), { playtype: "SP", difficulty: "BEGINNER" }); + t.strictSame(SplitFervidexChartRef("spn"), { playtype: "SP", difficulty: "NORMAL" }); + t.strictSame(SplitFervidexChartRef("sph"), { playtype: "SP", difficulty: "HYPER" }); + t.strictSame(SplitFervidexChartRef("spa"), { playtype: "SP", difficulty: "ANOTHER" }); + t.strictSame(SplitFervidexChartRef("spl"), { playtype: "SP", difficulty: "LEGGENDARIA" }); + t.strictSame(SplitFervidexChartRef("dpn"), { playtype: "DP", difficulty: "NORMAL" }); + t.strictSame(SplitFervidexChartRef("dph"), { playtype: "DP", difficulty: "HYPER" }); + t.strictSame(SplitFervidexChartRef("dpa"), { playtype: "DP", difficulty: "ANOTHER" }); + t.strictSame(SplitFervidexChartRef("dpl"), { playtype: "DP", difficulty: "LEGGENDARIA" }); + + t.throws( + () => SplitFervidexChartRef("INVALID" as "spn"), + new InternalFailure(`Invalid fervidex difficulty of INVALID`) as any + ); + + t.end(); +}); + +t.test("#KtchifyAssist", (t) => { + t.equal(KtchifyAssist("ASCR_LEGACY"), "FULL ASSIST"); + t.equal(KtchifyAssist("AUTO_SCRATCH"), "AUTO SCRATCH"); + t.equal(KtchifyAssist("FULL_ASSIST"), "FULL ASSIST"); + t.equal(KtchifyAssist("LEGACY_NOTE"), "LEGACY NOTE"); + t.equal(KtchifyAssist(null), "NO ASSIST"); + t.equal(KtchifyAssist(undefined), "NO ASSIST"); + + t.end(); +}); + +t.test("#KtchifyGauge", (t) => { + t.equal(KtchifyGauge("ASSISTED_EASY"), "ASSISTED EASY"); + t.equal(KtchifyGauge("EASY"), "EASY"); + t.equal(KtchifyGauge("HARD"), "HARD"); + t.equal(KtchifyGauge("EX_HARD"), "EX HARD"); + t.equal(KtchifyGauge(null), "NORMAL"); + t.equal(KtchifyGauge(undefined), "NORMAL"); + + t.end(); +}); + +t.test("#KtchifyRange", (t) => { + t.equal(KtchifyRange("HIDDEN_PLUS"), "HIDDEN+"); + t.equal(KtchifyRange("LIFT"), "LIFT"); + t.equal(KtchifyRange("LIFT_SUD_PLUS"), "LIFT SUD+"); + t.equal(KtchifyRange("SUDDEN_PLUS"), "SUDDEN+"); + t.equal(KtchifyRange("SUD_PLUS_HID_PLUS"), "SUD+ HID+"); + t.equal(KtchifyRange(null), "NONE"); + t.equal(KtchifyRange(undefined), "NONE"); + + t.end(); +}); + +t.test("#KtchifyRandom", (t) => { + t.equal(KtchifyRandom("MIRROR"), "MIRROR"); + t.equal(KtchifyRandom("R_RANDOM"), "R-RANDOM"); + t.equal(KtchifyRandom("S_RANDOM"), "S-RANDOM"); + t.equal(KtchifyRandom("RANDOM"), "RANDOM"); + t.equal(KtchifyRandom(null), "NONRAN"); + t.equal(KtchifyRandom(undefined), "NONRAN"); + + t.end(); +}); + +let baseFervidexScore: FervidexScore = GetKTDataJSON("./fervidex/base.json"); + +let baseDryScore = { + game: "iidx", + service: "Fervidex", + comment: null, + importType: "ir/fervidex", + scoreData: { + score: 68, + percent: 4.325699745547074, + grade: "F", + lamp: "FAILED", + hitData: { + pgreat: 34, + great: 0, + good: 0, + bad: 0, + poor: 6, + }, + hitMeta: { + fast: 0, + slow: 0, + maxCombo: 34, + gaugeHistory: [100, 50], + gauge: 50, + bp: 6, + comboBreak: null, + gsm: undefined, + }, + }, + scoreMeta: { + assist: "NO ASSIST", + gauge: "HARD", + random: "RANDOM", + range: "SUDDEN+", + }, +}; + +t.test("#ConverterIRFervidex", (t) => { + t.beforeEach(ResetDBState); + + t.test("Should convert a valid fervidex score into a dry score.", async (t) => { + let res = await ConverterIRFervidex( + baseFervidexScore, + { version: "27" }, + "ir/fervidex", + logger + ); + + t.hasStrict( + res, + { + song: Testing511Song, + chart: Testing511SPA, + dryScore: baseDryScore, + } as any, // broken + "Should return a dry score." + ); + + t.end(); + }); + + t.test("Should reject scores on unknown charts", (t) => { + t.rejects( + ConverterIRFervidex( + deepmerge(baseFervidexScore, { chart: "spl" }), + { version: "27" }, + "ir/fervidex", + logger + ), + { message: /could not find chart/giu } as any + ); + + t.end(); + }); + + t.test("Should throw internal failure on chart-song desync", async (t) => { + await db.songs.iidx.remove({}); // this forces desync + + t.rejects( + ConverterIRFervidex(baseFervidexScore, { version: "27" }, "ir/fervidex", logger), + { message: /Song 1 \(iidx\) has no parent song/giu } as any + ); + + t.end(); + }); + + t.test("Should throw invalid score on percent > 100.", (t) => { + t.rejects( + ConverterIRFervidex( + // @ts-expect-error eternally broken deepmerge + deepmerge(baseFervidexScore, { ex_score: 9999 }), + { version: "27" }, + "ir/fervidex", + logger + ), + { message: /Invalid score of 9999 for chart.*Resulted in percent/giu } as any + ); + + t.end(); + }); + + t.test("Should throw invalid score on gauge > 100.", (t) => { + t.rejects( + ConverterIRFervidex( + // @ts-expect-error eternally broken deepmerge + deepmerge(baseFervidexScore, { gauge: [150] }), + { version: "27" }, + "ir/fervidex", + logger + ), + { message: /Invalid value of gauge 150/giu } as any + ); + + t.end(); + }); + + t.test("Should convert undeflow gauge to null.", async (t) => { + let res = await ConverterIRFervidex( + deepmerge(baseFervidexScore, { gauge: [10, 5, 249, 248] }), + { version: "27" }, + "ir/fervidex", + logger + ); + + t.hasStrict( + res, + { + song: Testing511Song, + chart: Testing511SPA, + dryScore: deepmerge(baseDryScore, { + scoreData: { hitMeta: { gauge: null, gaugeHistory: [10, 5, null, null] } }, + }), + } as any, // broken + "Should return a dry score." + ); + + t.end(); + }); + + t.end(); +}); + +t.teardown(CloseMongoConnection); diff --git a/server/src/score-import/import-types/ir/fervidex/converter.ts b/server/src/score-import/import-types/ir/fervidex/converter.ts index a45236c5c..f64d02296 100644 --- a/server/src/score-import/import-types/ir/fervidex/converter.ts +++ b/server/src/score-import/import-types/ir/fervidex/converter.ts @@ -24,7 +24,7 @@ export const FERVIDEX_LAMP_LOOKUP = { 7: "FULL COMBO", }; -function KtchifyAssist( +export function KtchifyAssist( assist: FervidexScore["option"]["assist"] ): DryScore<"iidx:SP" | "iidx:DP">["scoreMeta"]["assist"] { switch (assist) { @@ -42,7 +42,7 @@ function KtchifyAssist( } } -function KtchifyGauge( +export function KtchifyGauge( gauge: FervidexScore["option"]["gauge"] ): DryScore<"iidx:SP" | "iidx:DP">["scoreMeta"]["gauge"] { switch (gauge) { @@ -51,7 +51,7 @@ function KtchifyGauge( case "EASY": return "EASY"; case "EX_HARD": - return "EX-HARD"; + return "EX HARD"; case "HARD": return "HARD"; case null: @@ -60,7 +60,7 @@ function KtchifyGauge( } } -function KtchifyRange( +export function KtchifyRange( gauge: FervidexScore["option"]["range"] ): DryScore<"iidx:SP" | "iidx:DP">["scoreMeta"]["range"] { switch (gauge) { @@ -80,7 +80,7 @@ function KtchifyRange( } } -function KtchifyRandom( +export function KtchifyRandom( gauge: FervidexScore["option"]["style"] ): DryScore<"iidx:SP" | "iidx:DP">["scoreMeta"]["random"] { switch (gauge) { diff --git a/server/src/score-import/import-types/ir/fervidex/types.ts b/server/src/score-import/import-types/ir/fervidex/types.ts index 607320ff3..6065b7eb2 100644 --- a/server/src/score-import/import-types/ir/fervidex/types.ts +++ b/server/src/score-import/import-types/ir/fervidex/types.ts @@ -34,8 +34,8 @@ export interface FervidexScore { | "LIFT" | "LIFT_SUD_PLUS" | null; - style?: "RANDOM" | "R_RANDOM" | "S_RANDOM" | "MIRROR"; - assist?: "AUTO_SCRATCH" | "LEGACY_NOTE" | "ASCR_LEGACY" | "FULL_ASSIST"; + style?: "RANDOM" | "R_RANDOM" | "S_RANDOM" | "MIRROR" | null; + assist?: "AUTO_SCRATCH" | "LEGACY_NOTE" | "ASCR_LEGACY" | "FULL_ASSIST" | null; }; pacemaker: {