From 0cc190c128c646e217de121a549e97beaefe1206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 21 Sep 2022 11:01:50 +0200 Subject: [PATCH] Optional filename when preset uses fn test/include/exclude (#14954) --- packages/babel-core/src/config/full.ts | 8 ++- packages/babel-core/test/config-chain.js | 90 ++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/packages/babel-core/src/config/full.ts b/packages/babel-core/src/config/full.ts index 30b31e1376d5..36b68623281d 100644 --- a/packages/babel-core/src/config/full.ts +++ b/packages/babel-core/src/config/full.ts @@ -406,11 +406,17 @@ const instantiatePlugin = makeWeakCache(function* ( return new Plugin(plugin, options, alias, externalDependencies); }); +const needsFilename = (val: unknown) => val && typeof val !== "function"; + const validateIfOptionNeedsFilename = ( options: ValidatedOptions, descriptor: UnloadedDescriptor, ): void => { - if (options.test || options.include || options.exclude) { + if ( + needsFilename(options.test) || + needsFilename(options.include) || + needsFilename(options.exclude) + ) { const formattedPresetName = descriptor.name ? `"${descriptor.name}"` : "/* your preset */"; diff --git a/packages/babel-core/test/config-chain.js b/packages/babel-core/test/config-chain.js index eb080c0f27d2..cfc92e0bdd2e 100644 --- a/packages/babel-core/test/config-chain.js +++ b/packages/babel-core/test/config-chain.js @@ -236,6 +236,96 @@ describe("buildConfigChain", function () { expect(opts.comments).toBeUndefined(); }); }); + + describe("filename requirement", () => { + const BASE_OPTS = { + cwd: fixture("nonexistant-fake"), + babelrc: false, + configFile: false, + }; + + describe("in config", () => { + it("requires filename if string", () => { + expect(() => + loadOptions({ + ...BASE_OPTS, + test: fixture("nonexistant-fake"), + }), + ).toThrow(/no filename was passed/); + }); + + it("requires filename if RegExp", () => { + expect(() => + loadOptions({ + ...BASE_OPTS, + test: /file/, + }), + ).toThrow(/no filename was passed/); + }); + + it("does not require filename if function", () => { + const mock = jest.fn().mockReturnValue(true); + + expect(() => + loadOptions({ + ...BASE_OPTS, + test: mock, + }), + ).not.toThrow(); + expect(mock).toHaveBeenCalledWith(undefined, expect.anything()); + + expect(() => + loadOptions({ + ...BASE_OPTS, + filename: "some-filename", + test: mock, + }), + ).not.toThrow(); + expect(mock.mock.calls[1][0].endsWith("some-filename")).toBe(true); + }); + }); + + describe("in preset", () => { + it("requires filename if string", () => { + expect(() => + loadOptions({ + ...BASE_OPTS, + presets: [() => ({ test: fixture("nonexistant-fake") })], + }), + ).toThrow(/requires a filename/); + }); + + it("requires filename if RegExp", () => { + expect(() => + loadOptions({ + ...BASE_OPTS, + presets: [() => ({ test: /file/ })], + }), + ).toThrow(/requires a filename/); + }); + + it("does not require filename if function", () => { + const mock = jest.fn().mockReturnValue(true); + + expect(() => + loadOptions({ + ...BASE_OPTS, + presets: [() => ({ test: mock })], + }), + ).not.toThrow(); + expect(mock).toHaveBeenCalledWith(undefined, expect.anything()); + + expect(() => + loadOptions({ + ...BASE_OPTS, + filename: "some-filename", + presets: [() => ({ test: mock })], + }), + ).not.toThrow(); + expect(mock.mock.calls[1][0].endsWith("some-filename")).toBe(true); + }); + }); + }); }); describe("include", () => {