66 lines
3.6 KiB
JavaScript
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');
|
|
}
|
|
});
|