Skip to content

Commit cc4d26b

Browse files
nzakasmdjermanovic
andauthored
fix: Ensure deprecated context.parserServices warns (#17593)
* fix: Ensure deprecated context.parserServices warns Updated RuleTester to emit a deprecation warning whenever `context.parserServices` is used. * Update lib/rule-tester/rule-tester.js Co-authored-by: Milos Djermanovic <[email protected]> * Update lib/rule-tester/rule-tester.js Co-authored-by: Milos Djermanovic <[email protected]> --------- Co-authored-by: Milos Djermanovic <[email protected]>
1 parent 1ea4cfb commit cc4d26b

2 files changed

Lines changed: 88 additions & 51 deletions

File tree

lib/rule-tester/rule-tester.js

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,22 @@ function emitCodePathCurrentSegmentsWarning(ruleName) {
396396
}
397397
}
398398

399+
/**
400+
* Emit a deprecation warning if `context.parserServices` is used.
401+
* @param {string} ruleName Name of the rule.
402+
* @returns {void}
403+
*/
404+
function emitParserServicesWarning(ruleName) {
405+
if (!emitParserServicesWarning[`warned-${ruleName}`]) {
406+
emitParserServicesWarning[`warned-${ruleName}`] = true;
407+
process.emitWarning(
408+
`"${ruleName}" rule is using \`context.parserServices\`, which is deprecated and will be removed in ESLint v9. Please use \`sourceCode.parserServices\` instead.`,
409+
"DeprecationWarning"
410+
);
411+
}
412+
}
413+
414+
399415
//------------------------------------------------------------------------------
400416
// Public Interface
401417
//------------------------------------------------------------------------------
@@ -627,26 +643,37 @@ class RuleTester {
627643
freezeDeeply(context.settings);
628644
freezeDeeply(context.parserOptions);
629645

630-
const newContext = Object.freeze(
631-
Object.create(
632-
context,
633-
Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
634-
methodName,
635-
{
636-
value(...args) {
637-
638-
// emit deprecation warning
639-
emitDeprecatedContextMethodWarning(ruleName, methodName);
640-
641-
// call the original method
642-
return context[methodName].call(this, ...args);
643-
},
644-
enumerable: true
645-
}
646-
]))
647-
)
646+
// wrap all deprecated methods
647+
const newContext = Object.create(
648+
context,
649+
Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
650+
methodName,
651+
{
652+
value(...args) {
653+
654+
// emit deprecation warning
655+
emitDeprecatedContextMethodWarning(ruleName, methodName);
656+
657+
// call the original method
658+
return context[methodName].call(this, ...args);
659+
},
660+
enumerable: true
661+
}
662+
]))
648663
);
649664

665+
// emit warning about context.parserServices
666+
const parserServices = context.parserServices;
667+
668+
Object.defineProperty(newContext, "parserServices", {
669+
get() {
670+
emitParserServicesWarning(ruleName);
671+
return parserServices;
672+
}
673+
});
674+
675+
Object.freeze(newContext);
676+
650677
return (typeof rule === "function" ? rule : rule.create)(newContext);
651678
}
652679
}));

tests/lib/rule-tester/rule-tester.js

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,39 +1243,6 @@ describe("RuleTester", () => {
12431243
});
12441244
});
12451245

1246-
it("should pass-through services from parseForESLint to the rule", () => {
1247-
const enhancedParserPath = require.resolve("../../fixtures/parsers/enhanced-parser");
1248-
const disallowHiRule = {
1249-
create: context => ({
1250-
Literal(node) {
1251-
assert.strictEqual(context.parserServices, context.sourceCode.parserServices);
1252-
1253-
const disallowed = context.sourceCode.parserServices.test.getMessage(); // returns "Hi!"
1254-
1255-
if (node.value === disallowed) {
1256-
context.report({ node, message: `Don't use '${disallowed}'` });
1257-
}
1258-
}
1259-
})
1260-
};
1261-
1262-
ruleTester.run("no-hi", disallowHiRule, {
1263-
valid: [
1264-
{
1265-
code: "'Hello!'",
1266-
parser: enhancedParserPath
1267-
}
1268-
],
1269-
invalid: [
1270-
{
1271-
code: "'Hi!'",
1272-
parser: enhancedParserPath,
1273-
errors: [{ message: "Don't use 'Hi!'" }]
1274-
}
1275-
]
1276-
});
1277-
});
1278-
12791246
it("should prevent invalid options schemas", () => {
12801247
assert.throws(() => {
12811248
ruleTester.run("no-invalid-schema", require("../../fixtures/testers/rule-tester/no-invalid-schema"), {
@@ -2515,6 +2482,48 @@ describe("RuleTester", () => {
25152482
);
25162483
});
25172484

2485+
it("should pass-through services from parseForESLint to the rule and log deprecation notice", () => {
2486+
const enhancedParserPath = require.resolve("../../fixtures/parsers/enhanced-parser");
2487+
const disallowHiRule = {
2488+
create: context => ({
2489+
Literal(node) {
2490+
assert.strictEqual(context.parserServices, context.sourceCode.parserServices);
2491+
2492+
const disallowed = context.sourceCode.parserServices.test.getMessage(); // returns "Hi!"
2493+
2494+
if (node.value === disallowed) {
2495+
context.report({ node, message: `Don't use '${disallowed}'` });
2496+
}
2497+
}
2498+
})
2499+
};
2500+
2501+
ruleTester.run("no-hi", disallowHiRule, {
2502+
valid: [
2503+
{
2504+
code: "'Hello!'",
2505+
parser: enhancedParserPath
2506+
}
2507+
],
2508+
invalid: [
2509+
{
2510+
code: "'Hi!'",
2511+
parser: enhancedParserPath,
2512+
errors: [{ message: "Don't use 'Hi!'" }]
2513+
}
2514+
]
2515+
});
2516+
2517+
assert.strictEqual(processStub.callCount, 1, "calls `process.emitWarning()` once");
2518+
assert.deepStrictEqual(
2519+
processStub.getCall(0).args,
2520+
[
2521+
"\"no-hi\" rule is using `context.parserServices`, which is deprecated and will be removed in ESLint v9. Please use `sourceCode.parserServices` instead.",
2522+
"DeprecationWarning"
2523+
]
2524+
);
2525+
2526+
});
25182527
Object.entries({
25192528
getSource: "getText",
25202529
getSourceLines: "getLines",
@@ -2583,6 +2592,7 @@ describe("RuleTester", () => {
25832592

25842593
});
25852594

2595+
25862596
});
25872597

25882598
/**

0 commit comments

Comments
 (0)