mirror of
https://github.com/hanzoai/babel.git
synced 2026-09-24 16:56:45 +00:00
187 lines
5.8 KiB
TypeScript
187 lines
5.8 KiB
TypeScript
import { expect, it, describe } from "tstyche";
|
|
import type { NodePath, Visitor, TraverseOptions } from "../src/index.ts";
|
|
import { default as traverse, visitors } from "../src/index.ts";
|
|
import type * as t from "@babel/types";
|
|
|
|
describe("traverse", () => {
|
|
describe("NodePath#get", () => {
|
|
it("TryStatement.handler.body", () => {
|
|
const path = {} as NodePath<t.TryStatement>;
|
|
const body = path.get("handler.body");
|
|
expect(body).type.toBe<NodePath<t.BlockStatement | null>>();
|
|
});
|
|
|
|
it("ExportDeclaration.declaration", () => {
|
|
const path = {} as NodePath<t.ExportDeclaration>;
|
|
const declaration = path.get("declaration");
|
|
expect(declaration).type.toBe<
|
|
NodePath<
|
|
| t.VariableDeclaration
|
|
| t.FunctionDeclaration
|
|
| t.ClassDeclaration
|
|
| t.TSDeclareFunction
|
|
| t.TSEnumDeclaration
|
|
| t.TSImportEqualsDeclaration
|
|
| t.TSInterfaceDeclaration
|
|
| t.TSModuleDeclaration
|
|
| t.TSTypeAliasDeclaration
|
|
| t.EnumDeclaration
|
|
| t.InterfaceDeclaration
|
|
| t.OpaqueType
|
|
| t.TypeAlias
|
|
| t.Expression
|
|
| null
|
|
>
|
|
>();
|
|
});
|
|
|
|
it("TaggedTemplateExpression.tag.object", () => {
|
|
const path = {} as NodePath<t.TaggedTemplateExpression>;
|
|
const object = path.get("tag.object");
|
|
expect(object).type.toBe<NodePath<t.Expression | t.Super | null>>();
|
|
});
|
|
|
|
it("AssignmentExpression.left.object", () => {
|
|
const path = {} as NodePath<t.AssignmentExpression>;
|
|
const object = path.get("left.object");
|
|
expect(object).type.toBe<NodePath<t.Expression | t.Super | null>>();
|
|
});
|
|
|
|
it("ClassDeclaration.body.body", () => {
|
|
const path = {} as NodePath<t.ClassDeclaration>;
|
|
const body = path.get("body.body");
|
|
expect(body).type.toBe<
|
|
NodePath<
|
|
| t.ClassMethod
|
|
| t.ClassPrivateMethod
|
|
| t.ClassProperty
|
|
| t.ClassPrivateProperty
|
|
| t.ClassAccessorProperty
|
|
| t.TSDeclareMethod
|
|
| t.TSIndexSignature
|
|
| t.StaticBlock
|
|
>[]
|
|
>();
|
|
});
|
|
|
|
it("should support template literal expressions - number", () => {
|
|
const path = {} as NodePath<t.BlockStatement>;
|
|
const index: number = 0;
|
|
const statement = path.get(`body.${index}`);
|
|
const statement2 = path.get(`body.0`);
|
|
expect(statement).type.toBe(statement2);
|
|
});
|
|
|
|
it("should support template literal expressions - string", () => {
|
|
const path = {} as NodePath<t.ClassDeclaration>;
|
|
const bodyKey: string = "body";
|
|
const body = path.get(`body.${bodyKey}`);
|
|
expect(body).type.toBe<NodePath<t.Node | null>>();
|
|
});
|
|
|
|
it("should support const string type", () => {
|
|
const path = {} as NodePath<t.ClassDeclaration>;
|
|
const key = "body" as const;
|
|
const statement = path.get(`body.${key}`);
|
|
const statement2 = path.get(`body.body`);
|
|
expect(statement).type.toBe(statement2);
|
|
});
|
|
|
|
it("falsy path", () => {
|
|
const path = {} as NodePath<t.ClassDeclaration>;
|
|
const body = path.get(`body.x`);
|
|
expect(body).type.toBe<NodePath<null>>();
|
|
});
|
|
});
|
|
|
|
describe("Visitor", () => {
|
|
it("top-level enter and exit", () => {
|
|
traverse({} as t.Node, {
|
|
enter(path) {
|
|
expect(path).type.toBe<NodePath<t.Node>>();
|
|
expect(path.type).type.toBe<t.Node["type"]>();
|
|
},
|
|
exit(path) {
|
|
expect(path).type.toBe<NodePath<t.Node>>();
|
|
expect(path.type).type.toBe<t.Node["type"]>();
|
|
},
|
|
noScope: true,
|
|
});
|
|
});
|
|
|
|
describe("Union types", () => {
|
|
it("traverse", () => {
|
|
traverse({} as t.Node, {
|
|
"ImportDeclaration|ExportDeclaration"(path) {
|
|
expect(path).type.toBe<
|
|
NodePath<t.ImportDeclaration | t.ExportDeclaration>
|
|
>();
|
|
},
|
|
noScope: true,
|
|
});
|
|
traverse({} as t.Node, {} as Visitor);
|
|
});
|
|
|
|
it("visitors.explode", () => {
|
|
visitors.explode({
|
|
"ImportDeclaration|ExportDeclaration"(path) {
|
|
expect(path).type.toBe<
|
|
NodePath<t.ImportDeclaration | t.ExportDeclaration>
|
|
>();
|
|
},
|
|
noScope: true,
|
|
});
|
|
visitors.explode({
|
|
"ImportDeclaration|ExportDeclaration"(path) {
|
|
expect(path).type.toBe<NodePath<t.Node>>();
|
|
},
|
|
noScope: true,
|
|
} as TraverseOptions & Visitor);
|
|
});
|
|
|
|
it("NodePath#traverse", () => {
|
|
(({}) as NodePath<t.Node>).traverse({
|
|
"ImportDeclaration|ExportDeclaration"(path) {
|
|
expect(path).type.toBe<
|
|
NodePath<t.ImportDeclaration | t.ExportDeclaration>
|
|
>();
|
|
},
|
|
noScope: true,
|
|
});
|
|
(({}) as NodePath<t.Node>).traverse({
|
|
"ImportDeclaration|ExportDeclaration"(path) {
|
|
expect(path).type.toBe<NodePath<t.Node>>();
|
|
},
|
|
noScope: true,
|
|
} as TraverseOptions & Visitor);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("NodePath#is*", () => {
|
|
it("allows null", () => {
|
|
const path = {} as NodePath<t.VariableDeclarator>;
|
|
const init = path.get("init");
|
|
expect(init).type.toBe<NodePath<t.Expression | null>>();
|
|
if (init.isIdentifier()) {
|
|
expect(init).type.toBe<NodePath<t.Identifier>>();
|
|
}
|
|
});
|
|
|
|
it("virtual types", () => {
|
|
const path = {} as NodePath<t.Node>;
|
|
if (path.isBindingIdentifier()) {
|
|
expect(path).type.toBe<NodePath<t.Identifier>>();
|
|
}
|
|
});
|
|
});
|
|
|
|
it.todo("NodePath#assert*", () => {
|
|
const path = {} as NodePath<t.Expression>;
|
|
// @ts-expect-error Assertions require every name in the call target to be declared with an explicit type annotation.
|
|
path.assertIdentifier();
|
|
|
|
expect(path).type.toBe<NodePath<t.Identifier>>();
|
|
});
|
|
});
|