Files
ytplayer/frontend/stats-core.test.js

68 lines
3.1 KiB
JavaScript

'use strict';
const { test } = require('node:test');
const assert = require('node:assert');
const SC = require('./stats-core');
const at = (y, m, d, h = 12) => new Date(y, m - 1, d, h);
const songA = { id: 'aaaaaaaaaaa', title: 'Goodness of God', channel: 'Bethel Music - Topic' };
const songB = { id: 'bbbbbbbbbbb', title: 'Build My Life', channel: 'Housefires' };
test('record accumulates seconds and plays per local day', () => {
let s = SC.empty();
s = SC.record(s, songA, 100, true, at(2026, 9, 18));
s = SC.record(s, songA, 50, false, at(2026, 9, 18));
s = SC.record(s, songB, 30, true, at(2026, 9, 19));
assert.deepStrictEqual(s.days['2026-09-18'], { s: 150, p: 1, songs: { aaaaaaaaaaa: 1 } });
assert.strictEqual(s.days['2026-09-19'].p, 1);
assert.strictEqual(s.meta.aaaaaaaaaaa.t, 'Goodness of God');
});
test('old days are pruned', () => {
let s = SC.empty();
s = SC.record(s, songA, 10, true, at(2024, 1, 1));
s = SC.record(s, songA, 10, true, at(2026, 9, 18));
assert.deepStrictEqual(Object.keys(s.days), ['2026-09-18']);
});
test('streak counts consecutive 5-minute days, allowing today to be pending', () => {
let s = SC.empty();
for (const d of [10, 11, 12, 15, 16, 17]) s = SC.record(s, songA, 400, true, at(2026, 9, d));
s = SC.record(s, songA, 60, true, at(2026, 9, 18)); // today, under 5 min so far
const st = SC.streaks(s, at(2026, 9, 18));
assert.strictEqual(st.current, 3); // 15,16,17
assert.strictEqual(st.best, 3);
s = SC.record(s, songA, 400, true, at(2026, 9, 18));
assert.strictEqual(SC.streaks(s, at(2026, 9, 18)).current, 4);
});
test('summary: month totals, top artists (Topic stripped), top songs with sparkline, heatmap', () => {
let s = SC.empty();
s = SC.record(s, songA, 3600, true, at(2026, 8, 20)); // last month
s = SC.record(s, songA, 1800, true, at(2026, 9, 14)); // this month (Mon)
s = SC.record(s, songA, 1800, true, at(2026, 9, 17));
s = SC.record(s, songB, 600, true, at(2026, 9, 17));
const sum = SC.summarize(s, at(2026, 9, 18));
assert.strictEqual(sum.thisMonthSec, 4200);
assert.strictEqual(sum.lastMonthSec, 3600);
assert.strictEqual(sum.totalPlays, 4);
assert.strictEqual(sum.songsPlayed, 2);
assert.deepStrictEqual(sum.topArtists, [{ name: 'Bethel Music', plays: 2 }, { name: 'Housefires', plays: 1 }]);
assert.strictEqual(sum.topSongs[0].title, 'Goodness of God');
assert.strictEqual(sum.topSongs[0].plays, 3);
assert.strictEqual(sum.topSongs[0].spark.length, 30);
assert.strictEqual(sum.topSongs[0].spark.at(-2), 1); // Sep 17
assert.strictEqual(sum.heat.length, 16);
const cur = sum.heat[15];
assert.strictEqual(cur[0].date, '2026-09-14'); // Monday of this week
assert.strictEqual(cur[0].minutes, 30);
assert.strictEqual(cur[6].future, true); // Sunday Sep 20 hasn't happened
assert.strictEqual(sum.peak.day, 'Thursday'); // Sep 17 had 40 min
});
test('fmtHours and artistOf', () => {
assert.strictEqual(SC.fmtHours(152280), '42h 18m');
assert.strictEqual(SC.fmtHours(600), '10m');
assert.strictEqual(SC.artistOf('BethelVEVO'), 'Bethel');
assert.strictEqual(SC.artistOf(''), 'Unknown');
});