mirror of
https://github.com/acamarata/nrel-spa.git
synced 2026-06-30 19:04:25 +00:00
88 lines
4 KiB
JavaScript
88 lines
4 KiB
JavaScript
// bin/test.js
|
|
// Run 10 diverse test cases through both your JS port and the C reference (spa_cli) and compare.
|
|
|
|
'use strict';
|
|
|
|
const { spawnSync } = require('child_process');
|
|
const path = require('path');
|
|
const { getSpa } = require('../index');
|
|
|
|
// Constants for C invocation
|
|
const DELTA_UT1 = 0.0;
|
|
const DELTA_T = 67.0;
|
|
const SLOPE = 0.0;
|
|
const AZM_ROT = 0.0;
|
|
const ATMOS_REF = 0.5667;
|
|
|
|
// Helper to format fractional hours into "HH:MM:SS" or "N/A"
|
|
function formatJS(hour) {
|
|
if (typeof hour !== 'number' || isNaN(hour) || hour < 0 || hour >= 24) {
|
|
return 'N/A';
|
|
}
|
|
const total = Math.round(hour * 3600);
|
|
const H = Math.floor(total / 3600);
|
|
const M = Math.floor((total % 3600) / 60);
|
|
const S = total % 60;
|
|
return [H, M, S]
|
|
.map(v => v.toString().padStart(2, '0'))
|
|
.join(':');
|
|
}
|
|
|
|
// Ten diverse test cases
|
|
const cases = [
|
|
{ label: 'New York Summer', dateUTC: new Date(Date.UTC(2025, 5, 21, 0,0,0)), lat: 40.7128, lon: -74.0060, tz: -4, elevation: 10, pressure: 1013, temperature: 20 },
|
|
{ label: 'New York Winter', dateUTC: new Date(Date.UTC(2025,11,21, 0,0,0)), lat: 40.7128, lon: -74.0060, tz: -5, elevation: 10, pressure: 1013, temperature: 5 },
|
|
{ label: 'London Summer', dateUTC: new Date(Date.UTC(2025, 5, 21, 0,0,0)), lat: 51.5074, lon: -0.1278, tz: 1, elevation: 11, pressure: 1013, temperature: 18 },
|
|
{ label: 'London Winter', dateUTC: new Date(Date.UTC(2025,11,21, 0,0,0)), lat: 51.5074, lon: -0.1278, tz: 0, elevation: 11, pressure: 1013, temperature: 7 },
|
|
{ label: 'Tokyo Summer', dateUTC: new Date(Date.UTC(2025, 5, 21, 0,0,0)), lat: 35.6895, lon: 139.6917, tz: 9, elevation: 40, pressure: 1013, temperature: 22 },
|
|
{ label: 'Sydney Winter', dateUTC: new Date(Date.UTC(2025, 5, 21, 0,0,0)), lat: -33.8688,lon: 151.2093, tz: 10, elevation: 58, pressure: 1013, temperature: 15 },
|
|
{ label: 'Reykjavik Mids', dateUTC: new Date(Date.UTC(2025, 5, 21, 0,0,0)), lat: 64.1466, lon: -21.9426,tz: 0, elevation: 0, pressure: 1013, temperature: 10 },
|
|
{ label: 'Cape Town Summer', dateUTC: new Date(Date.UTC(2025,11,21, 0,0,0)), lat: -33.9249,lon: 18.4241, tz: 2, elevation: 25, pressure: 1013, temperature: 18 },
|
|
{ label: 'Quito Equinox', dateUTC: new Date(Date.UTC(2025, 2, 20, 0,0,0)), lat: -0.1807, lon: -78.4678,tz: -5, elevation:2850, pressure: 789, temperature: 14 },
|
|
{ label: 'Tromso Polar', dateUTC: new Date(Date.UTC(2025,11,21, 0,0,0)), lat: 69.6492, lon: 18.9553,tz: 1, elevation: 0, pressure: 1013, temperature: -2 }
|
|
];
|
|
|
|
// Print header
|
|
console.log(
|
|
'Location | Date | C Rise | JS Rise | C Noon | JS Noon | C Set | JS Set'
|
|
);
|
|
console.log('-'.repeat(83));
|
|
|
|
cases.forEach(({ label, dateUTC, lat, lon, tz, elevation, pressure, temperature }) => {
|
|
const dateStr = dateUTC.toISOString().slice(0,10);
|
|
|
|
// JS calculation
|
|
const jsResult = getSpa(dateUTC, lat, lon, tz, { elevation, pressure, temperature });
|
|
const jsRise = formatJS(jsResult.sunrise);
|
|
const jsNoon = formatJS(jsResult.solarNoon);
|
|
const jsSet = formatJS(jsResult.sunset);
|
|
|
|
// C reference via spa_cli
|
|
const cli = path.join(__dirname, 'spa_cli');
|
|
const args = [
|
|
dateUTC.getUTCFullYear(), dateUTC.getUTCMonth()+1, dateUTC.getUTCDate(),
|
|
dateUTC.getUTCHours(), dateUTC.getUTCMinutes(), dateUTC.getUTCSeconds(),
|
|
DELTA_UT1, DELTA_T, tz,
|
|
lon, lat,
|
|
elevation, pressure, temperature,
|
|
SLOPE, AZM_ROT, ATMOS_REF
|
|
].map(String);
|
|
|
|
const stdout = spawnSync(cli, args, { encoding: 'utf8' }).stdout || '';
|
|
let cRise = 'N/A', cNoon = 'N/A', cSet = 'N/A';
|
|
stdout.split(/\r?\n/).forEach(line => {
|
|
const match = line.match(/(\d{2}:\d{2}:\d{2})/);
|
|
if (match) {
|
|
const key = line.toLowerCase();
|
|
if (key.includes('sunrise')) cRise = match[1];
|
|
else if (key.includes('solar noon')) cNoon = match[1];
|
|
else if (key.includes('sunset')) cSet = match[1];
|
|
}
|
|
});
|
|
|
|
// Print row
|
|
console.log(
|
|
`${label.padEnd(16)} | ${dateStr} | ${cRise.padEnd(8)} | ${jsRise.padEnd(8)} | ` +
|
|
`${cNoon.padEnd(8)} | ${jsNoon.padEnd(8)} | ${cSet.padEnd(8)} | ${jsSet}`
|
|
);
|
|
});
|