recast/test/jsx.ts
2024-06-18 18:57:29 +02:00

127 lines
3.5 KiB
TypeScript

"use strict";
import { parse } from "../lib/parser";
import { Printer } from "../lib/printer";
import assert from "assert";
import * as types from "ast-types";
const nodeMajorVersion = parseInt(process.versions.node, 10);
for (const { title, parser } of [
{ title: "Babel JSX Compatibility", parser: require("../parsers/babel") },
{ title: "Esprima JSX Compatibility", parser: require("../parsers/esprima") },
]) {
(nodeMajorVersion >= 6 ? describe : xdescribe)(title, function () {
const printer = new Printer({ tabWidth: 2 });
const parseOptions = { parser };
function check(source: string) {
const ast1 = parse(source, parseOptions);
const ast2 = parse(printer.printGenerically(ast1).code, parseOptions);
types.astNodesAreEquivalent.assert(ast1, ast2);
}
it("should parse and print attribute comments", function () {
check("<b /* comment */ />");
check("<b /* multi\nline\ncomment */ />");
});
it("should parse and print child comments", function () {
check("<b>{/* comment */}</b>");
check("<b>{/* multi\nline\ncomment */}</b>");
});
it("should parse and print literal attributes", function () {
check('<b className="hello" />');
});
it("should parse and print expression attributes", function () {
check("<b className={classes} />");
});
it("should parse and print chidren", function () {
check("<label><input /></label>");
});
it("should parse and print literal chidren", function () {
check("<b>hello world</b>");
});
it("should parse and print expression children", function () {
check("<b>{this.props.user.name}</b>");
});
it("should parse and print namespaced elements", function () {
check("<Foo.Bar />");
});
// Esprima does not parse JSX fragments: https://github.com/jquery/esprima/issues/2020
(/esprima/i.test(title)
? xit
: it)("should parse and print fragments", function () {
check(["<>", " <td>Hello</td>", " <td>world!</td>", "</>"].join("\n"));
});
});
}
it("should not remove trailing whitespaces", function () {
const printer = new Printer({ tabWidth: 2 });
const source =
"function App() {\n" +
' const name = "world";\n' +
"\n" +
" return (\n" +
' <div className="app">\n' +
" hello {name}\n" +
" </div>\n" +
" );\n" +
"}";
const ast = parse(source);
ast.program.body[0].body.body[1].argument.openingElement.attributes[0].name.name =
"abc";
const code = printer.printGenerically(ast).code;
assert.equal(
code,
"function App() {\n" +
' const name = "world";\n' +
"\n" +
" return (\n" +
' <div abc="app">hello {name}\n' +
" </div>\n" +
" );\n" +
"}",
);
});
it("should not double parentheses in Babel", function () {
const printer = new Printer({ tabWidth: 2 });
const source =
"function App() {\n" +
' const name = "world";\n' +
"\n" +
" return (\n" +
' <div className="app">\n' +
" hello {name}\n" +
" </div>\n" +
" );\n" +
"}";
const ast = parse(source, { parser: require("../parsers/babel") });
ast.program.body[0].body.body[1].argument.openingElement.attributes[0].name.name =
"abc";
const code = printer.printGenerically(ast).code;
assert.equal(
code,
"function App() {\n" +
' const name = "world";\n' +
"\n" +
" return (\n" +
' <div abc="app">hello {name}\n' +
" </div>\n" +
" );\n" +
"}",
);
});