Skip to content

Commit

Permalink
test: improve matchMedia mocking
Browse files Browse the repository at this point in the history
  • Loading branch information
dsanders11 committed Nov 27, 2024
1 parent 0c7e997 commit aa3fee7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 37 deletions.
24 changes: 9 additions & 15 deletions src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,26 +173,20 @@ export class App {
if (this.state.isUsingSystemTheme) {
window.ElectronFiddle.setNativeTheme('system');

if (!!window.matchMedia) {
const { matches } = window.matchMedia(
'(prefers-color-scheme: dark)',
);
setSystemTheme(matches);
}
const { matches } = window.matchMedia('(prefers-color-scheme: dark)');
setSystemTheme(matches);
}
},
);

// change theme when system theme changes
if (!!window.matchMedia) {
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', ({ matches }) => {
if (this.state.isUsingSystemTheme) {
setSystemTheme(matches);
}
});
}
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', ({ matches }) => {
if (this.state.isUsingSystemTheme) {
setSystemTheme(matches);
}
});
}

/**
Expand Down
34 changes: 12 additions & 22 deletions tests/renderer/app-spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,24 +273,6 @@ describe('App component', () => {
});

describe('setupThemeListeners()', () => {
const addEventListenerMock = jest.fn();
beforeEach(() => {
// matchMedia mock
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: addEventListenerMock,
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
});

describe('isUsingSystemTheme reaction', () => {
beforeEach(() => {
window.ElectronFiddle.setNativeTheme = jest.fn();
Expand Down Expand Up @@ -336,32 +318,40 @@ describe('App component', () => {

describe('prefers-color-scheme event listener', () => {
it('adds an event listener to the "change" event', () => {
const spy = jest.spyOn(window, 'matchMedia');
app.setupThemeListeners();
expect(addEventListenerMock).toHaveBeenCalledWith(
const { addEventListener } = spy.mock.results[0].value;
expect(addEventListener).toHaveBeenCalledWith(
'change',
expect.anything(),
);
});

it('does nothing if not isUsingSystemTheme', () => {
const spy = jest.spyOn(window, 'matchMedia');
app.setupThemeListeners();
const callback = addEventListenerMock.mock.calls[0][1];
const { addEventListener } = spy.mock.results[0].value;
const callback = addEventListener.mock.calls[0][1];
app.state.isUsingSystemTheme = false;
callback({ matches: true });
expect(app.state.setTheme).not.toHaveBeenCalled();
});

it('sets dark theme if isUsingSystemTheme and prefers dark', () => {
const spy = jest.spyOn(window, 'matchMedia');
app.setupThemeListeners();
const callback = addEventListenerMock.mock.calls[0][1];
const { addEventListener } = spy.mock.results[0].value;
const callback = addEventListener.mock.calls[0][1];
app.state.isUsingSystemTheme = true;
callback({ matches: true });
expect(app.state.setTheme).toHaveBeenCalledWith(defaultDark.file);
});

it('sets light theme if isUsingSystemTheme and not prefers dark', () => {
const spy = jest.spyOn(window, 'matchMedia');
app.setupThemeListeners();
const callback = addEventListenerMock.mock.calls[0][1];
const { addEventListener } = spy.mock.results[0].value;
const callback = addEventListener.mock.calls[0][1];
app.state.isUsingSystemTheme = true;
callback({ matches: false });
expect(app.state.setTheme).toHaveBeenCalledWith(defaultLight.file);
Expand Down
10 changes: 10 additions & 0 deletions tests/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,14 @@ beforeEach(() => {
mocked(window.localStorage.getItem).mockReset();
mocked(window.localStorage.removeItem).mockReset();
mocked(window.open).mockReset();
window.matchMedia = jest.fn((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
}));
});

0 comments on commit aa3fee7

Please sign in to comment.