Repository: IanVS/prettier-plugin-sort-imports (ts)

Issue:
Add importOrderCaseInsensitive option again
There's value in sorting uppercase first: constants, constructors and functions become sorted in that order.

Support for case sensitive sorting was dropped here #63 


Pull request description:
Re-add `importOrderCaseSensitive` option for case-sensitive sorting
Implements a custom natural sort algorithm which allows for numeric natural sorting while also sorting all uppercase letters before all lowercase letters, which is the desired behavior here.

For example, when `importOrderCaseSensitive` is false (the default):

```js
import ExampleComponent from './ExampleComponent';
import ExamplesList from './ExamplesList';
import ExampleWidget from './ExampleWidget';
```

Compared with `"importOrderCaseSensitive": true`:

```js
import ExampleComponent from './ExampleComponent';
import ExampleWidget from './ExampleWidget';
import ExamplesList from './ExamplesList';
```

Closes #151

Patch:
diff --git a/README.md b/README.md
index 01f834b..4979962 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,7 @@ This project is based on [@trivago/prettier-plugin-sort-imports](https://github.
       - [7. Enable/disable plugin or use different order in certain folders or files](#7-enabledisable-plugin-or-use-different-order-in-certain-folders-or-files)
     - [`importOrderTypeScriptVersion`](#importordertypescriptversion)
     - [`importOrderParserPlugins`](#importorderparserplugins)
+    - [`importOrderCaseSensitive`](#importordercasesensitive)
   - [Prevent imports from being sorted](#prevent-imports-from-being-sorted)
   - [Comments](#comments)
 - [FAQ / Troubleshooting](#faq--troubleshooting)
@@ -139,6 +140,7 @@ module.exports = {
     importOrder: ['^@core/(.*)$', '', '^@server/(.*)$', '', '^@ui/(.*)$', '', '^[./]'],
     importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'],
     importOrderTypeScriptVersion: '5.0.0',
+    importOrderCaseSensitive: false,
 };
 ```
 
@@ -393,6 +395,33 @@ with options as a JSON string of the plugin array:
 "importOrderParserPlugins": []
 ```
 
+#### `importOrderCaseSensitive`
+
+**type**: `boolean`
+
+**default value**: `false`
+
+A boolean value to enable case-sensitivity in the sorting algorithm
+used to order imports within each match group.
+
+For example, when false (or not specified):
+
+```javascript
+import {CatComponent, catFilter, DogComponent, dogFilter} from './animals';
+import ExampleComponent from './ExampleComponent';
+import ExamplesList from './ExamplesList';
+import ExampleWidget from './ExampleWidget';
+```
+
+compared with `"importOrderCaseSensitive": true`:
+
+```javascript
+import ExampleComponent from './ExampleComponent';
+import ExampleWidget from './ExampleWidget';
+import ExamplesList from './ExamplesList';
+import {CatComponent, DogComponent, catFilter, dogFilter} from './animals';
+```
+
 ### Prevent imports from being sorted
 
 This plugin supports standard prettier ignore comments. By default, side-effect imports (like
diff --git a/src/index.ts b/src/index.ts
index dbd5cff..63625ef 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -50,6 +50,12 @@ export const options: Record<
         description:
             'Version of TypeScript in use in the project.  Determines some output syntax when using TypeScript.',
     },
+    importOrderCaseSensitive: {
+        type: 'boolean',
+        category: 'Global',
+        default: false,
+        description: 'Provide a case sensitivity boolean flag',
+    },
 };
 
 export const parsers = {
diff --git a/src/natural-sort/index.ts b/src/natural-sort/index.ts
index afe301b..2117603 100644
--- a/src/natural-sort/index.ts
+++ b/src/natural-sort/index.ts
@@ -1,12 +1,47 @@
 export function naturalSort(a: string, b: string): number {
     const left = typeof a === 'string' ? a : String(a);
-
     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#syntax
     const sortOptions: Intl.CollatorOptions = {
         sensitivity: 'base',
         numeric: true,
         caseFirst: 'lower',
     };
-
     return left.localeCompare(b, 'en', sortOptions);
 }
+
+/**
+ * Using a custom comparison function here, as `String.localeCompare` does not
+ * support sorting characters with all uppercase letters before lowercase
+ * letters, which is the desired behavior for a case-sensitive import sort. When
+ * `sensitivity` is set to `base`, `String.localeCompare` sorts alphabetically
+ * and then by case, but we want to sort by case first (then alphabetical).
+ */
+const numericRegex = /^\d+/;
+export function naturalSortCaseSensitive(a: string, b: string) {
+    let aIndex = 0;
+    let bIndex = 0;
+    while (aIndex < Math.max(a.length, b.length)) {
+        // check if we've encountered a number and compare appropriately if so
+        const aNumericMatch = a.slice(aIndex).match(numericRegex);
+        const bNumericMatch = b.slice(bIndex).match(numericRegex);
+        if (aNumericMatch && !bNumericMatch) return -1;
+        if (!aNumericMatch && bNumericMatch) return 1;
+        if (aNumericMatch && bNumericMatch) {
+            const aNumber = parseInt(aNumericMatch[0]);
+            const bNumber = parseInt(bNumericMatch[0]);
+            if (aNumber > bNumber) return 1;
+            if (aNumber < bNumber) return -1;
+            aIndex += aNumericMatch[0].length;
+            bIndex += bNumericMatch[0].length;
+        }
+        // otherwise just compare characters directly
+        const aChar = a[aIndex];
+        const bChar = b[bIndex];
+        if (aChar && !bChar) return 1;
+        if (!aChar && bChar) return -1;
+        if (aChar !== bChar) return aChar.charCodeAt(0) - bChar.charCodeAt(0);
+        aIndex++;
+        bIndex++;
+    }
+    return 0;
+}
diff --git a/src/types.ts b/src/types.ts
index e8974fb..136d93c 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -26,7 +26,10 @@ export interface PrettierOptions
 /** Subset of options that need to be normalized, or affect normalization */
 export type NormalizableOptions = Pick<
     PrettierOptions,
-    'importOrder' | 'importOrderParserPlugins' | 'importOrderTypeScriptVersion'
+    | 'importOrder'
+    | 'importOrderParserPlugins'
+    | 'importOrderTypeScriptVersion'
+    | 'importOrderCaseSensitive'
 > &
     // filepath can be undefined when running prettier via the api on text input
     Pick<Partial<PrettierOptions>, 'filepath'>;
@@ -63,6 +66,7 @@ export type ImportRelated = ImportOrLine | SomeSpecifier;
 export interface ExtendedOptions {
     importOrder: PrettierOptions['importOrder'];
     importOrderCombineTypeAndValueImports: boolean;
+    importOrderCaseSensitive: boolean;
     hasAnyCustomGroupSeparatorsInImportOrder: boolean;
     provideGapAfterTopOfFileComments: boolean;
     plugins: ParserPlugin[];
@@ -79,7 +83,9 @@ export type GetSortedNodes = (
 
 export type GetSortedNodesByImportOrder = (
     nodes: ImportDeclaration[],
-    options: Pick<ExtendedOptions, 'importOrder'>,
+    options: Pick<ExtendedOptions, 'importOrder'> & {
+        importOrderCaseSensitive?: boolean;
+    },
 ) => ImportOrLine[];
 
 export type GetChunkTypeOfNode = (node: ImportDeclaration) => ChunkType;
diff --git a/src/utils/get-sorted-import-specifiers.ts b/src/utils/get-sorted-import-specifiers.ts
index 19cc050..87013e6 100644
--- a/src/utils/get-sorted-import-specifiers.ts
+++ b/src/utils/get-sorted-import-specifiers.ts
@@ -1,6 +1,7 @@
 import { type ImportDeclaration } from '@babel/types';
 
-import { naturalSort } from '../natural-sort';
+import type { PluginConfig } from '../../types';
+import { naturalSort, naturalSortCaseSensitive } from '../natural-sort';
 
 /**
  * This function returns import nodes with alphabetically sorted module
@@ -12,7 +13,11 @@ import { naturalSort } from '../natural-sort';
  *
  * @param node Import declaration node
  */
-export const getSortedImportSpecifiers = (node: ImportDeclaration) => {
+export const getSortedImportSpecifiers = (
+    node: ImportDeclaration,
+    options?: Pick<PluginConfig, 'importOrderCaseSensitive'>,
+) => {
+    const { importOrderCaseSensitive } = options || {};
     node.specifiers.sort((a, b) => {
         if (a.type !== b.type) {
             return a.type === 'ImportDefaultSpecifier' ? -1 : 1;
@@ -25,8 +30,10 @@ export const getSortedImportSpecifiers = (node: ImportDeclaration) => {
             // flow uses null for value import specifiers
             return a.importKind === 'value' || a.importKind == null ? -1 : 1;
         }
-
-        return naturalSort(a.local.name, b.local.name);
+        const sortFn = importOrderCaseSensitive
+            ? naturalSortCaseSensitive
+            : naturalSort;
+        return sortFn(a.local.name, b.local.name);
     });
     return node;
 };
diff --git a/src/utils/get-sorted-nodes-by-import-order.ts b/src/utils/get-sorted-nodes-by-import-order.ts
index 791ad6e..dc0f8e3 100644
--- a/src/utils/get-sorted-nodes-by-import-order.ts
+++ b/src/utils/get-sorted-nodes-by-import-order.ts
@@ -21,7 +21,7 @@ import {
  */
 export const getSortedNodesByImportOrder: GetSortedNodesByImportOrder = (
     originalNodes,
-    { importOrder },
+    { importOrder, importOrderCaseSensitive },
 ) => {
     if (
         process.env.NODE_ENV === 'test' &&
@@ -83,10 +83,14 @@ export const getSortedNodesByImportOrder: GetSortedNodesByImportOrder = (
 
         if (groupNodes.length === 0) continue;
 
-        const sortedInsideGroup = getSortedNodesGroup(groupNodes);
+        const sortedInsideGroup = getSortedNodesGroup(groupNodes, {
+            importOrderCaseSensitive,
+        });
 
         // Sort the import specifiers
-        sortedInsideGroup.forEach((node) => getSortedImportSpecifiers(node));
+        sortedInsideGroup.forEach((node) =>
+            getSortedImportSpecifiers(node, { importOrderCaseSensitive }),
+        );
 
         finalNodes.push(...sortedInsideGroup);
     }
diff --git a/src/utils/get-sorted-nodes-group.ts b/src/utils/get-sorted-nodes-group.ts
index da58f36..9e6d2ae 100644
--- a/src/utils/get-sorted-nodes-group.ts
+++ b/src/utils/get-sorted-nodes-group.ts
@@ -1,7 +1,15 @@
 import type { ImportDeclaration } from '@babel/types';
 
-import { naturalSort } from '../natural-sort';
+import type { PluginConfig } from '../../types';
+import { naturalSort, naturalSortCaseSensitive } from '../natural-sort';
 
-export const getSortedNodesGroup = (imports: ImportDeclaration[]) => {
-    return imports.sort((a, b) => naturalSort(a.source.value, b.source.value));
+export const getSortedNodesGroup = (
+    imports: ImportDeclaration[],
+    options?: Pick<PluginConfig, 'importOrderCaseSensitive'>,
+) => {
+    const { importOrderCaseSensitive } = options || {};
+    const sortFn = importOrderCaseSensitive
+        ? naturalSortCaseSensitive
+        : naturalSort;
+    return imports.sort((a, b) => sortFn(a.source.value, b.source.value));
 };
diff --git a/src/utils/normalize-plugin-options.ts b/src/utils/normalize-plugin-options.ts
index c114424..aa692c3 100644
--- a/src/utils/normalize-plugin-options.ts
+++ b/src/utils/normalize-plugin-options.ts
@@ -107,6 +107,7 @@ export function examineAndNormalizePluginOptions(
     return {
         importOrder,
         importOrderCombineTypeAndValueImports,
+        importOrderCaseSensitive: !!options.importOrderCaseSensitive,
         hasAnyCustomGroupSeparatorsInImportOrder: importOrder.some(
             isCustomGroupSeparator,
         ),
diff --git a/types/index.d.ts b/types/index.d.ts
index 35886bb..3578c73 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -45,6 +45,30 @@ export interface PluginConfig {
      */
     importOrderTypeScriptVersion?: string;
 
+    /**
+     * A boolean value to enable case-sensitivity in the sorting algorithm
+     * used to order imports within each match group.
+     *
+     * For example, when false (or not specified):
+     *
+     * ```js
+     * import ExampleComponent from './ExampleComponent';
+     * import ExamplesList from './ExamplesList';
+     * import ExampleWidget from './ExampleWidget';
+     * ```
+     *
+     * compared with `"importOrderCaseSensitive": true`:
+     *
+     * ```js
+     * import ExampleComponent from './ExampleComponent';
+     * import ExampleWidget from './ExampleWidget';
+     * import ExamplesList from './ExamplesList';
+     * ```
+     *
+     * @default false
+     */
+    importOrderCaseSensitive?: boolean;
+
     /**
      * A collection of plugins for babel parser. The plugin passes this list to babel parser, so it can understand the syntaxes
      * used in the file being formatted. The plugin uses prettier itself to figure out the parser it needs to use but if that fails,


Test patch:
diff --git a/src/natural-sort/__tests__/natural-sort.spec.ts b/src/natural-sort/__tests__/natural-sort.spec.ts
index fa57e55..eabee67 100644
--- a/src/natural-sort/__tests__/natural-sort.spec.ts
+++ b/src/natural-sort/__tests__/natural-sort.spec.ts
@@ -1,26 +1,115 @@
-import { expect, test } from 'vitest';
+import { describe, expect, test } from 'vitest';
 
-import { naturalSort } from '..';
+import { naturalSort, naturalSortCaseSensitive } from '..';
 
-test('should sort normal things alphabetically', () => {
-    expect(
-        ['a', 'h', 'b', 'i', 'c', 'd', 'j', 'e', 'k', 'f', 'g'].sort((a, b) =>
-            naturalSort(a, b),
-        ),
-    ).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']);
-});
+describe('naturalSort', () => {
+    test('should sort normal things alphabetically', () => {
+        expect(
+            ['a', 'h', 'b', 'i', 'c', 'd', 'j', 'e', 'k', 'f', 'g'].sort(
+                (a, b) => naturalSort(a, b),
+            ),
+        ).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']);
+    });
+
+    test('should ignore capitalization differences', () => {
+        expect(
+            ['./ExampleComponent', './ExamplesList', './ExampleWidget'].sort(
+                (a, b) => naturalSort(a, b),
+            ),
+        ).toEqual(['./ExampleComponent', './ExamplesList', './ExampleWidget']);
+    });
 
-test('should ignore capitalization differences', () => {
-    // We have no option to cause case-sensitive sorting, so this is the "default" case!
-    expect(
-        ['./ExampleView', './ExamplesList'].sort((a, b) => naturalSort(a, b)),
-    ).toEqual(['./ExamplesList', './ExampleView']);
+    test('should sort things numerically', () => {
+        expect(
+            [
+                'a2',
+                'a3',
+                'a10',
+                'a1',
+                'a11',
+                'a9',
+                'a1b',
+                'file000b',
+                'file000a',
+                'file00a',
+                'file00z',
+            ].sort(naturalSort),
+        ).toEqual([
+            'a1',
+            'a1b',
+            'a2',
+            'a3',
+            'a9',
+            'a10',
+            'a11',
+            'file000a',
+            'file00a',
+            'file000b',
+            'file00z',
+        ]);
+    });
 });
 
-test('should sort things numerically', () => {
-    expect(
-        ['a2', 'a3', 'a10', 'a1', 'a11', 'a9'].sort((a, b) =>
-            naturalSort(a, b),
-        ),
-    ).toEqual(['a1', 'a2', 'a3', 'a9', 'a10', 'a11']);
+describe('naturalSortCaseSensitive', () => {
+    test('should not ignore capitalization differences', () => {
+        expect(
+            ['./ExampleComponent', './ExamplesList', './ExampleWidget'].sort(
+                (a, b) => naturalSortCaseSensitive(a, b),
+            ),
+        ).toEqual(['./ExampleComponent', './ExampleWidget', './ExamplesList']);
+    });
+
+    test('should sort numerically and case-sensitively', () => {
+        expect(
+            [
+                'file1',
+                'File10',
+                'AbA',
+                'file10',
+                'files10',
+                'file1z',
+                'file10ab',
+                'file2s',
+                'a',
+                'Ab',
+                'file20',
+                'file22',
+                'file11',
+                'file2',
+                'File20',
+                'file000b',
+                'file000a',
+                'file00a',
+                'file00z',
+                'aaa',
+                'AAA',
+                'bBb',
+                'BBB',
+            ].sort(naturalSortCaseSensitive),
+        ).toEqual([
+            'AAA',
+            'Ab',
+            'AbA',
+            'BBB',
+            'File10',
+            'File20',
+            'a',
+            'aaa',
+            'bBb',
+            'file000a',
+            'file00a',
+            'file000b',
+            'file00z',
+            'file1',
+            'file1z',
+            'file2',
+            'file2s',
+            'file10',
+            'file10ab',
+            'file11',
+            'file20',
+            'file22',
+            'files10',
+        ]);
+    });
 });
diff --git a/src/utils/__tests__/get-sorted-import-specifiers.spec.ts b/src/utils/__tests__/get-sorted-import-specifiers.spec.ts
index b40dab5..fa015be 100644
--- a/src/utils/__tests__/get-sorted-import-specifiers.spec.ts
+++ b/src/utils/__tests__/get-sorted-import-specifiers.spec.ts
@@ -70,3 +70,20 @@ test('should group type imports after value imports - flow', () => {
         'TypeB',
     ]);
 });
+
+test('should sort case-sensitively', () => {
+    const code = `import { ExampleComponent, ExamplesList, ExampleWidget } from '@components/e';`;
+    const [importNode] = getImportNodes(code);
+    const sortedImportSpecifiers = getSortedImportSpecifiers(importNode, {
+        importOrderCaseSensitive: true,
+    });
+    const specifiersList = getSortedNodesModulesNames(
+        sortedImportSpecifiers.specifiers,
+    );
+
+    expect(specifiersList).toEqual([
+        'ExampleComponent',
+        'ExampleWidget',
+        'ExamplesList',
+    ]);
+});
diff --git a/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts b/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts
index 5d18a5f..eb0c4be 100644
--- a/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts
+++ b/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts
@@ -274,3 +274,28 @@ test('it does not add multiple custom import separators', () => {
         './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',
+    ]);
+});
diff --git a/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts b/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts
index 2a2aae6..3bc6258 100644
--- a/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts
+++ b/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts
@@ -13,6 +13,7 @@ const defaultOptions = examineAndNormalizePluginOptions({
     // First separator for top-of-file comments, second to separate side-effect and ignored chunks, for easier test readability
     importOrder: testingOnly.normalizeImportOrderOption(['', '']),
     importOrderTypeScriptVersion: '5.0.0',
+    importOrderCaseSensitive: false,
     importOrderParserPlugins: [],
     filepath: __filename,
 });
diff --git a/src/utils/__tests__/normalize-plugin-options.spec.ts b/src/utils/__tests__/normalize-plugin-options.spec.ts
index ecdd1df..92133c7 100644
--- a/src/utils/__tests__/normalize-plugin-options.spec.ts
+++ b/src/utils/__tests__/normalize-plugin-options.spec.ts
@@ -96,6 +96,7 @@ describe('examineAndNormalizePluginOptions', () => {
             examineAndNormalizePluginOptions({
                 importOrder: DEFAULT_IMPORT_ORDER,
                 importOrderParserPlugins: [],
+                importOrderCaseSensitive: false,
                 importOrderTypeScriptVersion: '1.0.0',
                 filepath: __filename,
             } as NormalizableOptions),
@@ -107,6 +108,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 '^[.]',
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: [],
             provideGapAfterTopOfFileComments: false,
         });
@@ -121,6 +123,7 @@ describe('examineAndNormalizePluginOptions', () => {
                     '^[./]',
                 ],
                 importOrderParserPlugins: [],
+                importOrderCaseSensitive: false,
                 importOrderTypeScriptVersion: '1.0.0',
                 filepath: __filename,
             } as NormalizableOptions),
@@ -133,6 +136,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 '^[./]',
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: [],
             provideGapAfterTopOfFileComments: false,
         });
@@ -142,6 +146,7 @@ describe('examineAndNormalizePluginOptions', () => {
             examineAndNormalizePluginOptions({
                 importOrder: [''],
                 importOrderParserPlugins: [],
+                importOrderCaseSensitive: false,
                 importOrderTypeScriptVersion: '1.0.0',
                 filepath: __filename,
             } as NormalizableOptions),
@@ -153,6 +158,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 THIRD_PARTY_MODULES_SPECIAL_WORD,
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: [],
             provideGapAfterTopOfFileComments: true,
         });
@@ -173,6 +179,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 '^[.]',
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: ['typescript'],
             provideGapAfterTopOfFileComments: false,
         });
@@ -184,6 +191,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 importOrder: DEFAULT_IMPORT_ORDER,
                 importOrderParserPlugins: ['typescript', 'jsx'],
                 importOrderTypeScriptVersion: '5.0.0',
+                importOrderCaseSensitive: false,
                 filepath: __filename,
             } as NormalizableOptions),
         ).toEqual({
@@ -194,6 +202,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 '^[.]',
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: ['typescript'],
             provideGapAfterTopOfFileComments: false,
         });
@@ -203,6 +212,7 @@ describe('examineAndNormalizePluginOptions', () => {
             examineAndNormalizePluginOptions({
                 importOrder: DEFAULT_IMPORT_ORDER,
                 importOrderParserPlugins: [],
+                importOrderCaseSensitive: false,
                 importOrderTypeScriptVersion: '1.0.0',
                 filepath: undefined,
             } as NormalizableOptions),
@@ -214,6 +224,7 @@ describe('examineAndNormalizePluginOptions', () => {
                 '^[.]',
             ],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: [],
             provideGapAfterTopOfFileComments: false,
         });
@@ -224,6 +235,7 @@ describe('examineAndNormalizePluginOptions', () => {
             examineAndNormalizePluginOptions({
                 importOrder: [],
                 importOrderParserPlugins: [],
+                importOrderCaseSensitive: false,
                 importOrderTypeScriptVersion: '1.0.0',
                 filepath: __filename,
             } as NormalizableOptions),
@@ -231,6 +243,7 @@ describe('examineAndNormalizePluginOptions', () => {
             hasAnyCustomGroupSeparatorsInImportOrder: false,
             importOrder: [],
             importOrderCombineTypeAndValueImports: true,
+            importOrderCaseSensitive: false,
             plugins: [],
             provideGapAfterTopOfFileComments: false,
         });
diff --git a/tests/ImportOrderCaseSensitive/__snapshots__/ppsi.spec.ts.snap b/tests/ImportOrderCaseSensitive/__snapshots__/ppsi.spec.ts.snap
new file mode 100644
index 0000000..a93b151
--- /dev/null
+++ b/tests/ImportOrderCaseSensitive/__snapshots__/ppsi.spec.ts.snap
@@ -0,0 +1,20 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`mixed-case.ts - typescript-verify > mixed-case.ts 1`] = `
+
+import c from "c";
+import b from "b";
+import a from "a";
+
+import {cat, Dog} from "C";
+import B from "B";
+import A from "A";
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+import A from "A";
+import B from "B";
+import { Dog, cat } from "C";
+import a from "a";
+import b from "b";
+import c from "c";
+
+`;
diff --git a/tests/ImportOrderCaseSensitive/mixed-case.ts b/tests/ImportOrderCaseSensitive/mixed-case.ts
new file mode 100644
index 0000000..7b0a094
--- /dev/null
+++ b/tests/ImportOrderCaseSensitive/mixed-case.ts
@@ -0,0 +1,8 @@
+
+import c from "c";
+import b from "b";
+import a from "a";
+
+import {cat, Dog} from "C";
+import B from "B";
+import A from "A";
diff --git a/tests/ImportOrderCaseSensitive/ppsi.spec.ts b/tests/ImportOrderCaseSensitive/ppsi.spec.ts
new file mode 100644
index 0000000..596a005
--- /dev/null
+++ b/tests/ImportOrderCaseSensitive/ppsi.spec.ts
@@ -0,0 +1,7 @@
+import {run_spec} from '../../test-setup/run_spec';
+
+run_spec(__dirname, ["typescript"], {
+    importOrder: ['^@core/(.*)$', '^@server/(.*)', '^@ui/(.*)$', '^[./]'],
+    importOrderCaseSensitive: true,
+    importOrderParserPlugins: ['typescript']
+});