Files
babel/packages/babel-core/test/external-dependencies.js
Huáng JùnliàngandGitHub 254525d565 Enforce node protocol import (#17207)
* enable prefer-node-protocol rule

* prefer node protocol import

* fix broken scripts

* fix e2e-old-babel error

* strip node: protocol for old node versions

* update Makefile.mjs
2025-03-31 10:49:22 -04:00

285 lines
7.8 KiB
JavaScript

import path from "node:path";
import { fileURLToPath } from "node:url";
import { transformSync } from "../lib/index.js";
const cwd = path.dirname(fileURLToPath(import.meta.url));
function transform(code, opts) {
return transformSync(code, { cwd, configFile: false, ...opts });
}
describe("externalDependencies", () => {
function makePlugin(external) {
return api => {
api.cache.invalidate(() => "");
api.addExternalDependency(external);
return { visitor: {} };
};
}
function makePreset(external, plugins = []) {
return api => {
api.cache.invalidate(() => "");
api.addExternalDependency(external);
return { plugins };
};
}
it("can be set by plugins", () => {
const { externalDependencies } = transform("", {
plugins: [makePlugin("./foo")],
});
expect(externalDependencies).toEqual(new Set(["./foo"]));
});
it("returns a fresh set", () => {
const options = {
plugins: [makePlugin("./foo")],
};
const res1 = transform("", options);
const res2 = transform("", options);
expect(res1.externalDependencies).toEqual(res2.externalDependencies);
expect(res1.externalDependencies).not.toBe(res2.externalDependencies);
});
it("can be set multiple times by the same plugin", () => {
const { externalDependencies } = transform("", {
plugins: [
function (api) {
api.cache.never();
api.addExternalDependency("./foo");
api.addExternalDependency("./bar");
return { visitor: {} };
},
],
});
expect(externalDependencies).toEqual(new Set(["./foo", "./bar"]));
});
it("can be set by presets", () => {
const { externalDependencies } = transform("", {
presets: [makePreset("./foo")],
});
expect(externalDependencies).toEqual(new Set(["./foo"]));
});
it("can be set multiple times by the same preset", () => {
const { externalDependencies } = transform("", {
presets: [
function (api) {
api.cache.never();
api.addExternalDependency("./foo");
api.addExternalDependency("./bar");
return { plugins: [] };
},
],
});
expect(externalDependencies).toEqual(new Set(["./foo", "./bar"]));
});
it("can be set by multiple plugins and presets", () => {
const { externalDependencies } = transform("", {
plugins: [makePlugin("./plugin1"), makePlugin("./plugin2")],
presets: [
makePreset("./preset", [
makePlugin("./preset-plugin1"),
makePlugin("./preset-plugin2"),
]),
],
});
expect(externalDependencies).toEqual(
new Set([
"./plugin1",
"./plugin2",
"./preset",
"./preset-plugin1",
"./preset-plugin2",
]),
);
});
describe("cached plugins", () => {
it("returned when set by cached plugins", () => {
const plugin = jest.fn(makePlugin("./foo"));
const result1 = transform("", { plugins: [plugin] });
const result2 = transform("", { plugins: [plugin] });
expect(plugin).toHaveBeenCalledTimes(1);
expect(new Set(result1.externalDependencies)).toEqual(new Set(["./foo"]));
expect(new Set(result2.externalDependencies)).toEqual(new Set(["./foo"]));
});
it("cached external dependencies are merged with new ones", () => {
const plugin1 = jest.fn(makePlugin("./foo"));
const plugin2 = jest.fn((api, { file }) => {
api.addExternalDependency(file);
api.cache.never();
return { visitor: {} };
});
const result1 = transform("", {
plugins: [plugin1, [plugin2, { file: "./file1" }]],
});
const result2 = transform("", {
plugins: [plugin1, [plugin2, { file: "./file2" }]],
});
expect(plugin1).toHaveBeenCalledTimes(1);
expect(plugin2).toHaveBeenCalledTimes(2);
expect(new Set(result1.externalDependencies)).toEqual(
new Set(["./foo", "./file1"]),
);
expect(new Set(result2.externalDependencies)).toEqual(
new Set(["./foo", "./file2"]),
);
});
});
describe("cache validation", () => {
it("cache must be configured", () => {
function plugin(api) {
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin] })).toThrow(
/A plugin\/preset has external untracked dependencies/,
);
});
it("cache.forever() is disallowed", () => {
function plugin(api) {
api.cache.forever();
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin] })).toThrow(
/A plugin\/preset has external untracked dependencies/,
);
});
it("cache.never() is a valid configuration", () => {
function plugin(api) {
api.cache.never();
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin] })).not.toThrow();
});
it("cache.using() is a valid configuration", () => {
function plugin(api) {
api.cache.using(() => "");
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin] })).not.toThrow();
});
it("cache.invalidate() is a valid configuration", () => {
function plugin(api) {
api.cache.invalidate(() => "");
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin] })).not.toThrow();
});
it("cache must be configured in the same plugin that uses addExternalDependency", () => {
function plugin1(api) {
api.cache.never();
return { visitor: {} };
}
function plugin2(api) {
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() => transform("", { plugins: [plugin1, plugin2] })).toThrow(
/A plugin\/preset has external untracked dependencies/,
);
});
it("cache does not need to be configured in other plugins", () => {
function plugin1() {
return { visitor: {} };
}
function plugin2(api) {
api.cache.never();
api.addExternalDependency("./foo");
return { visitor: {} };
}
expect(() =>
transform("", { plugins: [plugin1, plugin2] }),
).not.toThrow();
});
});
describe("regressions", () => {
describe("#14233", () => {
it("no external dependencies", () => {
const code = `let a = 1`;
function pluginA(api) {
api.cache.never();
return { name: "plugin-a" };
}
function pluginB() {
return { name: "plugin-b", inherits: pluginA };
}
expect(() => {
transform(code, { plugins: [pluginB] });
transform(code, { plugins: [pluginB] });
}).not.toThrow();
});
it("with external dependencies", () => {
const code = `let a = 1`;
let pluginAdep = "./a-foo";
function pluginA(api) {
api.cache.never();
api.addExternalDependency(pluginAdep);
return { name: "plugin-a" };
}
const pluginB = jest.fn(function pluginB(api) {
api.cache.using(() => 0);
api.addExternalDependency("./b-foo");
return { name: "plugin-b", inherits: pluginA };
});
const result1 = transform(code, { plugins: [pluginB] });
pluginAdep = "./a-bar";
const result2 = transform(code, { plugins: [pluginB] });
expect(pluginB).toHaveBeenCalledTimes(1);
expect(new Set(result1.externalDependencies)).toEqual(
new Set(["./a-foo", "./b-foo"]),
);
expect(new Set(result2.externalDependencies)).toEqual(
new Set(["./a-bar", "./b-foo"]),
);
});
});
});
});