Tooling to test ESLint rules with comprehensive TypeScript support and advanced testing capabilities
—
Helper functions for test case formatting and test framework integration.
Template tag function to mark code samples as "should not format with prettier" for plugin-test-formatting lint rule compliance.
/**
* Simple no-op template tag to mark code samples as "should not format with prettier"
* for the plugin-test-formatting lint rule
* @param raw - Template strings array from template literal
* @param keys - Interpolated values from template literal
* @returns The original string with interpolations applied
*/
function noFormat(raw: TemplateStringsArray, ...keys: string[]): string;Usage Examples:
import { noFormat } from "@typescript-eslint/rule-tester";
// Mark test code that should not be formatted by prettier
const testCode = noFormat`
const x = 1 ; // Intentionally poorly formatted
function foo( ) { return 'hello' ; }
`;
// Use in test cases where formatting matters for the rule being tested
const ruleTester = new RuleTester();
ruleTester.run("spacing-rule", spacingRule, {
valid: [
// Normal test case (may be formatted by prettier)
"const x = 1;",
// Test case with specific formatting that should be preserved
noFormat`const x = 1; // This spacing is intentional`,
],
invalid: [
{
code: noFormat`var x=1;`, // Preserve original formatting for testing
errors: [{ messageId: "noVar" }],
output: noFormat`const x=1;`, // Preserve formatting in expected output
},
],
});Real-world scenarios where noFormat is essential for rule testing.
Whitespace and Formatting Rules:
import { RuleTester, noFormat } from "@typescript-eslint/rule-tester";
const ruleTester = new RuleTester();
// Testing a rule that enforces specific spacing
ruleTester.run("object-spacing", objectSpacingRule, {
valid: [
// These should preserve exact spacing for testing
noFormat`const obj = { key: 'value' };`, // Valid spacing
noFormat`const arr = [ 1, 2, 3 ];`, // Valid array spacing
],
invalid: [
{
code: noFormat`const obj = { key:'value' };`, // Invalid: no space after colon
errors: [{ messageId: "missingSpaceAfterColon" }],
output: noFormat`const obj = { key: 'value' };`, // Fixed spacing
},
{
code: noFormat`const obj = {key: 'value'};`, // Invalid: no spaces inside braces
errors: [{ messageId: "missingSpaceInsideBraces" }],
output: noFormat`const obj = { key: 'value' };`, // Fixed spacing
},
],
});Indentation Rules:
// Testing indentation rules where exact whitespace matters
ruleTester.run("indent-rule", indentRule, {
valid: [
noFormat`
function foo() {
return {
prop: 'value',
nested: {
deep: 'value'
}
};
}`,
],
invalid: [
{
code: noFormat`
function foo() {
return {
prop: 'value',
nested: {
deep: 'value'
}
};
}`,
errors: [
{ messageId: "wrongIndentation", line: 4 },
{ messageId: "wrongIndentation", line: 5 },
],
output: noFormat`
function foo() {
return {
prop: 'value',
nested: {
deep: 'value'
}
};
}`,
},
],
});Comment Formatting Rules:
// Testing rules that care about comment formatting
ruleTester.run("comment-spacing", commentSpacingRule, {
valid: [
noFormat`const x = 1; // This is a comment`,
noFormat`const y = 2; // This has extra spaces`,
],
invalid: [
{
code: noFormat`const x = 1;//No space before comment`,
errors: [{ messageId: "spaceBeforeComment" }],
output: noFormat`const x = 1; //No space before comment`,
},
{
code: noFormat`const x = 1; //No space after slashes`,
errors: [{ messageId: "spaceAfterSlashes" }],
output: noFormat`const x = 1; // No space after slashes`,
},
],
});String Literal Formatting:
// Testing rules about string formatting where quotes and escaping matter
ruleTester.run("string-format", stringFormatRule, {
valid: [
noFormat`const str = "hello world";`,
noFormat`const template = \`Hello \${name}\`;`,
],
invalid: [
{
code: noFormat`const str = 'hello world';`, // Single quotes
errors: [{ messageId: "useDoubleQuotes" }],
output: noFormat`const str = "hello world";`, // Fixed to double quotes
},
{
code: noFormat`const str = "hello\\nworld";`, // Escaped newline
errors: [{ messageId: "useTemplateForMultiline" }],
output: noFormat`const str = \`hello
world\`;`, // Convert to template literal
},
],
});Semicolon and ASI Rules:
// Testing automatic semicolon insertion rules
ruleTester.run("semicolon-rule", semicolonRule, {
valid: [
noFormat`const x = 1;`,
noFormat`
const a = 1
const b = 2;`, // Mixed semicolon usage
],
invalid: [
{
code: noFormat`
const x = 1
const y = 2`, // Missing semicolons
errors: [
{ messageId: "missingSemicolon", line: 2 },
{ messageId: "missingSemicolon", line: 3 },
],
output: noFormat`
const x = 1;
const y = 2;`,
},
],
});The noFormat function is specifically designed to work with prettier and linting tools that enforce code formatting.
Without noFormat (problematic):
// This test might fail if prettier reformats the code
const testCode = `const x = 1;`; // prettier will normalize this
ruleTester.run("spacing-rule", spacingRule, {
invalid: [
{
code: testCode, // May be reformatted, breaking the test
errors: [{ messageId: "badSpacing" }],
},
],
});With noFormat (correct):
// This test preserves exact formatting
const testCode = noFormat`const x = 1;`; // formatting preserved
ruleTester.run("spacing-rule", spacingRule, {
invalid: [
{
code: testCode, // Exact formatting maintained
errors: [{ messageId: "badSpacing" }],
},
],
});The noFormat function supports all template literal features including interpolation.
// Dynamic test generation with preserved formatting
function generateFormattingTest(varName: string, spacing: string) {
return noFormat`const${spacing}${varName}${spacing}=${spacing}1;`;
}
const tests = [
{
code: generateFormattingTest("x", " "), // "const x = 1;"
errors: [{ messageId: "badSpacing" }],
},
{
code: generateFormattingTest("y", ""), // "const y = 1;"
errors: [{ messageId: "noSpacing" }],
},
];
// Template literals with complex interpolation
const complexTest = noFormat`
function ${functionName}(${params}) {
${body}
}`;The noFormat function is implemented as a simple template tag that preserves the original string structure:
function noFormat(raw: TemplateStringsArray, ...keys: string[]): string {
return String.raw({ raw }, ...keys);
}This implementation:
String.raw() to prevent escape sequence processing${...} syntaxInstall with Tessl CLI
npx tessl i tessl/npm-typescript-eslint--rule-tester