From 64e556ab1b5526c0b060c8a5103dc7a42f8362d2 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 12 Feb 2025 06:39:14 +0100 Subject: [PATCH 01/14] feat: option to reset theme to system settings --- src/lib/stores/theme.store.ts | 13 ++++++++++++- src/lib/utils/theme.utils.ts | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lib/stores/theme.store.ts b/src/lib/stores/theme.store.ts index 98f3adc0..3dc7df10 100644 --- a/src/lib/stores/theme.store.ts +++ b/src/lib/stores/theme.store.ts @@ -1,5 +1,10 @@ import type { Theme } from "$lib/types/theme"; -import { applyTheme, initTheme } from "$lib/utils/theme.utils"; +import { + applyTheme, + getThemeFromSystemSettings, + initTheme, + resetTheme, +} from "$lib/utils/theme.utils"; import { writable } from "svelte/store"; const initialTheme: Theme | undefined = initTheme(); @@ -14,6 +19,12 @@ export const initThemeStore = () => { applyTheme({ theme, preserve: true }); set(theme); }, + + resetToSystemSettings: () => { + const theme = getThemeFromSystemSettings(); + resetTheme(theme); + set(theme); + }, }; }; diff --git a/src/lib/utils/theme.utils.ts b/src/lib/utils/theme.utils.ts index b8921dc2..7bb8f505 100644 --- a/src/lib/utils/theme.utils.ts +++ b/src/lib/utils/theme.utils.ts @@ -50,3 +50,17 @@ export const applyTheme = ({ localStorage.setItem(LOCALSTORAGE_THEME_KEY, JSON.stringify(theme)); } }; + +export const getThemeFromSystemSettings = (): Theme => { + const isDarkPreferred = window.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; + + return isDarkPreferred ? Theme.DARK : Theme.LIGHT; +}; + +export const resetTheme = (theme: Theme) => { + applyTheme({ theme, preserve: false }); + + localStorage.removeItem(LOCALSTORAGE_THEME_KEY); +}; From 4010316528b5fdeb753e5276700d3124dbd8e08d Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 12 Feb 2025 06:52:40 +0100 Subject: [PATCH 02/14] feat: invert to remove firstly the value in localstorage --- src/lib/utils/theme.utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/utils/theme.utils.ts b/src/lib/utils/theme.utils.ts index 7bb8f505..be18fdc7 100644 --- a/src/lib/utils/theme.utils.ts +++ b/src/lib/utils/theme.utils.ts @@ -60,7 +60,7 @@ export const getThemeFromSystemSettings = (): Theme => { }; export const resetTheme = (theme: Theme) => { - applyTheme({ theme, preserve: false }); - localStorage.removeItem(LOCALSTORAGE_THEME_KEY); + + applyTheme({ theme, preserve: false }); }; From 5e8a2c08e2398300629205345a759922ecc86083 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 10:06:17 +0100 Subject: [PATCH 03/14] add initial value inside the initiator --- src/lib/stores/theme.store.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/stores/theme.store.ts b/src/lib/stores/theme.store.ts index 1b36bcb1..90ccc62a 100644 --- a/src/lib/stores/theme.store.ts +++ b/src/lib/stores/theme.store.ts @@ -14,9 +14,9 @@ export interface ThemeStore extends Readable { resetToSystemSettings: () => void; } -const initialTheme: ThemeStoreData = initTheme(); - export const initThemeStore = (): ThemeStore => { + const initialTheme: ThemeStoreData = initTheme(); + const { subscribe, set } = writable(initialTheme); return { From 130c1958bd062ee1c91473ddca51d8c6ee311fde Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 10:06:23 +0100 Subject: [PATCH 04/14] add tests --- src/tests/lib/stores/theme.store.spec.ts | 148 +++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/tests/lib/stores/theme.store.spec.ts diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts new file mode 100644 index 00000000..0b5a888b --- /dev/null +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -0,0 +1,148 @@ +import { initThemeStore, themeStore } from "$lib"; +import { Theme } from "$lib/types/theme"; +import * as envUtils from "$lib/utils/env.utils"; +import * as themeUtils from "$lib/utils/theme.utils"; +import { THEME_ATTRIBUTE } from "$lib/utils/theme.utils"; +import { get } from "svelte/store"; + +describe("theme-store", () => { + beforeEach(() => { + vi.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); + + window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); + + vi.spyOn(envUtils, "isNode").mockReturnValue(false); + }); + + afterEach(() => { + window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); + }); + + it("should initialise with the no theme if the theme is not set", () => { + expect(get(themeStore)).toBeUndefined(); + }); + + it.each(Object.values(Theme))( + "should initialise with the current '%s' theme", + (theme) => { + window.document.documentElement.setAttribute(THEME_ATTRIBUTE, theme); + + const spy = vi.spyOn(themeUtils, "initTheme"); + + const mockThemeStore = initThemeStore(); + + expect(get(mockThemeStore)).toBe(theme); + expect(spy).toHaveBeenCalledOnce(); + }, + ); + + it("should apply and store the selected theme", () => { + const spy = vi.spyOn(themeUtils, "applyTheme"); + + themeStore.select(Theme.LIGHT); + + expect(get(themeStore)).toBe(Theme.LIGHT); + expect(spy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true }); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.LIGHT, + ); + + themeStore.select(Theme.DARK); + + expect(get(themeStore)).toBe(Theme.DARK); + expect(spy).toHaveBeenCalledWith({ theme: Theme.DARK, preserve: true }); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.DARK, + ); + + // Just to double-check, we set it to light once more + themeStore.select(Theme.LIGHT); + + expect(get(themeStore)).toBe(Theme.LIGHT); + expect(spy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true }); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.LIGHT, + ); + }); + + it("should refresh to the current theme", () => { + const spy = vi.spyOn(themeUtils, "resetTheme"); + + // We mock window.matchMedia to match the DARK theme + Object.defineProperty(window, "matchMedia", { + writable: true, + enumerable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: true, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); + + // We first set the store, then we mock that the attribute may be changed in a different way + themeStore.select(Theme.LIGHT); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.LIGHT, + ); + window.document.documentElement.setAttribute(THEME_ATTRIBUTE, Theme.DARK); + + themeStore.resetToSystemSettings(); + + expect(get(themeStore)).toBe(Theme.DARK); + expect(spy).toHaveBeenCalledWith(Theme.DARK); + + // We mock window.matchMedia to match the LIGHT theme + Object.defineProperty(window, "matchMedia", { + writable: true, + enumerable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); + + // We first set the store, then we mock that the attribute may be changed in a different way + themeStore.select(Theme.DARK); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.DARK, + ); + window.document.documentElement.setAttribute(THEME_ATTRIBUTE, Theme.LIGHT); + + themeStore.resetToSystemSettings(); + + expect(get(themeStore)).toBe(Theme.LIGHT); + expect(spy).toHaveBeenCalledWith(Theme.LIGHT); + }); + + it("should handle gracefully when the theme is not set", () => { + window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); + + const mockThemeStore = initThemeStore(); + + expect(get(mockThemeStore)).toBe(Theme.DARK); + }); + + it("should handle gracefully when the theme is not correctly set", () => { + window.document.documentElement.setAttribute( + THEME_ATTRIBUTE, + "invalid-theme", + ); + + const mockThemeStore = initThemeStore(); + + expect(get(mockThemeStore)).toBe(Theme.DARK); + }); +}); From 41eb6ec1e9f5aab6454efe6a94e4e77915418c80 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 10:13:09 +0100 Subject: [PATCH 05/14] more tests --- src/tests/lib/stores/theme.store.spec.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index 0b5a888b..be066a6e 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -2,7 +2,7 @@ import { initThemeStore, themeStore } from "$lib"; import { Theme } from "$lib/types/theme"; import * as envUtils from "$lib/utils/env.utils"; import * as themeUtils from "$lib/utils/theme.utils"; -import { THEME_ATTRIBUTE } from "$lib/utils/theme.utils"; +import { LOCALSTORAGE_THEME_KEY, THEME_ATTRIBUTE } from "$lib/utils/theme.utils"; import { get } from "svelte/store"; describe("theme-store", () => { @@ -67,7 +67,7 @@ describe("theme-store", () => { ); }); - it("should refresh to the current theme", () => { + it("should reset to the current system theme", () => { const spy = vi.spyOn(themeUtils, "resetTheme"); // We mock window.matchMedia to match the DARK theme @@ -97,6 +97,10 @@ describe("theme-store", () => { expect(get(themeStore)).toBe(Theme.DARK); expect(spy).toHaveBeenCalledWith(Theme.DARK); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.DARK, + ); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); // We mock window.matchMedia to match the LIGHT theme Object.defineProperty(window, "matchMedia", { @@ -125,6 +129,10 @@ describe("theme-store", () => { expect(get(themeStore)).toBe(Theme.LIGHT); expect(spy).toHaveBeenCalledWith(Theme.LIGHT); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( + Theme.LIGHT, + ); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); }); it("should handle gracefully when the theme is not set", () => { From 57cf8149e3e157db3a7623e4395fd383e7cd29ab Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:13:52 +0000 Subject: [PATCH 06/14] Updating formatting --- src/tests/lib/stores/theme.store.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index be066a6e..69213fea 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -2,7 +2,10 @@ import { initThemeStore, themeStore } from "$lib"; import { Theme } from "$lib/types/theme"; import * as envUtils from "$lib/utils/env.utils"; import * as themeUtils from "$lib/utils/theme.utils"; -import { LOCALSTORAGE_THEME_KEY, THEME_ATTRIBUTE } from "$lib/utils/theme.utils"; +import { + LOCALSTORAGE_THEME_KEY, + THEME_ATTRIBUTE, +} from "$lib/utils/theme.utils"; import { get } from "svelte/store"; describe("theme-store", () => { From 8173b61497ea40eae96d27b7fc1af06092bfed41 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 10:30:59 +0100 Subject: [PATCH 07/14] refactor: move spy at top level --- src/tests/lib/stores/theme.store.spec.ts | 67 +++++++++++++----------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index 69213fea..56f2f308 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -7,8 +7,13 @@ import { THEME_ATTRIBUTE, } from "$lib/utils/theme.utils"; import { get } from "svelte/store"; +import type { MockInstance } from "vitest"; describe("theme-store", () => { + let initThemeSpy: MockInstance; + let applyThemeSpy: MockInstance; + let resetThemeSpy: MockInstance; + beforeEach(() => { vi.clearAllMocks(); vi.restoreAllMocks(); @@ -17,6 +22,10 @@ describe("theme-store", () => { window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); vi.spyOn(envUtils, "isNode").mockReturnValue(false); + + initThemeSpy = vi.spyOn(themeUtils, "initTheme"); + applyThemeSpy = vi.spyOn(themeUtils, "applyTheme"); + resetThemeSpy = vi.spyOn(themeUtils, "resetTheme"); }); afterEach(() => { @@ -32,60 +41,63 @@ describe("theme-store", () => { (theme) => { window.document.documentElement.setAttribute(THEME_ATTRIBUTE, theme); - const spy = vi.spyOn(themeUtils, "initTheme"); - const mockThemeStore = initThemeStore(); expect(get(mockThemeStore)).toBe(theme); - expect(spy).toHaveBeenCalledOnce(); + expect(initThemeSpy).toHaveBeenCalledOnce(); }, ); it("should apply and store the selected theme", () => { - const spy = vi.spyOn(themeUtils, "applyTheme"); - themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); - expect(spy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true }); + expect(applyThemeSpy).toHaveBeenCalledWith({ + theme: Theme.LIGHT, + preserve: true, + }); expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( Theme.LIGHT, ); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBe( + JSON.stringify(Theme.LIGHT), + ); themeStore.select(Theme.DARK); expect(get(themeStore)).toBe(Theme.DARK); - expect(spy).toHaveBeenCalledWith({ theme: Theme.DARK, preserve: true }); + expect(applyThemeSpy).toHaveBeenCalledWith({ + theme: Theme.DARK, + preserve: true, + }); expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( Theme.DARK, ); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBe( + JSON.stringify(Theme.DARK), + ); // Just to double-check, we set it to light once more themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); - expect(spy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true }); + expect(applyThemeSpy).toHaveBeenCalledWith({ + theme: Theme.LIGHT, + preserve: true, + }); expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( Theme.LIGHT, ); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBe( + JSON.stringify(Theme.LIGHT), + ); }); it("should reset to the current system theme", () => { - const spy = vi.spyOn(themeUtils, "resetTheme"); - // We mock window.matchMedia to match the DARK theme Object.defineProperty(window, "matchMedia", { - writable: true, - enumerable: true, - value: vi.fn().mockImplementation((query) => ({ + value: vi.fn().mockImplementation(() => ({ matches: true, - media: query, - onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), })), }); @@ -99,7 +111,7 @@ describe("theme-store", () => { themeStore.resetToSystemSettings(); expect(get(themeStore)).toBe(Theme.DARK); - expect(spy).toHaveBeenCalledWith(Theme.DARK); + expect(resetThemeSpy).toHaveBeenCalledWith(Theme.DARK); expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( Theme.DARK, ); @@ -107,17 +119,8 @@ describe("theme-store", () => { // We mock window.matchMedia to match the LIGHT theme Object.defineProperty(window, "matchMedia", { - writable: true, - enumerable: true, - value: vi.fn().mockImplementation((query) => ({ + value: vi.fn().mockImplementation(() => ({ matches: false, - media: query, - onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), })), }); @@ -131,7 +134,7 @@ describe("theme-store", () => { themeStore.resetToSystemSettings(); expect(get(themeStore)).toBe(Theme.LIGHT); - expect(spy).toHaveBeenCalledWith(Theme.LIGHT); + expect(resetThemeSpy).toHaveBeenCalledWith(Theme.LIGHT); expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBe( Theme.LIGHT, ); From 2bd79d89e732ccbd6dad38ceebd4292c237b3e1b Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 10:37:47 +0100 Subject: [PATCH 08/14] review --- src/tests/lib/stores/theme.store.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index 56f2f308..0dd328e6 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -28,7 +28,7 @@ describe("theme-store", () => { resetThemeSpy = vi.spyOn(themeUtils, "resetTheme"); }); - afterEach(() => { + afterAll(() => { window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); }); @@ -94,6 +94,8 @@ describe("theme-store", () => { }); it("should reset to the current system theme", () => { + const originalMatchMedia = window.matchMedia; + // We mock window.matchMedia to match the DARK theme Object.defineProperty(window, "matchMedia", { value: vi.fn().mockImplementation(() => ({ @@ -139,6 +141,11 @@ describe("theme-store", () => { Theme.LIGHT, ); expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); + + Object.defineProperty(window, "matchMedia", { + writable: true, + value: originalMatchMedia + }); }); it("should handle gracefully when the theme is not set", () => { From 0245e47fff8939d2ba2c2c02767c69eee0db9c00 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:38:35 +0000 Subject: [PATCH 09/14] Updating formatting --- src/tests/lib/stores/theme.store.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index 0dd328e6..b57b92b9 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -144,7 +144,7 @@ describe("theme-store", () => { Object.defineProperty(window, "matchMedia", { writable: true, - value: originalMatchMedia + value: originalMatchMedia, }); }); From 0cb62815d013048e4fa6a9eaa2a0f12fcc421c20 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 12 Feb 2025 13:37:58 +0100 Subject: [PATCH 10/14] Update src/tests/lib/stores/theme.store.spec.ts Co-authored-by: Yusef Habib --- src/tests/lib/stores/theme.store.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index b57b92b9..64bfcec6 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -32,7 +32,7 @@ describe("theme-store", () => { window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); }); - it("should initialise with the no theme if the theme is not set", () => { + it("should initialize with no theme if the theme is not set", () => { expect(get(themeStore)).toBeUndefined(); }); From 01fdbed6f65df27046073ede8b0ca8234e8c2ec4 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 13:55:54 +0100 Subject: [PATCH 11/14] rename mock --- src/tests/lib/stores/theme.store.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index 64bfcec6..e9c3e99c 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -41,9 +41,9 @@ describe("theme-store", () => { (theme) => { window.document.documentElement.setAttribute(THEME_ATTRIBUTE, theme); - const mockThemeStore = initThemeStore(); + const themeStore = initThemeStore(); - expect(get(mockThemeStore)).toBe(theme); + expect(get(themeStore)).toBe(theme); expect(initThemeSpy).toHaveBeenCalledOnce(); }, ); @@ -151,9 +151,9 @@ describe("theme-store", () => { it("should handle gracefully when the theme is not set", () => { window.document.documentElement.removeAttribute(THEME_ATTRIBUTE); - const mockThemeStore = initThemeStore(); + const themeStore = initThemeStore(); - expect(get(mockThemeStore)).toBe(Theme.DARK); + expect(get(themeStore)).toBe(Theme.DARK); }); it("should handle gracefully when the theme is not correctly set", () => { @@ -162,8 +162,8 @@ describe("theme-store", () => { "invalid-theme", ); - const mockThemeStore = initThemeStore(); + const themeStore = initThemeStore(); - expect(get(mockThemeStore)).toBe(Theme.DARK); + expect(get(themeStore)).toBe(Theme.DARK); }); }); From 2fff31f0878741782670cb4d6310f25b332326b1 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 13:58:01 +0100 Subject: [PATCH 12/14] add expectation before selection --- src/tests/lib/stores/theme.store.spec.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index e9c3e99c..b6d75301 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -34,6 +34,8 @@ describe("theme-store", () => { it("should initialize with no theme if the theme is not set", () => { expect(get(themeStore)).toBeUndefined(); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBeNull(); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); }); it.each(Object.values(Theme))( @@ -49,6 +51,11 @@ describe("theme-store", () => { ); it("should apply and store the selected theme", () => { + expect(get(themeStore)).toBeUndefined(); + expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBeNull(); + expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); + + themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); From 3526f16ed33e0a341eec9c0f32d4173e286346c2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 12:58:55 +0000 Subject: [PATCH 13/14] Updating formatting --- src/tests/lib/stores/theme.store.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index b6d75301..c8f8d760 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -55,7 +55,6 @@ describe("theme-store", () => { expect(document.documentElement.getAttribute(THEME_ATTRIBUTE)).toBeNull(); expect(localStorage.getItem(LOCALSTORAGE_THEME_KEY)).toBeNull(); - themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); From fa9a9073ab3efcf95ae483087abcd59237ac54f1 Mon Sep 17 00:00:00 2001 From: Antonio Ventilii Date: Wed, 12 Feb 2025 14:00:24 +0100 Subject: [PATCH 14/14] add expectation on spy calls times --- src/tests/lib/stores/theme.store.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/lib/stores/theme.store.spec.ts b/src/tests/lib/stores/theme.store.spec.ts index c8f8d760..89f9fd59 100644 --- a/src/tests/lib/stores/theme.store.spec.ts +++ b/src/tests/lib/stores/theme.store.spec.ts @@ -58,6 +58,7 @@ describe("theme-store", () => { themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); + expect(applyThemeSpy).toHaveBeenCalledOnce(); expect(applyThemeSpy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true, @@ -72,6 +73,7 @@ describe("theme-store", () => { themeStore.select(Theme.DARK); expect(get(themeStore)).toBe(Theme.DARK); + expect(applyThemeSpy).toHaveBeenCalledTimes(2); expect(applyThemeSpy).toHaveBeenCalledWith({ theme: Theme.DARK, preserve: true, @@ -87,6 +89,7 @@ describe("theme-store", () => { themeStore.select(Theme.LIGHT); expect(get(themeStore)).toBe(Theme.LIGHT); + expect(applyThemeSpy).toHaveBeenCalledTimes(3); expect(applyThemeSpy).toHaveBeenCalledWith({ theme: Theme.LIGHT, preserve: true,