Files
codex-bot 1a3a2566e3 SUNDIAL solar dial v0.3: round screen, NOAA solar math, day/night arc
- 466px round layout, designWidth 466 (S4 41mm 466x466)
- solar position + dayProgress in src/common/solar.js (pure, TDD'd)
- sunrise/sunset sweep, night moon, countdown, 30s refresh
- tests: solar math, page logic, circle geometry/contrast
2026-09-09 15:09:14 +01:00

33 lines
1.6 KiB
JavaScript

// Compatibility contract, NOT a reproduction of the watch's native crash.
// Marker must use documented numeric positioning, not chained transforms.
const fs = require('node:fs');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const solar = require('../src/common/solar.js');
const ux = fs.readFileSync('src/pages/index/index.ux', 'utf8');
const body = ux.match(/<script>([\s\S]*?)<\/script>/)[1]
.replace(/import\s+solar\s+from\s+'[^']*';?/, '')
.replace('export default', '');
const spec = vm.runInNewContext('(' + body + ')', {solar, Date, Math, String, Number});
const page = Object.assign({}, spec, JSON.parse(JSON.stringify(spec.private)));
page.onInit();
page.update();
assert.ok(page.markerStyle && Number.isFinite(parseFloat(page.markerStyle.left)),
'marker must expose a finite left coordinate via a bound style object');
assert.match(ux, /style="{{\s*markerStyle\s*}}"/);
assert.doesNotMatch(ux, /transform\s*:/);
assert.doesNotMatch(ux, /width:\s*0px/);
const size = Number(ux.match(/\.sunDot\s*\{[^}]*width:\s*(\d+)px/)[1]);
// Check actual bound marker box, not an unused constant.
for (let angle = -270; angle <= 90; angle++) {
page.sunAngle = angle;
page.positionMarker();
const x = parseFloat(page.markerStyle.left), y = parseFloat(page.markerStyle.top);
assert.ok(Number.isInteger(x) && Number.isInteger(y));
for (const dx of [0, size]) for (const dy of [0, size]) {
assert.ok(Math.hypot(x + dx - 233, y + dy - 233) <= 200,
`marker box leaves the 400px dial at angle ${angle}`);
}
}
console.log('MARKER PASS: bound coordinates, no transforms, actual box fits all angles');