From 7260005bd86e7f8aeb6b65f5c1464eb7fc65f013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Fri, 5 Apr 2024 21:12:25 +0200 Subject: [PATCH] feat: consolidate syntax highlighting code into standalone plugin (#9783) --- src/core/components/curl.jsx | 20 ++-- src/core/components/example.jsx | 9 +- src/core/components/live-response.jsx | 5 +- src/core/components/model-example.jsx | 2 +- src/core/components/param-body.jsx | 4 +- src/core/components/response-body.jsx | 2 +- src/core/components/response.jsx | 2 +- src/core/index.js | 2 + .../plugins/oas3/components/request-body.jsx | 6 +- .../request-snippets/request-snippets.jsx | 12 +-- .../plugins/syntax-highlighting/after-load.js | 25 +++++ .../components/HighlightCode.jsx} | 93 ++++++++++++------- .../components/SyntaxHighlighter.jsx | 43 +++++++++ src/core/plugins/syntax-highlighting/index.js | 20 ++++ .../syntax-highlighting/root-injects.js | 22 +++++ src/core/presets/base/index.js | 2 + .../base/plugins/core-components/index.js | 2 - src/core/syntax-highlighting.js | 39 -------- test/unit/components/highlight-code.jsx | 23 ++++- test/unit/components/response-body.jsx | 11 +-- 20 files changed, 231 insertions(+), 113 deletions(-) create mode 100644 src/core/plugins/syntax-highlighting/after-load.js rename src/core/{components/highlight-code.jsx => plugins/syntax-highlighting/components/HighlightCode.jsx} (52%) create mode 100644 src/core/plugins/syntax-highlighting/components/SyntaxHighlighter.jsx create mode 100644 src/core/plugins/syntax-highlighting/index.js create mode 100644 src/core/plugins/syntax-highlighting/root-injects.js delete mode 100644 src/core/syntax-highlighting.js diff --git a/src/core/components/curl.jsx b/src/core/components/curl.jsx index eefce029..79909995 100644 --- a/src/core/components/curl.jsx +++ b/src/core/components/curl.jsx @@ -1,32 +1,30 @@ import React from "react" import PropTypes from "prop-types" import { CopyToClipboard } from "react-copy-to-clipboard" -import {SyntaxHighlighter, getStyle} from "core/syntax-highlighting" import get from "lodash/get" import { requestSnippetGenerator_curl_bash } from "../plugins/request-snippets/fn" export default class Curl extends React.Component { static propTypes = { getConfigs: PropTypes.func.isRequired, + getComponent: PropTypes.func.isRequired, request: PropTypes.object.isRequired } render() { - let { request, getConfigs } = this.props + let { request, getConfigs, getComponent } = this.props let curl = requestSnippetGenerator_curl_bash(request) const config = getConfigs() + const SyntaxHighlighter = getComponent("SyntaxHighlighter", true) - const curlBlock = get(config, "syntaxHighlight.activated") - ? - {curl} - - : + const curlBlock = get(config, "syntaxHighlight.activated") ? ( + + {curl} + + ) : ( + ) return (
diff --git a/src/core/components/example.jsx b/src/core/components/example.jsx index ad6ad8cf..6cd63742 100644 --- a/src/core/components/example.jsx +++ b/src/core/components/example.jsx @@ -11,9 +11,9 @@ export default function Example(props) { const { example, showValue, getComponent, getConfigs } = props const Markdown = getComponent("Markdown", true) - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) - if(!example) return null + if (!example) return null return (
@@ -28,7 +28,10 @@ export default function Example(props) { {showValue && example.has("value") ? (
Example Value
- +
) : null}
diff --git a/src/core/components/live-response.jsx b/src/core/components/live-response.jsx index dc85f535..eb7665a4 100644 --- a/src/core/components/live-response.jsx +++ b/src/core/components/live-response.jsx @@ -69,13 +69,14 @@ export default class LiveResponse extends React.Component { const hasHeaders = returnObject.length !== 0 const Markdown = getComponent("Markdown", true) const RequestSnippets = getComponent("RequestSnippets", true) - const Curl = getComponent("curl") + const Curl = getComponent("curl", true) return (
{ curlRequest && (requestSnippetsEnabled === true || requestSnippetsEnabled === "true" ? - : ) } + : + )} { url &&

Request URL

diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx index 447b1591..6b942799 100644 --- a/src/core/components/model-example.jsx +++ b/src/core/components/model-example.jsx @@ -50,7 +50,7 @@ const ModelExample = ({ }) => { const { defaultModelRendering, defaultModelExpandDepth } = getConfigs() const ModelWrapper = getComponent("ModelWrapper") - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) const exampleTabId = randomBytes(5).toString("base64") const examplePanelId = randomBytes(5).toString("base64") const modelTabId = randomBytes(5).toString("base64") diff --git a/src/core/components/param-body.jsx b/src/core/components/param-body.jsx index 11eeef9f..966b48fb 100644 --- a/src/core/components/param-body.jsx +++ b/src/core/components/param-body.jsx @@ -104,7 +104,7 @@ export default class ParamBody extends PureComponent { const Button = getComponent("Button") const TextArea = getComponent("TextArea") - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) const ContentType = getComponent("contentType") // for domains where specSelectors not passed let parameter = specSelectors ? specSelectors.parameterWithMetaByIdentity(pathMethod, param) : param @@ -148,7 +148,7 @@ export default class ParamBody extends PureComponent { contentTypes={ consumes } onChange={onChangeConsumes} className="body-param-content-type" - ariaLabel="Parameter content type" + ariaLabel="Parameter content type" controlId={controlId} /> diff --git a/src/core/components/response-body.jsx b/src/core/components/response-body.jsx index 4a1e1c21..43544b36 100644 --- a/src/core/components/response-body.jsx +++ b/src/core/components/response-body.jsx @@ -53,7 +53,7 @@ export default class ResponseBody extends React.PureComponent { render() { let { content, contentType, url, headers={}, getConfigs, getComponent } = this.props const { parsedContent } = this.state - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) const downloadName = "response_" + new Date().getTime() let body, bodyEl url = url || "" diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx index 7835f632..8c34510e 100644 --- a/src/core/components/response.jsx +++ b/src/core/components/response.jsx @@ -98,7 +98,7 @@ export default class Response extends React.Component { let links = response.get("links") const ResponseExtension = getComponent("ResponseExtension") const Headers = getComponent("headers") - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) const ModelExample = getComponent("modelExample") const Markdown = getComponent("Markdown", true) const OperationLink = getComponent("operationLink") diff --git a/src/core/index.js b/src/core/index.js index c3725f66..9d910f67 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -26,6 +26,7 @@ import UtilPlugin from "./plugins/util" import ViewPlugin from "./plugins/view" import ViewLegacyPlugin from "core/plugins/view-legacy" import DownloadUrlPlugin from "./plugins/download-url" +import SyntaxHighlightingPlugin from "core/plugins/syntax-highlighting" import SafeRenderPlugin from "./plugins/safe-render" import { parseSearch } from "./utils" @@ -271,5 +272,6 @@ SwaggerUI.plugins = { View: ViewPlugin, ViewLegacy: ViewLegacyPlugin, DownloadUrl: DownloadUrlPlugin, + SyntaxHighlighting: SyntaxHighlightingPlugin, SafeRender: SafeRenderPlugin, } diff --git a/src/core/plugins/oas3/components/request-body.jsx b/src/core/plugins/oas3/components/request-body.jsx index 7c979908..4777bc3b 100644 --- a/src/core/plugins/oas3/components/request-body.jsx +++ b/src/core/plugins/oas3/components/request-body.jsx @@ -71,7 +71,7 @@ const RequestBody = ({ const Markdown = getComponent("Markdown", true) const ModelExample = getComponent("modelExample") const RequestBodyEditor = getComponent("RequestBodyEditor") - const HighlightCode = getComponent("highlightCode") + const HighlightCode = getComponent("HighlightCode", true) const ExamplesSelectValueRetainer = getComponent("ExamplesSelectValueRetainer") const Example = getComponent("Example") const ParameterIncludeEmpty = getComponent("ParameterIncludeEmpty") @@ -152,7 +152,7 @@ const RequestBody = ({ { Map.isMap(bodyProperties) && bodyProperties.entrySeq().map(([key, schema]) => { if (schema.get("readOnly")) return - + const oneOf = schema.get("oneOf")?.get(0)?.toJS() const anyOf = schema.get("anyOf")?.get(0)?.toJS() schema = fromJS(fn.mergeJsonSchema(schema.toJS(), oneOf ?? anyOf ?? {})) @@ -169,7 +169,7 @@ const RequestBody = ({ let initialValue = fn.getSampleSchema(schema, false, { includeWriteOnly: true }) - + if (initialValue === false) { initialValue = "false" } diff --git a/src/core/plugins/request-snippets/request-snippets.jsx b/src/core/plugins/request-snippets/request-snippets.jsx index 46174b3c..336d65fd 100644 --- a/src/core/plugins/request-snippets/request-snippets.jsx +++ b/src/core/plugins/request-snippets/request-snippets.jsx @@ -3,7 +3,6 @@ import PropTypes from "prop-types" import get from "lodash/get" import isFunction from "lodash/isFunction" import { CopyToClipboard } from "react-copy-to-clipboard" -import { SyntaxHighlighter, getStyle } from "core/syntax-highlighting" const style = { cursor: "pointer", @@ -42,6 +41,7 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom const ArrowIcon = getComponent("ArrowUpIcon") const ArrowDownIcon = getComponent("ArrowDownIcon") + const SyntaxHighlighter = getComponent("SyntaxHighlighter", true) const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first()) const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded()) @@ -99,16 +99,16 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom } } - const SnippetComponent = canSyntaxHighlight - ? {snippet} - : + ) : ( + ) return (
@@ -147,7 +147,7 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom
}
- ) + ) } RequestSnippets.propTypes = { diff --git a/src/core/plugins/syntax-highlighting/after-load.js b/src/core/plugins/syntax-highlighting/after-load.js new file mode 100644 index 00000000..5ac16250 --- /dev/null +++ b/src/core/plugins/syntax-highlighting/after-load.js @@ -0,0 +1,25 @@ +/** + * @prettier + */ +import SyntaxHighlighter from "react-syntax-highlighter/dist/esm/light" +import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript" +import json from "react-syntax-highlighter/dist/esm/languages/hljs/json" +import xml from "react-syntax-highlighter/dist/esm/languages/hljs/xml" +import bash from "react-syntax-highlighter/dist/esm/languages/hljs/bash" +import yaml from "react-syntax-highlighter/dist/esm/languages/hljs/yaml" +import http from "react-syntax-highlighter/dist/esm/languages/hljs/http" +import powershell from "react-syntax-highlighter/dist/esm/languages/hljs/powershell" +import javascript from "react-syntax-highlighter/dist/esm/languages/hljs/javascript" + +const afterLoad = () => { + SyntaxHighlighter.registerLanguage("json", json) + SyntaxHighlighter.registerLanguage("js", js) + SyntaxHighlighter.registerLanguage("xml", xml) + SyntaxHighlighter.registerLanguage("yaml", yaml) + SyntaxHighlighter.registerLanguage("http", http) + SyntaxHighlighter.registerLanguage("bash", bash) + SyntaxHighlighter.registerLanguage("powershell", powershell) + SyntaxHighlighter.registerLanguage("javascript", javascript) +} + +export default afterLoad diff --git a/src/core/components/highlight-code.jsx b/src/core/plugins/syntax-highlighting/components/HighlightCode.jsx similarity index 52% rename from src/core/components/highlight-code.jsx rename to src/core/plugins/syntax-highlighting/components/HighlightCode.jsx index 29f075e3..aeb8a232 100644 --- a/src/core/components/highlight-code.jsx +++ b/src/core/plugins/syntax-highlighting/components/HighlightCode.jsx @@ -1,30 +1,30 @@ +/** + * @prettier + */ import React, { useRef, useEffect } from "react" import PropTypes from "prop-types" -import cx from "classnames" -import {SyntaxHighlighter, getStyle} from "core/syntax-highlighting" +import classNames from "classnames" import get from "lodash/get" -import isFunction from "lodash/isFunction" import saveAs from "js-file-download" import { CopyToClipboard } from "react-copy-to-clipboard" -const HighlightCode = ({value, fileName = "response.txt", className, downloadable, getConfigs, canCopy, language}) => { - const config = isFunction(getConfigs) ? getConfigs() : null - const canSyntaxHighlight = get(config, "syntaxHighlight") !== false && get(config, "syntaxHighlight.activated", true) +const HighlightCode = ({ + value, + fileName = "response.txt", + className, + downloadable, + getConfigs, + getComponent, + canCopy, + language, +}) => { + const config = getConfigs() + const canSyntaxHighlight = + get(config, "syntaxHighlight") !== false && + get(config, "syntaxHighlight.activated", true) const rootRef = useRef(null) - useEffect(() => { - const childNodes = Array - .from(rootRef.current.childNodes) - .filter(node => !!node.nodeType && node.classList.contains("microlight")) - - // eslint-disable-next-line no-use-before-define - childNodes.forEach(node => node.addEventListener("mousewheel", handlePreventYScrollingBeyondElement, { passive: false })) - - return () => { - // eslint-disable-next-line no-use-before-define - childNodes.forEach(node => node.removeEventListener("mousewheel", handlePreventYScrollingBeyondElement)) - } - }, [value, className, language]) + const SyntaxHighlighter = getComponent("SyntaxHighlighter", true) const handleDownload = () => { saveAs(value, fileName) @@ -32,7 +32,11 @@ const HighlightCode = ({value, fileName = "response.txt", className, downloadabl const handlePreventYScrollingBeyondElement = (e) => { const { target, deltaY } = e - const { scrollHeight: contentHeight, offsetHeight: visibleHeight, scrollTop } = target + const { + scrollHeight: contentHeight, + offsetHeight: visibleHeight, + scrollTop, + } = target const scrollOffset = visibleHeight + scrollTop const isElementScrollable = contentHeight > visibleHeight const isScrollingPastTop = scrollTop === 0 && deltaY < 0 @@ -43,31 +47,57 @@ const HighlightCode = ({value, fileName = "response.txt", className, downloadabl } } + useEffect(() => { + const childNodes = Array.from(rootRef.current.childNodes).filter( + (node) => !!node.nodeType && node.classList.contains("microlight") + ) + + // eslint-disable-next-line no-use-before-define + childNodes.forEach((node) => + node.addEventListener( + "mousewheel", + handlePreventYScrollingBeyondElement, + { passive: false } + ) + ) + + return () => { + // eslint-disable-next-line no-use-before-define + childNodes.forEach((node) => + node.removeEventListener( + "mousewheel", + handlePreventYScrollingBeyondElement + ) + ) + } + }, [value, className, language]) + return (
{canCopy && (
-
)} - {!downloadable ? null : + {!downloadable ? null : ( - } + )} - {canSyntaxHighlight - ? {value} - :
{value}
- } - + ) : ( +
{value}
+ )}
) } @@ -75,11 +105,12 @@ const HighlightCode = ({value, fileName = "response.txt", className, downloadabl HighlightCode.propTypes = { value: PropTypes.string.isRequired, getConfigs: PropTypes.func.isRequired, + getComponent: PropTypes.func.isRequired, className: PropTypes.string, downloadable: PropTypes.bool, fileName: PropTypes.string, language: PropTypes.string, - canCopy: PropTypes.bool + canCopy: PropTypes.bool, } export default HighlightCode diff --git a/src/core/plugins/syntax-highlighting/components/SyntaxHighlighter.jsx b/src/core/plugins/syntax-highlighting/components/SyntaxHighlighter.jsx new file mode 100644 index 00000000..af570107 --- /dev/null +++ b/src/core/plugins/syntax-highlighting/components/SyntaxHighlighter.jsx @@ -0,0 +1,43 @@ +/** + * @prettier + */ +import React from "react" +import PropTypes from "prop-types" +import ReactSyntaxHighlighter from "react-syntax-highlighter/dist/esm/light" +import get from "lodash/get" + +const SyntaxHighlighter = ({ + language, + className = "", + getConfigs, + syntaxHighlighting = {}, + children = null, +}) => { + const configs = getConfigs() + const theme = get(configs, "syntaxHighlight.theme") + const { styles, defaultStyle } = syntaxHighlighting + const style = styles?.[theme] ?? defaultStyle + + return ( + + {children} + + ) +} + +SyntaxHighlighter.propTypes = { + language: PropTypes.string.isRequired, + className: PropTypes.string, + getConfigs: PropTypes.func.isRequired, + syntaxHighlighting: PropTypes.shape({ + styles: PropTypes.object, + defaultStyle: PropTypes.object, + }), + children: PropTypes.node, +} + +export default SyntaxHighlighter diff --git a/src/core/plugins/syntax-highlighting/index.js b/src/core/plugins/syntax-highlighting/index.js new file mode 100644 index 00000000..91eb51c2 --- /dev/null +++ b/src/core/plugins/syntax-highlighting/index.js @@ -0,0 +1,20 @@ +/** + * @prettier + */ +import afterLoad from "./after-load" +import { styles, defaultStyle } from "./root-injects" +import SyntaxHighlighter from "./components/SyntaxHighlighter" +import HighlightCode from "./components/HighlightCode" + +const SyntaxHighlightingPlugin = () => ({ + afterLoad, + rootInjects: { + syntaxHighlighting: { styles, defaultStyle }, + }, + components: { + SyntaxHighlighter, + HighlightCode, + }, +}) + +export default SyntaxHighlightingPlugin diff --git a/src/core/plugins/syntax-highlighting/root-injects.js b/src/core/plugins/syntax-highlighting/root-injects.js new file mode 100644 index 00000000..5264bde8 --- /dev/null +++ b/src/core/plugins/syntax-highlighting/root-injects.js @@ -0,0 +1,22 @@ +/** + * @prettier + */ +import agate from "react-syntax-highlighter/dist/esm/styles/hljs/agate" +import arta from "react-syntax-highlighter/dist/esm/styles/hljs/arta" +import monokai from "react-syntax-highlighter/dist/esm/styles/hljs/monokai" +import nord from "react-syntax-highlighter/dist/esm/styles/hljs/nord" +import obsidian from "react-syntax-highlighter/dist/esm/styles/hljs/obsidian" +import tomorrowNight from "react-syntax-highlighter/dist/esm/styles/hljs/tomorrow-night" +import idea from "react-syntax-highlighter/dist/esm/styles/hljs/idea" + +export const styles = { + agate, + arta, + monokai, + nord, + obsidian, + "tomorrow-night": tomorrowNight, + idea, +} + +export const defaultStyle = agate diff --git a/src/core/presets/base/index.js b/src/core/presets/base/index.js index d45fb574..7ee4891a 100644 --- a/src/core/presets/base/index.js +++ b/src/core/presets/base/index.js @@ -18,6 +18,7 @@ import UtilPlugin from "core/plugins/util" import ViewPlugin from "core/plugins/view" import ViewLegacyPlugin from "core/plugins/view-legacy" import DownloadUrlPlugin from "core/plugins/download-url" +import SyntaxHighlightingPlugin from "core/plugins/syntax-highlighting" import SafeRenderPlugin from "core/plugins/safe-render" // ad-hoc plugins import CoreComponentsPlugin from "core/presets/base/plugins/core-components" @@ -45,6 +46,7 @@ const BasePreset = () => [ FilterPlugin, OnCompletePlugin, RequestSnippetsPlugin, + SyntaxHighlightingPlugin, SafeRenderPlugin(), ] diff --git a/src/core/presets/base/plugins/core-components/index.js b/src/core/presets/base/plugins/core-components/index.js index 4ba1f455..f4836bc2 100644 --- a/src/core/presets/base/plugins/core-components/index.js +++ b/src/core/presets/base/plugins/core-components/index.js @@ -27,7 +27,6 @@ import OperationSummaryMethod from "core/components/operation-summary-method" import OperationSummaryPath from "core/components/operation-summary-path" import OperationExt from "core/components/operation-extensions" import OperationExtRow from "core/components/operation-extension-row" -import HighlightCode from "core/components/highlight-code" import Responses from "core/components/responses" import Response from "core/components/response" import ResponseExtension from "core/components/response-extension" @@ -103,7 +102,6 @@ const CoreComponentsPlugin = () => ({ OperationSummary, OperationSummaryMethod, OperationSummaryPath, - highlightCode: HighlightCode, responses: Responses, response: Response, ResponseExtension: ResponseExtension, diff --git a/src/core/syntax-highlighting.js b/src/core/syntax-highlighting.js deleted file mode 100644 index fcca99b1..00000000 --- a/src/core/syntax-highlighting.js +++ /dev/null @@ -1,39 +0,0 @@ -import SyntaxHighlighter from "react-syntax-highlighter/dist/esm/light" -import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript" -import json from "react-syntax-highlighter/dist/esm/languages/hljs/json" -import xml from "react-syntax-highlighter/dist/esm/languages/hljs/xml" -import bash from "react-syntax-highlighter/dist/esm/languages/hljs/bash" -import yaml from "react-syntax-highlighter/dist/esm/languages/hljs/yaml" -import http from "react-syntax-highlighter/dist/esm/languages/hljs/http" -import powershell from "react-syntax-highlighter/dist/esm/languages/hljs/powershell" -import javascript from "react-syntax-highlighter/dist/esm/languages/hljs/javascript" - -import agate from "react-syntax-highlighter/dist/esm/styles/hljs/agate" -import arta from "react-syntax-highlighter/dist/esm/styles/hljs/arta" -import monokai from "react-syntax-highlighter/dist/esm/styles/hljs/monokai" -import nord from "react-syntax-highlighter/dist/esm/styles/hljs/nord" -import obsidian from "react-syntax-highlighter/dist/esm/styles/hljs/obsidian" -import tomorrowNight from "react-syntax-highlighter/dist/esm/styles/hljs/tomorrow-night" -import idea from "react-syntax-highlighter/dist/esm/styles/hljs/idea" - -SyntaxHighlighter.registerLanguage("json", json) -SyntaxHighlighter.registerLanguage("js", js) -SyntaxHighlighter.registerLanguage("xml", xml) -SyntaxHighlighter.registerLanguage("yaml", yaml) -SyntaxHighlighter.registerLanguage("http", http) -SyntaxHighlighter.registerLanguage("bash", bash) -SyntaxHighlighter.registerLanguage("powershell", powershell) -SyntaxHighlighter.registerLanguage("javascript", javascript) - -const styles = {agate, arta, monokai, nord, obsidian, "tomorrow-night": tomorrowNight, idea} -export const availableStyles = Object.keys(styles) - -export const getStyle = name => { - if (!availableStyles.includes(name)) { - console.warn(`Request style '${name}' is not available, returning default instead`) - return agate - } - return styles[name] -} - -export {SyntaxHighlighter, styles} diff --git a/test/unit/components/highlight-code.jsx b/test/unit/components/highlight-code.jsx index 1df14e78..99b0e23d 100644 --- a/test/unit/components/highlight-code.jsx +++ b/test/unit/components/highlight-code.jsx @@ -1,26 +1,39 @@ import React from "react" import expect from "expect" import { shallow, mount } from "enzyme" -import HighlightCode from "core/components/highlight-code" +import HighlightCode from "core/plugins/syntax-highlighting/components/HighlightCode" +import SyntaxHighlighter from "core/plugins/syntax-highlighting/components/SyntaxHighlighter" -const fakeGetConfigs = () => ({syntaxHighlight: {activated: true, theme: "agate"}}) +const fakeGetConfigs = () => ({ syntaxHighlight: { activated: true, theme: "agate" }}) +const fakeGetComponent = (name, isContainer) => { + const components = { HighlightCode, SyntaxHighlighter } + const Component = components[name] + + if (isContainer) { + return ({ ...props }) => { + return + } + } + + return Component +} describe("", () => { it("should render a Download button if downloadable", () => { - const props = {downloadable: true, getConfigs: fakeGetConfigs } + const props = { downloadable: true, getConfigs: fakeGetConfigs, getComponent: fakeGetComponent } const wrapper = shallow() expect(wrapper.find(".download-contents").length).toEqual(1) }) it("should render a Copy To Clipboard button if copyable", () => { - const props = {canCopy: true, getConfigs: fakeGetConfigs } + const props = { canCopy: true, getConfigs: fakeGetConfigs, getComponent: fakeGetComponent } const wrapper = shallow() expect(wrapper.find("CopyToClipboard").length).toEqual(1) }) it("should render values in a preformatted element", () => { const value = "test text" - const props = {value: value, getConfigs: fakeGetConfigs} + const props = { value, getConfigs: fakeGetConfigs, getComponent: fakeGetComponent } const wrapper = mount() const preTag = wrapper.find("pre") diff --git a/test/unit/components/response-body.jsx b/test/unit/components/response-body.jsx index 8771905f..bf80249f 100644 --- a/test/unit/components/response-body.jsx +++ b/test/unit/components/response-body.jsx @@ -3,9 +3,8 @@ import { shallow } from "enzyme" import ResponseBody from "core/components/response-body" describe("", function () { - const highlightCodeComponent = () => null const components = { - highlightCode: highlightCodeComponent + HighlightCode: () => null } const props = { getComponent: c => components[c], @@ -15,27 +14,27 @@ describe("", function () { props.contentType = "application/json" props.content = "{\"key\": \"a test value\"}" const wrapper = shallow() - expect(wrapper.find("highlightCodeComponent").length).toEqual(1) + expect(wrapper.find("HighlightCode").length).toEqual(1) }) it("renders ResponseBody as 'text/html'", function () { props.contentType = "application/json" props.content = "Result" const wrapper = shallow() - expect(wrapper.find("highlightCodeComponent").length).toEqual(1) + expect(wrapper.find("HighlightCode").length).toEqual(1) }) it("renders ResponseBody as 'image/svg'", function () { props.contentType = "image/svg" const wrapper = shallow() - expect(wrapper.find("highlightCodeComponent").length).toEqual(0) + expect(wrapper.find("HighlightCode").length).toEqual(0) }) it("should render a copyable highlightCodeComponent for text types", function () { props.contentType = "text/plain" props.content = "test text" const wrapper = shallow() - expect(wrapper.find("highlightCodeComponent[canCopy]").length).toEqual(1) + expect(wrapper.find("HighlightCode[canCopy]").length).toEqual(1) }) it("should render Download file link for non-empty Blob response", function () {