Add lastCompletedVoting function

This commit is contained in:
Kalle 2022-05-22 00:06:44 +03:00
parent dbc0149df3
commit 4b71413f7c
4 changed files with 108 additions and 2 deletions

28
app/core/plus.test.ts Normal file
View File

@ -0,0 +1,28 @@
import { suite } from "uvu";
import * as assert from "uvu/assert";
import { lastCompletedVoting } from "./plus";
const LastCompletedVoting = suite("lastCompletedVoting()");
LastCompletedVoting("Previous month if voting yet to happen", () => {
assert.equal(lastCompletedVoting(new Date(Date.UTC(2022, 4, 1))), {
month: 3,
year: 2022,
});
});
LastCompletedVoting("Previous month if voting in progress", () => {
assert.equal(lastCompletedVoting(new Date(Date.UTC(2022, 4, 7))), {
month: 3,
year: 2022,
});
});
LastCompletedVoting("Same month if voting over", () => {
assert.equal(lastCompletedVoting(new Date(Date.UTC(2022, 4, 15))), {
month: 4,
year: 2022,
});
});
LastCompletedVoting.run();

49
app/core/plus.ts Normal file
View File

@ -0,0 +1,49 @@
interface MonthYear {
month: number;
year: number;
}
export function lastCompletedVoting(now: Date): MonthYear {
const thisMonthsRange = monthsVotingRange({
month: now.getMonth(),
year: now.getFullYear(),
});
if (thisMonthsRange.endDate.getTime() < now.getTime()) {
return {
month: thisMonthsRange.endDate.getMonth(),
year: thisMonthsRange.endDate.getFullYear(),
};
}
return previousMonth({
month: thisMonthsRange.endDate.getMonth(),
year: thisMonthsRange.endDate.getFullYear(),
});
}
/** Range of first Friday of a month to the following Monday (this range is when voting is active) */
function monthsVotingRange({ month, year }: MonthYear) {
const startDate = new Date(Date.UTC(year, month, 1, 10));
while (startDate.getDay() !== 5) {
startDate.setDate(startDate.getDate() + 1);
}
const endDate = new Date(startDate.getTime());
endDate.setDate(endDate.getDate() + 3);
return { startDate, endDate };
}
function previousMonth(input: MonthYear): MonthYear {
let { month, year } = input;
month--;
if (month < 0) {
month = 11;
year--;
}
return { month, year };
}

28
package-lock.json generated
View File

@ -44,7 +44,9 @@
"stylelint-order": "^5.0.0",
"ts-node": "^10.7.0",
"tsconfig-paths": "^4.0.0",
"typescript": "^4.5.5"
"tsm": "^2.2.1",
"typescript": "^4.5.5",
"uvu": "^0.5.3"
},
"engines": {
"node": ">=14"
@ -13403,6 +13405,21 @@
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"dev": true
},
"node_modules/tsm": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tsm/-/tsm-2.2.1.tgz",
"integrity": "sha512-qvJB0baPnxQJolZru11mRgGTdNlx17WqgJnle7eht3Vhb+VUR4/zFA5hFl6NqRe7m8BD9w/6yu0B2XciRrdoJA==",
"dev": true,
"dependencies": {
"esbuild": "^0.14.0"
},
"bin": {
"tsm": "bin.js"
},
"engines": {
"node": ">=12"
}
},
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
@ -24231,6 +24248,15 @@
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"dev": true
},
"tsm": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tsm/-/tsm-2.2.1.tgz",
"integrity": "sha512-qvJB0baPnxQJolZru11mRgGTdNlx17WqgJnle7eht3Vhb+VUR4/zFA5hFl6NqRe7m8BD9w/6yu0B2XciRrdoJA==",
"dev": true,
"requires": {
"esbuild": "^0.14.0"
}
},
"tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",

View File

@ -16,6 +16,7 @@
"prettier:check": "prettier --check .",
"prettier:write": "prettier --write .",
"typecheck": "tsc --noEmit",
"test:unit": "uvu -r tsm -r tsconfig-paths/register -i cypress",
"cy:open": "cypress open",
"checks": "npm run lint:styles && npm run lint:ts && npm run prettier:check && npm run typecheck"
},
@ -58,7 +59,9 @@
"stylelint-order": "^5.0.0",
"ts-node": "^10.7.0",
"tsconfig-paths": "^4.0.0",
"typescript": "^4.5.5"
"tsm": "^2.2.1",
"typescript": "^4.5.5",
"uvu": "^0.5.3"
},
"engines": {
"node": ">=14"