Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Rule Tester checks for missing placeholder data in the message #18073

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: share regular expression for message placeholders
  • Loading branch information
DMartens committed Feb 9, 2024
commit 494317e136d4a6c3cfd8a3b26090938244202205
2 changes: 1 addition & 1 deletion lib/linter/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";

const { Linter } = require("./linter");
const interpolate = require("./interpolate");
const { interpolate } = require("./interpolate");
const SourceCodeFixer = require("./source-code-fixer");

module.exports = {
Expand Down
33 changes: 20 additions & 13 deletions lib/linter/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@
// Public Interface
//------------------------------------------------------------------------------

module.exports = (text, data) => {
if (!data) {
return text;
}
module.exports = {
getPlaceholderMatcher() {
return /\{\{([^{}]+?)\}\}/gu;
},
interpolate(text, data) {
if (!data) {
return text;
}

// Substitution content for any {{ }} markers.
return text.replace(/\{\{([^{}]+?)\}\}/gu, (fullMatch, termWithWhitespace) => {
const term = termWithWhitespace.trim();
const matcher = module.exports.getPlaceholderMatcher();
DMartens marked this conversation as resolved.
Show resolved Hide resolved

if (term in data) {
return data[term];
}
// Substitution content for any {{ }} markers.
return text.replace(matcher, (fullMatch, termWithWhitespace) => {
const term = termWithWhitespace.trim();

// Preserve old behavior: If parameter name not provided, don't replace it.
return fullMatch;
});
if (term in data) {
return data[term];
}

// Preserve old behavior: If parameter name not provided, don't replace it.
return fullMatch;
});
}
};
2 changes: 1 addition & 1 deletion lib/linter/report-translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

const assert = require("assert");
const ruleFixer = require("./rule-fixer");
const interpolate = require("./interpolate");
const { interpolate } = require("./interpolate");

//------------------------------------------------------------------------------
// Typedefs
Expand Down
9 changes: 5 additions & 4 deletions lib/rule-tester/rule-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const
equal = require("fast-deep-equal"),
Traverser = require("../shared/traverser"),
{ getRuleOptionsSchema } = require("../config/flat-config-helpers"),
{ Linter, SourceCodeFixer, interpolate } = require("../linter"),
{ Linter, SourceCodeFixer } = require("../linter"),
{ interpolate, getPlaceholderMatcher } = require("../linter/interpolate"),
stringify = require("json-stable-stringify-without-jsonify");

const { FlatConfigArray } = require("../config/flat-config-array");
Expand Down Expand Up @@ -304,15 +305,15 @@ function throwForbiddenMethodError(methodName, prototype) {
};
}

const messagePlaceholderRegex = /\{\{([^{}]+?)\}\}/gu;

/**
* Extracts names of {{ placeholders }} from the reported message.
* @param {string} message Reported message
* @returns {string[]} Array of placeholder names
*/
function getMessagePlaceholders(message) {
return Array.from(message.matchAll(messagePlaceholderRegex), ([, name]) => name.trim());
const matcher = getPlaceholderMatcher();

return Array.from(message.matchAll(matcher), ([, name]) => name.trim());
}

const metaSchemaDescription = `
Expand Down
30 changes: 29 additions & 1 deletion tests/lib/linter/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,40 @@
//------------------------------------------------------------------------------

const assert = require("chai").assert;
const interpolate = require("../../../lib/linter/interpolate");
const { getPlaceholderMatcher, interpolate } = require("../../../lib/linter/interpolate");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

describe("getPlaceholderMatcher", () => {
it("returns a global regular expression", () => {
const matcher = getPlaceholderMatcher();

assert.strictEqual(matcher.global, true);
});

it("matches text with placeholders", () => {
const matcher = getPlaceholderMatcher();

assert.match("{{ placeholder }}", matcher);
});

it("does not match text without placeholders", () => {
const matcher = getPlaceholderMatcher();

assert.notMatch("no placeholders in sight", matcher);
});

it("captures the text inside the placeholder", () => {
const matcher = getPlaceholderMatcher();
const text = "{{ placeholder }}";
const matches = Array.from(text.matchAll(matcher));

assert.deepStrictEqual(matches, [[text, " placeholder "]]);
});
});

describe("interpolate()", () => {
it("passes through text without {{ }}", () => {
const message = "This is a very important message!";
Expand Down