mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
223646398e
Multi-page Vite build: index.html serves a new standalone landing (src/landing), app/index.html serves the app at /app/. The PWA service worker and manifest are scoped to /app/, so the landing stays uncontrolled and always-fresh; hash view-state routing is unchanged. The landing reuses src/core and the chart-renderer service only (never stores/orchestration/modals/components) and lazy-loads Vega. Its demos drive the real core: a hero snippet switcher over CHART_EXAMPLES, an interactive Chart Builder over a new profiled core fixture (sample-dataset), and a Theme Builder gallery with three from-scratch custom themes plus built-in presets.
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { inferColumnType } from '@core/type-inference';
|
|
import {
|
|
CHART_INTENTS,
|
|
defaultBuilderConfig,
|
|
intentApplicable,
|
|
isBuilderConfigValid,
|
|
} from '@core/chart-builder';
|
|
import {
|
|
SAMPLE_DATASET_COLUMNS,
|
|
SAMPLE_DATASET_NAME,
|
|
SAMPLE_DATASET_ROWS,
|
|
} from '@core/sample-dataset';
|
|
|
|
describe('sample-dataset fixture', () => {
|
|
it('declares column types that match what inference derives from the rows', () => {
|
|
for (const { name, type } of SAMPLE_DATASET_COLUMNS.columnTypes) {
|
|
const values = SAMPLE_DATASET_ROWS.map((row) => row[name]);
|
|
expect(inferColumnType(values), name).toBe(type);
|
|
}
|
|
});
|
|
|
|
it('declares column stats that match the rows', () => {
|
|
for (const stat of SAMPLE_DATASET_COLUMNS.columnStats ?? []) {
|
|
const values = SAMPLE_DATASET_ROWS.map((row) => row[stat.name]);
|
|
expect(stat.distinct, stat.name).toBe(new Set(values).size);
|
|
const numbers = values.filter((v): v is number => typeof v === 'number');
|
|
if (numbers.length === values.length) {
|
|
expect(stat.numericExtent, stat.name).toEqual({
|
|
min: Math.min(...numbers),
|
|
max: Math.max(...numbers),
|
|
});
|
|
} else {
|
|
expect(stat.numericExtent, stat.name).toBeNull();
|
|
}
|
|
}
|
|
});
|
|
|
|
it('opens the builder on a valid default chart', () => {
|
|
const config = defaultBuilderConfig(SAMPLE_DATASET_NAME, SAMPLE_DATASET_COLUMNS);
|
|
expect(isBuilderConfigValid(config)).toBe(true);
|
|
});
|
|
|
|
it('makes every intent applicable, so the demo strip is fully live', () => {
|
|
for (const intent of CHART_INTENTS) {
|
|
expect(intentApplicable(intent, SAMPLE_DATASET_COLUMNS), intent).toBe(true);
|
|
}
|
|
});
|
|
});
|