0
# Utility Functions
1
2
Helper functions for test case formatting and test framework integration.
3
4
## Capabilities
5
6
### Code Formatting Control
7
8
Template tag function to mark code samples as "should not format with prettier" for plugin-test-formatting lint rule compliance.
9
10
```typescript { .api }
11
/**
12
* Simple no-op template tag to mark code samples as "should not format with prettier"
13
* for the plugin-test-formatting lint rule
14
* @param raw - Template strings array from template literal
15
* @param keys - Interpolated values from template literal
16
* @returns The original string with interpolations applied
17
*/
18
function noFormat(raw: TemplateStringsArray, ...keys: string[]): string;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import { noFormat } from "@typescript-eslint/rule-tester";
25
26
// Mark test code that should not be formatted by prettier
27
const testCode = noFormat`
28
const x = 1 ; // Intentionally poorly formatted
29
function foo( ) { return 'hello' ; }
30
`;
31
32
// Use in test cases where formatting matters for the rule being tested
33
const ruleTester = new RuleTester();
34
35
ruleTester.run("spacing-rule", spacingRule, {
36
valid: [
37
// Normal test case (may be formatted by prettier)
38
"const x = 1;",
39
40
// Test case with specific formatting that should be preserved
41
noFormat`const x = 1; // This spacing is intentional`,
42
],
43
invalid: [
44
{
45
code: noFormat`var x=1;`, // Preserve original formatting for testing
46
errors: [{ messageId: "noVar" }],
47
output: noFormat`const x=1;`, // Preserve formatting in expected output
48
},
49
],
50
});
51
```
52
53
### Practical Use Cases
54
55
Real-world scenarios where noFormat is essential for rule testing.
56
57
**Whitespace and Formatting Rules:**
58
59
```typescript
60
import { RuleTester, noFormat } from "@typescript-eslint/rule-tester";
61
62
const ruleTester = new RuleTester();
63
64
// Testing a rule that enforces specific spacing
65
ruleTester.run("object-spacing", objectSpacingRule, {
66
valid: [
67
// These should preserve exact spacing for testing
68
noFormat`const obj = { key: 'value' };`, // Valid spacing
69
noFormat`const arr = [ 1, 2, 3 ];`, // Valid array spacing
70
],
71
invalid: [
72
{
73
code: noFormat`const obj = { key:'value' };`, // Invalid: no space after colon
74
errors: [{ messageId: "missingSpaceAfterColon" }],
75
output: noFormat`const obj = { key: 'value' };`, // Fixed spacing
76
},
77
{
78
code: noFormat`const obj = {key: 'value'};`, // Invalid: no spaces inside braces
79
errors: [{ messageId: "missingSpaceInsideBraces" }],
80
output: noFormat`const obj = { key: 'value' };`, // Fixed spacing
81
},
82
],
83
});
84
```
85
86
**Indentation Rules:**
87
88
```typescript
89
// Testing indentation rules where exact whitespace matters
90
ruleTester.run("indent-rule", indentRule, {
91
valid: [
92
noFormat`
93
function foo() {
94
return {
95
prop: 'value',
96
nested: {
97
deep: 'value'
98
}
99
};
100
}`,
101
],
102
invalid: [
103
{
104
code: noFormat`
105
function foo() {
106
return {
107
prop: 'value',
108
nested: {
109
deep: 'value'
110
}
111
};
112
}`,
113
errors: [
114
{ messageId: "wrongIndentation", line: 4 },
115
{ messageId: "wrongIndentation", line: 5 },
116
],
117
output: noFormat`
118
function foo() {
119
return {
120
prop: 'value',
121
nested: {
122
deep: 'value'
123
}
124
};
125
}`,
126
},
127
],
128
});
129
```
130
131
**Comment Formatting Rules:**
132
133
```typescript
134
// Testing rules that care about comment formatting
135
ruleTester.run("comment-spacing", commentSpacingRule, {
136
valid: [
137
noFormat`const x = 1; // This is a comment`,
138
noFormat`const y = 2; // This has extra spaces`,
139
],
140
invalid: [
141
{
142
code: noFormat`const x = 1;//No space before comment`,
143
errors: [{ messageId: "spaceBeforeComment" }],
144
output: noFormat`const x = 1; //No space before comment`,
145
},
146
{
147
code: noFormat`const x = 1; //No space after slashes`,
148
errors: [{ messageId: "spaceAfterSlashes" }],
149
output: noFormat`const x = 1; // No space after slashes`,
150
},
151
],
152
});
153
```
154
155
**String Literal Formatting:**
156
157
```typescript
158
// Testing rules about string formatting where quotes and escaping matter
159
ruleTester.run("string-format", stringFormatRule, {
160
valid: [
161
noFormat`const str = "hello world";`,
162
noFormat`const template = \`Hello \${name}\`;`,
163
],
164
invalid: [
165
{
166
code: noFormat`const str = 'hello world';`, // Single quotes
167
errors: [{ messageId: "useDoubleQuotes" }],
168
output: noFormat`const str = "hello world";`, // Fixed to double quotes
169
},
170
{
171
code: noFormat`const str = "hello\\nworld";`, // Escaped newline
172
errors: [{ messageId: "useTemplateForMultiline" }],
173
output: noFormat`const str = \`hello
174
world\`;`, // Convert to template literal
175
},
176
],
177
});
178
```
179
180
**Semicolon and ASI Rules:**
181
182
```typescript
183
// Testing automatic semicolon insertion rules
184
ruleTester.run("semicolon-rule", semicolonRule, {
185
valid: [
186
noFormat`const x = 1;`,
187
noFormat`
188
const a = 1
189
const b = 2;`, // Mixed semicolon usage
190
],
191
invalid: [
192
{
193
code: noFormat`
194
const x = 1
195
const y = 2`, // Missing semicolons
196
errors: [
197
{ messageId: "missingSemicolon", line: 2 },
198
{ messageId: "missingSemicolon", line: 3 },
199
],
200
output: noFormat`
201
const x = 1;
202
const y = 2;`,
203
},
204
],
205
});
206
```
207
208
### Integration with Prettier
209
210
The noFormat function is specifically designed to work with prettier and linting tools that enforce code formatting.
211
212
**Without noFormat (problematic):**
213
214
```typescript
215
// This test might fail if prettier reformats the code
216
const testCode = `const x = 1;`; // prettier will normalize this
217
218
ruleTester.run("spacing-rule", spacingRule, {
219
invalid: [
220
{
221
code: testCode, // May be reformatted, breaking the test
222
errors: [{ messageId: "badSpacing" }],
223
},
224
],
225
});
226
```
227
228
**With noFormat (correct):**
229
230
```typescript
231
// This test preserves exact formatting
232
const testCode = noFormat`const x = 1;`; // formatting preserved
233
234
ruleTester.run("spacing-rule", spacingRule, {
235
invalid: [
236
{
237
code: testCode, // Exact formatting maintained
238
errors: [{ messageId: "badSpacing" }],
239
},
240
],
241
});
242
```
243
244
### Template Literal Features
245
246
The noFormat function supports all template literal features including interpolation.
247
248
```typescript
249
// Dynamic test generation with preserved formatting
250
function generateFormattingTest(varName: string, spacing: string) {
251
return noFormat`const${spacing}${varName}${spacing}=${spacing}1;`;
252
}
253
254
const tests = [
255
{
256
code: generateFormattingTest("x", " "), // "const x = 1;"
257
errors: [{ messageId: "badSpacing" }],
258
},
259
{
260
code: generateFormattingTest("y", ""), // "const y = 1;"
261
errors: [{ messageId: "noSpacing" }],
262
},
263
];
264
265
// Template literals with complex interpolation
266
const complexTest = noFormat`
267
function ${functionName}(${params}) {
268
${body}
269
}`;
270
```
271
272
## Technical Implementation
273
274
The noFormat function is implemented as a simple template tag that preserves the original string structure:
275
276
```typescript
277
function noFormat(raw: TemplateStringsArray, ...keys: string[]): string {
278
return String.raw({ raw }, ...keys);
279
}
280
```
281
282
This implementation:
283
- Uses `String.raw()` to prevent escape sequence processing
284
- Preserves all whitespace and formatting exactly as written
285
- Supports template literal interpolation with `${...}` syntax
286
- Returns the exact string that would result from the template literal
287
- Has no runtime overhead beyond string concatenation