60 lines
5.8 KiB
HTML
60 lines
5.8 KiB
HTML
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>Chrome Sketcher dimensional diagnostics harness</title>
|
|
<pre id="result">running</pre>
|
|
<script type="module">
|
|
import { createSketch, solveSketch } from '/src/facade/sketcher.ts'
|
|
|
|
const output = document.querySelector('#result')
|
|
const report = { schemaVersion: 1, browserId: 'chrome', crossOriginIsolated: globalThis.crossOriginIsolated === true, status: 'running' }
|
|
try {
|
|
const referenceInput = createSketch('chrome-reference', [{ id: 'line', type: 'line', start: { x: 0, y: 0 }, end: { x: 2, y: 1 } }], [
|
|
{ id: 'horizontal', type: 'horizontal', geometryId: 'line' },
|
|
{ id: 'reference-length', type: 'distance', first: { geometryId: 'line', point: 'start' }, second: { geometryId: 'line', point: 'end' }, value: 99, driving: false },
|
|
])
|
|
const duplicateInput = createSketch('chrome-duplicate', [{ id: 'line', type: 'line', start: { x: 0, y: 0 }, end: { x: 1, y: 0 } }], [
|
|
{ id: 'length-1', type: 'distance', first: { geometryId: 'line', point: 'start' }, second: { geometryId: 'line', point: 'end' }, value: 5 },
|
|
{ id: 'length-2', type: 'distance', first: { geometryId: 'line', point: 'start' }, second: { geometryId: 'line', point: 'end' }, value: 5 },
|
|
])
|
|
const conflictInput = createSketch('chrome-conflict', [{ id: 'line', type: 'line', start: { x: 0, y: 0 }, end: { x: 1, y: 0 } }], [
|
|
{ id: 'length-1', type: 'distance', first: { geometryId: 'line', point: 'start' }, second: { geometryId: 'line', point: 'end' }, value: 5 },
|
|
{ id: 'length-2', type: 'distance', first: { geometryId: 'line', point: 'start' }, second: { geometryId: 'line', point: 'end' }, value: 8 },
|
|
])
|
|
const coincidentInput = createSketch('chrome-coincident', [
|
|
{ id: 'first', type: 'line', start: { x: 0, y: 0 }, end: { x: 2, y: 0 } },
|
|
{ id: 'second', type: 'line', start: { x: 5, y: 3 }, end: { x: 6, y: 4 } },
|
|
], [{ id: 'coincident', type: 'coincident', first: { geometryId: 'first', point: 'end' }, second: { geometryId: 'second', point: 'start' } }])
|
|
const blockInput = createSketch('chrome-block', [{ id: 'line', type: 'line', start: { x: 1, y: 2 }, end: { x: 4, y: 6 } }], [{ id: 'block', type: 'block', geometryId: 'line' }])
|
|
const reference = solveSketch(referenceInput)
|
|
const duplicate = solveSketch(duplicateInput)
|
|
const conflict = solveSketch(conflictInput)
|
|
const coincident = solveSketch(coincidentInput)
|
|
const block = solveSketch(blockInput)
|
|
const markerDirectory = await navigator.storage.getDirectory()
|
|
const markerName = 'sketcher-diagnostics-chrome-marker.json'
|
|
const marker = await markerDirectory.getFileHandle(markerName, { create: true })
|
|
const writable = await marker.createWritable()
|
|
await writable.write(JSON.stringify({ suite: 'SK-06/SK-07', cases: 5 }))
|
|
await writable.close()
|
|
const markerPayload = JSON.parse(await (await marker.getFile()).text())
|
|
await markerDirectory.removeEntry(markerName)
|
|
let markerRemoved = false
|
|
try { await markerDirectory.getFileHandle(markerName) } catch (error) { markerRemoved = error?.name === 'NotFoundError' }
|
|
report.fixtures = {
|
|
reference: { status: reference.status, degreesOfFreedom: reference.degreesOfFreedom, diagnostic: reference.diagnostics.some((diagnostic) => diagnostic.code === 'REFERENCE_DIMENSION' && diagnostic.constraintId === 'reference-length'), unchangedEnd: reference.snapshot.geometry[0].type === 'line' && reference.snapshot.geometry[0].end.x === 2 },
|
|
redundant: { status: duplicate.status, diagnostic: duplicate.diagnostics.some((diagnostic) => diagnostic.code === 'REDUNDANT_CONSTRAINT' && diagnostic.constraintId === 'length-2') },
|
|
conflicting: { status: conflict.status, diagnostic: conflict.diagnostics.some((diagnostic) => diagnostic.code === 'CONSTRAINT_CONFLICT' && diagnostic.constraintId === 'length-2'), notConverged: conflict.diagnostics.some((diagnostic) => diagnostic.code === 'SOLVER_NOT_CONVERGED') },
|
|
coincident: { status: coincident.status, residual: coincident.residual, sharedPoint: coincident.snapshot.geometry[0].type === 'line' && coincident.snapshot.geometry[1].type === 'line' && coincident.snapshot.geometry[0].end.x === coincident.snapshot.geometry[1].start.x && coincident.snapshot.geometry[0].end.y === coincident.snapshot.geometry[1].start.y },
|
|
block: { status: block.status, degreesOfFreedom: block.degreesOfFreedom, unchanged: block.snapshot.geometry[0].type === 'line' && block.snapshot.geometry[0].start.x === 1 && block.snapshot.geometry[0].start.y === 2 && block.snapshot.geometry[0].end.x === 4 && block.snapshot.geometry[0].end.y === 6 },
|
|
}
|
|
report.opfs = { markerSuite: markerPayload.suite, markerRemoved }
|
|
report.status = report.crossOriginIsolated && report.fixtures.reference.status === 'under-constrained' && report.fixtures.reference.degreesOfFreedom === 3 && report.fixtures.reference.diagnostic && report.fixtures.reference.unchangedEnd && report.fixtures.redundant.status === 'under-constrained' && report.fixtures.redundant.diagnostic && report.fixtures.conflicting.status === 'conflicting' && report.fixtures.conflicting.diagnostic && report.fixtures.conflicting.notConverged && report.fixtures.coincident.status === 'under-constrained' && report.fixtures.coincident.residual === 0 && report.fixtures.coincident.sharedPoint && report.fixtures.block.status === 'solved' && report.fixtures.block.degreesOfFreedom === 0 && report.fixtures.block.unchanged && report.opfs.markerSuite === 'SK-06/SK-07' && report.opfs.markerRemoved ? 'pass' : 'failed'
|
|
} catch (error) {
|
|
report.status = 'failed'
|
|
report.error = error instanceof Error ? error.message : String(error)
|
|
}
|
|
output.textContent = JSON.stringify(report, null, 2)
|
|
await fetch('/__chrome-sketcher-diagnostics-report', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(report) })
|
|
if (report.status !== 'pass') throw new Error(report.error || 'Chrome Sketcher diagnostics harness failed.')
|
|
</script>
|