feat(web): follow system dark mode and simplify workspace hint
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { afterEach, beforeEach, expect, it, vi } from 'vitest';
|
||||
const hooks = vi.hoisted(() => ({slots: [] as any[], cursor: 0, effects: [] as (() => void)[]}));
|
||||
vi.mock('react', async importOriginal => ({
|
||||
...await importOriginal<typeof import('react')>(),
|
||||
useRef(value: unknown) { const i = hooks.cursor++; return hooks.slots[i] ??= {current:value}; },
|
||||
useState(value: unknown) { const i = hooks.cursor++; if (!(i in hooks.slots)) hooks.slots[i] = value; return [hooks.slots[i], (v: unknown) => { hooks.slots[i] = v; }]; },
|
||||
useEffect(fn: () => (() => void) | undefined, deps: unknown[]) {
|
||||
const i = hooks.cursor++, previous = hooks.slots[i];
|
||||
if (!previous || deps.some((v, n) => v !== previous.deps[n])) hooks.effects.push(() => { previous?.cleanup?.(); hooks.slots[i] = {deps, cleanup:fn()}; });
|
||||
},
|
||||
}));
|
||||
import { useNightMode } from './nightMode';
|
||||
|
||||
const media = {matches: false, addEventListener: vi.fn(), removeEventListener: vi.fn()};
|
||||
const render = () => { hooks.cursor = 0; const result = useNightMode(); hooks.effects.splice(0).forEach(effect => effect()); return result; };
|
||||
beforeEach(() => { hooks.slots = []; hooks.cursor = 0; hooks.effects = []; media.matches = false; vi.clearAllMocks(); vi.stubGlobal('window', {matchMedia: vi.fn(() => media)}); });
|
||||
afterEach(() => { hooks.slots.forEach(s => s?.cleanup?.()); vi.unstubAllGlobals(); });
|
||||
|
||||
it('reflects the current system color scheme', () => {
|
||||
media.matches = true;
|
||||
expect(render()).toBe(true);
|
||||
expect(media.addEventListener).toHaveBeenCalledWith('change', expect.any(Function));
|
||||
});
|
||||
|
||||
it('updates when the system scheme changes and unsubscribes on cleanup', () => {
|
||||
expect(render()).toBe(false);
|
||||
const listener = media.addEventListener.mock.calls[0][1] as (event: MediaQueryListEvent) => void;
|
||||
listener({matches: true} as MediaQueryListEvent);
|
||||
expect(render()).toBe(true);
|
||||
hooks.slots.forEach(s => s?.cleanup?.());
|
||||
expect(media.removeEventListener).toHaveBeenCalledWith('change', listener);
|
||||
});
|
||||
Reference in New Issue
Block a user