/ src / tests / path-utils.test.ts
path-utils.test.ts
  1  import { describe, it, expect } from "@jest/globals";
  2  import {
  3    normalizePath,
  4    expandHome,
  5    convertToWindowsPath,
  6  } from "../utils/path-utils.js";
  7  
  8  describe("Path Utilities", () => {
  9    describe("convertToWindowsPath", () => {
 10      it("leaves Unix paths unchanged", () => {
 11        expect(convertToWindowsPath("/usr/local/bin")).toBe("/usr/local/bin");
 12        expect(convertToWindowsPath("/home/user/some path")).toBe(
 13          "/home/user/some path"
 14        );
 15      });
 16  
 17      it("converts WSL paths to Windows format", () => {
 18        expect(convertToWindowsPath("/mnt/c/NS/MyKindleContent")).toBe(
 19          "C:\\NS\\MyKindleContent"
 20        );
 21      });
 22  
 23      it("converts Unix-style Windows paths to Windows format", () => {
 24        expect(convertToWindowsPath("/c/NS/MyKindleContent")).toBe(
 25          "C:\\NS\\MyKindleContent"
 26        );
 27      });
 28  
 29      it("leaves Windows paths unchanged but ensures backslashes", () => {
 30        expect(convertToWindowsPath("C:\\NS\\MyKindleContent")).toBe(
 31          "C:\\NS\\MyKindleContent"
 32        );
 33        expect(convertToWindowsPath("C:/NS/MyKindleContent")).toBe(
 34          "C:\\NS\\MyKindleContent"
 35        );
 36      });
 37  
 38      it("handles Windows paths with spaces", () => {
 39        expect(convertToWindowsPath("C:\\Program Files\\Some App")).toBe(
 40          "C:\\Program Files\\Some App"
 41        );
 42        expect(convertToWindowsPath("C:/Program Files/Some App")).toBe(
 43          "C:\\Program Files\\Some App"
 44        );
 45      });
 46  
 47      it("handles uppercase and lowercase drive letters", () => {
 48        expect(convertToWindowsPath("/mnt/d/some/path")).toBe("D:\\some\\path");
 49        expect(convertToWindowsPath("/d/some/path")).toBe("D:\\some\\path");
 50      });
 51    });
 52  
 53    describe("normalizePath", () => {
 54      it("preserves Unix paths", () => {
 55        expect(normalizePath("/usr/local/bin")).toBe("/usr/local/bin");
 56        expect(normalizePath("/home/user/some path")).toBe(
 57          "/home/user/some path"
 58        );
 59        expect(normalizePath('"/usr/local/some app/"')).toBe(
 60          "/usr/local/some app"
 61        );
 62      });
 63  
 64      it("removes surrounding quotes", () => {
 65        expect(normalizePath('"C:\\NS\\My Kindle Content"')).toBe(
 66          "C:\\NS\\My Kindle Content"
 67        );
 68      });
 69  
 70      it("normalizes backslashes", () => {
 71        expect(normalizePath("C:\\\\NS\\\\MyKindleContent")).toBe(
 72          "C:\\NS\\MyKindleContent"
 73        );
 74      });
 75  
 76      it("converts forward slashes to backslashes on Windows", () => {
 77        expect(normalizePath("C:/NS/MyKindleContent")).toBe(
 78          "C:\\NS\\MyKindleContent"
 79        );
 80      });
 81  
 82      it("handles WSL paths", () => {
 83        expect(normalizePath("/mnt/c/NS/MyKindleContent")).toBe(
 84          "C:\\NS\\MyKindleContent"
 85        );
 86      });
 87  
 88      it("handles Unix-style Windows paths", () => {
 89        expect(normalizePath("/c/NS/MyKindleContent")).toBe(
 90          "C:\\NS\\MyKindleContent"
 91        );
 92      });
 93  
 94      it("handles paths with spaces and mixed slashes", () => {
 95        expect(normalizePath("C:/NS/My Kindle Content")).toBe(
 96          "C:\\NS\\My Kindle Content"
 97        );
 98        expect(normalizePath("/mnt/c/NS/My Kindle Content")).toBe(
 99          "C:\\NS\\My Kindle Content"
100        );
101        expect(normalizePath("C:\\Program Files (x86)\\App Name")).toBe(
102          "C:\\Program Files (x86)\\App Name"
103        );
104        expect(normalizePath('"C:\\Program Files\\App Name"')).toBe(
105          "C:\\Program Files\\App Name"
106        );
107        expect(normalizePath("  C:\\Program Files\\App Name  ")).toBe(
108          "C:\\Program Files\\App Name"
109        );
110      });
111  
112      it("preserves spaces in all path formats", () => {
113        expect(normalizePath("/mnt/c/Program Files/App Name")).toBe(
114          "C:\\Program Files\\App Name"
115        );
116        expect(normalizePath("/c/Program Files/App Name")).toBe(
117          "C:\\Program Files\\App Name"
118        );
119        expect(normalizePath("C:/Program Files/App Name")).toBe(
120          "C:\\Program Files\\App Name"
121        );
122      });
123  
124      it("handles special characters in paths", () => {
125        // Test ampersand in path
126        expect(normalizePath("C:\\NS\\Sub&Folder")).toBe("C:\\NS\\Sub&Folder");
127        expect(normalizePath("C:/NS/Sub&Folder")).toBe("C:\\NS\\Sub&Folder");
128        expect(normalizePath("/mnt/c/NS/Sub&Folder")).toBe("C:\\NS\\Sub&Folder");
129  
130        // Test tilde in path (short names in Windows)
131        expect(normalizePath("C:\\NS\\MYKIND~1")).toBe("C:\\NS\\MYKIND~1");
132        expect(
133          normalizePath("/Users/NEMANS~1/FOLDER~2/SUBFO~1/Public/P12PST~1")
134        ).toBe("/Users/NEMANS~1/FOLDER~2/SUBFO~1/Public/P12PST~1");
135  
136        // Test other special characters
137        expect(normalizePath("C:\\Path with #hash")).toBe("C:\\Path with #hash");
138        expect(normalizePath("C:\\Path with (parentheses)")).toBe(
139          "C:\\Path with (parentheses)"
140        );
141        expect(normalizePath("C:\\Path with [brackets]")).toBe(
142          "C:\\Path with [brackets]"
143        );
144        expect(normalizePath("C:\\Path with @at+plus$dollar%percent")).toBe(
145          "C:\\Path with @at+plus$dollar%percent"
146        );
147      });
148  
149      it("capitalizes lowercase drive letters for Windows paths", () => {
150        expect(normalizePath("c:/windows/system32")).toBe(
151          "C:\\windows\\system32"
152        );
153        expect(normalizePath("/mnt/d/my/folder")) // WSL path with lowercase drive
154          .toBe("D:\\my\\folder");
155        expect(normalizePath("/e/another/folder")) // Unix-style Windows path with lowercase drive
156          .toBe("E:\\another\\folder");
157      });
158  
159      it("handles UNC paths correctly", () => {
160        // UNC paths should preserve the leading double backslash
161        const uncPath = "\\\\SERVER\\share\\folder";
162        expect(normalizePath(uncPath)).toBe("\\\\SERVER\\share\\folder");
163  
164        // Test UNC path with double backslashes that need normalization
165        const uncPathWithDoubles = "\\\\\\\\SERVER\\\\share\\\\folder";
166        expect(normalizePath(uncPathWithDoubles)).toBe(
167          "\\\\SERVER\\share\\folder"
168        );
169      });
170  
171      it("returns normalized non-Windows/WSL/Unix-style Windows paths as is after basic normalization", () => {
172        // Relative path
173        const relativePath = "some/relative/path";
174        expect(normalizePath(relativePath)).toBe(
175          relativePath.replace(/\//g, "\\")
176        );
177  
178        // A path that looks somewhat absolute but isn't a drive or recognized Unix root for Windows conversion
179        const otherAbsolutePath = "\\someserver\\share\\file";
180        expect(normalizePath(otherAbsolutePath)).toBe(otherAbsolutePath);
181      });
182    });
183  
184    describe("expandHome", () => {
185      it("expands ~ to home directory", () => {
186        const result = expandHome("~/test");
187        expect(result).toContain("test");
188        expect(result).not.toContain("~");
189      });
190  
191      it("expands bare ~ to home directory", () => {
192        const result = expandHome("~");
193        expect(result).not.toContain("~");
194        expect(result.length).toBeGreaterThan(0);
195      });
196  
197      it("leaves other paths unchanged", () => {
198        expect(expandHome("C:/test")).toBe("C:/test");
199      });
200    });
201  });