1+ // packages/react-router-dev/__tests__/windows-paths.test.ts
2+ import { describe , expect , it , beforeAll , afterAll } from "vitest" ;
3+ import path from "path" ;
4+ import fs from "fs" ;
5+ import os from "os" ;
6+
7+ describe ( "Windows path handling with spaces" , ( ) => {
8+ let tempDir : string ;
9+ let tempFile : string ;
10+
11+ beforeAll ( ( ) => {
12+ // Create a test directory with spaces
13+ tempDir = path . join ( os . tmpdir ( ) , "react router test" , "with spaces" ) ;
14+ tempFile = path . join ( tempDir , "test-route.jsx" ) ;
15+
16+ // Ensure the directory exists
17+ fs . mkdirSync ( tempDir , { recursive : true } ) ;
18+
19+ // Write test JSX content
20+ fs . writeFileSync ( tempFile , `
21+ export default function TestRoute() {
22+ return <div>Test Route</div>;
23+ }
24+ ` ) ;
25+ } ) ;
26+
27+ afterAll ( ( ) => {
28+ // Cleanup
29+ if ( fs . existsSync ( tempFile ) ) {
30+ fs . unlinkSync ( tempFile ) ;
31+ }
32+ if ( fs . existsSync ( tempDir ) ) {
33+ fs . rmSync ( tempDir , { recursive : true } ) ;
34+ }
35+ } ) ;
36+
37+ it ( "should fail to read file when path contains URI-encoded spaces" , ( ) => {
38+ // Simulate what happens in the vite plugin with encoded paths
39+ const encodedPath = encodeURIComponent ( tempFile ) ;
40+
41+ // This demonstrates the current bug - encoded paths fail
42+ expect ( ( ) => {
43+ fs . readFileSync ( encodedPath , "utf-8" ) ;
44+ } ) . toThrow ( / E N O E N T | n o s u c h f i l e o r d i r e c t o r y / ) ;
45+ } ) ;
46+
47+ it ( "should successfully read file after decoding URI components" , ( ) => {
48+ // Simulate the fix
49+ const encodedPath = encodeURIComponent ( tempFile ) ;
50+ const decodedPath = decodeURIComponent ( encodedPath ) ;
51+ const normalizedPath = path . normalize ( decodedPath ) ;
52+
53+ // This should work with the fix
54+ expect ( ( ) => {
55+ const content = fs . readFileSync ( normalizedPath , "utf-8" ) ;
56+ expect ( content ) . toContain ( "TestRoute" ) ;
57+ } ) . not . toThrow ( ) ;
58+ } ) ;
59+
60+ it ( "should decode URI components in Windows-style paths" , ( ) => {
61+ // Test the specific fix for Windows paths with spaces
62+ const windowsPath = "C:\\Program Files\\My App\\routes\\index.tsx" ;
63+ const encodedPath = encodeURIComponent ( windowsPath ) ;
64+
65+ // Verify encoding happened
66+ expect ( encodedPath ) . toContain ( "%20" ) ; // space becomes %20
67+ expect ( encodedPath ) . toContain ( "%5C" ) ; // backslash becomes %5C
68+
69+ // Verify decoding works
70+ const decodedPath = decodeURIComponent ( encodedPath ) ;
71+ const normalizedPath = path . normalize ( decodedPath ) ;
72+
73+ expect ( normalizedPath ) . toBe ( windowsPath ) ;
74+ } ) ;
75+
76+ it ( "should handle the exact error scenario from KOVI HAIR issue" , ( ) => {
77+ // This recreates the exact scenario from the GitHub issue
78+ const koviPath = "D:\\KOVI HAIR\\kovi-dev\\app\\routes\\layout.jsx" ;
79+ const encodedPath = koviPath . replace ( / \\ / g, '%5C' ) . replace ( / / g, '%20' ) ;
80+
81+ // This is what currently fails
82+ expect ( ( ) => {
83+ fs . readFileSync ( encodedPath , "utf-8" ) ;
84+ } ) . toThrow ( / E N O E N T / ) ;
85+
86+ // This is what should work with the fix
87+ const fixedPath = path . normalize ( decodeURIComponent ( encodedPath ) ) ;
88+ expect ( fixedPath ) . toBe ( koviPath ) ;
89+ } ) ;
90+ } ) ;
0 commit comments