Skip to content
This repository has been archived by the owner on Aug 18, 2021. It is now read-only.

add support for preset & plugins in babelOptions #784

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/parse.js
Expand Up @@ -17,6 +17,8 @@ module.exports = function(code, options) {
rootMode: options.babelOptions.rootMode,
envName: options.babelOptions.envName,
configFile: options.babelOptions.configFile,
presets: options.babelOptions.presets,
plugins: options.babelOptions.plugins,
babelrc: options.babelOptions.babelrc,
babelrcRoots: options.babelOptions.babelrcRoots,
extends: options.babelOptions.extends,
Expand Down
161 changes: 161 additions & 0 deletions test/specs/babel-options.js
@@ -0,0 +1,161 @@
"use strict";

const eslint = require("eslint");
const unpad = require("dedent");

const parser = require("../..");

function verifyAndAssertMessagesWithSpecificESLint(
code,
rules,
expectedMessages,
sourceType,
overrideConfig,
linter
) {
const config = {
parser: "current-babel-eslint",
rules,
env: {
node: true,
es6: true,
},
parserOptions: {
sourceType,
ecmaFeatures: {
globalReturn: true,
},
},
};

if (overrideConfig) {
for (const key in overrideConfig) {
config[key] = overrideConfig[key];
}
}

const messages = linter.verify(code, config);

if (messages.length !== expectedMessages.length) {
throw new Error(
`Expected ${expectedMessages.length} message(s), got ${
messages.length
}\n${JSON.stringify(messages, null, 2)}`
);
}

messages.forEach((message, i) => {
const formatedMessage = `${message.line}:${message.column} ${
message.message
}${message.ruleId ? ` ${message.ruleId}` : ""}`;
const expectedMessage = expectedMessages[i];
if (typeof expectedMessage === "string") {
if (formatedMessage !== expectedMessage) {
throw new Error(
`
Message ${i} does not match:
Expected: ${expectedMessage}
Actual: ${formatedMessage}
`
);
}
} else if (
typeof expectedMessage === "object" &&
expectedMessage !== null &&
typeof expectedMessage.matcher === "function" &&
typeof expectedMessage.message === "string"
) {
if (!expectedMessage.matcher(formatedMessage)) {
throw new Error(
`
Message ${i} does not match:
Expected: ${expectedMessage.message}
Actual: ${formatedMessage}
`
);
}
} else {
throw new Error(
"expected messages must be string or object { matcher: function, message: string }: " +
i +
" -> " +
typeof expectedMessage[i]
);
}
});
}

function verifyAndAssertMessages(
code,
rules,
expectedMessages,
sourceType,
overrideConfig
) {
const linter = new eslint.Linter();
linter.defineParser("current-babel-eslint", parser);

verifyAndAssertMessagesWithSpecificESLint(
unpad(`${code}`),
rules || {},
expectedMessages || [],
sourceType,
overrideConfig,
linter
);
}

describe("babel options", () => {
it("uses the plugins and presets specified in the options", () => {
const code = "class AClass { classProp = 123 };";

const rules = { "no-unused-vars": 1, semi: 1 };

const babelOptions = {
root: __dirname,
rootMode: "root",
babelrc: false,
presets: ["@babel/preset-env"],
plugins: [],
};

verifyAndAssertMessages(
code,
rules,
[
{
matcher: message => message.startsWith("1:25 Parsing error:"),
message: "1:25 Parsing error: <path> <rest of message>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message is a bit confusing to me - is that what's coming from Babel's parser?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's the error from Babel.

To show that the new feature is working, I had to devise a test case showing that the babel configuration gets changed by the provided config.

Unfortunately babel's error messages contain the full path to the file (which is machine dependent) so I couldn't just match the strings exactly.

And in fact, showing that the correct lint error is shown in one case (with correct babel config) and that babel errors (and the exact error text doesn't matter) in the other case seemed like an adequate test.

I'm all ears if someone has suggestions for a better way to test the feature though...

},
],
undefined,
{
parserOptions: {
requireConfigFile: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected that this option would always be used in conjunction with requireConfigFile: false? I'm curious what the behavior would be when this is true.

We should also probably update the README if we're going to make this change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're not using a babel config file then you need to disable requireConfigFile. Seemed clear to me, so my thought is that the existing documentation is good enough. ;-)

babelOptions: {
...babelOptions,
presets: ["@babel/preset-env"],
plugins: [],
},
},
}
);

verifyAndAssertMessages(
code,
rules,
["1:7 'AClass' is defined but never used. no-unused-vars"],
undefined,
{
parserOptions: {
requireConfigFile: false,
babelOptions: {
...babelOptions,
presets: ["@babel/preset-env"],
plugins: ["@babel/plugin-proposal-class-properties"],
},
},
}
);
});
});