chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
import { test, expect } from "@perspective-dev/test";
|
||||
import perspective from "../perspective_client";
|
||||
|
||||
const JAN_1_2024_UTC = 1704067200000;
|
||||
|
||||
test.describe("Date timezone invariance", function () {
|
||||
let SAVED_TZ: string | undefined;
|
||||
|
||||
test.beforeEach(() => {
|
||||
SAVED_TZ = process.env.TZ;
|
||||
process.env.TZ = "Europe/Amsterdam";
|
||||
});
|
||||
|
||||
test.afterEach(() => {
|
||||
process.env.TZ = SAVED_TZ;
|
||||
});
|
||||
|
||||
test("date strings serialize to UTC midnight epoch ms", async function () {
|
||||
const table = await perspective.table({ d: "date" });
|
||||
await table.update({ d: ["2024-01-01"] });
|
||||
const view = await table.view();
|
||||
const cols = (await view.to_columns()) as { d: number[] };
|
||||
expect(cols.d).toEqual([JAN_1_2024_UTC]);
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("date epoch ms input round-trips exactly", async function () {
|
||||
const table = await perspective.table({ d: "date" });
|
||||
await table.update({ d: [JAN_1_2024_UTC] });
|
||||
const view = await table.view();
|
||||
const cols = (await view.to_columns()) as { d: number[] };
|
||||
expect(cols.d).toEqual([JAN_1_2024_UTC]);
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("formatted output prints the stored calendar day", async function () {
|
||||
const table = await perspective.table({ d: "date" });
|
||||
await table.update({ d: ["2024-01-01"] });
|
||||
const view = await table.view();
|
||||
expect(await view.to_columns_string({ formatted: true })).toEqual(
|
||||
'{"d":["2024-01-01"]}',
|
||||
);
|
||||
expect(await view.to_csv()).toEqual('"d"\n2024-01-01\n');
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("day_bucket stays on the UTC calendar day at the day boundary", async function () {
|
||||
const table = await perspective.table({ t: "datetime" });
|
||||
|
||||
// 23:59 UTC is already the next day in Europe/Amsterdam
|
||||
await table.update({ t: ["2020-01-31 23:59:00"] });
|
||||
const view = await table.view({
|
||||
expressions: { bucket: `bucket("t", 'D')` },
|
||||
});
|
||||
|
||||
const cols = (await view.to_columns()) as { bucket: number[] };
|
||||
|
||||
// 2020-01-31T00:00:00Z
|
||||
expect(cols.bucket).toEqual([1580428800000]);
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("day_of_week and hour_of_day compute in UTC", async function () {
|
||||
const table = await perspective.table({ t: "datetime" });
|
||||
await table.update({ t: ["2020-01-31 23:59:00"] });
|
||||
const view = await table.view({
|
||||
expressions: {
|
||||
dow: `day_of_week("t")`,
|
||||
hod: `hour_of_day("t")`,
|
||||
},
|
||||
});
|
||||
|
||||
const cols = (await view.to_columns()) as {
|
||||
dow: string[];
|
||||
hod: number[];
|
||||
};
|
||||
|
||||
// Friday 23:00 UTC, not Saturday 00:59 Amsterdam
|
||||
expect(cols.dow).toEqual(["6 Friday"]);
|
||||
expect(cols.hod).toEqual([23]);
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("JSON date output agrees with Arrow date32 day arithmetic", async function () {
|
||||
const table = await perspective.table({ d: "date" });
|
||||
await table.update({ d: ["2024-01-01"] });
|
||||
const view = await table.view();
|
||||
const cols = (await view.to_columns()) as { d: number[] };
|
||||
expect(cols.d[0] % 86400000).toEqual(0);
|
||||
expect(cols.d[0] / 86400000).toEqual(19723); // days since epoch
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user