converter tests

This commit is contained in:
zkldi
2021-05-18 08:07:39 +01:00
parent cfc500e1b7
commit d53de4c4d0
7 changed files with 255 additions and 10 deletions
@@ -73,7 +73,7 @@ export async function UpdateUsersGamePlaytypeStats(
classes,
};
logger.info(`Created new player gamestats for ${game} (${playtype})`);
logger.info(`Created new gamestats for ${game} (${playtype})`);
await db["game-stats"].insert(newStats);
}
@@ -0,0 +1,225 @@
/* 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 { ConvertFileS3, ParseDifficulty, ResolveS3Lamp } from "./converter";
import { S3Score } from "./types";
import deepmerge from "deepmerge";
const logger = CreateLogCtx("converter.test.ts");
function cfile(data: S3Score) {
return ConvertFileS3(data, {}, "file/solid-state-squad", logger);
}
t.test("#ConvertFileS3", (t) => {
t.beforeEach(ResetDBState);
t.beforeEach(() => {
delete BaseS3Score._id; // just incase
});
function mfile(merge: Partial<S3Score>) {
return cfile(deepmerge(BaseS3Score, merge));
}
const dryScore = {
game: "iidx",
comment: null,
importType: "file/solid-state-squad",
service: "Solid State Squad",
scoreData: {
// percent: 6.36, -- fpa
grade: "F",
score: 100,
lamp: "FULL COMBO",
hitData: {
pgreat: 25,
great: 50,
good: 0,
bad: 0,
poor: 4,
},
hitMeta: {},
},
scoreMeta: {},
timeAchieved: 1287460462000,
};
const BaseS3Score = GetKTDataJSON("./s3/s3score.json");
t.test("Should import a valid S3 score", async (t) => {
const res = await cfile(BaseS3Score);
t.hasStrict(
res,
{
chart: Testing511SPA,
song: Testing511Song,
dryScore,
} as any,
"Should correctly return the song, chart and DryScore."
);
t.end();
});
t.test("Should support comments in S3 scores", async (t) => {
const res = await mfile({ comment: "FOO BAR" });
t.hasStrict(
res,
{
chart: Testing511SPA,
song: Testing511Song,
dryScore: deepmerge(dryScore, { comment: "FOO BAR" }),
} as any,
"Should correctly return the song, chart and DryScore."
);
t.end();
});
t.test("Should find song case-insensitively", async (t) => {
await db.charts.iidx.remove({});
await db.charts.iidx.insert(GetKTDataJSON("./kamaitachi/ktblack-charts-iidx.json"));
await db.songs.iidx.remove({});
await db.songs.iidx.insert(GetKTDataJSON("./kamaitachi/ktblack-songs-iidx.json"));
const res = await mfile({ songname: "gamBOL", diff: 7 });
t.hasStrict(
res,
{
chart: { songID: 7, difficulty: "HYPER", playtype: "SP" },
song: { title: "GAMBOL" },
// dryScore, dont care
} as any,
"Should correctly return the song, chart and DryScore."
);
t.end();
});
t.test("Should reject invalid styles in S3 scores", (t) => {
t.rejects(mfile({ styles: "3rd,4th,INVALID" }), {
message: /Song has invalid style INVALID/u,
} as any);
t.end();
});
t.test("Should throw ktdatanf if no song", (t) => {
t.rejects(mfile({ songname: "INVALID SONG TITLE" }), {
message: /Could not find song with title INVALID SONG TITLE/u,
} as any);
t.end();
});
t.test("Should throw ktdatanf if no song", (t) => {
t.rejects(mfile({ diff: "B" }), {
message: /Could not find chart 5\.1\.1\. \(SP LEGGENDARIA/u,
} as any);
t.end();
});
t.test("Should throw a skipscore if the song is 5key", (t) => {
t.rejects(mfile({ diff: 5 }), {
message: /5KEY scores are not supported/u,
} as any);
t.end();
});
t.test("Should throw an invalidscore if the difficulty is invalid", (t) => {
t.rejects(mfile({ diff: "INVALID" as any }), {
message: /Invalid difficulty INVALID/u,
} as any);
t.end();
});
t.test("Should throw an invalidscore if the hardeasy is invalid", (t) => {
t.rejects(mfile({ mods: { hardeasy: "INVALID" } as any, cleartype: "cleared" }), {
message: /Invalid cleartype of 'cleared' with hardeasy of INVALID/u,
} as any);
t.end();
});
t.test("Should throw an invalidscore if the cleartype is invalid", (t) => {
t.rejects(mfile({ cleartype: "INVALID" as any }), {
message: /Invalid cleartype of INVALID/u,
} as any);
t.end();
});
t.test("Should throw an invalidscore if the exscore is greater than MAX", (t) => {
t.rejects(mfile({ exscore: 10000 }), {
message: /Percent was greater than 100%/u,
} as any);
t.end();
});
t.test("Should throw an invalidscore if the date is invalid.", (t) => {
t.rejects(mfile({ date: "INVALID" }), {
message: /Invalid timestamp of INVALID - could not parse/u,
} as any);
t.end();
});
t.end();
});
t.test("#ParseDifficulty", (t) => {
t.beforeEach(ResetDBState);
t.strictSame(ParseDifficulty("L7"), { playtype: "SP", difficulty: "NORMAL" });
t.strictSame(ParseDifficulty(7), { playtype: "SP", difficulty: "HYPER" });
t.strictSame(ParseDifficulty("A"), { playtype: "SP", difficulty: "ANOTHER" });
t.strictSame(ParseDifficulty("B"), { playtype: "SP", difficulty: "LEGGENDARIA" });
t.strictSame(ParseDifficulty("L14"), { playtype: "DP", difficulty: "NORMAL" });
t.strictSame(ParseDifficulty(14), { playtype: "DP", difficulty: "HYPER" });
t.strictSame(ParseDifficulty("A14"), { playtype: "DP", difficulty: "ANOTHER" });
t.strictSame(ParseDifficulty("B14"), { playtype: "DP", difficulty: "LEGGENDARIA" });
t.throws(() => ParseDifficulty(5));
t.end();
});
t.test("#ResolveS3Lamp", (t) => {
t.beforeEach(ResetDBState);
const BaseS3Score = GetKTDataJSON("./s3/s3score.json");
t.equal(ResolveS3Lamp({ cleartype: "played" } as S3Score, logger), "FAILED");
t.equal(ResolveS3Lamp({ cleartype: "cleared", mods: {} } as S3Score, logger), "CLEAR");
t.equal(
ResolveS3Lamp({ cleartype: "cleared", mods: { hardeasy: "E" } } as S3Score, logger),
"EASY CLEAR"
);
t.equal(
ResolveS3Lamp({ cleartype: "cleared", mods: { hardeasy: "H" } } as S3Score, logger),
"HARD CLEAR"
);
t.equal(ResolveS3Lamp({ cleartype: "combo" } as S3Score, logger), "FULL COMBO");
t.equal(ResolveS3Lamp({ cleartype: "comboed" } as S3Score, logger), "FULL COMBO");
t.equal(ResolveS3Lamp({ cleartype: "perfect" } as S3Score, logger), "FULL COMBO");
t.equal(ResolveS3Lamp({ cleartype: "perfected" } as S3Score, logger), "FULL COMBO");
t.throws(() => ResolveS3Lamp({ cleartype: "invalid" } as any, logger));
t.throws(() =>
ResolveS3Lamp({ cleartype: "cleared", mods: { hardeasy: "invalid" } } as any, logger)
);
t.end();
});
t.teardown(CloseMongoConnection);
@@ -13,15 +13,15 @@ import {
GetGradeFromPercent,
} from "../../../framework/common/score-utils";
function ParseDifficulty(
diff: string | number
export function ParseDifficulty(
diff: S3Score["diff"]
): { playtype: Playtypes["iidx"]; difficulty: Difficulties["iidx:SP" | "iidx:DP"] } {
switch (diff) {
case "L7":
return { playtype: "SP", difficulty: "NORMAL" };
case 7:
return { playtype: "SP", difficulty: "HYPER" };
case "A7":
case "A":
return { playtype: "SP", difficulty: "ANOTHER" };
case "B":
return { playtype: "SP", difficulty: "LEGGENDARIA" };
@@ -40,7 +40,7 @@ function ParseDifficulty(
}
}
function ResolveS3Lamp(data: S3Score, logger: KtLogger): Lamps["iidx:SP" | "iidx:DP"] {
export function ResolveS3Lamp(data: S3Score, logger: KtLogger): Lamps["iidx:SP" | "iidx:DP"] {
if (data.cleartype === "played") {
return "FAILED";
} else if (data.cleartype === "cleared") {
@@ -94,7 +94,7 @@ function ConvertVersion(joinedStyles: string) {
const convertedStyle = S3_VERSION_CONV[style];
if (!convertedStyle) {
throw new InvalidScoreFailure(`Song has invalid style ${style}`);
throw new InvalidScoreFailure(`Song has invalid style ${style}.`);
}
return convertedStyle;
@@ -193,7 +193,7 @@ t.test("#ParseSolidStateXML", (t) => {
() =>
ParseSolidStateXML(
MockMulterFile(
GetKTDataBuffer("./s3/billion-laughs.xml"),
GetKTDataBuffer("./s3/danger/billion-laughs.xml"),
"billion-laughs.xml"
),
{},
@@ -213,7 +213,10 @@ t.test("#ParseSolidStateXML", (t) => {
const time = process.hrtime.bigint();
const res = ParseSolidStateXML(
MockMulterFile(GetKTDataBuffer("./s3/specific-blaugh.xml"), "specific-blaugh.xml"),
MockMulterFile(
GetKTDataBuffer("./s3/danger/specific-blaugh.xml"),
"specific-blaugh.xml"
),
{},
logger
);
@@ -17,7 +17,7 @@ const PR_SolidState: PrudenceSchema = {
song: [
{
id: p.isPositiveInteger,
diff: p.isIn("L7", 7, "A", "B", "5", "L14", 14, "A14", "B14"),
diff: p.isIn("L7", 7, "A", "B", 5, "L14", 14, "A14", "B14"),
songname: "string",
styles: "string",
@@ -2,7 +2,7 @@ import { integer } from "kamaitachi-common";
export interface S3Score {
id: integer;
diff: "5" | "L7" | 7 | "A" | "B" | "L14" | 14 | "A14" | "B14";
diff: 5 | "L7" | 7 | "A" | "B" | "L14" | 14 | "A14" | "B14";
songname: string;
exscore: integer;
styles: string;
@@ -0,0 +1,17 @@
{
"id": 187,
"diff": "A",
"songname": "5.1.1.",
"styles": "3rd",
"exscore": 100,
"scorebreakdown": {
"justgreats": 25,
"greats": 50,
"good": 0,
"bad": 0,
"poor": 4
},
"mods": {},
"cleartype": "perfect",
"date": "2010-10-19 04:54:22"
}