diff --git a/__mocks__/@docusaurus/Translate.js b/__mocks__/@docusaurus/Translate.js new file mode 100644 index 00000000..5a9576ee --- /dev/null +++ b/__mocks__/@docusaurus/Translate.js @@ -0,0 +1,13 @@ +// Mock for @docusaurus/Translate +// This is used in tests to replace the Docusaurus Translate module + +import React from 'react'; + +const Translate = ({ children }) => { + return <>{children}>; +}; + +export default Translate; + +// Also export translate function for cases where it's destructured +export const translate = (id, { message }) => message || id; \ No newline at end of file diff --git a/__mocks__/@docusaurus/router.js b/__mocks__/@docusaurus/router.js new file mode 100644 index 00000000..2d76b7d7 --- /dev/null +++ b/__mocks__/@docusaurus/router.js @@ -0,0 +1,6 @@ +module.exports = { + Redirect: ({ to }) =>
, + useHistory: () => ({}), + useLocation: () => ({}), + Link: ({ to, children }) => {children}, +}; \ No newline at end of file diff --git a/__mocks__/@docusaurus/theme-common.js b/__mocks__/@docusaurus/theme-common.js new file mode 100644 index 00000000..895ec496 --- /dev/null +++ b/__mocks__/@docusaurus/theme-common.js @@ -0,0 +1,7 @@ +// __mocks__/@docusaurus/theme-common.js +module.exports.ThemeClassNames = { + common: { + admonition: 'admonition', + admonitionType: (type) => `admonition-type-${type}`, + } +}; \ No newline at end of file diff --git a/__mocks__/@theme-original/DocCard.js b/__mocks__/@theme-original/DocCard.js new file mode 100644 index 00000000..b1d93d87 --- /dev/null +++ b/__mocks__/@theme-original/DocCard.js @@ -0,0 +1,11 @@ +module.exports = { + __esModule: true, + default: ({ item }) => { + const React = require('react'); + return React.createElement( + 'div', + { 'data-testid': 'original-doc-card' }, + item?.label || 'Original Doc Card' + ); + }, +}; \ No newline at end of file diff --git a/__mocks__/@theme/Admonition/Icon/Danger.js b/__mocks__/@theme/Admonition/Icon/Danger.js new file mode 100644 index 00000000..1270cd93 --- /dev/null +++ b/__mocks__/@theme/Admonition/Icon/Danger.js @@ -0,0 +1,6 @@ +import React from 'react'; + +// Mock for the Danger icon +const IconDanger = () => â ī¸; + +export default IconDanger; \ No newline at end of file diff --git a/__mocks__/@theme/Admonition/Layout.js b/__mocks__/@theme/Admonition/Layout.js new file mode 100644 index 00000000..29a2d085 --- /dev/null +++ b/__mocks__/@theme/Admonition/Layout.js @@ -0,0 +1,20 @@ +// __mocks__/@theme/Admonition/Layout.js +// Mock for the Admonition Layout component + +import React from 'react'; + +const AdmonitionLayout = ({ title, icon, children, className }) => { + return ( ++ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
|---|---|---|---|---|---|---|---|---|---|
| index.tsx | +
+
+ |
+ 100% | +5/5 | +100% | +6/6 | +100% | +4/4 | +100% | +5/5 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| 1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 | + + + + + + + + + + + + +14x + + + + + + + + + + + + + + +13x + + + + + + + + +14x + + + + + +14x +14x + + + + + + + | import React, { type ReactNode } from "react";
+import clsx from "clsx";
+import { ThemeClassNames } from "@docusaurus/theme-common";
+
+import type { Props } from "@theme/Admonition/Layout";
+
+import styles from "./styles.module.css";
+
+function AdmonitionContainer({
+ type,
+ className,
+ children,
+}: Pick<Props, "type" | "className"> & { children: ReactNode }) {
+ return (
+ <div
+ className={clsx(
+ ThemeClassNames.common.admonition,
+ ThemeClassNames.common.admonitionType(type),
+ styles.admonition,
+ className
+ )}
+ >
+ {children}
+ </div>
+ );
+}
+
+function AdmonitionHeading({ icon, title }: Pick<Props, "icon" | "title">) {
+ return (
+ <div className={styles.admonitionHeading}>
+ <span className={styles.admonitionIcon}>{icon}</span>
+ {/* {title} */}
+ </div>
+ );
+}
+
+function AdmonitionContent({ children }: Pick<Props, "children">) {
+ return children ? (
+ <div className={styles.admonitionContent}>{children}</div>
+ ) : null;
+}
+
+export default function AdmonitionLayout(props: Props): ReactNode {
+ const { type, icon, title, children, className } = props;
+ return (
+ <AdmonitionContainer type={type} className={className}>
+ {title || icon ? <AdmonitionHeading title={title} icon={icon} /> : null}
+ <AdmonitionContent>{children}</AdmonitionContent>
+ </AdmonitionContainer>
+ );
+}
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| 1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 | + + + + + + +1x + +1x + + + + + + + + + + + +6x + + + + + + + + + | import React, {type ReactNode} from 'react';
+import clsx from 'clsx';
+import Translate from '@docusaurus/Translate';
+import type {Props} from '@theme/Admonition/Type/Danger';
+import AdmonitionLayout from '@theme/Admonition/Layout';
+import IconDanger from '@theme/Admonition/Icon/Danger';
+
+const infimaClassName = 'alert alert--danger';
+
+const defaultProps = {
+ icon: <IconDanger />,
+ title: (
+ <Translate
+ id="theme.admonition.danger"
+ description="The default label used for the Danger admonition (:::danger)">
+ danger
+ </Translate>
+ ),
+};
+
+export default function AdmonitionTypeDanger(props: Props): ReactNode {
+ return (
+ <AdmonitionLayout
+ {...defaultProps}
+ {...props}
+ className={clsx(infimaClassName, props.className)}>
+ {props.children}
+ </AdmonitionLayout>
+ );
+}
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
|---|---|---|---|---|---|---|---|---|---|
| Danger.tsx | +
+
+ |
+ 100% | +3/3 | +100% | +0/0 | +100% | +1/1 | +100% | +3/3 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| 1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 | + + + + + + + + +1x + + + + + + + + + + +1x +1x +1x +1x + + + + + + + + | import React from 'react';
+import AdmonitionTypeNote from '@theme/Admonition/Type/Note';
+import AdmonitionTypeTip from '@theme/Admonition/Type/Tip';
+import AdmonitionTypeInfo from '@theme/Admonition/Type/Info';
+import AdmonitionTypeWarning from '@theme/Admonition/Type/Warning';
+import AdmonitionTypeDanger from '@theme/Admonition/Type/Danger';
+import AdmonitionTypeCaution from '@theme/Admonition/Type/Caution';
+import type AdmonitionTypes from '@theme/Admonition/Types';
+
+const admonitionTypes: typeof AdmonitionTypes = {
+ note: AdmonitionTypeNote,
+ tip: AdmonitionTypeTip,
+ info: AdmonitionTypeInfo,
+ warning: AdmonitionTypeWarning,
+ danger: AdmonitionTypeDanger,
+};
+
+// Undocumented legacy admonition type aliases
+// Provide hardcoded/untranslated retrocompatible label
+// See also https://github.com/facebook/docusaurus/issues/7767
+const admonitionAliases: typeof AdmonitionTypes = {
+ secondary: (props) => <AdmonitionTypeNote title="secondary" {...props} />,
+ important: (props) => <AdmonitionTypeInfo title="important" {...props} />,
+ success: (props) => <AdmonitionTypeTip title="success" {...props} />,
+ caution: AdmonitionTypeCaution,
+};
+
+export default {
+ ...admonitionTypes,
+ ...admonitionAliases,
+};
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ ++ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| 1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 | + + + + + +13x +13x +12x + +1x + + +1x + + + +13x +13x +13x + + | import React, {type ComponentType, type ReactNode} from 'react';
+import {processAdmonitionProps} from '@docusaurus/theme-common';
+import type {Props} from '@theme/Admonition';
+import AdmonitionTypes from '@theme/Admonition/Types';
+
+function getAdmonitionTypeComponent(type: string): ComponentType<Props> {
+ const component = AdmonitionTypes[type];
+ if (component) {
+ return component;
+ }
+ console.warn(
+ `No admonition component found for admonition type "${type}". Using Info as fallback.`,
+ );
+ return AdmonitionTypes.info!;
+}
+
+export default function Admonition(unprocessedProps: Props): ReactNode {
+ const props = processAdmonitionProps(unprocessedProps);
+ const AdmonitionTypeComponent = getAdmonitionTypeComponent(props.type);
+ return <AdmonitionTypeComponent {...props} />;
+}
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +| File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
|---|---|---|---|---|---|---|---|---|---|
| Admonition | +
+
+ |
+ 100% | +13/13 | +100% | +2/2 | +100% | +5/5 | +100% | +13/13 | +
| Admonition/Layout | +
+
+ |
+ 100% | +5/5 | +100% | +6/6 | +100% | +4/4 | +100% | +5/5 | +
| Admonition/Type | +
+
+ |
+ 100% | +3/3 | +100% | +0/0 | +100% | +1/1 | +100% | +3/3 | +