Repository: eslint/eslint
File: lib/rule-tester/flat-rule-tester.js (JavaScript)

Code before:
        function testInvalidTemplate(item) {
            assert.ok(typeof item.code === "string", "Test case must specify a string value for 'code'");
            if (item.name) {
                assert.ok(typeof item.name === "string", "Optional test case property 'name' must be a string");
            }
            assert.ok(item.errors || item.errors === 0,
                `Did not specify errors for an invalid test of ${ruleName}`);

            if (Array.isArray(item.errors) && item.errors.length === 0) {
                assert.fail("Invalid cases must have at least one error");
            }

            const ruleHasMetaMessages = hasOwnProperty(rule, "meta") && hasOwnProperty(rule.meta, "messages");
            const friendlyIDList = ruleHasMetaMessages ? `[${Object.keys(rule.meta.messages).map(key => `'${key}'`).join(", ")}]` : null;

            const result = runRuleForItem(item);
            const messages = result.messages;

            for (const message of messages) {
                if (hasOwnProperty(message, "suggestions")) {

                    /** @type {Map<string, number>} */
                    const seenMessageIndices = new Map();

                    for (let i = 0; i < message.suggestions.length; i += 1) {
                        const suggestionMessage = getSuggestionMessage(message.suggestions[i]);
                        const previous = seenMessageIndices.get(suggestionMessage);

                        assert.ok(!seenMessageIndices.has(suggestionMessage), `Suggestion message '${suggestionMessage}' reported from suggestion ${i} was previously reported by suggestion ${previous}. Suggestion messages should be unique within an error.`);
                        seenMessageIndices.set(suggestionMessage, i);
                    }
                }
            }

            if (typeof item.errors === "number") {

                if (item.errors === 0) {
                    assert.fail("Invalid cases must have 'error' value greater than 0");
                }

                assert.strictEqual(messages.length, item.errors, util.format("Should have %d error%s but had %d: %s",
                    item.errors,
                    item.errors === 1 ? "" : "s",
                    messages.length,
                    util.inspect(messages)));
            } else {
                assert.strictEqual(
                    messages.length, item.errors.length, util.format(
                        "Should have %d error%s but had %d: %s",
                        item.errors.length,
                        item.errors.length === 1 ? "" : "s",

Review comment (suggestion):
```suggestion
                        const suggestionMessage = message.suggestions[i].desc;
```

Actual messages are the output from `linter.verify()` and as such are processed by [`report-translator`](https://github.com/eslint/eslint/blob/main/lib/linter/report-translator.js) so we can just use the already calculated `desc` here.

Code after:

                    /** @type {Map<string, number>} */
                    const seenMessageIndices = new Map();

                    for (let i = 0; i < message.suggestions.length; i += 1) {
                        const suggestionMessage = message.suggestions[i].desc;
                        const previous = seenMessageIndices.get(suggestionMessage);

                        assert.ok(!seenMessageIndices.has(suggestionMessage), `Suggestion message '${suggestionMessage}' reported from suggestion ${i} was previously reported by suggestion ${previous}. Suggestion messages should be unique within an error.`);
                        seenMessageIndices.set(suggestionMessage, i);
                    }
                }
            }

            if (typeof item.errors === "number") {

                if (item.errors === 0) {
                    assert.fail("Invalid cases must have 'error' value greater than 0");
                }

                assert.strictEqual(messages.length, item.errors, util.format("Should have %d error%s but had %d: %s",
                    item.errors,
                    item.errors === 1 ? "" : "s",
                    messages.length,
                    util.inspect(messages)));
            } else {
                assert.strictEqual(
                    messages.length, item.errors.length, util.format(
                        "Should have %d error%s but had %d: %s",
                        item.errors.length,
                        item.errors.length === 1 ? "" : "s",
                        messages.length,
                        util.inspect(messages)
                    )
                );

                const hasMessageOfThisRule = messages.some(m => m.ruleId === ruleId);

                for (let i = 0, l = item.errors.length; i < l; i++) {
                    const error = item.errors[i];
                    const message = messages[i];

                    assert(hasMessageOfThisRule, "Error rule name should be the same as the name of the rule being tested");

                    if (typeof error === "string" || error instanceof RegExp) {

                        // Just an error message.
                        assertMessageMatches(message.message, error);
                    } else if (typeof error === "object" && error !== null) {

                        /*