mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-08 22:59:52 +03:00
converter tests
This commit is contained in:
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user