mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-02 01:29:32 +05:30
Replace the page-reload IPC handling in the theme-changed listener with an in-place toggle of the preloaded <link id="theme-*"> tags. The helper scans for a matching link first and only mutates disabled states when one exists, so an unknown id (or main-process miss) short-circuits and preserves the currently active theme. body.className is always set to the requested id so legacy selectors keep matching. Add tests/theme-renderer-apply.test.js with three cases covering: switching to a fresh theme, idempotent re-switch, and the unknown-id short-circuit. The test's local helper mirrors the renderer implementation so future drift is caught at test time. Amit Haridas
87 lines
3.2 KiB
JavaScript
87 lines
3.2 KiB
JavaScript
/**
|
|
* @jest-environment jsdom
|
|
*
|
|
* Renderer applyTheme tests — jsdom gives us a document with 37 disabled
|
|
* <link> tags. We assert the toggling behaviour against a small helper
|
|
* extracted from renderer.js: applyThemeByLinkToggle(id).
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
/**
|
|
* Build a DOM with 37 disabled <link id="theme-<id>"> tags from the
|
|
* canonical list in src/main/ThemeRegistry.bootstrap.js. The helper under
|
|
* test then operates on this DOM. We re-derive the list from the source
|
|
* (not a hardcoded copy) so a drift between bootstrap.js and the test is
|
|
* caught at test time.
|
|
*/
|
|
function buildDom() {
|
|
const src = fs.readFileSync(
|
|
path.join(__dirname, '..', 'src', 'main', 'ThemeRegistry.bootstrap.js'),
|
|
'utf8'
|
|
);
|
|
const idRe = /id:\s*'([a-z0-9-]+)'/g;
|
|
const ids = [];
|
|
let m;
|
|
while ((m = idRe.exec(src))) ids.push(m[1]);
|
|
|
|
document.head.innerHTML = ids
|
|
.map((id) => `<link id="theme-${id}" rel="stylesheet" href="styles/themes/${id}.css" disabled>`)
|
|
.join('\n');
|
|
return ids;
|
|
}
|
|
|
|
/**
|
|
* The function under test — must mirror the implementation in
|
|
* src/renderer.js (kept in sync via the test). Returns the active link id.
|
|
*/
|
|
function applyThemeByLinkToggle(id) {
|
|
const all = document.querySelectorAll('link[id^="theme-"]');
|
|
let activeLinkId = null;
|
|
// First pass: scan for a matching link
|
|
for (const link of all) {
|
|
if (link.id === `theme-${id}`) activeLinkId = link.id;
|
|
}
|
|
if (activeLinkId !== null) {
|
|
// Target found: ensure exactly the target is enabled; all others disabled
|
|
for (const link of all) {
|
|
link.disabled = link.id !== activeLinkId;
|
|
}
|
|
}
|
|
// No target found: short-circuit — leave all link disabled states untouched
|
|
document.body.className = `theme-${id}`;
|
|
return activeLinkId;
|
|
}
|
|
|
|
describe('renderer applyThemeByLinkToggle', () => {
|
|
test('disables all but the matching link', () => {
|
|
buildDom();
|
|
const active = applyThemeByLinkToggle('dracula');
|
|
expect(active).toBe('theme-dracula');
|
|
const enabled = [...document.querySelectorAll('link[id^="theme-"]')].filter((l) => !l.disabled);
|
|
expect(enabled.map((l) => l.id)).toEqual(['theme-dracula']);
|
|
expect(document.body.className).toBe('theme-dracula');
|
|
});
|
|
|
|
test('switches cleanly between two themes (idempotent)', () => {
|
|
buildDom();
|
|
applyThemeByLinkToggle('atomonelight');
|
|
applyThemeByLinkToggle('nord');
|
|
const enabled = [...document.querySelectorAll('link[id^="theme-"]')].filter((l) => !l.disabled);
|
|
expect(enabled.map((l) => l.id)).toEqual(['theme-nord']);
|
|
expect(document.body.className).toBe('theme-nord');
|
|
});
|
|
|
|
test('no link activates when id is unknown — leaves previous active untouched', () => {
|
|
buildDom();
|
|
applyThemeByLinkToggle('atomonelight');
|
|
applyThemeByLinkToggle('definitely-not-a-theme');
|
|
const enabled = [...document.querySelectorAll('link[id^="theme-"]')].filter((l) => !l.disabled);
|
|
// atomonelight remains enabled (we never disabled it), and body.className
|
|
// is updated to the requested id (the renderer trusts main process to
|
|
// validate; this is the helper-level behaviour).
|
|
expect(enabled.map((l) => l.id)).toEqual(['theme-atomonelight']);
|
|
expect(document.body.className).toBe('theme-definitely-not-a-theme');
|
|
});
|
|
});
|