prettier-plugin-imports
Version:
A prettier plugins to sort imports in provided RegEx order
301 lines (288 loc) • 6.47 kB
text/typescript
import { expect, test } from 'vitest';
import { getImportNodes } from './get-import-nodes';
import { getSortedNodesByImportOrder } from './get-sorted-nodes-by-import-order';
import { getSortedNodesModulesNames } from './get-sorted-nodes-modules-names';
import { getSortedNodesNamesAndNewlines } from './get-sorted-nodes-names-and-newlines';
import { testingOnly } from './normalize-plugin-options';
import type { ImportDeclaration } from '@babel/types';
const code = `// first comment
// second comment
import z from 'z';
import c, { cD } from 'c';
import g from 'g';
import { tC, tA, tB } from 't';
import k, { kE, kB } from 'k';
import * as a from 'a';
import * as local from './local';
import * as x from 'x';
import path from 'path';
import url from 'node:url';
import * as fs from "node:fs/promises"
import BY from 'BY';
import Ba from 'Ba';
import XY from 'XY';
import Xa from 'Xa';
`;
test('it returns all sorted nodes', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption(['^[./]']),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'a',
'Ba',
'BY',
'c',
'g',
'k',
't',
'x',
'Xa',
'XY',
'z',
'./local',
]);
expect(
sorted
.filter((node) => node.type === 'ImportDeclaration')
.map((importDeclaration) =>
getSortedNodesModulesNames(importDeclaration.specifiers),
),
).toEqual([
['fs'],
['url'], // `node:url` comes before `path`
['path'],
['a'],
['Ba'],
['BY'],
['c', 'cD'],
['g'],
['k', 'kB', 'kE'],
['tA', 'tB', 'tC'],
['x'],
['Xa'],
['XY'],
['z'],
['local'],
]);
});
test('it returns all sorted nodes with sort order', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption([
'^a$',
'^t$',
'^k$',
'^B',
'^[./]',
]),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'c',
'g',
'x',
'Xa',
'XY',
'z',
'a',
't',
'k',
'Ba',
'BY',
'./local',
]);
expect(
sorted
.filter((node) => node.type === 'ImportDeclaration')
.map((importDeclaration) =>
getSortedNodesModulesNames(importDeclaration.specifiers),
),
).toEqual([
['fs'],
['url'], // `node:url` comes before `path`
['path'],
['c', 'cD'],
['g'],
['x'],
['Xa'],
['XY'],
['z'],
['a'],
['tA', 'tB', 'tC'],
['k', 'kB', 'kE'],
['Ba'],
['BY'],
['local'],
]);
});
test('it returns all sorted import nodes with sorted import specifiers', () => {
const code = `
import { tC, tA, tB } from 't';
import k, { kE, kB } from 'k';
import {type B, A} from 'z';
`;
const result = getImportNodes(code, {
plugins: ['typescript'],
});
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption(['^[./]']),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual(['k', 't', 'z']);
expect(
sorted
.filter((node) => node.type === 'ImportDeclaration')
.map((importDeclaration) =>
getSortedNodesModulesNames(importDeclaration.specifiers),
),
).toEqual([
['k', 'kB', 'kE'],
['tA', 'tB', 'tC'],
['A', 'B'],
]);
});
test('it returns all sorted nodes with builtin specifiers at the top', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption(['^[./]']),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'a',
'Ba',
'BY',
'c',
'g',
'k',
't',
'x',
'Xa',
'XY',
'z',
'./local',
]);
});
test('it returns all sorted nodes with custom third party modules and builtins at top', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption([
'^a$',
'<THIRD_PARTY_MODULES>',
'^t$',
'^k$',
'^[./]',
]),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'a',
'Ba',
'BY',
'c',
'g',
'x',
'Xa',
'XY',
'z',
't',
'k',
'./local',
]);
});
test('it returns all sorted nodes with custom separation', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption([
'^a$',
'<THIRD_PARTY_MODULES>',
'^t$',
'',
'^k$',
'^[./]',
]),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'a',
'Ba',
'BY',
'c',
'g',
'x',
'Xa',
'XY',
'z',
't',
'',
'k',
'./local',
]);
});
test('it does not add multiple custom import separators', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption([
'^a$',
'<THIRD_PARTY_MODULES>',
'^t$',
'',
'notfound',
'',
'^k$',
'^[./]',
]),
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'a',
'Ba',
'BY',
'c',
'g',
'x',
'Xa',
'XY',
'z',
't',
'',
'k',
'./local',
]);
});
test('it should sort nodes case-sensitively', () => {
const result = getImportNodes(code);
const sorted = getSortedNodesByImportOrder(result, {
importOrder: testingOnly.normalizeImportOrderOption(['^[./]']),
importOrderCaseSensitive: true,
}) as ImportDeclaration[];
expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([
'node:fs/promises',
'node:url',
'path',
'BY',
'Ba',
'XY',
'Xa',
'a',
'c',
'g',
'k',
't',
'x',
'z',
'./local',
]);
});