mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-08-01 19:21:34 -07:00
e64ff1a0ee
- Add `subminer anime` / `--anime` and a tray entry to open a browser that searches installed Aniyomi extension sources, shows cover art and episodes, and plays into mpv with overlay/mining attached - Add an Extensions tab to add repos and install/update/remove sources, and per-source settings for sources needing config - Support searching all sources at once with streaming, per-source results and status - Prefer Japanese audio/subtitle tracks from the source and keep the primary subtitle slot reserved for Japanese - Fix window/tray/Dock handling so the browser and mpv can be switched between without quitting the app or losing the Dock icon - Add anime.repos, anime.extensionsDir, anime.preferredQuality config keys (no bundled repos or discovery)
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { describeInstalled, sourceOptionLabel, summarizeSearch } from './format';
|
|
import type { AnimeBrowserSearchResult } from '../types/anime-browser';
|
|
|
|
const result = (
|
|
entryCount: number,
|
|
failures: AnimeBrowserSearchResult['failures'] = [],
|
|
): AnimeBrowserSearchResult => ({
|
|
entries: Array.from({ length: entryCount }, (_unused, index) => ({
|
|
url: `/a/${index}`,
|
|
title: `Anime ${index}`,
|
|
thumbnailUrl: null,
|
|
sourceId: 's',
|
|
sourceName: 'Source',
|
|
})),
|
|
hasNextPage: false,
|
|
failures,
|
|
});
|
|
|
|
test('sourceOptionLabel omits the language for an all-language source', () => {
|
|
assert.equal(sourceOptionLabel({ id: '1', name: 'Nyaa', lang: 'ja', pkg: 'p' }), 'Nyaa (ja)');
|
|
assert.equal(sourceOptionLabel({ id: '2', name: 'Jellyfin', lang: 'all', pkg: 'p' }), 'Jellyfin');
|
|
});
|
|
|
|
test('summarizeSearch counts results and singularizes one', () => {
|
|
assert.equal(summarizeSearch(result(4)), '4 results');
|
|
assert.equal(summarizeSearch(result(1)), '1 result');
|
|
assert.equal(summarizeSearch(result(0)), '0 results');
|
|
});
|
|
|
|
test('summarizeSearch names the sources that failed alongside the ones that answered', () => {
|
|
const summary = summarizeSearch(
|
|
result(6, [
|
|
{ sourceId: 'a', sourceName: 'Alpha', error: 'login required' },
|
|
{ sourceId: 'b', sourceName: 'Beta', error: 'timed out' },
|
|
]),
|
|
);
|
|
assert.equal(summary, '6 results · 2 unavailable: Alpha, Beta');
|
|
});
|
|
|
|
test('describeInstalled reports sources and languages when the extension loaded', () => {
|
|
assert.equal(
|
|
describeInstalled({
|
|
pkg: 'multi',
|
|
name: 'One, Two',
|
|
langs: ['en', 'ja'],
|
|
sourceCount: 2,
|
|
error: null,
|
|
}),
|
|
'multi · 2 sources · en, ja',
|
|
);
|
|
});
|
|
|
|
test('describeInstalled falls back to the package alone when nothing loaded', () => {
|
|
assert.equal(
|
|
describeInstalled({ pkg: 'broken', name: 'broken', langs: [], sourceCount: 0, error: 'boom' }),
|
|
'broken',
|
|
);
|
|
});
|