llm-semantic-visualizer / tests /spatialSliderDefaults.test.js
hbauzan's picture
feat(compare): group contrast visibility L1+L2 (v2.1.0)
35c1912
Raw
History Blame Contribute Delete
4.58 kB
import { describe, it, expect, afterEach } from 'vitest';
import {
GLOBAL_SPATIAL_DEFAULTS,
SPATIAL_DEFAULT_OVERRIDES,
resolveSpatialDefaults,
} from '../src/ui/spatialSliderDefaults.js';
describe('resolveSpatialDefaults', () => {
/** @type {Array<{ key: string, previous: object|undefined }>} */
const savedKeys = [];
afterEach(() => {
for (const { key, previous } of savedKeys.splice(0)) {
if (previous === undefined) {
delete SPATIAL_DEFAULT_OVERRIDES[key];
} else {
SPATIAL_DEFAULT_OVERRIDES[key] = previous;
}
}
});
function setOverride(key, partial) {
savedKeys.push({
key,
previous: SPATIAL_DEFAULT_OVERRIDES[key]
? { ...SPATIAL_DEFAULT_OVERRIDES[key] }
: undefined,
});
SPATIAL_DEFAULT_OVERRIDES[key] = partial;
}
it('returns global mid defaults when no overrides exist', () => {
const d = resolveSpatialDefaults({
workspaceMode: 'ARITHMETIC',
viewMode: 'NAVIGATION',
renderMode: 'RIBBONS',
});
expect(d.threadSpacing).toBe(GLOBAL_SPATIAL_DEFAULTS.threadSpacing);
expect(d.threadVectorDistance).toBe(GLOBAL_SPATIAL_DEFAULTS.threadVectorDistance);
expect(d.threadAmplitudeY).toBe(GLOBAL_SPATIAL_DEFAULTS.threadAmplitudeY);
expect(d.threadWidth).toBe(GLOBAL_SPATIAL_DEFAULTS.threadWidth);
expect(d.threadThickness).toBe(GLOBAL_SPATIAL_DEFAULTS.threadThickness);
expect(d.threadSpacingY).toBe(d.threadVectorDistance);
});
it('applies workspace → view → render layers (more specific wins)', () => {
setOverride('ARITHMETIC', { threadSpacing: 0.5 });
setOverride('ARITHMETIC|NAVIGATION', { threadAmplitudeY: 9.0 });
setOverride('ARITHMETIC|NAVIGATION|POINTS', { threadThickness: 0.12 });
const d = resolveSpatialDefaults({
workspaceMode: 'ARITHMETIC',
viewMode: 'NAVIGATION',
renderMode: 'POINTS',
});
expect(d.threadSpacing).toBe(0.5);
expect(d.threadAmplitudeY).toBe(9.0);
expect(d.threadThickness).toBe(0.12);
expect(d.threadWidth).toBe(GLOBAL_SPATIAL_DEFAULTS.threadWidth);
});
it('does not leak overrides from a different context', () => {
setOverride('COMPARE|ANALYSIS|POINTS', { threadWidth: 0.25 });
const d = resolveSpatialDefaults({
workspaceMode: 'ARITHMETIC',
viewMode: 'NAVIGATION',
renderMode: 'POINTS',
});
expect(d.threadWidth).toBe(GLOBAL_SPATIAL_DEFAULTS.threadWidth);
});
it('applies captured ARITHMETIC|ANALYSIS|POINTS preset (Amplitude 40)', () => {
// Production override lives in SPATIAL_DEFAULT_OVERRIDES — assert the seam.
const d = resolveSpatialDefaults({
workspaceMode: 'ARITHMETIC',
viewMode: 'ANALYSIS',
renderMode: 'POINTS',
});
expect(d.threadSpacing).toBe(0.4);
expect(d.threadVectorDistance).toBe(10.0);
expect(d.threadAmplitudeY).toBe(40.0);
expect(d.threadWidth).toBe(0.2);
expect(d.threadThickness).toBe(0.05);
});
it('applies captured COMPARE|NAVIGATION|POINTS preset', () => {
const d = resolveSpatialDefaults({
workspaceMode: 'COMPARE',
viewMode: 'NAVIGATION',
renderMode: 'POINTS',
});
expect(d.threadSpacing).toBe(0.7);
expect(d.threadVectorDistance).toBe(10.0);
expect(d.threadAmplitudeY).toBe(4.9);
expect(d.threadWidth).toBe(0.1);
expect(d.threadThickness).toBe(0.01);
});
it('applies COMPARE|ANALYSIS|POINTS preset with Amplitude 16', () => {
const d = resolveSpatialDefaults({
workspaceMode: 'COMPARE',
viewMode: 'ANALYSIS',
renderMode: 'POINTS',
});
expect(d.threadSpacing).toBe(1.45);
expect(d.threadVectorDistance).toBe(1.0);
expect(d.threadAmplitudeY).toBe(16.0);
expect(d.threadWidth).toBe(0.2);
expect(d.threadThickness).toBe(0.01);
});
it('applies COMPARE|ANALYSIS|RIBBONS twin with Amplitude 16', () => {
const d = resolveSpatialDefaults({
workspaceMode: 'COMPARE',
viewMode: 'ANALYSIS',
renderMode: 'RIBBONS',
});
expect(d.threadAmplitudeY).toBe(16.0);
expect(d.threadSpacing).toBe(1.45);
expect(d.threadVectorDistance).toBe(1.0);
});
it('applies captured COMPARE|NAVIGATION|RIBBONS preset', () => {
const d = resolveSpatialDefaults({
workspaceMode: 'COMPARE',
viewMode: 'NAVIGATION',
renderMode: 'RIBBONS',
});
expect(d.threadSpacing).toBe(1.55);
expect(d.threadVectorDistance).toBe(10.0);
expect(d.threadAmplitudeY).toBe(7.0);
expect(d.threadWidth).toBe(0.057);
expect(d.threadThickness).toBe(0.05);
});
});