diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-10-05 16:31:51 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-10-05 16:43:07 +0200 |
commit | e50fb638f73528e96ceb88f7c3feee613c397344 (patch) | |
tree | a1cdf61f37dbd64208d85b94164f0c5fbeef4169 /tests/xxx_jsx_rewrite.rs | |
parent | 9d90e35d51555d9f853f2eccfa771f47d71a6bc1 (diff) | |
download | markdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.tar.gz markdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.tar.bz2 markdown-rs-e50fb638f73528e96ceb88f7c3feee613c397344.zip |
Add support for rewriting JSX
Diffstat (limited to 'tests/xxx_jsx_rewrite.rs')
-rw-r--r-- | tests/xxx_jsx_rewrite.rs | 355 |
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(()) +} |