aboutsummaryrefslogtreecommitdiffstats
path: root/tests/xxx_mdx_plugin_recma_jsx_rewrite.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/xxx_mdx_plugin_recma_jsx_rewrite.rs')
-rw-r--r--tests/xxx_mdx_plugin_recma_jsx_rewrite.rs381
1 files changed, 381 insertions, 0 deletions
diff --git a/tests/xxx_mdx_plugin_recma_jsx_rewrite.rs b/tests/xxx_mdx_plugin_recma_jsx_rewrite.rs
new file mode 100644
index 0000000..497155f
--- /dev/null
+++ b/tests/xxx_mdx_plugin_recma_jsx_rewrite.rs
@@ -0,0 +1,381 @@
+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, Location, ParseOptions};
+use pretty_assertions::assert_eq;
+use test_utils::{
+ hast_util_to_swc::hast_util_to_swc,
+ mdast_util_to_hast::mdast_util_to_hast,
+ mdx_plugin_recma_document::{mdx_plugin_recma_document, Options as DocumentOptions},
+ mdx_plugin_recma_jsx_rewrite::{mdx_plugin_recma_jsx_rewrite, Options as RewriteOptions},
+ swc::{parse_esm, parse_expression, serialize},
+};
+
+fn from_markdown(value: &str, options: &RewriteOptions) -> Result<String, String> {
+ let location = Location::new(value.as_bytes());
+ let mdast = micromark_to_mdast(
+ value,
+ &ParseOptions {
+ constructs: Constructs::mdx(),
+ mdx_esm_parse: Some(Box::new(parse_esm)),
+ mdx_expression_parse: Some(Box::new(parse_expression)),
+ ..ParseOptions::default()
+ },
+ )?;
+ let hast = mdast_util_to_hast(&mdast);
+ let program = hast_util_to_swc(&hast, Some("example.mdx".into()), Some(&location))?;
+ let program = mdx_plugin_recma_document(program, &DocumentOptions::default(), Some(&location))?;
+ let program = mdx_plugin_recma_jsx_rewrite(program, options, Some(&location));
+ let value = serialize(&program.module);
+ Ok(value)
+}
+
+#[test]
+fn mdx_plugin_recma_jsx_rewrite_test() -> 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",
+ );
+
+ assert_eq!(
+ from_markdown("# <Hi />", &RewriteOptions {
+ development: true,
+ ..Default::default()
+ })?,
+ "function _createMdxContent(props) {
+ const _components = Object.assign({
+ h1: \"h1\"
+ }, props.components), { Hi } = _components;
+ if (!Hi) _missingMdxReference(\"Hi\", true, \"1:3-1:9\");
+ 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, place) {
+ throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\" + (place ? \"\\nIt’s referenced in your code at `\" + place + \"` in `example.mdx`\" : \"\"));
+}
+",
+ "should create missing reference helpers w/o positional info in `development` mode",
+ );
+
+ Ok(())
+}