From 006b15b467a5cd835a6eab1b49023100bdc8f2e6 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Fri, 13 Oct 2023 19:32:56 +0200
Subject: refactor(components): rewrite Code component and usePrism hook

* move Prism styles to Sass placeholders to avoid repeats
* let usePrism consumer define its plugins (remove default ones)
* remove `plugins` prop from Code component
* add new props to Code component to let consumer configure plugins
(and handle plugin list from the given options)

However there are some problems with Prism plugins: line-highlight and
treeview does not seems to be loaded. I don't want to use Babel instead
of SWC so I have no solution for now.
---
 src/utils/hooks/use-prism/use-prism.test.tsx | 91 ++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)
 create mode 100644 src/utils/hooks/use-prism/use-prism.test.tsx

(limited to 'src/utils/hooks/use-prism/use-prism.test.tsx')

diff --git a/src/utils/hooks/use-prism/use-prism.test.tsx b/src/utils/hooks/use-prism/use-prism.test.tsx
new file mode 100644
index 0000000..f7e83a2
--- /dev/null
+++ b/src/utils/hooks/use-prism/use-prism.test.tsx
@@ -0,0 +1,91 @@
+import { describe, expect, it } from '@jest/globals';
+import { renderHook } from '@testing-library/react';
+import type { PropsWithChildren, ReactElement } from 'react';
+import { type IntlConfig, IntlProvider } from 'react-intl';
+import {
+  type PrismLanguage,
+  usePrism,
+  type PrismAvailablePlugin,
+  type PrismAttributes,
+  type PrismToolbarAttributes,
+} from './use-prism';
+
+type WrapperProps = {
+  children: ReactElement<unknown>;
+};
+
+const createWrapper = (
+  Wrapper: typeof IntlProvider,
+  props: PropsWithChildren<IntlConfig>
+) =>
+  function CreatedWrapper({ children }: WrapperProps) {
+    return <Wrapper {...props}>{children}</Wrapper>;
+  };
+
+const toolbarAttributes: PrismToolbarAttributes = {
+  'data-prismjs-color-scheme-dark': 'Dark Theme 🌙',
+  'data-prismjs-color-scheme-light': 'Light Theme 🌞',
+  'data-prismjs-copy': 'Copy',
+  'data-prismjs-copy-error': 'Use Ctrl+c to copy',
+  'data-prismjs-copy-success': 'Copied!',
+};
+
+describe('usePrism', () => {
+  it('returns the className and the attributes', () => {
+    const { result } = renderHook(() => usePrism({}), {
+      wrapper: createWrapper(IntlProvider, { locale: 'en' }),
+    });
+
+    expect(result.current.className).toStrictEqual('');
+    expect(result.current.attributes).toStrictEqual(toolbarAttributes);
+  });
+
+  it('can return a className based on the given language', () => {
+    const language: PrismLanguage = 'docker';
+    const { result } = renderHook(() => usePrism({ language }), {
+      wrapper: createWrapper(IntlProvider, { locale: 'en' }),
+    });
+
+    expect(result.current.className).toStrictEqual(`language-${language}`);
+  });
+
+  it('can return a className based on the given plugins', () => {
+    const pluginWithClass: PrismAvailablePlugin = 'diff-highlight';
+    const { result } = renderHook(
+      () => usePrism({ plugins: [pluginWithClass] }),
+      {
+        wrapper: createWrapper(IntlProvider, { locale: 'en' }),
+      }
+    );
+
+    expect(result.current.className).toMatch(pluginWithClass);
+  });
+
+  it('can return a className based on the given language and plugins', () => {
+    const language: PrismLanguage = 'javascript';
+    const pluginWithClass: PrismAvailablePlugin = 'diff-highlight';
+    const { result } = renderHook(
+      () => usePrism({ language, plugins: [pluginWithClass] }),
+      {
+        wrapper: createWrapper(IntlProvider, { locale: 'en' }),
+      }
+    );
+
+    expect(result.current.className).toMatch(`language-diff-${language}`);
+    expect(result.current.className).toMatch(pluginWithClass);
+  });
+
+  it('can return the default attributes with the given owns', () => {
+    const attributes: Partial<PrismAttributes> = {
+      'data-filter-output': '(out)',
+    };
+    const { result } = renderHook(() => usePrism({ attributes }), {
+      wrapper: createWrapper(IntlProvider, { locale: 'en' }),
+    });
+
+    expect(result.current.attributes).toStrictEqual({
+      ...toolbarAttributes,
+      ...attributes,
+    });
+  });
+});
-- 
cgit v1.2.3

