wifi-densepose/vendor/midstream/npm-wasm/tests/browser_test.html

526 lines
16 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Midstream WASM Browser Test Suite</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 10px;
margin-bottom: 20px;
}
h1 { margin: 0; font-size: 2em; }
.subtitle { opacity: 0.9; margin-top: 5px; }
.test-section {
background: white;
padding: 20px;
margin-bottom: 15px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-item {
padding: 10px;
margin: 5px 0;
border-left: 4px solid #ddd;
background: #f9f9f9;
font-family: monospace;
}
.test-item.pass { border-color: #4caf50; background: #e8f5e9; }
.test-item.fail { border-color: #f44336; background: #ffebee; }
.test-item.running { border-color: #2196f3; background: #e3f2fd; }
.summary {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-top: 20px;
}
.metric {
display: inline-block;
margin: 10px 20px 10px 0;
font-size: 1.2em;
}
.metric strong { color: #667eea; }
button {
background: #667eea;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
margin: 5px;
}
button:hover { background: #5568d3; }
button:disabled { background: #ccc; cursor: not-allowed; }
pre {
background: #2d3748;
color: #e2e8f0;
padding: 15px;
border-radius: 6px;
overflow-x: auto;
font-size: 13px;
}
</style>
</head>
<body>
<div class="header">
<h1>🚀 Midstream WASM Browser Test Suite</h1>
<p class="subtitle">Comprehensive validation of WebAssembly functionality</p>
</div>
<div class="test-section">
<h2>🎮 Test Controls</h2>
<button onclick="runAllTests()">Run All Tests</button>
<button onclick="clearResults()">Clear Results</button>
</div>
<div id="results"></div>
<div class="summary" id="summary" style="display: none;">
<h2>📊 Test Summary</h2>
<div id="summaryContent"></div>
</div>
<script type="module">
import init, {
version,
TemporalCompare,
NanoScheduler,
StrangeLoop,
QuicMultistream,
benchmark_dtw
} from '../pkg/midstream_wasm.js';
let wasmInitialized = false;
let results = { total: 0, passed: 0, failed: 0, tests: [] };
async function initWasm() {
if (!wasmInitialized) {
await init();
wasmInitialized = true;
console.log('✅ WASM initialized');
}
}
function addResult(category, name, status, details = '') {
results.total++;
if (status === 'pass') results.passed++;
if (status === 'fail') results.failed++;
results.tests.push({ category, name, status, details });
const resultsDiv = document.getElementById('results');
let categorySection = document.getElementById('cat-' + category.replace(/\s+/g, '-'));
if (!categorySection) {
categorySection = document.createElement('div');
categorySection.className = 'test-section';
categorySection.id = 'cat-' + category.replace(/\s+/g, '-');
categorySection.innerHTML = `<h2>${category}</h2>`;
resultsDiv.appendChild(categorySection);
}
const testItem = document.createElement('div');
testItem.className = `test-item ${status}`;
const icon = status === 'pass' ? '✅' : status === 'fail' ? '❌' : '⏳';
testItem.innerHTML = `
${icon} ${name}
${details ? `<pre>${details}</pre>` : ''}
`;
categorySection.appendChild(testItem);
}
function updateSummary() {
const summaryDiv = document.getElementById('summary');
const contentDiv = document.getElementById('summaryContent');
summaryDiv.style.display = 'block';
const successRate = results.total > 0
? ((results.passed / results.total) * 100).toFixed(1)
: 0;
contentDiv.innerHTML = `
<div class="metric">Total: <strong>${results.total}</strong></div>
<div class="metric">✅ Passed: <strong>${results.passed}</strong></div>
<div class="metric">❌ Failed: <strong>${results.failed}</strong></div>
<div class="metric">Success Rate: <strong>${successRate}%</strong></div>
`;
}
window.clearResults = function() {
document.getElementById('results').innerHTML = '';
document.getElementById('summary').style.display = 'none';
results = { total: 0, passed: 0, failed: 0, tests: [] };
};
window.runAllTests = async function() {
clearResults();
try {
await initWasm();
// Module Information
testModuleInfo();
// Temporal Comparison
await testTemporalCompare();
// NanoScheduler
await testNanoScheduler();
// Meta-Learning
testMetaLearning();
// QUIC Multistream
testQuicMultistream();
// Performance
testPerformance();
// Browser Compatibility
testBrowserAPIs();
updateSummary();
} catch (error) {
addResult('Initialization', 'WASM Module', 'fail', error.message);
updateSummary();
}
};
function testModuleInfo() {
try {
const ver = version();
addResult('Module Info', `Version: ${ver}`, 'pass');
} catch (e) {
addResult('Module Info', 'Version', 'fail', e.message);
}
}
async function testTemporalCompare() {
try {
const tc = new TemporalCompare();
addResult('Temporal Compare', 'Constructor', 'pass');
// DTW test
const seq1 = new Float64Array([1, 2, 3, 4, 5]);
const seq2 = new Float64Array([1, 2, 3, 4, 5]);
const dtwDist = tc.dtw(seq1, seq2);
if (dtwDist === 0) {
addResult('Temporal Compare', 'DTW (identical sequences)', 'pass',
`Distance: ${dtwDist}`);
} else {
addResult('Temporal Compare', 'DTW (identical sequences)', 'fail',
`Expected 0, got ${dtwDist}`);
}
// LCS test
const lcsSeq1 = new Int32Array([1, 2, 3, 4, 5]);
const lcsSeq2 = new Int32Array([1, 3, 5]);
const lcsLen = tc.lcs(lcsSeq1, lcsSeq2);
if (lcsLen === 3) {
addResult('Temporal Compare', 'LCS', 'pass', `Length: ${lcsLen}`);
} else {
addResult('Temporal Compare', 'LCS', 'fail',
`Expected 3, got ${lcsLen}`);
}
// Edit distance
const editDist = tc.edit_distance('kitten', 'sitting');
if (editDist === 3) {
addResult('Temporal Compare', 'Edit Distance', 'pass',
`Distance: ${editDist}`);
} else {
addResult('Temporal Compare', 'Edit Distance', 'fail',
`Expected 3, got ${editDist}`);
}
// Comprehensive analysis
const testSeq1 = Float64Array.from({length: 50}, (_, i) => Math.sin(i/5));
const testSeq2 = Float64Array.from({length: 50}, (_, i) => Math.sin(i/5 + 0.3));
const metrics = tc.analyze(testSeq1, testSeq2);
addResult('Temporal Compare', 'Comprehensive Analysis', 'pass',
`DTW: ${metrics.dtw_distance.toFixed(2)}\n` +
`LCS: ${metrics.lcs_length}\n` +
`Edit: ${metrics.edit_distance}\n` +
`Similarity: ${(metrics.similarity_score * 100).toFixed(1)}%`
);
} catch (e) {
addResult('Temporal Compare', 'Tests', 'fail', e.message);
}
}
async function testNanoScheduler() {
try {
const scheduler = new NanoScheduler();
addResult('NanoScheduler', 'Constructor', 'pass');
// Test now_ns
const now = scheduler.now_ns();
if (typeof now === 'number' && now > 0) {
addResult('NanoScheduler', 'now_ns()', 'pass',
`Time: ${now.toFixed(0)}ns`);
} else {
addResult('NanoScheduler', 'now_ns()', 'fail',
`Invalid time: ${now}`);
}
// Test scheduling
let taskExecuted = false;
const taskId = scheduler.schedule(() => {
taskExecuted = true;
}, 10000000); // 10ms
if (typeof taskId === 'number' && taskId > 0) {
addResult('NanoScheduler', 'schedule()', 'pass',
`Task ID: ${taskId}`);
} else {
addResult('NanoScheduler', 'schedule()', 'fail',
`Invalid task ID: ${taskId}`);
}
// Test pending count
const pending = scheduler.pending_count;
addResult('NanoScheduler', 'pending_count', 'pass',
`Pending: ${pending}`);
// Test tick after delay
await new Promise(resolve => setTimeout(resolve, 20));
const executed = scheduler.tick();
if (taskExecuted) {
addResult('NanoScheduler', 'tick() execution', 'pass',
`Executed ${executed} tasks`);
} else {
addResult('NanoScheduler', 'tick() execution', 'fail',
'Task not executed');
}
// Test cancel
const cancelId = scheduler.schedule(() => {}, 1000000000);
const cancelled = scheduler.cancel(cancelId);
if (cancelled) {
addResult('NanoScheduler', 'cancel()', 'pass');
} else {
addResult('NanoScheduler', 'cancel()', 'fail',
'Failed to cancel task');
}
} catch (e) {
addResult('NanoScheduler', 'Tests', 'fail', e.message);
}
}
function testMetaLearning() {
try {
const loop = new StrangeLoop(0.1);
addResult('Meta-Learning', 'Constructor', 'pass');
// Test observation
loop.observe('pattern-a', 0.5);
loop.observe('pattern-b', 0.8);
loop.observe('pattern-c', 0.3);
if (loop.iteration_count === 3 && loop.pattern_count === 3) {
addResult('Meta-Learning', 'observe()', 'pass',
`Iterations: ${loop.iteration_count}, Patterns: ${loop.pattern_count}`);
} else {
addResult('Meta-Learning', 'observe()', 'fail',
`Unexpected counts: ${loop.iteration_count}, ${loop.pattern_count}`);
}
// Test get_confidence
const confidence = loop.get_confidence('pattern-b');
if (confidence !== undefined && confidence >= 0 && confidence <= 1) {
addResult('Meta-Learning', 'get_confidence()', 'pass',
`Confidence: ${(confidence * 100).toFixed(1)}%`);
} else {
addResult('Meta-Learning', 'get_confidence()', 'fail',
`Invalid confidence: ${confidence}`);
}
// Test best pattern
const best = loop.best_pattern();
if (best && best.pattern_id === 'pattern-b') {
addResult('Meta-Learning', 'best_pattern()', 'pass',
`Best: ${best.pattern_id} (${(best.confidence * 100).toFixed(1)}%)`);
} else {
addResult('Meta-Learning', 'best_pattern()', 'fail',
`Unexpected best pattern: ${best?.pattern_id}`);
}
// Test reflection
const reflection = loop.reflect();
if (reflection && typeof reflection === 'object') {
addResult('Meta-Learning', 'reflect()', 'pass',
`Patterns: ${JSON.stringify(Object.keys(reflection))}`);
} else {
addResult('Meta-Learning', 'reflect()', 'fail',
'Invalid reflection object');
}
} catch (e) {
addResult('Meta-Learning', 'Tests', 'fail', e.message);
}
}
function testQuicMultistream() {
try {
const quic = new QuicMultistream();
addResult('QUIC Multistream', 'Constructor', 'pass');
// Test open stream
const streamId = quic.open_stream(128);
if (typeof streamId === 'number' && quic.stream_count === 1) {
addResult('QUIC Multistream', 'open_stream()', 'pass',
`Stream ID: ${streamId}, Count: ${quic.stream_count}`);
} else {
addResult('QUIC Multistream', 'open_stream()', 'fail',
`Invalid stream: ${streamId}`);
}
// Test send
const data = new Uint8Array([1, 2, 3, 4, 5]);
const sent = quic.send(streamId, data);
if (sent === 5) {
addResult('QUIC Multistream', 'send()', 'pass',
`Sent: ${sent} bytes`);
} else {
addResult('QUIC Multistream', 'send()', 'fail',
`Expected 5, got ${sent}`);
}
// Test receive
const received = quic.receive(streamId, 100);
if (received instanceof Uint8Array && received.length === 100) {
addResult('QUIC Multistream', 'receive()', 'pass',
`Received: ${received.length} bytes`);
} else {
addResult('QUIC Multistream', 'receive()', 'fail',
`Invalid receive: ${received?.length}`);
}
// Test stats
const stats = quic.get_stats(streamId);
if (stats && stats.stream_id === streamId) {
addResult('QUIC Multistream', 'get_stats()', 'pass',
`Sent: ${stats.bytes_sent}, Recv: ${stats.bytes_received}`);
} else {
addResult('QUIC Multistream', 'get_stats()', 'fail',
'Invalid stats');
}
// Test close
const closed = quic.close_stream(streamId);
if (closed && quic.stream_count === 0) {
addResult('QUIC Multistream', 'close_stream()', 'pass');
} else {
addResult('QUIC Multistream', 'close_stream()', 'fail',
`Failed to close stream`);
}
} catch (e) {
addResult('QUIC Multistream', 'Tests', 'fail', e.message);
}
}
function testPerformance() {
try {
// Benchmark DTW
const avgTime = benchmark_dtw(100, 100);
const throughput = 1000 / avgTime;
addResult('Performance', 'DTW Benchmark', 'pass',
`Avg time: ${avgTime.toFixed(3)}ms\n` +
`Throughput: ${throughput.toFixed(0)} ops/sec`
);
// Test different sizes
const time50 = benchmark_dtw(50, 50);
const time100 = benchmark_dtw(100, 50);
const time200 = benchmark_dtw(200, 50);
addResult('Performance', 'DTW Scaling', 'pass',
`50 elements: ${time50.toFixed(3)}ms\n` +
`100 elements: ${time100.toFixed(3)}ms\n` +
`200 elements: ${time200.toFixed(3)}ms`
);
} catch (e) {
addResult('Performance', 'Benchmarks', 'fail', e.message);
}
}
function testBrowserAPIs() {
// Check WebAssembly support
if (typeof WebAssembly !== 'undefined') {
addResult('Browser Compatibility', 'WebAssembly', 'pass',
'Full WASM support');
} else {
addResult('Browser Compatibility', 'WebAssembly', 'fail',
'No WASM support');
}
// Check Performance API
if (window.performance && typeof window.performance.now === 'function') {
addResult('Browser Compatibility', 'Performance API', 'pass',
`High-resolution timing available`);
} else {
addResult('Browser Compatibility', 'Performance API', 'fail',
'No Performance API');
}
// Check Crypto API
if (window.crypto && window.crypto.getRandomValues) {
addResult('Browser Compatibility', 'Crypto API', 'pass',
'Secure random available');
} else {
addResult('Browser Compatibility', 'Crypto API', 'fail',
'No Crypto API');
}
// Check typed arrays
const typedArrays = ['Float64Array', 'Int32Array', 'Uint8Array'];
const supported = typedArrays.filter(name => typeof window[name] !== 'undefined');
if (supported.length === typedArrays.length) {
addResult('Browser Compatibility', 'Typed Arrays', 'pass',
supported.join(', '));
} else {
addResult('Browser Compatibility', 'Typed Arrays', 'fail',
`Missing: ${typedArrays.filter(n => !supported.includes(n)).join(', ')}`);
}
// Check user agent
addResult('Browser Compatibility', 'User Agent', 'pass',
navigator.userAgent);
}
// Auto-run tests on load
window.addEventListener('load', () => {
console.log('Page loaded, ready to run tests');
});
</script>
</body>
</html>