Skip to content

Commit 7244ff1

Browse files
authored
fix(sort-modules): add missing partition cases
1 parent f071227 commit 7244ff1

2 files changed

Lines changed: 254 additions & 0 deletions

File tree

rules/sort-modules.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { createEslintRule } from '../utils/create-eslint-rule'
4848
import { reportAllErrors } from '../utils/report-all-errors'
4949
import { shouldPartition } from '../utils/should-partition'
5050
import { getGroupIndex } from '../utils/get-group-index'
51+
import { assertIsNever } from '../utils/assert-is-never'
5152
import { computeGroup } from '../utils/compute-group'
5253
import { rangeToDiff } from '../utils/range-to-diff'
5354
import { getSettings } from '../utils/get-settings'
@@ -193,22 +194,47 @@ function analyzeModule({
193194
>[][] = [[]]
194195
for (let node of module.body) {
195196
switch (node.type) {
197+
case AST_NODE_TYPES.TSNamespaceExportDeclaration:
198+
case AST_NODE_TYPES.ExportAllDeclaration:
199+
case AST_NODE_TYPES.ImportDeclaration:
200+
case AST_NODE_TYPES.DebuggerStatement:
201+
case AST_NODE_TYPES.ContinueStatement:
202+
case AST_NODE_TYPES.ReturnStatement:
203+
case AST_NODE_TYPES.EmptyStatement:
204+
case AST_NODE_TYPES.BreakStatement:
205+
case AST_NODE_TYPES.WithStatement:
206+
continue
196207
case AST_NODE_TYPES.ExportDefaultDeclaration:
197208
case AST_NODE_TYPES.ExportNamedDeclaration:
198209
case AST_NODE_TYPES.TSInterfaceDeclaration:
199210
case AST_NODE_TYPES.TSTypeAliasDeclaration:
200211
case AST_NODE_TYPES.FunctionDeclaration:
201212
case AST_NODE_TYPES.TSModuleDeclaration:
202213
break
214+
case AST_NODE_TYPES.TSImportEqualsDeclaration:
203215
case AST_NODE_TYPES.VariableDeclaration:
204216
case AST_NODE_TYPES.ExpressionStatement:
217+
case AST_NODE_TYPES.TSExportAssignment:
218+
case AST_NODE_TYPES.DoWhileStatement:
219+
case AST_NODE_TYPES.LabeledStatement:
220+
case AST_NODE_TYPES.SwitchStatement:
221+
case AST_NODE_TYPES.WhileStatement:
222+
case AST_NODE_TYPES.ForInStatement:
223+
case AST_NODE_TYPES.ForOfStatement:
224+
case AST_NODE_TYPES.ThrowStatement:
225+
case AST_NODE_TYPES.BlockStatement:
226+
case AST_NODE_TYPES.ForStatement:
227+
case AST_NODE_TYPES.TryStatement:
228+
case AST_NODE_TYPES.IfStatement:
205229
sortingNodeGroupsWithoutOverloadSignature.push([])
206230
continue
207231
case AST_NODE_TYPES.TSDeclareFunction:
208232
case AST_NODE_TYPES.TSEnumDeclaration:
209233
case AST_NODE_TYPES.ClassDeclaration:
210234
break
235+
/* v8 ignore next 2 -- @preserve Exhaustive guard. */
211236
default:
237+
assertIsNever(node)
212238
continue
213239
}
214240

test/rules/sort-modules.test.ts

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,234 @@ describe('sort-modules', () => {
285285
})
286286
})
287287

288+
it('creates partitions at if statements', async () => {
289+
await valid({
290+
code: dedent`
291+
enum B { b = 'b' }
292+
if (B.b === 'b') {}
293+
enum A { a = 'a' }
294+
`,
295+
options: [options],
296+
})
297+
})
298+
299+
it('creates partitions at while statements', async () => {
300+
await valid({
301+
code: dedent`
302+
enum B { b = 'b' }
303+
while (B.b === 'b') {}
304+
enum A { a = 'a' }
305+
`,
306+
options: [options],
307+
})
308+
})
309+
310+
it('creates partitions at for-in loops', async () => {
311+
await valid({
312+
code: dedent`
313+
enum B { b = 'b' }
314+
for (const key in B) {}
315+
enum A { a = 'a' }
316+
`,
317+
options: [options],
318+
})
319+
})
320+
321+
it('creates partitions at try/catch statements', async () => {
322+
await valid({
323+
code: dedent`
324+
enum B { b = 'b' }
325+
try { B.b } catch {}
326+
enum A { a = 'a' }
327+
`,
328+
options: [options],
329+
})
330+
})
331+
332+
it('creates partitions at for loops', async () => {
333+
await valid({
334+
code: dedent`
335+
enum B { b = 'b' }
336+
for (let i = 0; i < Object.keys(B).length; i++) {}
337+
enum A { a = 'a' }
338+
`,
339+
options: [options],
340+
})
341+
})
342+
343+
it('creates partitions at for-of loops', async () => {
344+
await valid({
345+
code: dedent`
346+
enum B { b = 'b' }
347+
for (const value of Object.values(B)) {}
348+
enum A { a = 'a' }
349+
`,
350+
options: [options],
351+
})
352+
})
353+
354+
it('creates partitions at do-while loops', async () => {
355+
await valid({
356+
code: dedent`
357+
enum B { b = 'b' }
358+
do { void B.b } while (false)
359+
enum A { a = 'a' }
360+
`,
361+
options: [options],
362+
})
363+
})
364+
365+
it('creates partitions at switch statements', async () => {
366+
await valid({
367+
code: dedent`
368+
enum B { b = 'b' }
369+
switch (B.b) { case 'b': break }
370+
enum A { a = 'a' }
371+
`,
372+
options: [options],
373+
})
374+
})
375+
376+
it('creates partitions at throw statements', async () => {
377+
await valid({
378+
code: dedent`
379+
enum B { b = 'b' }
380+
throw new Error(B.b)
381+
enum A { a = 'a' }
382+
`,
383+
options: [options],
384+
})
385+
})
386+
387+
it('creates partitions at block statements', async () => {
388+
await valid({
389+
code: dedent`
390+
enum B { b = 'b' }
391+
{ const x = B.b }
392+
enum A { a = 'a' }
393+
`,
394+
options: [options],
395+
})
396+
})
397+
398+
it('creates partitions at labeled statements', async () => {
399+
await valid({
400+
code: dedent`
401+
enum B { b = 'b' }
402+
label: { const x = B.b }
403+
enum A { a = 'a' }
404+
`,
405+
options: [options],
406+
})
407+
})
408+
409+
it('creates partitions at TypeScript import-equals declarations', async () => {
410+
await valid({
411+
code: dedent`
412+
enum B { b = 'b' }
413+
import foo = B
414+
enum A { a = 'a' }
415+
`,
416+
options: [options],
417+
})
418+
})
419+
420+
it('creates partitions at export assignments', async () => {
421+
await valid({
422+
code: dedent`
423+
enum B { b = 'b' }
424+
export = B
425+
enum A { a = 'a' }
426+
`,
427+
options: [options],
428+
})
429+
})
430+
431+
it('sorts across empty statements', async () => {
432+
await invalid({
433+
errors: [
434+
{
435+
messageId: 'unexpectedModulesOrder',
436+
data: { right: 'A', left: 'B' },
437+
},
438+
],
439+
code: dedent`
440+
enum B { b = 'b' }
441+
;
442+
enum A { a = 'a' }
443+
`,
444+
options: [options],
445+
})
446+
})
447+
448+
it('sorts across debugger statements', async () => {
449+
await invalid({
450+
errors: [
451+
{
452+
messageId: 'unexpectedModulesOrder',
453+
data: { right: 'A', left: 'B' },
454+
},
455+
],
456+
code: dedent`
457+
enum B { b = 'b' }
458+
debugger
459+
enum A { a = 'a' }
460+
`,
461+
options: [options],
462+
})
463+
})
464+
465+
it('sorts across import declarations', async () => {
466+
await invalid({
467+
errors: [
468+
{
469+
messageId: 'unexpectedModulesOrder',
470+
data: { right: 'A', left: 'B' },
471+
},
472+
],
473+
code: dedent`
474+
enum B { b = 'b' }
475+
import 'x'
476+
enum A { a = 'a' }
477+
`,
478+
options: [options],
479+
})
480+
})
481+
482+
it('sorts across export-all declarations', async () => {
483+
await invalid({
484+
errors: [
485+
{
486+
messageId: 'unexpectedModulesOrder',
487+
data: { right: 'A', left: 'B' },
488+
},
489+
],
490+
code: dedent`
491+
enum B { b = 'b' }
492+
export * from 'x'
493+
enum A { a = 'a' }
494+
`,
495+
options: [options],
496+
})
497+
})
498+
499+
it('sorts across namespace export declarations', async () => {
500+
await invalid({
501+
errors: [
502+
{
503+
messageId: 'unexpectedModulesOrder',
504+
data: { right: 'A', left: 'B' },
505+
},
506+
],
507+
code: dedent`
508+
enum B { b = 'b' }
509+
export as namespace Foo
510+
enum A { a = 'a' }
511+
`,
512+
options: [options],
513+
})
514+
})
515+
288516
it('accepts complex predefined group configurations', async () => {
289517
await valid({
290518
options: [

0 commit comments

Comments
 (0)