Ratings should be nullable.

Fixes #611
This commit is contained in:
zkldi
2021-12-30 18:49:26 +00:00
parent b2b33433fa
commit 21360031e0
7 changed files with 56 additions and 16 deletions
+1 -1
View File
@@ -82,7 +82,7 @@
"rimraf": "3.0.2",
"safe-json-stringify": "1.2.0",
"seq-logging": "^1.1.1",
"tachi-common": "0.4.12",
"tachi-common": "0.4.14",
"ts-node": "10.0.0",
"tsconfig-paths": "3.10.1",
"typescript": "4.3.4",
+4 -4
View File
@@ -63,7 +63,7 @@ specifiers:
safe-json-stringify: 1.2.0
seq-logging: ^1.1.1
supertest: 6.1.3
tachi-common: 0.4.12
tachi-common: 0.4.14
tap: 15.0.9
ts-node: 10.0.0
tsconfig-paths: 3.10.1
@@ -107,7 +107,7 @@ dependencies:
rimraf: 3.0.2
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
tachi-common: 0.4.12
tachi-common: 0.4.14
ts-node: 10.0.0_83f53b0a0c5616d3fa00ed4e30b9ce1b
tsconfig-paths: 3.10.1
typescript: 4.3.4
@@ -5386,8 +5386,8 @@ packages:
strip-ansi: 6.0.0
dev: true
/tachi-common/0.4.12:
resolution: {integrity: sha512-PsmVP5oJNnCvx3Omc6s6TVSheHmmiG/MJJAtUtcdeG8fwx38ulevVBiB2lSLTUldAh+HMtRvg5m0Qf/ts1QlwQ==}
/tachi-common/0.4.14:
resolution: {integrity: sha512-+D5ljllIWQNRohyENL/IhK+E/st7lP3kj5EydlxBCDla9eFGLFerwp7XxWtCj4tjvH3Mc0zhwuAU4P5y6gd9Cg==}
dependencies:
monk: 7.3.4
transitivePeerDependencies:
@@ -11,11 +11,15 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return BPI for IIDX", async (t) => {
const res = await CalculateRatings("iidx", "SP", 1, logger);
t.strictSame(res, { BPI: 0, ktLampRating: 0 }, "Should return BPI as a custom key.");
t.strictSame(res, { BPI: null, ktLampRating: null }, "Should return BPI as a custom key.");
const resDP = await CalculateRatings("iidx", "DP", 1, logger);
t.strictSame(resDP, { BPI: 0, ktLampRating: 0 }, "Should return BPI as a custom key.");
t.strictSame(
resDP,
{ BPI: null, ktLampRating: null },
"Should return BPI as a custom key."
);
t.end();
});
@@ -23,7 +27,7 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return VF6 for SDVX", async (t) => {
const res = await CalculateRatings("sdvx", "Single", 1, logger);
t.strictSame(res, { VF6: 0 }, "Should return VF6 keys.");
t.strictSame(res, { VF6: null }, "Should return VF6 keys.");
t.end();
});
@@ -31,7 +35,7 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return VF6 for USC:Keyboard", async (t) => {
const res = await CalculateRatings("usc", "Keyboard", 1, logger);
t.strictSame(res, { VF6: 0 }, "Should return VF6 keys.");
t.strictSame(res, { VF6: null }, "Should return VF6 keys.");
t.end();
});
@@ -39,7 +43,7 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return VF6 for USC:Controller", async (t) => {
const res = await CalculateRatings("usc", "Controller", 1, logger);
t.strictSame(res, { VF6: 0 }, "Should return VF6 keys.");
t.strictSame(res, { VF6: null }, "Should return VF6 keys.");
t.end();
});
@@ -47,11 +51,11 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return MFCP for DDR", async (t) => {
const res = await CalculateRatings("ddr", "SP", 1, logger);
t.strictSame(res, { MFCP: 0, ktRating: 0 }, "Should return MFCP keys.");
t.strictSame(res, { MFCP: null, ktRating: null }, "Should return MFCP keys.");
const resDP = await CalculateRatings("ddr", "DP", 1, logger);
t.strictSame(resDP, { MFCP: 0, ktRating: 0 }, "Should return MFCP keys.");
t.strictSame(resDP, { MFCP: null, ktRating: null }, "Should return MFCP keys.");
t.end();
});
@@ -59,11 +63,11 @@ t.test("#CalculateRatings", (t) => {
t.test("Should return skill for Gitadora", async (t) => {
const res = await CalculateRatings("gitadora", "Dora", 1, logger);
t.strictSame(res, { skill: 0 }, "Should return skill keys.");
t.strictSame(res, { skill: null }, "Should return skill keys.");
const resDP = await CalculateRatings("gitadora", "Gita", 1, logger);
t.strictSame(resDP, { skill: 0 }, "Should return skill keys.");
t.strictSame(resDP, { skill: null }, "Should return skill keys.");
t.end();
});
@@ -19,15 +19,29 @@ function LazySumAll(key: CustomCalcNames) {
playtype: playtype,
userID: userID,
isPrimary: true,
[`calculatedData.${key}`]: { $gt: 0 },
[`calculatedData.${key}`]: { $type: "number" },
});
if (sc.length === 0) {
return null;
}
const result = sc.reduce((a, b) => a + b.calculatedData[key]!, 0);
return result;
};
}
/**
* Curries a function that returns the sum of N best ratings on `key`.
*
* @param key - What rating value to sum.
* @param n - The amount of rating values to pull.
* @param returnMean - Optionally, if true, return the sum of these values divided by N.
*
* @returns - Number if the user has scores with that rating algorithm, null if they have
* no scores with this rating algorithm that are non-null.
*/
function LazyCalcN(key: CustomCalcNames, n: integer, returnMean?: boolean) {
return async (game: Game, playtype: Playtypes[Game], userID: integer) => {
const sc = await db["personal-bests"].find(
@@ -36,7 +50,7 @@ function LazyCalcN(key: CustomCalcNames, n: integer, returnMean?: boolean) {
playtype: playtype,
userID: userID,
isPrimary: true,
[`calculatedData.${key}`]: { $gt: 0 },
[`calculatedData.${key}`]: { $type: "number" },
},
{
limit: n,
@@ -44,6 +58,10 @@ function LazyCalcN(key: CustomCalcNames, n: integer, returnMean?: boolean) {
}
);
if (sc.length === 0) {
return null;
}
let result = sc.reduce((a, b) => a + b.calculatedData[key]!, 0);
if (returnMean) {
@@ -210,6 +228,10 @@ async function CalculateWACCARate(
}
);
if (best15Hot.length + best35Cold.length === 0) {
return null;
}
return (
best15Hot.reduce((a, r) => a + r.calculatedData.rate!, 0) +
best35Cold.reduce((a, r) => a + r.calculatedData.rate!, 0)
@@ -236,6 +258,10 @@ async function CalculateGitadoraSkill(
GetBestRatingOnSongs(coldSongIDs, userID, game, playtype, "skill"),
]);
if (bestHotScores.length + bestScores.length === 0) {
return null;
}
let skill = 0;
skill += bestHotScores.reduce((a, r) => a + r.calculatedData.skill!, 0);
skill += bestScores.reduce((a, r) => a + r.calculatedData.skill!, 0);
@@ -12,6 +12,10 @@ const logger = CreateLogCtx(__filename);
// more of an integration test
t.test("#UpdateUsersGamePlaytypeStats", (t) => {
t.beforeEach(ResetDBState);
t.beforeEach(async () => {
delete TestingIIDXSPScorePB._id;
await db["personal-bests"].insert(TestingIIDXSPScorePB);
});
t.test(
"Should create new UserGameStats and UserGameSettings if the user has none",
@@ -222,6 +222,9 @@ export function ConvertUSCChart(uscChartDoc: USCClientChart, playtype: Playtypes
data: {
hashSHA1: uscChartDoc.chartHash,
isOfficial: false,
bpm: uscChartDoc.bpm,
effector: uscChartDoc.effector,
illustrator: uscChartDoc.illustrator,
},
};
+3
View File
@@ -502,6 +502,9 @@ export const uscChart: ChartDocument<"usc:Controller" | "usc:Keyboard"> = {
data: {
hashSHA1: "USC_CHART_HASH",
isOfficial: false,
bpm: "128",
effector: "foo",
illustrator: "bar",
},
tierlistInfo: {},
isPrimary: true,