aboutsummaryrefslogtreecommitdiffstats
path: root/tests/xxx_jsx_rewrite.rs
diff options
context:
space:
mode:
authorLibravatar Titus Wormer <tituswormer@gmail.com>2022-10-05 16:31:51 +0200
committerLibravatar Titus Wormer <tituswormer@gmail.com>2022-10-05 16:43:07 +0200
commite50fb638f73528e96ceb88f7c3feee613c397344 (patch)
treea1cdf61f37dbd64208d85b94164f0c5fbeef4169 /tests/xxx_jsx_rewrite.rs
parent9d90e35d51555d9f853f2eccfa771f47d71a6bc1 (diff)
downloadmarkdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.tar.gz
markdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.tar.bz2
markdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.zip
Add support for rewriting JSX
Diffstat (limited to '')
-rw-r--r--tests/xxx_jsx_rewrite.rs355
1 files changed, 355 insertions, 0 deletions
diff --git a/tests/xxx_jsx_rewrite.rs b/tests/xxx_jsx_rewrite.rs
new file mode 100644
index 0000000..ad7c4b4
--- /dev/null
+++ b/tests/xxx_jsx_rewrite.rs
@@ -0,0 +1,355 @@
+extern crate micromark;
+extern crate swc_common;
+extern crate swc_ecma_ast;
+extern crate swc_ecma_codegen;
+mod test_utils;
+use micromark::{micromark_to_mdast, Constructs, Options};
+use pretty_assertions::assert_eq;
+use test_utils::{
+ jsx_rewrite::{jsx_rewrite, Options as RewriteOptions},
+ swc::{parse_esm, parse_expression, serialize},
+ to_document::{to_document, Options as DocumentOptions},
+ to_hast::to_hast,
+ to_swc::to_swc,
+};
+
+fn from_markdown(value: &str, options: &RewriteOptions) -> Result<String, String> {
+ let mdast = micromark_to_mdast(
+ value,
+ &Options {
+ constructs: Constructs::mdx(),
+ mdx_esm_parse: Some(Box::new(parse_esm)),
+ mdx_expression_parse: Some(Box::new(parse_expression)),
+ ..Options::default()
+ },
+ )?;
+ let hast = to_hast(&mdast);
+ let program = to_document(to_swc(&hast)?, &DocumentOptions::default())?;
+ let program = jsx_rewrite(program, options);
+ let value = serialize(&program.module);
+ Ok(value)
+}
+
+#[test]
+fn rewrite() -> Result<(), String> {
+ assert_eq!(
+ from_markdown("", &Default::default())?,
+ "function _createMdxContent(props) {
+ return <></>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should work on an empty file",
+ );
+
+ assert_eq!(
+ from_markdown("# hi", &Default::default())?,
+ "function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, props.components);
+ return <_components.h1 >{\"hi\"}</_components.h1>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should support passing in a layout (as `wrapper`) and components for literal tags",
+ );
+
+ assert_eq!(
+ from_markdown(
+ "export {MyLayout as default} from './a.js'\n\n# hi",
+ &Default::default()
+ )?,
+ "import { MyLayout as MDXLayout } from './a.js';
+function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, props.components);
+ return <_components.h1 >{\"hi\"}</_components.h1>;
+}
+function MDXContent(props = {}) {
+ return <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout>;
+}
+export default MDXContent;
+",
+ "should not support passing in a layout if one is defined locally",
+ );
+
+ assert_eq!(
+ from_markdown("# <Hi />", &Default::default())?,
+ "function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, props.components), { Hi } = _components;
+ if (!Hi) _missingMdxReference(\"Hi\", true);
+ return <_components.h1 ><Hi /></_components.h1>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support passing in a component",
+ );
+
+ assert_eq!(
+ from_markdown("<X />, <X.y />, <Y.Z />", &Default::default())?,
+ "function _createMdxContent(props) {
+ const _components = Object.assign({
+ p: \"p\"
+ }, props.components), { X , Y } = _components;
+ if (!X) _missingMdxReference(\"X\", true);
+ if (!X.y) _missingMdxReference(\"X.y\", true);
+ if (!Y) _missingMdxReference(\"Y\", false);
+ if (!Y.Z) _missingMdxReference(\"Y.Z\", true);
+ return <_components.p ><X />{\", \"}<X.y />{\", \"}<Y.Z /></_components.p>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support passing in component objects",
+ );
+
+ assert_eq!(
+ from_markdown("import {Hi} from './a.js'\n\n# <Hi />", &Default::default())?,
+ "import { Hi } from './a.js';
+function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, props.components);
+ return <_components.h1 ><Hi /></_components.h1>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should not support passing in a component if one is defined locally",
+ );
+
+ assert_eq!(
+ from_markdown("# <a-b />", &Default::default())?,
+ "function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\",
+ \"a-b\": \"a-b\"
+ }, props.components), _component0 = _components[\"a-b\"];
+ return <_components.h1 ><_component0 /></_components.h1>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should support passing in a component for a JSX identifier that is not a valid JS identifier",
+ );
+
+ assert_eq!(
+ from_markdown("# <Hi />", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+ })?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, _provideComponents(), props.components), { Hi } = _components;
+ if (!Hi) _missingMdxReference(\"Hi\", true);
+ return <_components.h1 ><Hi /></_components.h1>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support providing a layout, literal tags, and components",
+ );
+
+ assert_eq!(
+ from_markdown("", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+ })?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+function _createMdxContent(props) {
+ return <></>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should support a provider on an empty file",
+ );
+
+ assert_eq!(
+ from_markdown("<X />, <X.y />, <Y.Z />", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+ })?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+function _createMdxContent(props) {
+ const _components = Object.assign({
+ p: \"p\"
+ }, _provideComponents(), props.components), { X , Y } = _components;
+ if (!X) _missingMdxReference(\"X\", true);
+ if (!X.y) _missingMdxReference(\"X.y\", true);
+ if (!Y) _missingMdxReference(\"Y\", false);
+ if (!Y.Z) _missingMdxReference(\"Y.Z\", true);
+ return <_components.p ><X />{\", \"}<X.y />{\", \"}<Y.Z /></_components.p>;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support providing component objects",
+ );
+
+ assert_eq!(
+ from_markdown("export function A() {
+ return <B />
+}
+
+<A />
+", &Default::default())?,
+ "export function A() {
+ return <B />;
+}
+function _createMdxContent(props) {
+ return <A />;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = props.components || {};
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should not support passing components in locally defined components",
+ );
+
+ assert_eq!(
+ from_markdown("export function A() {
+ return <B />
+}
+
+<A />
+", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+})?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+export function A() {
+ const { B } = _provideComponents();
+ if (!B) _missingMdxReference(\"B\", true);
+ return <B />;
+}
+function _createMdxContent(props) {
+ return <A />;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support providing components in locally defined components",
+ );
+
+ assert_eq!(
+ from_markdown("export function A() {
+ return <b-c />
+}
+
+<A />
+", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+})?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+export function A() {
+ const _components = Object.assign({
+ \"b-c\": \"b-c\"
+ }, _provideComponents()), _component0 = _components[\"b-c\"];
+ return <_component0 />;
+}
+function _createMdxContent(props) {
+ return <A />;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+",
+ "should support providing components with JSX identifiers that are not JS identifiers in locally defined components",
+ );
+
+ assert_eq!(
+ from_markdown("export function A() {
+ return <X />, <X.y />, <Y.Z />
+}
+
+<A />
+", &RewriteOptions {
+ provider_import_source: Some("x".into()),
+ ..Default::default()
+})?,
+ "import { useMDXComponents as _provideComponents } from \"x\";
+export function A() {
+ const { X , Y } = _provideComponents();
+ if (!X) _missingMdxReference(\"X\", true);
+ if (!X.y) _missingMdxReference(\"X.y\", true);
+ if (!Y) _missingMdxReference(\"Y\", false);
+ if (!Y.Z) _missingMdxReference(\"Y.Z\", true);
+ return <X />, <X.y />, <Y.Z />;
+}
+function _createMdxContent(props) {
+ return <A />;
+}
+function MDXContent(props = {}) {
+ const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
+ return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
+}
+export default MDXContent;
+function _missingMdxReference(id, component) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");
+}
+",
+ "should support providing components with JSX identifiers that are not JS identifiers in locally defined components",
+ );
+
+ Ok(())
+}