You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
senzapaura_es/scripts/medios.spec.mjs

152 lines
4.9 KiB

import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import {
argumentosDeEscucha,
argumentosDeOnda,
aSlug,
claveCanonica,
claveDeEscucha,
claveDeOnda,
comoDuracion,
enLaBandeja,
recorrerMasters,
resumirPicos
} from './medios.mjs';
describe('claveCanonica', () => {
it('agrupa por disco y numera como la pista', () => {
const clave = claveCanonica(
{ album: 'dos-orillas', numero: 3 },
'media-verdad',
'subidas/loquesea.mp3',
''
);
expect(clave).toBe('dos-orillas/03-media-verdad.mp3');
});
it('manda a singles lo que no tiene disco', () => {
// Un tema suelto no ocupa ninguna posición, así que no lleva número.
const clave = claveCanonica({}, 'dorina', 'subidas/Senza Paura - Dorina.mp3', '');
expect(clave).toBe('singles/dorina.mp3');
});
it('distingue las alternativas musicales del arreglo principal', () => {
const clave = claveCanonica(
{ album: 'como-si-nada', numero: 1 },
'como-si-nada',
'subidas/orq.mp3',
'-orquestal'
);
expect(clave).toBe('como-si-nada/01-como-si-nada-orquestal.mp3');
});
it('conserva la extensión, en minúsculas', () => {
expect(claveCanonica({}, 'dorina', 'subidas/DORINA.WAV', '')).toBe('singles/dorina.wav');
});
it('no numera un single aunque traiga número', () => {
// El número solo tiene sentido dentro de un disco; el esquema lo ignora,
// y el nombre del archivo tiene que decir lo mismo.
expect(claveCanonica({ numero: 4 }, 'dorina', 'subidas/x.mp3', '')).toBe('singles/dorina.mp3');
});
});
describe('enLaBandeja', () => {
it('reconoce lo que acaba de subir el panel', () => {
expect(enLaBandeja('subidas/Senza Paura - Dorina.mp3')).toBe(true);
// El panel puede escribir la clave con barra inicial.
expect(enLaBandeja('/subidas/dorina.mp3')).toBe(true);
});
it('deja en paz lo que ya está colocado', () => {
expect(enLaBandeja('singles/dorina.mp3')).toBe(false);
// Un disco que se llamara así no debe confundirse con la bandeja.
expect(enLaBandeja('subidas-de-tono/01-tema.mp3')).toBe(false);
});
});
describe('comoDuracion', () => {
it('escribe m:ss como lo espera el esquema', () => {
expect(comoDuracion(277.752)).toBe('4:38');
expect(comoDuracion(65)).toBe('1:05');
expect(comoDuracion(600)).toBe('10:00');
});
});
describe('aSlug', () => {
it('coincide con el del esquema', () => {
expect(aSlug('Vals criollo peruano')).toBe('vals-criollo-peruano');
expect(aSlug('Versión orquestal')).toBe('version-orquestal');
});
});
describe('escucha protegida', () => {
it('incluye los másteres importados sin Markdown y omite la bandeja', () => {
const raiz = fs.mkdtempSync(path.join(os.tmpdir(), 'senzapaura-medios-'));
try {
fs.mkdirSync(path.join(raiz, 'album'), { recursive: true });
fs.mkdirSync(path.join(raiz, 'subidas'), { recursive: true });
fs.writeFileSync(path.join(raiz, 'album', '01-tema.mp3'), 'master');
fs.writeFileSync(path.join(raiz, 'album', 'nota.txt'), 'no es audio');
fs.writeFileSync(path.join(raiz, 'subidas', 'pendiente.mp3'), 'pendiente');
expect(recorrerMasters(raiz).map((p) => path.relative(raiz, p))).toEqual([
path.join('album', '01-tema.mp3')
]);
} finally {
fs.rmSync(raiz, { recursive: true, force: true });
}
});
it('conserva la jerarquía y normaliza el formato', () => {
expect(claveDeEscucha('disco/01-tema.wav')).toBe('disco/01-tema.mp3');
});
it('codifica la canción completa a menor calidad', () => {
const args = argumentosDeEscucha(
'media/audio/singles/dorina.wav',
'media/escucha/singles/dorina.mp3'
);
expect(args).not.toContain('-ss');
expect(args).not.toContain('-t');
expect(args).toContain('libmp3lame');
expect(args).toContain('96k');
expect(args.at(-1)).toBe('media/escucha/singles/dorina.mp3');
});
});
describe('forma de onda', () => {
it('conserva la jerarquía y cambia el audio por JSON', () => {
expect(claveDeOnda('disco/01-tema.wav')).toBe('disco/01-tema.json');
});
it('decodifica a PCM mono ligero', () => {
const args = argumentosDeOnda('media/escucha/disco/01-tema.mp3');
expect(args).toContain('1');
expect(args).toContain('8000');
expect(args).toContain('s16le');
expect(args.at(-1)).toBe('pipe:1');
});
it('resume amplitudes, conserva silencios y normaliza el nivel', () => {
const pcm = Buffer.alloc(800);
// Cuatro bloques: silencio, pasaje suave y dos pasajes fuertes.
for (let i = 100; i < 200; i++) pcm.writeInt16LE(1_000, i * 2);
for (let i = 200; i < 400; i++) pcm.writeInt16LE(i % 2 ? 10_000 : -10_000, i * 2);
const picos = resumirPicos(pcm, 4);
expect(picos).toHaveLength(4);
expect(picos[0]).toBe(0);
expect(picos[1]).toBeGreaterThan(0);
expect(picos[1]).toBeLessThan(picos[2]);
expect(picos[2]).toBe(255);
expect(picos[3]).toBe(255);
});
it('devuelve la anchura pedida incluso para un audio vacío', () => {
expect(resumirPicos(Buffer.alloc(0), 3)).toEqual([0, 0, 0]);
});
});

Powered by TurnKey Linux.