diff options
| author | 2022-11-25 12:36:15 +0100 | |
|---|---|---|
| committer | 2022-11-25 12:36:15 +0100 | |
| commit | 53173e52b151537ad8510da5e7802f342d24a372 (patch) | |
| tree | d904053e6679d0a89db7affa8a9b20f160a26d65 /tests/test_utils/mdx_plugin_recma_document.rs | |
| parent | 7f06d55d84db512cc9b1eee0ef23db2d7bf30214 (diff) | |
| download | markdown-rs-53173e52b151537ad8510da5e7802f342d24a372.tar.gz markdown-rs-53173e52b151537ad8510da5e7802f342d24a372.tar.bz2 markdown-rs-53173e52b151537ad8510da5e7802f342d24a372.zip | |
Remove unneeded tests
Diffstat (limited to 'tests/test_utils/mdx_plugin_recma_document.rs')
| -rw-r--r-- | tests/test_utils/mdx_plugin_recma_document.rs | 662 | 
1 files changed, 0 insertions, 662 deletions
| diff --git a/tests/test_utils/mdx_plugin_recma_document.rs b/tests/test_utils/mdx_plugin_recma_document.rs deleted file mode 100644 index 48648b9..0000000 --- a/tests/test_utils/mdx_plugin_recma_document.rs +++ /dev/null @@ -1,662 +0,0 @@ -//! Turn a JavaScript AST, coming from MD(X), into a component. -//! -//! Port of <https://github.com/mdx-js/mdx/blob/main/packages/mdx/lib/plugin/recma-document.js>, -//! by the same author. - -use crate::test_utils::{ -    hast_util_to_swc::Program, -    swc_utils::{bytepos_to_point, prefix_error_with_point, span_to_position}, -}; -use markdown::{ -    unist::{Point, Position}, -    Location, -}; - -/// JSX runtimes (default: `JsxRuntime: Automatic`). -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] -pub enum JsxRuntime { -    /// Automatic runtime. -    /// -    /// With the automatic runtime, some module is expected to exist somewhere. -    /// That modules is expected to expose a certain API. -    /// The compiler adds an import of that module and compiles JSX away to -    /// function calls that use that API. -    #[default] -    Automatic, -    /// Classic runtime. -    /// -    /// With the classic runtime, you define two values yourself in each file, -    /// which are expected to work a certain way. -    /// The compiler compiles JSX away to function calls using those two values. -    Classic, -} - -/// Configuration. -#[derive(Debug, PartialEq, Eq)] -pub struct Options { -    /// Pragma for JSX (used in classic runtime). -    /// -    /// Default: `React.createElement`. -    pub pragma: Option<String>, -    /// Pragma for JSX fragments (used in classic runtime). -    /// -    /// Default: `React.Fragment`. -    pub pragma_frag: Option<String>, -    /// Where to import the identifier of `pragma` from (used in classic runtime). -    /// -    /// Default: `react`. -    pub pragma_import_source: Option<String>, -    /// Place to import automatic JSX runtimes from (used in automatic runtime). -    /// -    /// Default: `react`. -    pub jsx_import_source: Option<String>, -    /// JSX runtime to use. -    /// -    /// Default: `automatic`. -    pub jsx_runtime: Option<JsxRuntime>, -} - -impl Default for Options { -    /// Use the automatic JSX runtime with React. -    fn default() -> Self { -        Self { -            pragma: None, -            pragma_frag: None, -            pragma_import_source: None, -            jsx_import_source: None, -            jsx_runtime: Some(JsxRuntime::default()), -        } -    } -} - -#[allow(dead_code)] -pub fn mdx_plugin_recma_document( -    program: &mut Program, -    options: &Options, -    location: Option<&Location>, -) -> Result<(), String> { -    // New body children. -    let mut replacements = vec![]; - -    // Inject JSX configuration comment. -    if let Some(runtime) = &options.jsx_runtime { -        let mut pragmas = vec![]; -        let react = &"react".into(); -        let create_element = &"React.createElement".into(); -        let fragment = &"React.Fragment".into(); - -        if *runtime == JsxRuntime::Automatic { -            pragmas.push("@jsxRuntime automatic".into()); -            pragmas.push(format!( -                "@jsxImportSource {}", -                if let Some(jsx_import_source) = &options.jsx_import_source { -                    jsx_import_source -                } else { -                    react -                } -            )); -        } else { -            pragmas.push("@jsxRuntime classic".into()); -            pragmas.push(format!( -                "@jsx {}", -                if let Some(pragma) = &options.pragma { -                    pragma -                } else { -                    create_element -                } -            )); -            pragmas.push(format!( -                "@jsxFrag {}", -                if let Some(pragma_frag) = &options.pragma_frag { -                    pragma_frag -                } else { -                    fragment -                } -            )); -        } - -        if !pragmas.is_empty() { -            program.comments.insert( -                0, -                swc_common::comments::Comment { -                    kind: swc_common::comments::CommentKind::Block, -                    text: pragmas.join(" ").into(), -                    span: swc_common::DUMMY_SP, -                }, -            ); -        } -    } - -    // Inject an import in the classic runtime for the pragma (and presumably, -    // fragment). -    if options.jsx_runtime == Some(JsxRuntime::Classic) { -        let pragma = if let Some(pragma) = &options.pragma { -            pragma -        } else { -            "React" -        }; -        let sym = pragma.split('.').next().expect("first item always exists"); - -        replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -            swc_ecma_ast::ModuleDecl::Import(swc_ecma_ast::ImportDecl { -                specifiers: vec![swc_ecma_ast::ImportSpecifier::Named( -                    swc_ecma_ast::ImportNamedSpecifier { -                        local: swc_ecma_ast::Ident { -                            sym: sym.into(), -                            optional: false, -                            span: swc_common::DUMMY_SP, -                        }, -                        imported: None, -                        span: swc_common::DUMMY_SP, -                        is_type_only: false, -                    }, -                )], -                src: Box::new(swc_ecma_ast::Str { -                    value: (if let Some(source) = &options.pragma_import_source { -                        source.clone() -                    } else { -                        "react".into() -                    }) -                    .into(), -                    span: swc_common::DUMMY_SP, -                    raw: None, -                }), -                type_only: false, -                asserts: None, -                span: swc_common::DUMMY_SP, -            }), -        )); -    } - -    // Find the `export default`, the JSX expression, and leave the rest as it -    // is. -    let mut input = program.module.body.split_off(0); -    input.reverse(); -    let mut layout = false; -    let mut layout_position = None; -    let content = true; - -    while let Some(module_item) = input.pop() { -        match module_item { -            // ```js -            // export default props => <>{props.children}</> -            // ``` -            // -            // Treat it as an inline layout declaration. -            // -            // In estree, the below two are the same node (`ExportDefault`). -            swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportDefaultDecl( -                decl, -            )) => { -                if layout { -                    return Err(create_double_layout_message( -                        bytepos_to_point(&decl.span.lo, location).as_ref(), -                        layout_position.as_ref(), -                    )); -                } - -                layout = true; -                layout_position = span_to_position(&decl.span, location); -                match decl.decl { -                    swc_ecma_ast::DefaultDecl::Class(cls) => { -                        replacements.push(create_layout_decl(swc_ecma_ast::Expr::Class(cls))) -                    } -                    swc_ecma_ast::DefaultDecl::Fn(func) => { -                        replacements.push(create_layout_decl(swc_ecma_ast::Expr::Fn(func))) -                    } -                    swc_ecma_ast::DefaultDecl::TsInterfaceDecl(_) => { -                        return Err( -                            prefix_error_with_point( -                                "Cannot use TypeScript interface declarations as default export in MDX files. The default export is reserved for a layout, which must be a component".into(), -                                bytepos_to_point(&decl.span.lo, location).as_ref() -                            ) -                        ); -                    } -                } -            } -            swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportDefaultExpr( -                expr, -            )) => { -                if layout { -                    return Err(create_double_layout_message( -                        bytepos_to_point(&expr.span.lo, location).as_ref(), -                        layout_position.as_ref(), -                    )); -                } - -                layout = true; -                layout_position = span_to_position(&expr.span, location); -                replacements.push(create_layout_decl(*expr.expr)); -            } -            // ```js -            // export {a, b as c} from 'd' -            // export {a, b as c} -            // ``` -            swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportNamed( -                mut named_export, -            )) => { -                // SWC is currently crashing when generating code, w/o source -                // map, if an actual location is set on this node. -                named_export.span = swc_common::DUMMY_SP; - -                let mut index = 0; -                let mut id = None; - -                while index < named_export.specifiers.len() { -                    let mut take = false; -                    // Note: the `swc_ecma_ast::ExportSpecifier::Default` -                    // branch of this looks interesting, but as far as I -                    // understand it *is not* valid ES. -                    // `export a from 'b'` is a syntax error, even in SWC. -                    if let swc_ecma_ast::ExportSpecifier::Named(named) = -                        &named_export.specifiers[index] -                    { -                        if let Some(swc_ecma_ast::ModuleExportName::Ident(ident)) = &named.exported -                        { -                            if ident.sym.as_ref() == "default" { -                                // For some reason the AST supports strings -                                // instead of identifiers. -                                // Looks like some TC39 proposal. Ignore for now -                                // and only do things if this is an ID. -                                if let swc_ecma_ast::ModuleExportName::Ident(ident) = &named.orig { -                                    if layout { -                                        return Err(create_double_layout_message( -                                            bytepos_to_point(&ident.span.lo, location).as_ref(), -                                            layout_position.as_ref(), -                                        )); -                                    } -                                    layout = true; -                                    layout_position = span_to_position(&ident.span, location); -                                    take = true; -                                    id = Some(ident.clone()); -                                } -                            } -                        } -                    } - -                    if take { -                        named_export.specifiers.remove(index); -                    } else { -                        index += 1; -                    } -                } - -                if let Some(id) = id { -                    let source = named_export.src.clone(); - -                    // If there was just a default export, we can drop the original node. -                    if !named_export.specifiers.is_empty() { -                        // Pass through. -                        replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -                            swc_ecma_ast::ModuleDecl::ExportNamed(named_export), -                        )); -                    } - -                    // It’s an `export {x} from 'y'`, so generate an import. -                    if let Some(source) = source { -                        replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -                            swc_ecma_ast::ModuleDecl::Import(swc_ecma_ast::ImportDecl { -                                specifiers: vec![swc_ecma_ast::ImportSpecifier::Named( -                                    swc_ecma_ast::ImportNamedSpecifier { -                                        local: swc_ecma_ast::Ident { -                                            sym: "MDXLayout".into(), -                                            optional: false, -                                            span: swc_common::DUMMY_SP, -                                        }, -                                        imported: Some(swc_ecma_ast::ModuleExportName::Ident(id)), -                                        span: swc_common::DUMMY_SP, -                                        is_type_only: false, -                                    }, -                                )], -                                src: source, -                                type_only: false, -                                asserts: None, -                                span: swc_common::DUMMY_SP, -                            }), -                        )) -                    } -                    // It’s an `export {x}`, so generate a variable declaration. -                    else { -                        replacements.push(create_layout_decl(swc_ecma_ast::Expr::Ident(id))); -                    } -                } else { -                    // Pass through. -                    replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -                        swc_ecma_ast::ModuleDecl::ExportNamed(named_export), -                    )); -                } -            } -            swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::Import(mut x)) => { -                // SWC is currently crashing when generating code, w/o source -                // map, if an actual location is set on this node. -                x.span = swc_common::DUMMY_SP; -                // Pass through. -                replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -                    swc_ecma_ast::ModuleDecl::Import(x), -                )); -            } -            swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportDecl(_)) -            | swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportAll(_)) -            | swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::TsImportEquals(_)) -            | swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::TsExportAssignment( -                _, -            )) -            | swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::TsNamespaceExport( -                _, -            )) => { -                // Pass through. -                replacements.push(module_item); -            } -            swc_ecma_ast::ModuleItem::Stmt(swc_ecma_ast::Stmt::Expr(expr_stmt)) => { -                match *expr_stmt.expr { -                    swc_ecma_ast::Expr::JSXElement(elem) => { -                        replacements.append(&mut create_mdx_content( -                            Some(swc_ecma_ast::Expr::JSXElement(elem)), -                            layout, -                        )); -                    } -                    swc_ecma_ast::Expr::JSXFragment(mut frag) => { -                        // Unwrap if possible. -                        if frag.children.len() == 1 { -                            let item = frag.children.pop().unwrap(); - -                            if let swc_ecma_ast::JSXElementChild::JSXElement(elem) = item { -                                replacements.append(&mut create_mdx_content( -                                    Some(swc_ecma_ast::Expr::JSXElement(elem)), -                                    layout, -                                )); -                                continue; -                            } - -                            frag.children.push(item) -                        } - -                        replacements.append(&mut create_mdx_content( -                            Some(swc_ecma_ast::Expr::JSXFragment(frag)), -                            layout, -                        )); -                    } -                    _ => { -                        // Pass through. -                        replacements.push(swc_ecma_ast::ModuleItem::Stmt( -                            swc_ecma_ast::Stmt::Expr(expr_stmt), -                        )); -                    } -                } -            } -            swc_ecma_ast::ModuleItem::Stmt(stmt) => { -                replacements.push(swc_ecma_ast::ModuleItem::Stmt(stmt)); -            } -        } -    } - -    // Generate an empty component. -    if !content { -        replacements.append(&mut create_mdx_content(None, layout)); -    } - -    // ```jsx -    // export default MDXContent -    // ``` -    replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl( -        swc_ecma_ast::ModuleDecl::ExportDefaultExpr(swc_ecma_ast::ExportDefaultExpr { -            expr: Box::new(swc_ecma_ast::Expr::Ident(swc_ecma_ast::Ident { -                sym: "MDXContent".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            })), -            span: swc_common::DUMMY_SP, -        }), -    )); - -    program.module.body = replacements; - -    Ok(()) -} - -/// Create a content component. -fn create_mdx_content( -    expr: Option<swc_ecma_ast::Expr>, -    has_internal_layout: bool, -) -> Vec<swc_ecma_ast::ModuleItem> { -    // ```jsx -    // <MDXLayout {...props}>xxx</MDXLayout> -    // ``` -    let mut result = swc_ecma_ast::Expr::JSXElement(Box::new(swc_ecma_ast::JSXElement { -        opening: swc_ecma_ast::JSXOpeningElement { -            name: swc_ecma_ast::JSXElementName::Ident(swc_ecma_ast::Ident { -                sym: "MDXLayout".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            }), -            attrs: vec![swc_ecma_ast::JSXAttrOrSpread::SpreadElement( -                swc_ecma_ast::SpreadElement { -                    dot3_token: swc_common::DUMMY_SP, -                    expr: Box::new(swc_ecma_ast::Expr::Ident(swc_ecma_ast::Ident { -                        sym: "props".into(), -                        optional: false, -                        span: swc_common::DUMMY_SP, -                    })), -                }, -            )], -            self_closing: false, -            type_args: None, -            span: swc_common::DUMMY_SP, -        }, -        closing: Some(swc_ecma_ast::JSXClosingElement { -            name: swc_ecma_ast::JSXElementName::Ident(swc_ecma_ast::Ident { -                sym: "MDXLayout".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            }), -            span: swc_common::DUMMY_SP, -        }), -        // ```jsx -        // <_createMdxContent {...props} /> -        // ``` -        children: vec![swc_ecma_ast::JSXElementChild::JSXElement(Box::new( -            swc_ecma_ast::JSXElement { -                opening: swc_ecma_ast::JSXOpeningElement { -                    name: swc_ecma_ast::JSXElementName::Ident(swc_ecma_ast::Ident { -                        sym: "_createMdxContent".into(), -                        optional: false, -                        span: swc_common::DUMMY_SP, -                    }), -                    attrs: vec![swc_ecma_ast::JSXAttrOrSpread::SpreadElement( -                        swc_ecma_ast::SpreadElement { -                            dot3_token: swc_common::DUMMY_SP, -                            expr: Box::new(swc_ecma_ast::Expr::Ident(swc_ecma_ast::Ident { -                                sym: "props".into(), -                                optional: false, -                                span: swc_common::DUMMY_SP, -                            })), -                        }, -                    )], -                    self_closing: true, -                    type_args: None, -                    span: swc_common::DUMMY_SP, -                }, -                closing: None, -                children: vec![], -                span: swc_common::DUMMY_SP, -            }, -        ))], -        span: swc_common::DUMMY_SP, -    })); - -    if !has_internal_layout { -        // ```jsx -        // MDXLayout ? <MDXLayout>xxx</MDXLayout> : _createMdxContent(props) -        // ``` -        result = swc_ecma_ast::Expr::Cond(swc_ecma_ast::CondExpr { -            test: Box::new(swc_ecma_ast::Expr::Ident(swc_ecma_ast::Ident { -                sym: "MDXLayout".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            })), -            cons: Box::new(result), -            alt: Box::new(swc_ecma_ast::Expr::Call(swc_ecma_ast::CallExpr { -                callee: swc_ecma_ast::Callee::Expr(Box::new(swc_ecma_ast::Expr::Ident( -                    swc_ecma_ast::Ident { -                        sym: "_createMdxContent".into(), -                        optional: false, -                        span: swc_common::DUMMY_SP, -                    }, -                ))), -                args: vec![swc_ecma_ast::ExprOrSpread { -                    spread: None, -                    expr: Box::new(swc_ecma_ast::Expr::Ident(swc_ecma_ast::Ident { -                        sym: "props".into(), -                        optional: false, -                        span: swc_common::DUMMY_SP, -                    })), -                }], -                type_args: None, -                span: swc_common::DUMMY_SP, -            })), -            span: swc_common::DUMMY_SP, -        }); -    } - -    // ```jsx -    // function _createMdxContent(props) { -    //   return xxx -    // } -    // ``` -    let create_mdx_content = swc_ecma_ast::ModuleItem::Stmt(swc_ecma_ast::Stmt::Decl( -        swc_ecma_ast::Decl::Fn(swc_ecma_ast::FnDecl { -            ident: swc_ecma_ast::Ident { -                sym: "_createMdxContent".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            }, -            declare: false, -            function: Box::new(swc_ecma_ast::Function { -                params: vec![swc_ecma_ast::Param { -                    pat: swc_ecma_ast::Pat::Ident(swc_ecma_ast::BindingIdent { -                        id: swc_ecma_ast::Ident { -                            sym: "props".into(), -                            optional: false, -                            span: swc_common::DUMMY_SP, -                        }, -                        type_ann: None, -                    }), -                    decorators: vec![], -                    span: swc_common::DUMMY_SP, -                }], -                decorators: vec![], -                body: Some(swc_ecma_ast::BlockStmt { -                    stmts: vec![swc_ecma_ast::Stmt::Return(swc_ecma_ast::ReturnStmt { -                        arg: Some(Box::new(expr.unwrap_or({ -                            swc_ecma_ast::Expr::Lit(swc_ecma_ast::Lit::Null(swc_ecma_ast::Null { -                                span: swc_common::DUMMY_SP, -                            })) -                        }))), -                        span: swc_common::DUMMY_SP, -                    })], -                    span: swc_common::DUMMY_SP, -                }), -                is_generator: false, -                is_async: false, -                type_params: None, -                return_type: None, -                span: swc_common::DUMMY_SP, -            }), -        }), -    )); - -    // ```jsx -    // function MDXContent(props = {}) { -    //   return <MDXLayout>xxx</MDXLayout> -    // } -    // ``` -    let mdx_content = swc_ecma_ast::ModuleItem::Stmt(swc_ecma_ast::Stmt::Decl( -        swc_ecma_ast::Decl::Fn(swc_ecma_ast::FnDecl { -            ident: swc_ecma_ast::Ident { -                sym: "MDXContent".into(), -                optional: false, -                span: swc_common::DUMMY_SP, -            }, -            declare: false, -            function: Box::new(swc_ecma_ast::Function { -                params: vec![swc_ecma_ast::Param { -                    pat: swc_ecma_ast::Pat::Assign(swc_ecma_ast::AssignPat { -                        left: Box::new(swc_ecma_ast::Pat::Ident(swc_ecma_ast::BindingIdent { -                            id: swc_ecma_ast::Ident { -                                sym: "props".into(), -                                optional: false, -                                span: swc_common::DUMMY_SP, -                            }, -                            type_ann: None, -                        })), -                        right: Box::new(swc_ecma_ast::Expr::Object(swc_ecma_ast::ObjectLit { -                            props: vec![], -                            span: swc_common::DUMMY_SP, -                        })), -                        span: swc_common::DUMMY_SP, -                        type_ann: None, -                    }), -                    decorators: vec![], -                    span: swc_common::DUMMY_SP, -                }], -                decorators: vec![], -                body: Some(swc_ecma_ast::BlockStmt { -                    stmts: vec![swc_ecma_ast::Stmt::Return(swc_ecma_ast::ReturnStmt { -                        arg: Some(Box::new(result)), -                        span: swc_common::DUMMY_SP, -                    })], -                    span: swc_common::DUMMY_SP, -                }), -                is_generator: false, -                is_async: false, -                type_params: None, -                return_type: None, -                span: swc_common::DUMMY_SP, -            }), -        }), -    )); - -    vec![create_mdx_content, mdx_content] -} - -/// Create a layout, inside the document. -fn create_layout_decl(expr: swc_ecma_ast::Expr) -> swc_ecma_ast::ModuleItem { -    // ```jsx -    // const MDXLayout = xxx -    // ``` -    swc_ecma_ast::ModuleItem::Stmt(swc_ecma_ast::Stmt::Decl(swc_ecma_ast::Decl::Var(Box::new( -        swc_ecma_ast::VarDecl { -            kind: swc_ecma_ast::VarDeclKind::Const, -            declare: false, -            decls: vec![swc_ecma_ast::VarDeclarator { -                name: swc_ecma_ast::Pat::Ident(swc_ecma_ast::BindingIdent { -                    id: swc_ecma_ast::Ident { -                        sym: "MDXLayout".into(), -                        optional: false, -                        span: swc_common::DUMMY_SP, -                    }, -                    type_ann: None, -                }), -                init: Some(Box::new(expr)), -                span: swc_common::DUMMY_SP, -                definite: false, -            }], -            span: swc_common::DUMMY_SP, -        }, -    )))) -} - -/// Create an error message about multiple layouts. -fn create_double_layout_message(at: Option<&Point>, previous: Option<&Position>) -> String { -    prefix_error_with_point( -        format!( -            "Cannot specify multiple layouts{}", -            if let Some(previous) = previous { -                format!(" (previous: {:?})", previous) -            } else { -                "".into() -            } -        ), -        at, -    ) -} | 
