mirror of
https://github.com/fosrl/pangolin.git
synced 2026-09-16 23:59:53 +02:00
9298ec7cdb
Backup names were built inline from Date#getMonth, which is zero-indexed, so a backup taken on 12 September 2026 was written as db_2026-8-12_20-35-56.sqlite. No field was zero-padded either, giving names like db_2026-8-12_20-36-2.sqlite. Extract formatBackupTimestamp into server/lib and use it from both places that built the string: the backupDb helper in migrationsSqlite.ts and the inline copy in the 1.0.0-beta9 setup script. Padding every field also makes the names sort lexicographically in the order the backups were taken. Adds tests covering both reported names, single-digit padding and sort order. Reverting the helper to the old formula fails them with the exact name from the report.
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
import { formatBackupTimestamp } from "./backupFileName";
|
|
import { assertEquals } from "@test/assert";
|
|
|
|
// Local-time constructors are used throughout, matching formatBackupTimestamp,
|
|
// so these cases do not depend on the machine's timezone.
|
|
|
|
function testMonthIsOneIndexed() {
|
|
console.log("Running month indexing tests...");
|
|
|
|
// The case from the report: a backup taken on 12 September 2026 was named
|
|
// db_2026-8-12_... because Date#getMonth is zero-indexed.
|
|
{
|
|
const result = formatBackupTimestamp(new Date(2026, 8, 12, 20, 35, 56));
|
|
assertEquals(
|
|
result,
|
|
"2026-09-12_20-35-56",
|
|
"September must render as 09, not 8"
|
|
);
|
|
}
|
|
|
|
// The other reported name, db_2026-0-23_..., was a January backup.
|
|
{
|
|
const result = formatBackupTimestamp(new Date(2026, 0, 23, 20, 25, 49));
|
|
assertEquals(
|
|
result,
|
|
"2026-01-23_20-25-49",
|
|
"January must render as 01, not 0"
|
|
);
|
|
}
|
|
|
|
{
|
|
const result = formatBackupTimestamp(new Date(2026, 11, 31, 23, 59, 59));
|
|
assertEquals(
|
|
result,
|
|
"2026-12-31_23-59-59",
|
|
"December must render as 12"
|
|
);
|
|
}
|
|
}
|
|
|
|
function testEveryFieldIsZeroPadded() {
|
|
console.log("Running zero padding tests...");
|
|
|
|
// db_2026-8-12_20-36-2 in the report: a single-digit second was not padded.
|
|
{
|
|
const result = formatBackupTimestamp(new Date(2026, 8, 12, 20, 36, 2));
|
|
assertEquals(
|
|
result,
|
|
"2026-09-12_20-36-02",
|
|
"Single-digit seconds must be padded"
|
|
);
|
|
}
|
|
|
|
{
|
|
const result = formatBackupTimestamp(new Date(2026, 0, 1, 0, 0, 0));
|
|
assertEquals(
|
|
result,
|
|
"2026-01-01_00-00-00",
|
|
"Midnight on the first of the month must pad every field"
|
|
);
|
|
}
|
|
}
|
|
|
|
function testNamesSortChronologically() {
|
|
console.log("Running sort order tests...");
|
|
|
|
// Zero padding means a plain lexicographic sort of the backups directory
|
|
// lists the backups in the order they were taken.
|
|
const taken = [
|
|
new Date(2026, 8, 12, 20, 36, 2),
|
|
new Date(2026, 0, 23, 20, 25, 49),
|
|
new Date(2026, 8, 12, 20, 35, 56),
|
|
new Date(2026, 11, 31, 23, 59, 59)
|
|
];
|
|
|
|
const sorted = taken
|
|
.map((date) => formatBackupTimestamp(date))
|
|
.sort();
|
|
|
|
assertEquals(
|
|
sorted.join(","),
|
|
[
|
|
"2026-01-23_20-25-49",
|
|
"2026-09-12_20-35-56",
|
|
"2026-09-12_20-36-02",
|
|
"2026-12-31_23-59-59"
|
|
].join(","),
|
|
"Backup names must sort into the order the backups were taken"
|
|
);
|
|
}
|
|
|
|
// Run all tests
|
|
try {
|
|
testMonthIsOneIndexed();
|
|
testEveryFieldIsZeroPadded();
|
|
testNamesSortChronologically();
|
|
console.log("All tests passed successfully!");
|
|
} catch (error) {
|
|
console.error("Test failed:", error);
|
|
process.exit(1);
|
|
}
|