From 60c49f18389ff625177a57277ef8f292a31097bf Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Sat, 28 Oct 2023 17:12:58 +0200 Subject: refactor(providers,hooks): rewrite PrismThemeProvider & usePrismTheme * reuse Theme provider logic * move DOM mutation from provider to hook * add a script to init theme before page load --- .../hooks/use-prism-theme/use-prism-theme.test.tsx | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx (limited to 'src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx') diff --git a/src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx b/src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx new file mode 100644 index 0000000..8a178c9 --- /dev/null +++ b/src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx @@ -0,0 +1,134 @@ +import { describe, expect, it } from '@jest/globals'; +import { + act, + render, + renderHook, + screen as rtlScreen, +} from '@testing-library/react'; +import type { FC, ReactNode } from 'react'; +import { + PrismThemeProvider, + type PrismThemeProviderProps, +} from '../../providers/prism-theme-provider'; +import { usePrismTheme } from './use-prism-theme'; + +const codeSample1 = `const foo = 42;`; +const codeSample2 = `const bar = "baz";`; +const codeSample3 = `const baz = () => false;`; + +const ComponentTest: FC = () => { + usePrismTheme(); + + return ( +
+
{codeSample1}
+
{codeSample2}
+
{codeSample3}
+
+ ); +}; + +const createWrapper = ( + Wrapper: FC, + config: PrismThemeProviderProps +) => + function CreatedWrapper({ children }: { children: ReactNode }) { + return {children}; + }; + +describe('usePrismTheme', () => { + it('should return the default value without provider and prevent update', () => { + const defaultTheme = 'system'; + const { result } = renderHook(() => usePrismTheme()); + + expect(result.current.theme).toBe(defaultTheme); + + act(() => result.current.setTheme('dark')); + + expect(result.current.theme).toBe(defaultTheme); + }); + + it('should add an attribute on pre elements when matching a Prism block', () => { + const defaultTheme = 'light'; + const attribute = 'data-debitis'; + + render( + + + + ); + + expect(rtlScreen.getByText(codeSample1)).toHaveAttribute( + attribute, + defaultTheme + ); + expect(rtlScreen.getByText(codeSample2)).toHaveAttribute( + attribute, + defaultTheme + ); + expect(rtlScreen.getByText(codeSample3)).not.toHaveAttribute( + attribute, + defaultTheme + ); + }); + + it('can update the theme value using a setter', () => { + const defaultTheme = 'dark'; + + const { result } = renderHook(() => usePrismTheme(), { + wrapper: createWrapper(PrismThemeProvider, { + attribute: 'consequuntur', + defaultTheme, + storageKey: 'deleniti', + }), + }); + + expect(result.current.theme).toBe(defaultTheme); + + const newTheme = 'light'; + + act(() => result.current.setTheme(newTheme)); + + expect(result.current.theme).toBe(newTheme); + }); + + it('can toggle the theme from light to dark', () => { + const defaultTheme = 'light'; + + const { result } = renderHook(() => usePrismTheme(), { + wrapper: createWrapper(PrismThemeProvider, { + attribute: 'et', + defaultTheme, + storageKey: 'velit', + }), + }); + + expect(result.current.theme).toBe(defaultTheme); + + act(() => result.current.toggleTheme()); + + expect(result.current.theme).toBe('dark'); + }); + + it('can toggle the theme from dark to light', () => { + const defaultTheme = 'dark'; + + const { result } = renderHook(() => usePrismTheme(), { + wrapper: createWrapper(PrismThemeProvider, { + attribute: 'et', + defaultTheme, + storageKey: 'velit', + }), + }); + + expect(result.current.theme).toBe(defaultTheme); + + act(() => result.current.toggleTheme()); + + expect(result.current.theme).toBe('light'); + }); +}); -- cgit v1.2.3