mirror of
https://github.com/home-assistant/frontend.git
synced 2026-09-28 16:04:00 +01:00
* Update vitest monorepo to v5 * Add required Vite peer dependency for Vitest 5 * Migrate benchmarks to the Vitest 5 context API * Stub read-only jsdom globals in Vitest tests * Revise benchmark reporting instructions in README Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Aidan Timson <aidan@timmo.dev> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
82 lines
3.0 KiB
TypeScript
82 lines
3.0 KiB
TypeScript
import { describe, test } from "vitest";
|
|
import { downSampleLineData } from "../../src/components/chart/down-sample";
|
|
import { FIXED_EPOCH_MS, SCALES } from "../fixtures/history-states";
|
|
import { createSeededRandom } from "../fixtures/random";
|
|
|
|
// A typical chart is a few hundred CSS pixels wide
|
|
const MAX_DETAILS = 500;
|
|
|
|
const generatePoints = (seed: number, count: number): [number, number][] => {
|
|
const random = createSeededRandom(seed);
|
|
const points: [number, number][] = [];
|
|
let y = 100;
|
|
for (let i = 0; i < count; i++) {
|
|
y = Math.max(0, y + (random() - 0.5) * 10);
|
|
points.push([FIXED_EPOCH_MS + i * 30_000, y]);
|
|
}
|
|
return points;
|
|
};
|
|
|
|
// The chart data modules break the line with a null value. A handful of them
|
|
// stands for an entity that went unavailable; a series that is mostly null
|
|
// stands for the climate heating dataset, which emits one per inactive state.
|
|
const withGaps = (
|
|
points: [number, number][],
|
|
isGap: (index: number) => boolean
|
|
): [number, number | null][] =>
|
|
points.map(([x, y], index) => (isGap(index) ? [x, null] : [x, y]));
|
|
|
|
const small = generatePoints(1, SCALES.small);
|
|
const medium = generatePoints(2, SCALES.medium);
|
|
const large = generatePoints(3, SCALES.large);
|
|
const largeObjects = large.map((value) => ({ value }));
|
|
const largeFewGaps = withGaps(large, (index) => index % 20_000 === 0);
|
|
const largeMostlyGaps = withGaps(
|
|
large,
|
|
(index) => Math.floor(index / 50) % 3 !== 0
|
|
);
|
|
|
|
describe("downSampleLineData", () => {
|
|
test("min/max small (1k points)", async ({ bench }) => {
|
|
await bench("min/max small (1k points)", () => {
|
|
downSampleLineData(small, MAX_DETAILS);
|
|
}).run();
|
|
});
|
|
|
|
test("min/max medium (10k points)", async ({ bench }) => {
|
|
await bench("min/max medium (10k points)", () => {
|
|
downSampleLineData(medium, MAX_DETAILS);
|
|
}).run();
|
|
});
|
|
|
|
test("min/max large (100k points)", async ({ bench }) => {
|
|
await bench("min/max large (100k points)", () => {
|
|
downSampleLineData(large, MAX_DETAILS);
|
|
}).run({ time: 1000, warmupIterations: 2 });
|
|
});
|
|
|
|
test("mean large (100k points)", async ({ bench }) => {
|
|
await bench("mean large (100k points)", () => {
|
|
downSampleLineData(large, MAX_DETAILS, undefined, undefined, true);
|
|
}).run({ time: 1000, warmupIterations: 2 });
|
|
});
|
|
|
|
test("min/max large object points (100k points)", async ({ bench }) => {
|
|
await bench("min/max large object points (100k points)", () => {
|
|
downSampleLineData(largeObjects, MAX_DETAILS);
|
|
}).run({ time: 1000, warmupIterations: 2 });
|
|
});
|
|
|
|
test("min/max large with a few gaps (100k points)", async ({ bench }) => {
|
|
await bench("min/max large with a few gaps (100k points)", () => {
|
|
downSampleLineData(largeFewGaps, MAX_DETAILS);
|
|
}).run({ time: 1000, warmupIterations: 2 });
|
|
});
|
|
|
|
test("min/max large mostly gaps (100k points)", async ({ bench }) => {
|
|
await bench("min/max large mostly gaps (100k points)", () => {
|
|
downSampleLineData(largeMostlyGaps, MAX_DETAILS);
|
|
}).run({ time: 1000, warmupIterations: 2 });
|
|
});
|
|
});
|