aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/test_utils/swc.rs29
-rw-r--r--tests/test_utils/to_document.rs60
-rw-r--r--tests/test_utils/to_swc.rs2
-rw-r--r--tests/xxx_document.rs30
-rw-r--r--tests/xxx_swc.rs312
5 files changed, 234 insertions, 199 deletions
diff --git a/tests/test_utils/swc.rs b/tests/test_utils/swc.rs
index c0fffa0..80376b8 100644
--- a/tests/test_utils/swc.rs
+++ b/tests/test_utils/swc.rs
@@ -3,8 +3,11 @@ extern crate swc_common;
extern crate swc_ecma_ast;
extern crate swc_ecma_parser;
use micromark::{MdxExpressionKind, MdxSignal};
-use swc_common::{source_map::Pos, BytePos, FileName, SourceFile, Spanned};
+use swc_common::{
+ source_map::Pos, sync::Lrc, BytePos, FileName, FilePathMapping, SourceFile, SourceMap, Spanned,
+};
use swc_ecma_ast::{EsVersion, Expr, Module};
+use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
use swc_ecma_parser::{
error::Error as SwcError, parse_file_as_expr, parse_file_as_module, EsConfig, Syntax,
};
@@ -164,6 +167,30 @@ pub fn parse_expression_to_tree(
}
}
+/// Serialize an SWC module.
+/// To do: support comments.
+#[allow(dead_code)]
+pub fn serialize(module: &Module) -> String {
+ let mut buf = vec![];
+ let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+ // let comm = &program.comments as &dyn swc_common::comments::Comments;
+ {
+ let mut emitter = Emitter {
+ cfg: swc_ecma_codegen::Config {
+ ..Default::default()
+ },
+ cm: cm.clone(),
+ // To do: figure out how to pass them.
+ comments: None,
+ wr: JsWriter::new(cm, "\n", &mut buf, None),
+ };
+
+ emitter.emit_module(module).unwrap();
+ }
+
+ String::from_utf8_lossy(&buf).to_string()
+}
+
/// Check that the resulting AST of ESM is OK.
///
/// This checks that only module declarations (import/exports) are used, not
diff --git a/tests/test_utils/to_document.rs b/tests/test_utils/to_document.rs
index b44d029..96e9d7f 100644
--- a/tests/test_utils/to_document.rs
+++ b/tests/test_utils/to_document.rs
@@ -186,8 +186,10 @@ pub fn to_document(mut program: Program, options: &Options) -> Result<Program, S
swc_ecma_ast::DefaultDecl::Fn(func) => swc_ecma_ast::Expr::Fn(func),
swc_ecma_ast::DefaultDecl::TsInterfaceDecl(_) => {
// To do: improved error? Not sure what a real example of this is?
- unreachable!("Cannot use TypeScript interface declarations as default export in MDX")
- },
+ unreachable!(
+ "Cannot use TypeScript interface declarations as default export in MDX"
+ )
+ }
}));
}
swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportDefaultExpr(
@@ -206,7 +208,9 @@ pub fn to_document(mut program: Program, options: &Options) -> Result<Program, S
// 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_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;
@@ -220,8 +224,11 @@ pub fn to_document(mut program: Program, options: &Options) -> Result<Program, S
// 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 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.
@@ -254,29 +261,33 @@ pub fn to_document(mut program: Program, options: &Options) -> Result<Program, S
// 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)));
+ 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,
+ 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,
},
- 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,
- })))
+ )],
+ src: source,
+ type_only: false,
+ asserts: None,
+ span: swc_common::DUMMY_SP,
+ }),
+ ))
}
// It’s an `export {x}`, so generate a variable declaration.
else {
@@ -284,13 +295,14 @@ pub fn to_document(mut program: Program, options: &Options) -> Result<Program, S
}
} else {
// Pass through.
- replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportNamed(named_export)));
+ replacements.push(swc_ecma_ast::ModuleItem::ModuleDecl(
+ swc_ecma_ast::ModuleDecl::ExportNamed(named_export),
+ ));
}
}
swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::Import(_))
| swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportDecl(_))
| swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::ExportAll(_))
- // To do: handle TS things?
| swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::TsImportEquals(_))
| swc_ecma_ast::ModuleItem::ModuleDecl(swc_ecma_ast::ModuleDecl::TsExportAssignment(
_,
diff --git a/tests/test_utils/to_swc.rs b/tests/test_utils/to_swc.rs
index 59d60ee..6ed48b6 100644
--- a/tests/test_utils/to_swc.rs
+++ b/tests/test_utils/to_swc.rs
@@ -379,8 +379,6 @@ fn transform_root(
}
}
- // To do: remove whitespace?
- // To do: return a single child if there is one?
Ok(Some(swc_ecma_ast::JSXElementChild::JSXFragment(
create_fragment(nodes, node),
)))
diff --git a/tests/xxx_document.rs b/tests/xxx_document.rs
index 2d89f16..dcbb56b 100644
--- a/tests/xxx_document.rs
+++ b/tests/xxx_document.rs
@@ -5,37 +5,13 @@ extern crate swc_ecma_codegen;
mod test_utils;
use micromark::{micromark_to_mdast, Constructs, Options};
use pretty_assertions::assert_eq;
-use swc_common::{sync::Lrc, FilePathMapping, SourceMap};
-use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
use test_utils::{
- swc::{parse_esm, parse_expression},
+ swc::{parse_esm, parse_expression, serialize},
to_document::{to_document, Options as DocumentOptions},
to_hast::to_hast,
- to_swc::{to_swc, Program},
+ to_swc::to_swc,
};
-// To do: share with `xxx_swc`.
-fn serialize(program: &Program) -> String {
- let mut buf = vec![];
- let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
- // let comm = &program.comments as &dyn swc_common::comments::Comments;
- {
- let mut emitter = Emitter {
- cfg: swc_ecma_codegen::Config {
- ..Default::default()
- },
- cm: cm.clone(),
- // To do: figure out how to pass them.
- comments: None,
- wr: JsWriter::new(cm, "\n", &mut buf, None),
- };
-
- emitter.emit_module(&program.module).unwrap();
- }
-
- String::from_utf8_lossy(&buf).to_string()
-}
-
fn from_markdown(value: &str) -> Result<String, String> {
let mdast = micromark_to_mdast(
value,
@@ -48,7 +24,7 @@ fn from_markdown(value: &str) -> Result<String, String> {
)?;
let hast = to_hast(&mdast);
let program = to_document(to_swc(&hast)?, &DocumentOptions::default())?;
- let value = serialize(&program);
+ let value = serialize(&program.module);
Ok(value)
}
diff --git a/tests/xxx_swc.rs b/tests/xxx_swc.rs
index 5504432..26814cf 100644
--- a/tests/xxx_swc.rs
+++ b/tests/xxx_swc.rs
@@ -4,35 +4,12 @@ extern crate swc_ecma_ast;
extern crate swc_ecma_codegen;
mod test_utils;
use pretty_assertions::assert_eq;
-use swc_common::{sync::Lrc, FilePathMapping, SourceMap};
-use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
use test_utils::{
hast,
+ swc::serialize,
to_swc::{to_swc, Program},
};
-// To do: share with `xxx_document`.
-fn serialize(program: &Program) -> String {
- let mut buf = vec![];
- let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
- // let comm = &program.comments as &dyn swc_common::comments::Comments;
- {
- let mut emitter = Emitter {
- cfg: swc_ecma_codegen::Config {
- ..Default::default()
- },
- cm: cm.clone(),
- // To do: figure out how to pass them.
- comments: None,
- wr: JsWriter::new(cm, "\n", &mut buf, None),
- };
-
- emitter.emit_module(&program.module).unwrap();
- }
-
- String::from_utf8_lossy(&buf).to_string()
-}
-
#[test]
fn swc() -> Result<(), String> {
let comment_ast = to_swc(&hast::Node::Comment(hast::Comment {
@@ -83,7 +60,7 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&comment_ast),
+ serialize(&comment_ast.module),
// To do: comment should be in this.
"<>{}</>;\n",
"should support a `Comment` (serialize)",
@@ -155,98 +132,119 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&element_ast),
+ serialize(&element_ast.module),
"<a className=\"b\"/>;\n",
"should support an `Element` (serialize)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![],
- children: vec![hast::Node::Text(hast::Text {
- value: "a".into(),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![],
+ children: vec![hast::Node::Text(hast::Text {
+ value: "a".into(),
+ position: None,
+ })],
position: None,
- })],
- position: None,
- }))?),
+ }))?
+ .module
+ ),
"<a >{\"a\"}</a>;\n",
"should support an `Element` w/ children",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![("b".into(), hast::PropertyValue::String("c".into()),)],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![("b".into(), hast::PropertyValue::String("c".into()),)],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b=\"c\"/>;\n",
"should support an `Element` w/ a string attribute",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![("b".into(), hast::PropertyValue::Boolean(true),)],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![("b".into(), hast::PropertyValue::Boolean(true),)],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b/>;\n",
"should support an `Element` w/ a boolean (true) attribute",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![("b".into(), hast::PropertyValue::Boolean(false),)],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![("b".into(), hast::PropertyValue::Boolean(false),)],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a />;\n",
"should support an `Element` w/ a boolean (false) attribute",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![(
- "b".into(),
- hast::PropertyValue::CommaSeparated(vec!["c".into(), "d".into()]),
- )],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![(
+ "b".into(),
+ hast::PropertyValue::CommaSeparated(vec!["c".into(), "d".into()]),
+ )],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b=\"c, d\"/>;\n",
"should support an `Element` w/ a comma-separated attribute",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![
- ("data123".into(), hast::PropertyValue::Boolean(true),),
- ("dataFoo".into(), hast::PropertyValue::Boolean(true),),
- ("dataBAR".into(), hast::PropertyValue::Boolean(true),)
- ],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![
+ ("data123".into(), hast::PropertyValue::Boolean(true),),
+ ("dataFoo".into(), hast::PropertyValue::Boolean(true),),
+ ("dataBAR".into(), hast::PropertyValue::Boolean(true),)
+ ],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a data-123 data-foo data-b-a-r/>;\n",
"should support an `Element` w/ data attributes",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::Element(hast::Element {
- tag_name: "a".into(),
- properties: vec![
- ("role".into(), hast::PropertyValue::Boolean(true),),
- ("ariaValueNow".into(), hast::PropertyValue::Boolean(true),),
- ("ariaDescribedBy".into(), hast::PropertyValue::Boolean(true),)
- ],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::Element(hast::Element {
+ tag_name: "a".into(),
+ properties: vec![
+ ("role".into(), hast::PropertyValue::Boolean(true),),
+ ("ariaValueNow".into(), hast::PropertyValue::Boolean(true),),
+ ("ariaDescribedBy".into(), hast::PropertyValue::Boolean(true),)
+ ],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a role aria-valuenow aria-describedby/>;\n",
"should support an `Element` w/ aria attributes",
);
@@ -288,107 +286,131 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&mdx_element_ast),
+ serialize(&mdx_element_ast.module),
"<></>;\n",
"should support an `MdxElement` (fragment, serialize)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a />;\n",
"should support an `MdxElement` (element, no children)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a:b".into()),
- attributes: vec![],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a:b".into()),
+ attributes: vec![],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a:b />;\n",
"should support an `MdxElement` (element, namespace id)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a.b.c".into()),
- attributes: vec![],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a.b.c".into()),
+ attributes: vec![],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a.b.c />;\n",
"should support an `MdxElement` (element, member expression)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![],
- children: vec![hast::Node::Text(hast::Text {
- value: "b".into(),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![],
+ children: vec![hast::Node::Text(hast::Text {
+ value: "b".into(),
+ position: None,
+ })],
position: None,
- })],
- position: None,
- }))?),
+ }))?
+ .module
+ ),
"<a >{\"b\"}</a>;\n",
"should support an `MdxElement` (element, children)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
- name: "b".into(),
- value: None
- })],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
+ name: "b".into(),
+ value: None
+ })],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b/>;\n",
"should support an `MdxElement` (element, boolean attribute)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
- name: "b".into(),
- value: Some(hast::AttributeValue::Literal("c".into()))
- })],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
+ name: "b".into(),
+ value: Some(hast::AttributeValue::Literal("c".into()))
+ })],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b=\"c\"/>;\n",
"should support an `MdxElement` (element, attribute w/ literal value)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
- name: "b".into(),
- value: Some(hast::AttributeValue::Expression("c".into()))
- })],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![hast::AttributeContent::Property(hast::MdxJsxAttribute {
+ name: "b".into(),
+ value: Some(hast::AttributeValue::Expression("c".into()))
+ })],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a b={c}/>;\n",
"should support an `MdxElement` (element, attribute w/ expression value)",
);
assert_eq!(
- serialize(&to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
- name: Some("a".into()),
- attributes: vec![hast::AttributeContent::Expression("...c".into())],
- children: vec![],
- position: None,
- }))?),
+ serialize(
+ &to_swc(&hast::Node::MdxJsxElement(hast::MdxJsxElement {
+ name: Some("a".into()),
+ attributes: vec![hast::AttributeContent::Expression("...c".into())],
+ children: vec![],
+ position: None,
+ }))?
+ .module
+ ),
"<a {...c}/>;\n",
"should support an `MdxElement` (element, expression attribute)",
);
@@ -444,7 +466,7 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&mdx_expression_ast),
+ serialize(&mdx_expression_ast.module),
"<>{a}</>;\n",
"should support an `MdxExpression` (serialize)",
);
@@ -509,7 +531,7 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&mdxjs_esm_ast),
+ serialize(&mdxjs_esm_ast.module),
"import a from 'b';\n",
"should support an `MdxjsEsm` (serialize)",
);
@@ -565,7 +587,7 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&root_ast),
+ serialize(&root_ast.module),
"<>{\"a\"}</>;\n",
"should support a `Root` (serialize)",
);
@@ -618,7 +640,7 @@ fn swc() -> Result<(), String> {
);
assert_eq!(
- serialize(&text_ast),
+ serialize(&text_ast.module),
"<>{\"a\"}</>;\n",
"should support a `Text` (serialize)",
);