RankingTests

This commit is contained in:
zkldi
2021-04-29 17:47:33 +01:00
parent a8a6a249e6
commit 99e04bbe99
5 changed files with 148 additions and 12 deletions
+3 -3
View File
@@ -62,7 +62,7 @@ dependencies:
express-async-errors: 3.1.1_express@4.17.1
express-session: 1.17.1
fast-json-stable-hash: 1.0.1
kamaitachi-common: github.com/zkldi/Kamaitachi-common/6fa12357c7e4442e7452a1edff71fcc5c0840953
kamaitachi-common: github.com/zkldi/Kamaitachi-common/5ef579cbd353a2211965f3a88915ced535766daf
mongodb: 3.6.6
monk: 7.3.4
multer: 1.4.2
@@ -4638,8 +4638,8 @@ packages:
'@types/yoga-layout': 1.9.2
dev: true
github.com/zkldi/Kamaitachi-common/6fa12357c7e4442e7452a1edff71fcc5c0840953:
resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/6fa12357c7e4442e7452a1edff71fcc5c0840953}
github.com/zkldi/Kamaitachi-common/5ef579cbd353a2211965f3a88915ced535766daf:
resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/5ef579cbd353a2211965f3a88915ced535766daf}
name: kamaitachi-common
version: 0.1.0
dependencies:
@@ -0,0 +1,83 @@
import t from "tap";
import db, { CloseMongoConnection } from "../../../../db/db";
import ResetDBState from "../../../../test-utils/reset-db-state";
import { Testing511SPA, TestingIIDXSPScorePB } from "../../../../test-utils/test-data";
import { GetRankingInfo } from "./create-pb-doc";
import deepmerge from "deepmerge";
t.test("#GetRankingInfo", (t) => {
t.beforeEach(ResetDBState);
let chartID = Testing511SPA.chartID;
t.test("Ranking info for one score", async (t) => {
await db["score-pbs"].insert([
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 50 }, userID: 1 }),
]);
let { outOf, ranking } = await GetRankingInfo(chartID, 1, 50);
t.equal(outOf, 1, "Should correctly determine we're out of 1 score.");
t.equal(ranking, 1, "Should correctly determine we're #1.");
t.end();
});
t.test("Ranking info for multiple scores", async (t) => {
await db["score-pbs"].insert([
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 50 }, userID: 1 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 60 }, userID: 2 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 70 }, userID: 3 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 80 }, userID: 4 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 40 }, userID: 5 }),
]);
let { outOf, ranking } = await GetRankingInfo(chartID, 1, 50);
t.equal(outOf, 5, "Should correctly determine we're out of 5 scores.");
t.equal(ranking, 4, "Should correctly determine we're #4/5.");
t.end();
});
t.test("#1 in Ranking Info for scores", async (t) => {
// insert some fake scores - our percent is 50.
await db["score-pbs"].insert([
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 90 }, userID: 1 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 60 }, userID: 2 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 70 }, userID: 3 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 80 }, userID: 4 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 40 }, userID: 5 }),
]);
let { outOf, ranking } = await GetRankingInfo(chartID, 1, 90);
t.equal(outOf, 5, "Should correctly determine we're out of 5 scores.");
t.equal(ranking, 1, "Should correctly determine we're #1/5.");
t.end();
});
t.test("#Last in Ranking Info for scores", async (t) => {
// insert some fake scores - our percent is 50.
await db["score-pbs"].insert([
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 0 }, userID: 1 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 60 }, userID: 2 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 70 }, userID: 3 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 80 }, userID: 4 }),
deepmerge(TestingIIDXSPScorePB, { scoreData: { percent: 40 }, userID: 5 }),
]);
let { outOf, ranking } = await GetRankingInfo(chartID, 1, 0);
t.equal(outOf, 5, "Should correctly determine we're out of 5 scores.");
t.equal(ranking, 5, "Should correctly determine we're #5/5.");
t.end();
});
t.end();
});
t.teardown(CloseMongoConnection);
@@ -37,7 +37,7 @@ export async function CreatePBDoc(userID: integer, chartID: string, logger: KtLo
}
)) as ScoreDocument; // guaranteed to not be null, but...
const pbDoc = await MergeScoreLampIntoPB(userID, scorePB, lampPB);
const pbDoc = await MergeScoreLampIntoPB(userID, scorePB, lampPB, logger);
return pbDoc;
}
@@ -47,7 +47,7 @@ export async function GetRankingInfo(
userID: integer,
percent: number
): Promise<{ outOf: number; ranking: number }> {
let { outOf, ranking } = await db["score-pbs"].aggregate([
let res = await db["score-pbs"].aggregate([
// exclude the requesting user because we cannot know whether they already have a pb on this chart
// or not - this means we can exec the same logic regardless of whether they already have a pb or not.
{ $match: { chartID, userID: { $ne: userID } } },
@@ -55,16 +55,22 @@ export async function GetRankingInfo(
$group: {
_id: null,
outOf: { $sum: 1 },
ranking: { $sum: { $gte: ["$scoreData.percent", percent] } },
ranking: { $sum: { $cond: [{ $gte: ["$scoreData.percent", percent] }, 1, 0] } },
},
},
{ $project: { outOf: 1, ranking: 1 } },
// { $project: { outOf: 1, ranking: 1 } },
]);
if (!res[0]) {
return { outOf: 1, ranking: 1 };
}
let { outOf, ranking } = res[0];
// add one to both stats to account for not including the requesting user
// if the field is undefined, there's no other scores to compare to.
outOf = outOf ? outOf++ : 1;
ranking = ranking ? ranking++ : 1;
outOf++;
ranking++;
return { outOf, ranking };
}
@@ -79,7 +85,8 @@ const GAME_SPECIFIC_MERGE_FNS: Record<string, any> = {
async function MergeScoreLampIntoPB(
userID: integer,
scorePB: ScoreDocument,
lampPB: ScoreDocument
lampPB: ScoreDocument,
logger: KtLogger
): Promise<PBScoreDocument> {
let { outOf, ranking } = await GetRankingInfo(
scorePB.chartID,
@@ -99,6 +106,8 @@ async function MergeScoreLampIntoPB(
outOf,
ranking,
highlight: scorePB.highlight || lampPB.highlight,
game: scorePB.game,
playtype: scorePB.playtype,
scoreData: {
score: scorePB.scoreData.score,
percent: scorePB.scoreData.percent,
@@ -119,7 +128,7 @@ async function MergeScoreLampIntoPB(
let GameSpecificMergeFn = GAME_SPECIFIC_MERGE_FNS[scorePB.game];
if (GameSpecificMergeFn) {
await GameSpecificMergeFn(pbDoc, scorePB, lampPB);
await GameSpecificMergeFn(pbDoc, scorePB, lampPB, logger);
}
return pbDoc;
+5 -1
View File
@@ -1,5 +1,5 @@
import fs from "fs";
import { ChartDocument } from "kamaitachi-common";
import { ChartDocument, PBScoreDocument } from "kamaitachi-common";
import path from "path";
import { DryScore } from "../types";
@@ -12,6 +12,10 @@ export const TestingIIDXSPDryScore = GetKTDataJSON(
"./kamaitachi/iidx-dryscore.json"
) as DryScore<"iidx:SP">;
export const TestingIIDXSPScorePB = GetKTDataJSON(
"./kamaitachi/iidx-scorepb.json"
) as PBScoreDocument<"iidx:SP">;
export const Testing511SPA = GetKTDataJSON(
"./kamaitachi/iidx-511spa.json"
) as ChartDocument<"iidx:SP">;
@@ -0,0 +1,40 @@
{
"chartID": "c2311194e3897ddb5745b1760d2c0141f933e683",
"userID": 1,
"calculatedData": {
"rating": 0,
"lampRating": 0,
"gameSpecific": {
"BPI": 10.10,
"KESDC": 9.558413110870934,
"K%": null
}
},
"comments": [],
"composedFrom": {
"scorePB": "R9a8d45b332a5ab18ef6f11f052defe2fa497596e69991a8b13ead3ecc3dd17d1",
"lampPB": "R9a8d45b332a5ab18ef6f11f052defe2fa497596e69991a8b13ead3ecc3dd17d1"
},
"highlight": false,
"outOf": 1,
"ranking": 1,
"scoreData": {
"score": 1479,
"percent": 94.08396946564885,
"esd": 10.64453125,
"grade": "AAA",
"gradeIndex": -1,
"lamp": "EX HARD CLEAR",
"lampIndex": 6,
"hitData": {
"pgreat": 697,
"great": 85
},
"hitMeta": {
"bp": 2
}
},
"songID": 1,
"game": "iidx",
"playtype": "SP"
}