mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-12 05:16:19 -07:00
feat(anime): filter episodes and mark them watched by hand
- Add a filter box above the episode list for a number, range, or name substring, with a "N of M" counter - Read watch marks from the immersion tracker stats and show them per episode, with a watched count in the header, refreshed on window focus - Add a right-click menu to mark one episode or a whole catch-up span (this and everything below) watched/unwatched - Add setWatched/getWatchState IPC plumbing so a manual mark creates the stats row for an episode that was never played
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { filterEpisodes, parseEpisodeFilter } from './episode-filter';
|
||||
|
||||
const episode = (number: number | null, name: string) => ({ number, name });
|
||||
|
||||
const SEASON = [
|
||||
episode(1, 'Episode 1 - Departure'),
|
||||
episode(2, 'Episode 2 - The Long Road'),
|
||||
episode(12, 'Episode 12 - Homecoming'),
|
||||
episode(12.5, 'Episode 12.5 - Recap'),
|
||||
episode(18, 'Episode 18 - Finale'),
|
||||
episode(null, 'OVA: Beach Special'),
|
||||
];
|
||||
|
||||
test('an empty query keeps the whole list', () => {
|
||||
assert.deepEqual(filterEpisodes(SEASON, ' '), SEASON);
|
||||
assert.equal(parseEpisodeFilter(''), null);
|
||||
});
|
||||
|
||||
test('a number matches that episode, not every episode containing the digits', () => {
|
||||
assert.deepEqual(
|
||||
filterEpisodes(SEASON, '12').map((item) => item.number),
|
||||
[12, 12.5],
|
||||
);
|
||||
});
|
||||
|
||||
test('a number still matches names when the source reported no numbers', () => {
|
||||
const unnumbered = [episode(null, 'Episode 3'), episode(null, 'Episode 4')];
|
||||
assert.deepEqual(
|
||||
filterEpisodes(unnumbered, '3').map((item) => item.name),
|
||||
['Episode 3'],
|
||||
);
|
||||
});
|
||||
|
||||
test('a range keeps the episodes inside it, in either order', () => {
|
||||
assert.deepEqual(
|
||||
filterEpisodes(SEASON, '12-18').map((item) => item.number),
|
||||
[12, 12.5, 18],
|
||||
);
|
||||
assert.deepEqual(
|
||||
filterEpisodes(SEASON, '18 – 12').map((item) => item.number),
|
||||
[12, 12.5, 18],
|
||||
);
|
||||
});
|
||||
|
||||
test('a range skips episodes the source gave no number', () => {
|
||||
assert.deepEqual(filterEpisodes([episode(null, 'OVA')], '1-99'), []);
|
||||
});
|
||||
|
||||
test('anything else is a case-insensitive substring of the name', () => {
|
||||
assert.deepEqual(
|
||||
filterEpisodes(SEASON, 'home').map((item) => item.number),
|
||||
[12],
|
||||
);
|
||||
assert.deepEqual(
|
||||
filterEpisodes(SEASON, 'BEACH').map((item) => item.name),
|
||||
['OVA: Beach Special'],
|
||||
);
|
||||
assert.deepEqual(filterEpisodes(SEASON, 'nothing here'), []);
|
||||
});
|
||||
Reference in New Issue
Block a user