854 lines
23 KiB
JavaScript
854 lines
23 KiB
JavaScript
import babel from "../lib/index.js";
|
|
import sourceMap from "source-map";
|
|
import path from "path";
|
|
import generator from "@babel/generator";
|
|
import { fileURLToPath } from "url";
|
|
|
|
import _Plugin from "../lib/config/plugin.js";
|
|
const Plugin = _Plugin.default;
|
|
|
|
import presetEnv from "../../babel-preset-env/lib/index.js";
|
|
import pluginSyntaxFlow from "../../babel-plugin-syntax-flow/lib/index.js";
|
|
import pluginFlowStripTypes from "../../babel-plugin-transform-flow-strip-types/lib/index.js";
|
|
|
|
const cwd = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
function assertIgnored(result) {
|
|
expect(result).toBeNull();
|
|
}
|
|
|
|
function assertNotIgnored(result) {
|
|
expect(result).not.toBeNull();
|
|
}
|
|
|
|
function parse(code, opts) {
|
|
return babel.parse(code, { cwd, configFile: false, ...opts });
|
|
}
|
|
|
|
function transform(code, opts) {
|
|
return babel.transform(code, { cwd, configFile: false, ...opts });
|
|
}
|
|
|
|
function transformFile(filename, opts, cb) {
|
|
return babel.transformFile(filename, { cwd, configFile: false, ...opts }, cb);
|
|
}
|
|
function transformFileSync(filename, opts) {
|
|
return babel.transformFileSync(filename, { cwd, configFile: false, ...opts });
|
|
}
|
|
function transformFileAsync(filename, opts) {
|
|
return babel.transformFileAsync(filename, {
|
|
cwd,
|
|
configFile: false,
|
|
...opts,
|
|
});
|
|
}
|
|
|
|
function transformAsync(code, opts) {
|
|
return babel.transformAsync(code, { cwd, configFile: false, ...opts });
|
|
}
|
|
|
|
function transformFromAst(ast, code, opts) {
|
|
return babel.transformFromAst(ast, code, { cwd, configFile: false, ...opts });
|
|
}
|
|
|
|
describe("parser and generator options", function () {
|
|
const recast = {
|
|
parse: function (code, opts) {
|
|
return opts.parser.parse(code);
|
|
},
|
|
print: function (ast) {
|
|
return generator(ast);
|
|
},
|
|
};
|
|
|
|
function newTransform(string) {
|
|
return transform(string, {
|
|
ast: true,
|
|
parserOpts: {
|
|
parser: recast.parse,
|
|
plugins: ["flow"],
|
|
allowImportExportEverywhere: true,
|
|
},
|
|
generatorOpts: {
|
|
generator: recast.print,
|
|
},
|
|
});
|
|
}
|
|
|
|
it("options", function () {
|
|
const string = "original;";
|
|
expect(newTransform(string).ast).toEqual(
|
|
transform(string, { ast: true }).ast,
|
|
);
|
|
expect(newTransform(string).code).toBe(string);
|
|
});
|
|
|
|
it("experimental syntax", function () {
|
|
const experimental = "var a: number = 1;";
|
|
|
|
expect(newTransform(experimental).ast).toEqual(
|
|
transform(experimental, {
|
|
ast: true,
|
|
parserOpts: {
|
|
plugins: ["flow"],
|
|
},
|
|
}).ast,
|
|
);
|
|
expect(newTransform(experimental).code).toBe(experimental);
|
|
|
|
function newTransformWithPlugins(string) {
|
|
return transform(string, {
|
|
ast: true,
|
|
plugins: [cwd + "/../../babel-plugin-syntax-flow"],
|
|
parserOpts: {
|
|
parser: recast.parse,
|
|
},
|
|
generatorOpts: {
|
|
generator: recast.print,
|
|
},
|
|
});
|
|
}
|
|
|
|
expect(newTransformWithPlugins(experimental).ast).toEqual(
|
|
transform(experimental, {
|
|
ast: true,
|
|
parserOpts: {
|
|
plugins: ["flow"],
|
|
},
|
|
}).ast,
|
|
);
|
|
expect(newTransformWithPlugins(experimental).code).toBe(experimental);
|
|
});
|
|
|
|
it("other options", function () {
|
|
const experimental = "if (true) {\n import a from 'a';\n}";
|
|
|
|
expect(newTransform(experimental).ast).not.toBe(
|
|
transform(experimental, {
|
|
ast: true,
|
|
parserOpts: {
|
|
allowImportExportEverywhere: true,
|
|
},
|
|
}).ast,
|
|
);
|
|
expect(newTransform(experimental).code).toBe(experimental);
|
|
});
|
|
});
|
|
|
|
describe("api", function () {
|
|
it("exposes the resolvePlugin method", function () {
|
|
expect(() => babel.resolvePlugin("nonexistent-plugin")).toThrow(
|
|
/Cannot (?:find|resolve) module 'babel-plugin-nonexistent-plugin'/,
|
|
);
|
|
});
|
|
|
|
it("exposes the resolvePreset method", function () {
|
|
expect(() => babel.resolvePreset("nonexistent-preset")).toThrow(
|
|
/Cannot (?:find|resolve) module 'babel-preset-nonexistent-preset'/,
|
|
);
|
|
});
|
|
|
|
it("exposes types", function () {
|
|
expect(babel.types).toBeDefined();
|
|
});
|
|
|
|
it("exposes the parser's token types", function () {
|
|
expect(babel.tokTypes).toBeDefined();
|
|
});
|
|
|
|
it("transformFile", function () {
|
|
const options = {
|
|
babelrc: false,
|
|
};
|
|
Object.freeze(options);
|
|
return new Promise((resolve, reject) => {
|
|
transformFile(
|
|
cwd + "/fixtures/api/file.js",
|
|
options,
|
|
function (err, res) {
|
|
if (err) return reject(err);
|
|
expect(res.code).toBe("foo();");
|
|
// keep user options untouched
|
|
expect(options).toEqual({ babelrc: false });
|
|
resolve();
|
|
},
|
|
);
|
|
});
|
|
});
|
|
|
|
it("transformFileAsync", async function () {
|
|
const options = {
|
|
babelrc: false,
|
|
};
|
|
Object.freeze(options);
|
|
const res = await transformFileAsync(
|
|
cwd + "/fixtures/api/file.js",
|
|
options,
|
|
);
|
|
expect(res.code).toBe("foo();");
|
|
// keep user options untouched
|
|
expect(options).toEqual({ babelrc: false });
|
|
});
|
|
|
|
it("transformFileSync", function () {
|
|
const options = {
|
|
babelrc: false,
|
|
};
|
|
Object.freeze(options);
|
|
expect(transformFileSync(cwd + "/fixtures/api/file.js", options).code).toBe(
|
|
"foo();",
|
|
);
|
|
expect(options).toEqual({ babelrc: false });
|
|
});
|
|
|
|
it("transformFromAst should not mutate the AST", function () {
|
|
const program = "const identifier = 1";
|
|
const node = parse(program);
|
|
const { code } = transformFromAst(node, program, {
|
|
plugins: [
|
|
function () {
|
|
return {
|
|
visitor: {
|
|
Identifier: function (path) {
|
|
path.node.name = "replaced";
|
|
},
|
|
},
|
|
};
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(code).toBe("const replaced = 1;");
|
|
expect(node.program.body[0].declarations[0].id.name).toBe(
|
|
"identifier",
|
|
"original ast should not have been mutated",
|
|
);
|
|
});
|
|
|
|
it("transformFromAst should mutate the AST when cloneInputAst is false", function () {
|
|
const program = "const identifier = 1";
|
|
const node = parse(program);
|
|
const { code } = transformFromAst(node, program, {
|
|
cloneInputAst: false,
|
|
plugins: [
|
|
function () {
|
|
return {
|
|
visitor: {
|
|
Identifier: function (path) {
|
|
path.node.name = "replaced";
|
|
},
|
|
},
|
|
};
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(code).toBe("const replaced = 1;");
|
|
expect(node.program.body[0].declarations[0].id.name).toBe(
|
|
"replaced",
|
|
"original ast should have been mutated",
|
|
);
|
|
});
|
|
|
|
it("options throw on falsy true", function () {
|
|
return expect(function () {
|
|
transform("", {
|
|
plugins: [cwd + "/../../babel-plugin-syntax-jsx", false],
|
|
});
|
|
}).toThrow(/.plugins\[1\] must be a string, object, function/);
|
|
});
|
|
|
|
it("options merge backwards", function () {
|
|
return transformAsync("", {
|
|
presets: [cwd + "/../../babel-preset-env"],
|
|
plugins: [cwd + "/../../babel-plugin-syntax-jsx"],
|
|
}).then(function (result) {
|
|
expect(result.options.plugins[0].manipulateOptions.toString()).toEqual(
|
|
expect.stringContaining("jsx"),
|
|
);
|
|
});
|
|
});
|
|
|
|
it("option wrapPluginVisitorMethod", function () {
|
|
let calledRaw = 0;
|
|
let calledIntercept = 0;
|
|
|
|
transform("function foo() { bar(foobar); }", {
|
|
wrapPluginVisitorMethod: function (pluginAlias, visitorType, callback) {
|
|
if (pluginAlias !== "foobar") {
|
|
return callback;
|
|
}
|
|
|
|
expect(visitorType).toBe("enter");
|
|
|
|
return function () {
|
|
calledIntercept++;
|
|
return callback.apply(this, arguments);
|
|
};
|
|
},
|
|
|
|
plugins: [
|
|
new Plugin({
|
|
name: "foobar",
|
|
visitor: {
|
|
"Program|Identifier": function () {
|
|
calledRaw++;
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(calledRaw).toBe(4);
|
|
expect(calledIntercept).toBe(4);
|
|
});
|
|
|
|
it("pass per preset", function () {
|
|
let aliasBaseType = null;
|
|
|
|
function execTest(passPerPreset) {
|
|
return transform("type Foo = number; let x = (y): Foo => y;", {
|
|
sourceType: "script",
|
|
passPerPreset: passPerPreset,
|
|
presets: [
|
|
// First preset with our plugin, "before"
|
|
function () {
|
|
return {
|
|
plugins: [
|
|
new Plugin({
|
|
visitor: {
|
|
Function: function (path) {
|
|
const alias = path.scope
|
|
.getProgramParent()
|
|
.path.get("body")[0].node;
|
|
if (!babel.types.isTypeAlias(alias)) return;
|
|
|
|
// In case of `passPerPreset` being `false`, the
|
|
// alias node is already removed by Flow plugin.
|
|
if (!alias) {
|
|
return;
|
|
}
|
|
|
|
// In case of `passPerPreset` being `true`, the
|
|
// alias node should still exist.
|
|
aliasBaseType = alias.right.type; // NumberTypeAnnotation
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
};
|
|
},
|
|
|
|
// env preset
|
|
[presetEnv, { targets: { browsers: "ie 6" } }],
|
|
|
|
// Third preset for Flow.
|
|
() => ({
|
|
plugins: [pluginSyntaxFlow, pluginFlowStripTypes],
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
|
|
// 1. passPerPreset: true
|
|
|
|
let result = execTest(true);
|
|
|
|
expect(aliasBaseType).toBe("NumberTypeAnnotation");
|
|
|
|
expect(result.code).toBe("var x = function x(y) {\n return y;\n};");
|
|
|
|
// 2. passPerPreset: false
|
|
|
|
aliasBaseType = null;
|
|
|
|
result = execTest(false);
|
|
|
|
expect(aliasBaseType).toBeNull();
|
|
|
|
expect(result.code).toBe("var x = function x(y) {\n return y;\n};");
|
|
});
|
|
|
|
it("complex plugin and preset ordering", function () {
|
|
function pushPlugin(str) {
|
|
return {
|
|
visitor: {
|
|
Program(path) {
|
|
path.pushContainer(
|
|
"body",
|
|
babel.types.expressionStatement(babel.types.identifier(str)),
|
|
);
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
function pushPreset(str) {
|
|
return { plugins: [pushPlugin(str)] };
|
|
}
|
|
|
|
const oldEnv = process.env.BABEL_ENV;
|
|
process.env.BABEL_ENV = "development";
|
|
|
|
const result = transform("", {
|
|
cwd: path.join(cwd, "fixtures", "config", "complex-plugin-config"),
|
|
filename: path.join(
|
|
cwd,
|
|
"fixtures",
|
|
"config",
|
|
"complex-plugin-config",
|
|
"file.js",
|
|
),
|
|
presets: [pushPreset("argone"), pushPreset("argtwo")],
|
|
env: {
|
|
development: {
|
|
passPerPreset: true,
|
|
presets: [pushPreset("argthree"), pushPreset("argfour")],
|
|
},
|
|
},
|
|
});
|
|
|
|
if (oldEnv === undefined) {
|
|
delete process.env.BABEL_ENV;
|
|
} else {
|
|
process.env.BABEL_ENV = oldEnv;
|
|
}
|
|
|
|
expect(result.code).toBe(
|
|
[
|
|
"thirteen;",
|
|
"fourteen;",
|
|
"seventeen;",
|
|
"eighteen;",
|
|
"one;",
|
|
"two;",
|
|
"eleven;",
|
|
"twelve;",
|
|
"argtwo;",
|
|
"argone;",
|
|
"five;",
|
|
"six;",
|
|
"twentyone;",
|
|
"twentytwo;",
|
|
"three;",
|
|
"four;",
|
|
"nineteen;",
|
|
"twenty;",
|
|
"fifteen;",
|
|
"sixteen;",
|
|
"seven;",
|
|
"eight;",
|
|
"nine;",
|
|
"ten;",
|
|
"argthree;",
|
|
"argfour;",
|
|
].join("\n"),
|
|
);
|
|
});
|
|
|
|
it("interpreter directive backward-compat", function () {
|
|
function doTransform(code, preHandler) {
|
|
return transform(code, {
|
|
plugins: [
|
|
{
|
|
pre: preHandler,
|
|
},
|
|
],
|
|
}).code;
|
|
}
|
|
|
|
// Writes value properly.
|
|
expect(
|
|
doTransform("", file => {
|
|
file.shebang = "env node";
|
|
}),
|
|
).toBe(`#!env node`);
|
|
expect(
|
|
doTransform("#!env node", file => {
|
|
file.shebang = "env node2";
|
|
}),
|
|
).toBe(`#!env node2`);
|
|
expect(
|
|
doTransform("", file => {
|
|
file.shebang = "";
|
|
}),
|
|
).toBe(``);
|
|
expect(
|
|
doTransform("#!env node", file => {
|
|
file.shebang = "";
|
|
}),
|
|
).toBe(``);
|
|
|
|
// Reads value properly.
|
|
doTransform("", file => {
|
|
expect(file.shebang).toBe("");
|
|
});
|
|
doTransform("#!env node", file => {
|
|
expect(file.shebang).toBe("env node");
|
|
});
|
|
|
|
// Reads and writes properly.
|
|
expect(
|
|
doTransform("#!env node", file => {
|
|
expect(file.shebang).toBe("env node");
|
|
|
|
file.shebang = "env node2";
|
|
expect(file.shebang).toBe("env node2");
|
|
|
|
file.shebang = "env node3";
|
|
}),
|
|
).toBe(`#!env node3`);
|
|
});
|
|
|
|
it("source map merging", function () {
|
|
const result = transform(
|
|
[
|
|
/* eslint-disable max-len */
|
|
'function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }',
|
|
"",
|
|
"let Foo = function Foo() {",
|
|
" _classCallCheck(this, Foo);",
|
|
"};",
|
|
"",
|
|
"//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZG91dCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztJQUFNLEdBQUcsWUFBSCxHQUFHO3dCQUFILEdBQUciLCJmaWxlIjoidW5kZWZpbmVkIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRm9vIHt9XG4iXX0=",
|
|
/* eslint-enable max-len */
|
|
].join("\n"),
|
|
{
|
|
sourceMap: true,
|
|
},
|
|
);
|
|
|
|
expect(
|
|
[
|
|
"function _classCallCheck(instance, Constructor) {",
|
|
" if (!(instance instanceof Constructor)) {",
|
|
' throw new TypeError("Cannot call a class as a function");',
|
|
" }",
|
|
"}",
|
|
"",
|
|
"let Foo = function Foo() {",
|
|
" _classCallCheck(this, Foo);",
|
|
"};",
|
|
].join("\n"),
|
|
).toBe(result.code);
|
|
|
|
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
|
|
|
expect(
|
|
consumer.originalPositionFor({
|
|
line: 7,
|
|
column: 4,
|
|
}),
|
|
).toEqual({
|
|
name: null,
|
|
source: "stdout",
|
|
line: 1,
|
|
column: 6,
|
|
});
|
|
});
|
|
|
|
it("default source map filename", function () {
|
|
return transformAsync("var a = 10;", {
|
|
cwd: "/some/absolute",
|
|
filename: "/some/absolute/file/path.js",
|
|
sourceMaps: true,
|
|
}).then(function (result) {
|
|
expect(result.map.sources).toEqual(["path.js"]);
|
|
});
|
|
});
|
|
|
|
it("code option false", function () {
|
|
return transformAsync("foo('bar');", { code: false }).then(function (
|
|
result,
|
|
) {
|
|
expect(result.code).toBeFalsy();
|
|
});
|
|
});
|
|
|
|
it("ast option false", function () {
|
|
return transformAsync("foo('bar');", { ast: false }).then(function (
|
|
result,
|
|
) {
|
|
expect(result.ast).toBeFalsy();
|
|
});
|
|
});
|
|
|
|
it("ast option true", function () {
|
|
return transformAsync("foo('bar');", { ast: true }).then(function (result) {
|
|
expect(result.ast).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
it("ast option default", function () {
|
|
return transformAsync("foo('bar');").then(function (result) {
|
|
expect(result.ast).toBeFalsy();
|
|
});
|
|
});
|
|
|
|
it("auxiliaryComment option", function () {
|
|
return transformAsync("class Foo {}", {
|
|
auxiliaryCommentBefore: "before",
|
|
auxiliaryCommentAfter: "after",
|
|
plugins: [
|
|
function (babel) {
|
|
const t = babel.types;
|
|
return {
|
|
visitor: {
|
|
Program: function (path) {
|
|
path.unshiftContainer(
|
|
"body",
|
|
t.expressionStatement(t.identifier("start")),
|
|
);
|
|
path.pushContainer(
|
|
"body",
|
|
t.expressionStatement(t.identifier("end")),
|
|
);
|
|
},
|
|
},
|
|
};
|
|
},
|
|
],
|
|
}).then(function (result) {
|
|
expect(result.code).toBe(
|
|
"/*before*/\nstart;\n\n/*after*/\nclass Foo {}\n\n/*before*/\nend;\n\n/*after*/",
|
|
);
|
|
});
|
|
});
|
|
|
|
it("ignore option", function () {
|
|
return Promise.all([
|
|
transformAsync("", {
|
|
ignore: ["/foo"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/foo/node_modules"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/foo/node_modules/*"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/foo/**/*"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/foo/node_modules/*.bar"],
|
|
filename: "/foo/node_modules/foo.bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/foo/node_modules/*.foo"],
|
|
filename: "/foo/node_modules/foo.bar",
|
|
}).then(assertNotIgnored),
|
|
|
|
transformAsync("", {
|
|
ignore: ["/bar/**/*"],
|
|
filename: "/foo/node_modules/foo.bar",
|
|
}).then(assertNotIgnored),
|
|
]);
|
|
});
|
|
|
|
it("only option", function () {
|
|
return Promise.all([
|
|
transformAsync("", {
|
|
only: ["/foo"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertNotIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/*"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertNotIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/node_modules"],
|
|
filename: "/foo/node_modules/bar",
|
|
}).then(assertNotIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/node_modules/*.bar"],
|
|
filename: "/foo/node_modules/foo.bar",
|
|
}).then(assertNotIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/node_modules"],
|
|
filename: "/foo/node_module/bar",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/node_modules"],
|
|
filename: "/bar/node_modules/foo",
|
|
}).then(assertIgnored),
|
|
|
|
transformAsync("", {
|
|
only: ["/foo/node_modules/*.bar"],
|
|
filename: "/foo/node_modules/bar.foo",
|
|
}).then(assertIgnored),
|
|
]);
|
|
});
|
|
|
|
describe("env option", function () {
|
|
const oldBabelEnv = process.env.BABEL_ENV;
|
|
const oldNodeEnv = process.env.NODE_ENV;
|
|
|
|
beforeEach(function () {
|
|
// Tests need to run with the default and specific values for these. They
|
|
// need to be cleared for each test.
|
|
delete process.env.BABEL_ENV;
|
|
delete process.env.NODE_ENV;
|
|
});
|
|
|
|
afterAll(function () {
|
|
process.env.BABEL_ENV = oldBabelEnv;
|
|
process.env.NODE_ENV = oldNodeEnv;
|
|
});
|
|
|
|
it("default", function () {
|
|
const result = transform("foo;", {
|
|
env: {
|
|
development: { comments: false },
|
|
},
|
|
});
|
|
|
|
expect(result.options.comments).toBe(false);
|
|
});
|
|
|
|
it("BABEL_ENV", function () {
|
|
process.env.BABEL_ENV = "foo";
|
|
const result = transform("foo;", {
|
|
env: {
|
|
foo: { comments: false },
|
|
},
|
|
});
|
|
expect(result.options.comments).toBe(false);
|
|
});
|
|
|
|
it("NODE_ENV", function () {
|
|
process.env.NODE_ENV = "foo";
|
|
const result = transform("foo;", {
|
|
env: {
|
|
foo: { comments: false },
|
|
},
|
|
});
|
|
expect(result.options.comments).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("buildExternalHelpers", function () {
|
|
describe("smoke tests", function () {
|
|
it("builds external helpers in global output type", function () {
|
|
babel.buildExternalHelpers(null, "global");
|
|
});
|
|
|
|
it("builds external helpers in module output type", function () {
|
|
babel.buildExternalHelpers(null, "module");
|
|
});
|
|
|
|
it("builds external helpers in umd output type", function () {
|
|
babel.buildExternalHelpers(null, "umd");
|
|
});
|
|
|
|
it("builds external helpers in var output type", function () {
|
|
babel.buildExternalHelpers(null, "var");
|
|
});
|
|
});
|
|
|
|
it("all", function () {
|
|
const script = babel.buildExternalHelpers();
|
|
expect(script).toEqual(expect.stringContaining("classCallCheck"));
|
|
expect(script).toEqual(expect.stringContaining("inherits"));
|
|
});
|
|
|
|
it("allowlist", function () {
|
|
const script = babel.buildExternalHelpers(["inherits"]);
|
|
expect(script).not.toEqual(expect.stringContaining("classCallCheck"));
|
|
expect(script).toEqual(expect.stringContaining("inherits"));
|
|
});
|
|
|
|
it("empty allowlist", function () {
|
|
const script = babel.buildExternalHelpers([]);
|
|
expect(script).not.toEqual(expect.stringContaining("classCallCheck"));
|
|
expect(script).not.toEqual(expect.stringContaining("inherits"));
|
|
});
|
|
|
|
it("underscored", function () {
|
|
const script = babel.buildExternalHelpers(["typeof"]);
|
|
expect(script).toEqual(expect.stringContaining("typeof"));
|
|
});
|
|
});
|
|
|
|
describe("handle parsing errors", function () {
|
|
const options = {
|
|
babelrc: false,
|
|
};
|
|
|
|
it("only syntax plugin available", function () {
|
|
return new Promise(resolve => {
|
|
transformFile(
|
|
cwd + "/fixtures/api/parsing-errors/only-syntax/file.js",
|
|
options,
|
|
function (err) {
|
|
expect(err.message).toMatch(
|
|
"Support for the experimental syntax 'pipelineOperator' isn't currently enabled (1:3):",
|
|
);
|
|
expect(err.message).toMatch(
|
|
"Add @babel/plugin-proposal-pipeline-operator (https://git.io/vb4SU) to the " +
|
|
"'plugins' section of your Babel config to enable transformation.",
|
|
);
|
|
resolve();
|
|
},
|
|
);
|
|
});
|
|
});
|
|
|
|
it("both syntax and transform plugin available", function () {
|
|
return new Promise(resolve => {
|
|
transformFile(
|
|
cwd + "/fixtures/api/parsing-errors/syntax-and-transform/file.js",
|
|
options,
|
|
function (err) {
|
|
expect(err.message).toMatch(
|
|
"Support for the experimental syntax 'doExpressions' isn't currently enabled (1:2):",
|
|
);
|
|
expect(err.message).toMatch(
|
|
"Add @babel/plugin-proposal-do-expressions (https://git.io/vb4S3) to the " +
|
|
"'plugins' section of your Babel config to enable transformation.",
|
|
);
|
|
resolve();
|
|
},
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("missing helpers", function () {
|
|
it("should always throw", function () {
|
|
expect(() =>
|
|
babel.transformSync(``, {
|
|
configFile: false,
|
|
plugins: [
|
|
function () {
|
|
return {
|
|
visitor: {
|
|
Program(path) {
|
|
try {
|
|
path.pushContainer("body", this.addHelper("fooBar"));
|
|
} catch {}
|
|
path.pushContainer("body", this.addHelper("fooBar"));
|
|
},
|
|
},
|
|
};
|
|
},
|
|
],
|
|
}),
|
|
).toThrow();
|
|
});
|
|
});
|
|
});
|