Carpincho/test/estadisticas.test.cjs
2026-09-29 23:54:01 -03:00

66 lines
3.6 KiB
JavaScript

const {test} = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const stats = require('../src/gui_common/js/estadisticas.js');
const row = (time, values = {}) => ({fecha: `29/09/2026 ${time}`, ...values});
const metric = (result, key = 'temperatura_externa') => result.series.find(s => s.key === key);
test('empty history and malformed input', () => {
assert.equal(stats.analyze('[]').dated, 0);
assert.throws(() => stats.analyze('{}'));
assert.throws(() => stats.analyze('invalid'));
});
test('one unchanged record is enough', () => {
const result = stats.analyze([row('12:00:00', {temperatura_externa: 0, cambio: false})]);
assert.equal(result.changed, 0);
assert.equal(metric(result).mean, 0);
assert.equal(metric(result).count, 1);
});
test('missing values do not become zero and latest remains missing', () => {
const result = stats.analyze([row('12:00:00', {temperatura_externa: '-4'}), row('12:01:00', {temperatura_externa: 0}), row('12:02:00', {temperatura_externa: ''}), row('12:03:00', {temperatura_externa: null})]);
assert.equal(metric(result).mean, -2);
assert.equal(metric(result).count, 2);
assert.equal(metric(result).last, null);
assert.deepEqual(metric(result).points.map(p => p.value), [-4, 0, null, null]);
});
test('orders dates and excludes malformed rows without mutating input', () => {
const input = [row('13:00:00', {temperatura_externa: 20}), null, {}, row('12:00:00', {temperatura_externa: 10, cambio: true})];
const before = JSON.stringify(input);
const result = stats.analyze(input);
assert.equal(result.discarded, 2);
assert.equal(result.changed, 1);
assert.equal(metric(result).last, 20);
assert.equal(result.first, '29/09/2026 12:00:00');
assert.equal(JSON.stringify(input), before);
});
test('imperial temperature and wind conversion preserves absent measurements', () => {
const result = stats.analyze([row('12:00:00', {temperatura_externa: 0, viento_velocidad: 100})], 'SM');
assert.equal(metric(result).mean, 32);
assert.equal(metric(result).unit, '°F');
assert.equal(metric(result, 'viento_velocidad').unit, 'mph');
assert.ok(Math.abs(metric(result, 'viento_velocidad').mean - 62.1371192) < 0.000001);
assert.equal(metric(result, 'temperatura_interna').mean, null);
});
test('rain accumulators are not summed', () => {
const result = stats.analyze([row('12:00:00', {lluvia_acu_diaria: 10}), row('13:00:00', {lluvia_acu_diaria: 11})]);
assert.equal(metric(result, 'lluvia_acu_diaria').last, 11);
assert.equal(metric(result, 'lluvia_acu_diaria').max, 11);
});
test('both production adapters load the proper data source', async () => {
for (const mode of ['gui', 'gui_web']) {
let request;
const sandbox = {
configGeneralEMA: {ConfGeneral: {Modo: 'Recolector_IP', SistemaMetrico: 'SI'}},
document: {getElementById: id => id},
EstadisticasUI: {mount: async (root, options) => {assert.equal(root, 'estadisticas'); assert.equal(options.mode, 'Recolector_IP'); return options.load();}},
fsconf: {readFile: (file, encoding, cb) => {request = file; cb(null, '[]');}},
$: {ajax: options => {request = options.url; return Promise.resolve('[]');}}
};
const script = fs.readFileSync(`src/${mode}/controlador/funcionesgenerales.js`, 'utf8').split('async function graficoEstadisticas()')[1];
vm.runInNewContext('async function graficoEstadisticas()' + script, sandbox);
assert.equal(await sandbox.graficoEstadisticas(), '[]');
assert.equal(request, mode === 'gui' ? './logs/registro_diario.log' : '/VerHistorico');
}
});