llm-semantic-visualizer / tests /hoverTelemetry.test.js
hbauzan's picture
fix(ui): Galaxy/Compare polish and startup defaults
74f4fb6
Raw
History Blame Contribute Delete
5.31 kB
import { describe, it, expect } from 'vitest';
import {
resolveHoverTelemetry,
formatActivationValue,
formatHoverTokenLabel,
estimateMonospaceChars,
activationDisplayBudget,
MAX_ACTIVATION_DECIMALS,
} from '../src/ui/hoverTelemetry.js';
describe('resolveHoverTelemetry', () => {
it('returns null for empty hover', () => {
expect(resolveHoverTelemetry(null)).toBeNull();
expect(resolveHoverTelemetry(undefined)).toBeNull();
});
it('reads activation from pointsData[index] (POINTS mesh)', () => {
const data = {
index: 1,
point: { x: 10, y: 2, z: 0 },
userData: {
pointsData: [
{ activation: 0.01, meta: { type: 'compare', token: 'cat', dim: 0, val: 0.01 } },
{ activation: -0.0421, meta: { type: 'compare', token: 'cat', dim: 1, val: -0.0421 } },
],
},
};
const t = resolveHoverTelemetry(data);
expect(t.activation).toBe(-0.0421);
expect(t.token).toBe('cat');
expect(t.tokenLabel).toBe('cat');
expect(t.groupLabel).toBeNull();
expect(t.type).toBe('COMPARE');
expect(t.dim).toBe(1);
expect(t.point).toEqual({ x: 10, y: 2, z: 0 });
});
it('formats grouped token as group/token without spaces', () => {
expect(formatHoverTokenLabel('car', 'vehicles')).toBe('vehicles/car');
expect(formatHoverTokenLabel('car', null)).toBe('car');
expect(formatHoverTokenLabel('car', '')).toBe('car');
const t = resolveHoverTelemetry({
index: 0,
userData: {
pointsData: [{
activation: 0.2,
groupId: 'vehicles',
groupLabel: 'vehicles',
meta: {
type: 'compare',
token: 'car',
dim: 0,
val: 0.2,
groupId: 'vehicles',
groupLabel: 'vehicles',
},
}],
},
});
expect(t.token).toBe('car');
expect(t.groupLabel).toBe('vehicles');
expect(t.tokenLabel).toBe('vehicles/car');
});
it('maps ribbon actIdx through sourceDims when present', () => {
const data = {
index: 4,
face: { a: 6, b: 7, c: 8 },
userData: {
kind: 'wideRibbon',
activations: [0.1, 0.2, 0.3, 0.4],
sourceDims: [10, 20, 30, 40],
token: 'dog',
type: 'compare',
},
};
const t = resolveHoverTelemetry(data);
expect(t.activation).toBe(0.4);
expect(t.dim).toBe(40);
});
it('does not fall back to 0 when pointsData has a real value (regression)', () => {
// Legacy HUD read userData.val / data.activation — both missing on Points meshes
const data = {
index: 0,
point: { x: 1, y: 0, z: 0 },
userData: {
pointsData: [{ activation: 1.23e-7, meta: { dim: 0, val: 1.23e-7, type: 'res' } }],
},
};
expect(resolveHoverTelemetry(data).activation).toBe(1.23e-7);
});
it('reads activations[] on wideRibbon via face vertex index', () => {
const data = {
index: 4,
face: { a: 6, b: 7, c: 8 },
userData: {
kind: 'wideRibbon',
activations: [0.1, 0.2, 0.3, 0.4, 0.5],
token: 'dog',
type: 'compare',
},
};
const t = resolveHoverTelemetry(data);
expect(t.activation).toBe(0.4); // floor(6/2) = 3
expect(t.token).toBe('dog');
});
it('falls back to DIM #n when no token meta', () => {
const t = resolveHoverTelemetry({
index: 12,
userData: {
pointsData: [{ activation: 0.5, meta: { dim: 12, val: 0.5 } }],
},
});
expect(t.token).toBe('DIM #12');
});
});
describe('formatActivationValue', () => {
it('caps decimals at 32', () => {
expect(MAX_ACTIVATION_DECIMALS).toBe(32);
const tiny = 1e-30;
const s = formatActivationValue(tiny, { maxDecimals: 32, maxChars: 40 });
expect(s.includes('e') || s.length <= 40).toBe(true);
// Must not be the old HUD "0.0000"
expect(s).not.toBe('0.0000');
expect(Number(s)).not.toBe(0);
});
it('shows small magnitudes that toFixed(4) would hide', () => {
const s = formatActivationValue(0.00001234, { maxDecimals: 32, maxChars: 20 });
expect(s).not.toMatch(/^0\.0+$/);
expect(Math.abs(Number(s) - 0.00001234)).toBeLessThan(1e-8);
});
it('shrinks to fit maxChars without overflowing', () => {
const s = formatActivationValue(0.123456789012345, { maxDecimals: 32, maxChars: 8 });
expect(s.length).toBeLessThanOrEqual(8);
expect(s).not.toBe('0');
});
it('uses scientific when fixed form cannot fit', () => {
const s = formatActivationValue(1.23456789e-20, { maxDecimals: 32, maxChars: 10 });
expect(s.length).toBeLessThanOrEqual(10);
expect(s).toMatch(/e/i);
});
it('formats zero as 0', () => {
expect(formatActivationValue(0, { maxChars: 10 })).toBe('0');
});
});
describe('activationDisplayBudget', () => {
it('estimates monospace capacity', () => {
expect(estimateMonospaceChars(120, 12)).toBeGreaterThan(10);
});
it('switches to compact ACT: label when slot is narrow (mobile)', () => {
const wide = activationDisplayBudget(400, 'ACTIVATION: ', 12);
expect(wide.compactLabel).toBe(false);
const narrow = activationDisplayBudget(90, 'ACTIVATION: ', 11);
expect(narrow.compactLabel).toBe(true);
expect(narrow.maxChars).toBeGreaterThanOrEqual(4);
});
});