Skip to content

Commit

Permalink
Keep completed matches completed (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
Drarig29 authored Oct 29, 2021
1 parent 81a9397 commit 83a875a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 21 deletions.
16 changes: 12 additions & 4 deletions src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,8 @@ export class Create {
if (this.stage.type === 'round_robin' && opponent1 === null && opponent2 === null)
return;

const status = helpers.getMatchByeStatus(opponents);

let existing: Match | null = null;
let status = helpers.getMatchStatus(opponents);

if (this.updateMode) {
existing = await this.storage.selectFirst('match', {
Expand All @@ -363,6 +362,13 @@ export class Create {

const currentChildCount = existing?.child_count;
childCount = currentChildCount === undefined ? childCount : currentChildCount;

if (existing) {
// Keep the most advanced status when updating a match.
const existingStatus = helpers.getMatchStatus(existing);
if (existingStatus > status)
status = existingStatus;
}
}

const parentId = await this.insertMatch({
Expand Down Expand Up @@ -706,7 +712,8 @@ export class Create {
if (!existing)
return this.storage.insert('match', match);

if (!await this.storage.update('match', existing.id, { ...existing, ...helpers.getUpdatedMatchResults(match) }))
const updated = helpers.getUpdatedMatchResults(match, existing) as Match;
if (!await this.storage.update('match', existing.id, updated))
throw Error('Could not update the match.');

return existing.id;
Expand All @@ -730,7 +737,8 @@ export class Create {
if (!existing)
return this.storage.insert('match_game', matchGame);

if (!await this.storage.update('match_game', existing.id, { ...existing, ...helpers.getUpdatedMatchResults(matchGame) }))
const updated = helpers.getUpdatedMatchResults(matchGame, existing) as MatchGame;
if (!await this.storage.update('match_game', existing.id, updated))
throw Error('Could not update the match game.');

return existing.id;
Expand Down
43 changes: 26 additions & 17 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,18 +591,6 @@ export function isMatchParticipantLocked(match: MatchResults): boolean {
return match.status >= Status.Running;
}

/**
* Returns the status of a match based on the presence of the opponents.
*
* @param opponents The opponents of a match.
*/
export function getMatchByeStatus(opponents: Duel): Status {
return getMatchStatus({
opponent1: opponents[0],
opponent2: opponents[1],
});
}

/**
* Indicates whether a match has at least one BYE or not.
*
Expand All @@ -612,12 +600,31 @@ export function hasBye(match: Partial<MatchResults>): boolean {
return match.opponent1 === null || match.opponent2 === null;
}

/**
* Returns the status of a match based on the opponents of a match.
*
* @param opponents The opponents of a match.
*/
export function getMatchStatus(opponents: Duel): Status;

/**
* Returns the status of a match based on the results of a match.
*
* @param match Partial match results.
*/
export function getMatchStatus(match: Partial<MatchResults>): Status {
export function getMatchStatus(match: Partial<MatchResults>): Status;

/**
* Returns the status of a match based on information about it.
*
* @param arg The opponents or partial results of the match.
*/
export function getMatchStatus(arg: Duel | Partial<MatchResults>): Status {
const match = Array.isArray(arg) ? {
opponent1: arg[0],
opponent2: arg[1],
} : arg;

if (hasBye(match)) // At least one BYE.
return Status.Locked;

Expand Down Expand Up @@ -1250,12 +1257,14 @@ export function getParentMatchResults(storedParent: Match, scores: Scores): Part
* Gets the values which need to be updated in a match when it's updated on insertion.
*
* @param match The up to date match.
* @param existing The base match.
*/
export function getUpdatedMatchResults(match: MatchResults): MatchResults {
export function getUpdatedMatchResults<T extends MatchResults>(match: T, existing: T): T {
return {
status: match.status,
opponent1: match.opponent1,
opponent2: match.opponent2,
...existing,
...match,
opponent1: { ...existing.opponent1, ...match.opponent1 },
opponent2: { ...existing.opponent2, ...match.opponent2 },
};
}

Expand Down
48 changes: 48 additions & 0 deletions test/update.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,54 @@ describe('Seeding', () => {
assert.strictEqual((await storage.select('participant')).length, 8 + 6);
});

it('should update the seeding and keep completed matches completed', async () => {
await manager.update.seeding(0, [
'Team 1', 'Team 2',
'Team 3', 'Team 4',
'Team 5', 'Team 6',
'Team 7', 'Team 8',
]);

await manager.update.match({
id: 0,
opponent1: { score: 1, result: 'win' },
opponent2: { score: 0 },
});

await manager.update.seeding(0, [
'Team 1', 'Team 2', // Keep this pair.
'Team 4', 'Team 3',
'Team 6', 'Team 5',
'Team 8', 'Team 7',
]);

const match = await storage.select('match', 0);
assert.strictEqual(match.opponent1.result, 'win');
assert.strictEqual(match.status, Status.Completed);
});

it('should throw if a match is completed and would have to be changed', async () => {
await manager.update.seeding(0, [
'Team 1', 'Team 2',
'Team 3', 'Team 4',
'Team 5', 'Team 6',
'Team 7', 'Team 8',
]);

await manager.update.match({
id: 0,
opponent1: { score: 1, result: 'win' },
opponent2: { score: 0 },
});

await assert.isRejected(manager.update.seeding(0, [
'Team 2', 'Team 1', // Change this pair.
'Team 3', 'Team 4',
'Team 5', 'Team 6',
'Team 7', 'Team 8',
]), 'A match is locked.');
});

it('should throw if a match is locked and would have to be changed', async () => {
await manager.update.seeding(0, [
'Team 1', 'Team 2',
Expand Down

0 comments on commit 83a875a

Please sign in to comment.