mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-06-24 02:04:11 +00:00
Reject impossible LCK calendar dates
Date-driven LCK lookups should fail fast for impossible user input instead of silently returning an empty match list. The parser now validates month/day bounds with explicit leap-year handling, and the tests lock both direct normalization and schedule normalization behavior. Constraint: PR #55 review requested a regression for 2026-02-31 before implementation Rejected: Rely on Date parsing round-trip | explicit bounds avoid timezone and overflow normalization surprises Confidence: high Scope-risk: narrow Directive: Keep date validation before schedule filtering so invalid user dates cannot become misleading no-match responses Tested: node --test packages/lck-analytics/test/index.test.js scripts/skill-docs.test.js Tested: npm run lint --workspace lck-analytics Tested: npm test --workspace lck-analytics Tested: npm run ci Tested: getMatchResults('2026-02-31') rejection smoke Tested: getLckSummary('2026-04-01', { team: '한화', includeStandings: true }) live smoke Tested: lck-analytics script smokes for sync-oracle, build-match-report, and analyze-live-game
This commit is contained in:
parent
39c97ccacc
commit
2120ca7cc0
2 changed files with 52 additions and 2 deletions
|
|
@ -38,8 +38,7 @@ function normalizeDateInput(value) {
|
|||
}
|
||||
|
||||
const [year, month, day] = [match[1], match[2], match[3]];
|
||||
const candidate = new Date(`${year}-${month}-${day}T00:00:00+09:00`);
|
||||
if (Number.isNaN(candidate.getTime())) {
|
||||
if (!isValidCalendarDate(year, month, day)) {
|
||||
throw new Error("date must be a valid Date or YYYY-MM-DD string.");
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +50,40 @@ function normalizeDateInput(value) {
|
|||
};
|
||||
}
|
||||
|
||||
function isValidCalendarDate(year, month, day) {
|
||||
const numericYear = Number(year);
|
||||
const numericMonth = Number(month);
|
||||
const numericDay = Number(day);
|
||||
|
||||
if (!Number.isInteger(numericYear) || !Number.isInteger(numericMonth) || !Number.isInteger(numericDay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (numericMonth < 1 || numericMonth > 12 || numericDay < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const daysInMonth = [
|
||||
31,
|
||||
isLeapYear(numericYear) ? 29 : 28,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
30,
|
||||
31,
|
||||
][numericMonth - 1];
|
||||
return numericDay <= daysInMonth;
|
||||
}
|
||||
|
||||
function isLeapYear(year) {
|
||||
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
||||
}
|
||||
|
||||
function eventToKoreaDateTime(startTime) {
|
||||
const date = new Date(startTime);
|
||||
const parts = new Intl.DateTimeFormat("en-CA", {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const {
|
|||
parseOracleCsv,
|
||||
} = require("../src/index");
|
||||
const {
|
||||
normalizeDateInput,
|
||||
normalizeScheduleResponse,
|
||||
normalizeStandingsResponse,
|
||||
} = require("../src/parse");
|
||||
|
|
@ -45,6 +46,22 @@ test("normalizeScheduleResponse filters requested LCK date and Korean team alias
|
|||
assert.deepEqual(result.matches[0].score, { team1: 1, team2: 0 });
|
||||
});
|
||||
|
||||
test("date normalization rejects impossible calendar dates", () => {
|
||||
assert.equal(normalizeDateInput("2024-02-29").isoDate, "2024-02-29");
|
||||
assert.throws(
|
||||
() => normalizeDateInput("2026-02-31"),
|
||||
/date must be a valid Date or YYYY-MM-DD string\./,
|
||||
);
|
||||
assert.throws(
|
||||
() => normalizeDateInput("2026-02-29"),
|
||||
/date must be a valid Date or YYYY-MM-DD string\./,
|
||||
);
|
||||
assert.throws(
|
||||
() => normalizeScheduleResponse(schedulePayload, { date: "2026-02-31" }),
|
||||
/date must be a valid Date or YYYY-MM-DD string\./,
|
||||
);
|
||||
});
|
||||
|
||||
test("normalizeStandingsResponse keeps the LCK standings shape and alias resolution", () => {
|
||||
const table = normalizeStandingsResponse(standingsPayload, {
|
||||
tournament: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue