tahamajs/RR / Docs /visualizer /tests /layer_navigation.test.js
tahamajs's picture
download
raw
13.3 kB
/**
* tests/layer_navigation.test.js
* ==============================
* Comprehensive test suite for Layer-by-Layer 3D Navigation & UI Synchronization:
* - Verifies HTML elements and CSS classes for quick-jump layer pills
* - Tests dynamic pill generator across DistilBERT, RoBERTa, GPT-2, and Qwen
* - Tests active layer indicator synchronization (pills, scrubber, tree explorer)
* - Tests tree explorer layer-header click dispatching navigateToLayer
* - Tests spatial Y-coordinate layer altitude resolution logic
*/
import assert from 'node:assert';
import test, { describe, it } from 'node:test';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
describe('Layer-by-Layer 3D Navigation System', () => {
const htmlPath = path.resolve(__dirname, '../index.html');
const cssPath = path.resolve(__dirname, '../style.css');
const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
const cssContent = fs.readFileSync(cssPath, 'utf-8');
it('contains #layer-quick-pills container in index.html', () => {
assert.ok(
htmlContent.includes('id="layer-quick-pills"'),
'Expected index.html to contain element with id="layer-quick-pills"'
);
assert.ok(
htmlContent.includes('class="layer-quick-pills"'),
'Expected index.html to contain class="layer-quick-pills"'
);
});
it('contains comprehensive CSS styling for layer quick pills and active states', () => {
assert.ok(cssContent.includes('.layer-quick-pills'), 'Expected .layer-quick-pills CSS rule');
assert.ok(cssContent.includes('.layer-pill-btn'), 'Expected .layer-pill-btn CSS rule');
assert.ok(cssContent.includes('.layer-pill-btn.active'), 'Expected .layer-pill-btn.active CSS rule');
assert.ok(cssContent.includes('.layer-pill-btn:hover'), 'Expected .layer-pill-btn:hover CSS rule');
});
it('generates correct sequence of quick jump pills for various model architectures', () => {
// Mock DOM implementation for buildLayerQuickPills test
function createMockElement(tag) {
const attrs = {};
const classes = new Set();
return {
tagName: tag.toUpperCase(),
className: '',
textContent: '',
title: '',
onclick: null,
children: [],
setAttribute(k, v) { attrs[k] = v; },
getAttribute(k) { return attrs[k]; },
appendChild(child) { this.children.push(child); }
};
}
function simulateBuildLayerQuickPills(container, scrubber, modelKey, numLayers, onNavigate) {
container.children = [];
if (scrubber) {
scrubber.min = '0';
scrubber.max = String(Math.max(1, numLayers - 1));
}
// 1. Embeddings Pill
const embBtn = createMockElement('button');
embBtn.className = 'layer-pill-btn';
embBtn.setAttribute('data-layer', 'embeddings');
embBtn.textContent = 'Emb';
embBtn.title = 'Jump to Input Embeddings';
embBtn.onclick = () => onNavigate('embeddings');
container.appendChild(embBtn);
// 2. Layer Pills L0 .. L(numLayers - 1)
for (let i = 0; i < numLayers; i++) {
const lBtn = createMockElement('button');
lBtn.className = `layer-pill-btn ${i === 0 ? 'active' : ''}`;
lBtn.setAttribute('data-layer', String(i));
lBtn.textContent = `L${i}`;
lBtn.title = `Jump to Transformer Layer ${i}`;
lBtn.onclick = () => onNavigate(i);
container.appendChild(lBtn);
}
// 3. Output Pill
const outBtn = createMockElement('button');
outBtn.className = 'layer-pill-btn';
outBtn.setAttribute('data-layer', 'output');
outBtn.textContent = 'Out';
outBtn.title = 'Jump to Output Head / Classifier';
outBtn.onclick = () => onNavigate('output');
container.appendChild(outBtn);
}
const modelSpecs = [
{ key: 'distilbert', layers: 6, expectedTotal: 8 },
{ key: 'roberta', layers: 12, expectedTotal: 14 },
{ key: 'gpt2', layers: 12, expectedTotal: 14 },
{ key: 'qwen', layers: 28, expectedTotal: 30 }
];
for (const spec of modelSpecs) {
const container = createMockElement('div');
const scrubber = { min: '0', max: '0' };
const navEvents = [];
simulateBuildLayerQuickPills(container, scrubber, spec.key, spec.layers, (target) => navEvents.push(target));
assert.strictEqual(container.children.length, spec.expectedTotal, `Expected ${spec.expectedTotal} pills for ${spec.key}`);
assert.strictEqual(container.children[0].textContent, 'Emb');
assert.strictEqual(container.children[0].getAttribute('data-layer'), 'embeddings');
assert.strictEqual(container.children[spec.layers].textContent, `L${spec.layers - 1}`);
assert.strictEqual(container.children[container.children.length - 1].textContent, 'Out');
assert.strictEqual(container.children[container.children.length - 1].getAttribute('data-layer'), 'output');
// Verify click handler invokes onNavigate with correct arguments
container.children[0].onclick();
assert.strictEqual(navEvents[0], 'embeddings');
container.children[3].onclick();
assert.strictEqual(navEvents[1], 2);
container.children[container.children.length - 1].onclick();
assert.strictEqual(navEvents[2], 'output');
}
});
it('synchronizes active state across pills, scrubber, and tree explorer nodes', () => {
// Simulating the updateActiveLayerIndicator logic
function createMockClassList(initial = []) {
const set = new Set(initial);
return {
add: (...cls) => cls.forEach(c => set.add(c)),
remove: (...cls) => cls.forEach(c => set.delete(c)),
contains: (c) => set.has(c),
has: (c) => set.has(c)
};
}
const pills = [
{ dataset: { layer: 'embeddings' }, classList: createMockClassList() },
{ dataset: { layer: '0' }, classList: createMockClassList(['active']) },
{ dataset: { layer: '1' }, classList: createMockClassList() },
{ dataset: { layer: '2' }, classList: createMockClassList() },
{ dataset: { layer: 'output' }, classList: createMockClassList() }
];
const treeNodes = [
{ dataset: { layerIndex: '0' }, classList: createMockClassList(['open']) },
{ dataset: { layerIndex: '1' }, classList: createMockClassList() },
{ dataset: { layerIndex: '2' }, classList: createMockClassList() }
];
const scrubber = { value: '0' };
let stepLabelText = '';
function simulateUpdateActiveLayerIndicator(layerIdx, label) {
pills.forEach(btn => {
const targetLayer = btn.dataset.layer;
if (String(targetLayer) === String(layerIdx)) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
if (typeof layerIdx === 'number' && Number.isFinite(layerIdx)) {
scrubber.value = String(layerIdx);
}
stepLabelText = label || `Layer ${layerIdx}`;
treeNodes.forEach(node => {
const nodeIdx = node.dataset.layerIndex;
if (String(nodeIdx) === String(layerIdx)) {
node.classList.add('open', 'active-layer');
} else {
node.classList.remove('active-layer');
}
});
}
// Test navigating to Layer 2
simulateUpdateActiveLayerIndicator(2, 'Layer 2');
assert.ok(pills[3].classList.has('active'), 'Pill L2 must have active class');
assert.ok(!pills[1].classList.has('active'), 'Pill L0 must not have active class');
assert.strictEqual(scrubber.value, '2', 'Scrubber must be at value 2');
assert.strictEqual(stepLabelText, 'Layer 2');
assert.ok(treeNodes[2].classList.has('open'), 'Layer 2 tree node must be open');
assert.ok(treeNodes[2].classList.has('active-layer'), 'Layer 2 tree node must have active-layer class');
assert.ok(!treeNodes[0].classList.has('active-layer'), 'Layer 0 tree node must not have active-layer class');
// Test navigating to Embeddings
simulateUpdateActiveLayerIndicator('embeddings', 'Input Embeddings');
assert.ok(pills[0].classList.has('active'), 'Emb pill must be active');
assert.ok(!pills[3].classList.has('active'), 'L2 pill must not be active');
assert.strictEqual(stepLabelText, 'Input Embeddings');
// Test navigating to Output
simulateUpdateActiveLayerIndicator('output', 'Output Layer');
assert.ok(pills[4].classList.has('active'), 'Out pill must be active');
assert.strictEqual(stepLabelText, 'Output Layer');
});
it('computes spatial average Y coordinate altitude accurately for a given layer', () => {
const mockMeshes = [
{ userData: { parent_layer_index: 0, name: 'distilbert.transformer.layer.0.attention.q_lin' }, position: { y: 2.0, x: -3.0 } },
{ userData: { parent_layer_index: 0, name: 'distilbert.transformer.layer.0.attention.k_lin' }, position: { y: 2.2, x: -1.0 } },
{ userData: { parent_layer_index: 0, name: 'distilbert.transformer.layer.0.ffn.lin1' }, position: { y: 2.8, x: 2.0 } },
{ userData: { parent_layer_index: 1, name: 'distilbert.transformer.layer.1.attention.q_lin' }, position: { y: 6.0, x: -3.0 } },
{ userData: { parent_layer_index: 1, name: 'distilbert.transformer.layer.1.ffn.lin1' }, position: { y: 6.8, x: 2.0 } },
{ userData: { name: 'distilbert.embeddings.word_embeddings' }, position: { y: -2.0, x: 0.0 } },
{ userData: { name: 'distilbert.pre_classifier' }, position: { y: 15.0, x: 0.0 } }
];
function computeLayerTarget(layerIdentifier, meshes) {
const isEmb = layerIdentifier === 'embeddings' || layerIdentifier === 'emb';
const isOut = layerIdentifier === 'output' || layerIdentifier === 'out' || layerIdentifier === 'head';
let matchingMeshes = [];
if (isEmb) {
matchingMeshes = meshes.filter(m => (m.userData.name || '').toLowerCase().includes('embed'));
} else if (isOut) {
matchingMeshes = meshes.filter(m => {
const n = (m.userData.name || '').toLowerCase();
return n.includes('output') || n.includes('classifier') || n.includes('head') || n.includes('lm_head');
});
} else {
const numericIdx = parseInt(layerIdentifier, 10);
if (Number.isFinite(numericIdx)) {
matchingMeshes = meshes.filter(m => m.userData.parent_layer_index === numericIdx);
}
}
if (matchingMeshes.length === 0) return null;
const avgY = matchingMeshes.reduce((sum, m) => sum + m.position.y, 0) / matchingMeshes.length;
const primaryMesh = matchingMeshes.find(m => {
const n = (m.userData.name || '').toLowerCase();
return n.includes('q_lin') || n.includes('q_proj') || n.includes('query');
}) || matchingMeshes[0];
return { avgY, primaryMesh, count: matchingMeshes.length };
}
// Test layer 0 altitude
const layer0Result = computeLayerTarget(0, mockMeshes);
assert.ok(layer0Result !== null);
assert.strictEqual(layer0Result.count, 3);
const expectedLayer0Y = (2.0 + 2.2 + 2.8) / 3;
assert.strictEqual(Math.abs(layer0Result.avgY - expectedLayer0Y) < 1e-6, true);
assert.strictEqual(layer0Result.primaryMesh.userData.name, 'distilbert.transformer.layer.0.attention.q_lin');
// Test layer 1 altitude
const layer1Result = computeLayerTarget(1, mockMeshes);
assert.ok(layer1Result !== null);
assert.strictEqual(layer1Result.count, 2);
const expectedLayer1Y = (6.0 + 6.8) / 2;
assert.strictEqual(Math.abs(layer1Result.avgY - expectedLayer1Y) < 1e-6, true);
// Test embeddings altitude
const embResult = computeLayerTarget('embeddings', mockMeshes);
assert.ok(embResult !== null);
assert.strictEqual(embResult.avgY, -2.0);
// Test output altitude
const outResult = computeLayerTarget('output', mockMeshes);
assert.ok(outResult !== null);
assert.strictEqual(outResult.avgY, 15.0);
});
});

Xet Storage Details

Size:
13.3 kB
·
Xet hash:
4a3a343aae9608bc4ddf28afa69a4caa25de7d3298015903dc19313b9ed9e2f4

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.