Skip to content

Commit 1f80b89

Browse files
authored
Add regression tests for path casing normalization
PathUtilL0: - Folder casing normalization (create MiXeDcAsE, query lowercase) - Idempotency (calling twice returns same result) - Input casing independence (upper and lower resolve to same canonical) HostContextL0: - Root directory returns cached value across calls - Derived paths (Diag, Externals) share Root prefix casing
1 parent 1156027 commit 1f80b89

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

src/Test/L0/HostContextL0.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,52 @@ public async Task AuthMigrationAutoReset()
299299
}
300300
}
301301

302+
[Fact]
303+
[Trait("Level", "L0")]
304+
[Trait("Category", "Common")]
305+
public void GetDirectoryRootReturnsCachedValue()
306+
{
307+
try
308+
{
309+
Setup();
310+
311+
// Call GetDirectory(Root) twice — should return the same reference
312+
var root1 = _hc.GetDirectory(WellKnownDirectory.Root);
313+
var root2 = _hc.GetDirectory(WellKnownDirectory.Root);
314+
315+
Assert.NotNull(root1);
316+
Assert.Equal(root1, root2);
317+
Assert.True(Directory.Exists(root1));
318+
}
319+
finally
320+
{
321+
Teardown();
322+
}
323+
}
324+
325+
[Fact]
326+
[Trait("Level", "L0")]
327+
[Trait("Category", "Common")]
328+
public void GetDirectoryDerivedPathsUseRootCasing()
329+
{
330+
try
331+
{
332+
Setup();
333+
334+
var root = _hc.GetDirectory(WellKnownDirectory.Root);
335+
var diag = _hc.GetDirectory(WellKnownDirectory.Diag);
336+
var externals = _hc.GetDirectory(WellKnownDirectory.Externals);
337+
338+
// Diag and Externals should start with the same Root prefix
339+
Assert.StartsWith(root, diag);
340+
Assert.StartsWith(root, externals);
341+
}
342+
finally
343+
{
344+
Teardown();
345+
}
346+
}
347+
302348
private void Setup([CallerMemberName] string testName = "")
303349
{
304350
_tokenSource = new CancellationTokenSource();

src/Test/L0/Util/PathUtilL0.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,74 @@ public void GetCanonicalPath_NormalizesDriveLetter_OnWindows()
7878
Assert.True(char.IsUpper(result[0]),
7979
$"Expected uppercase drive letter but got: {result}");
8080
}
81+
82+
[Fact]
83+
[Trait("Level", "L0")]
84+
[Trait("Category", "Common")]
85+
public void GetCanonicalPath_NormalizesFolderCasing_OnWindows()
86+
{
87+
// Create a directory with known casing, then query with wrong casing
88+
var basePath = Path.GetTempPath();
89+
if (basePath.StartsWith(@"\\"))
90+
{
91+
return; // Skip UNC
92+
}
93+
94+
var realName = "PathUtilTest_MiXeDcAsE_" + Path.GetRandomFileName();
95+
var realDir = Path.Combine(basePath, realName);
96+
try
97+
{
98+
Directory.CreateDirectory(realDir);
99+
100+
// Query with all-lowercase version
101+
var wrongCased = Path.Combine(basePath, realName.ToLowerInvariant());
102+
103+
var result = PathUtil.GetCanonicalPath(wrongCased);
104+
105+
// The canonical result should contain the original mixed-case name
106+
Assert.Contains(realName, result);
107+
}
108+
finally
109+
{
110+
if (Directory.Exists(realDir))
111+
{
112+
Directory.Delete(realDir);
113+
}
114+
}
115+
}
116+
117+
[Fact]
118+
[Trait("Level", "L0")]
119+
[Trait("Category", "Common")]
120+
public void GetCanonicalPath_IsIdempotent_OnWindows()
121+
{
122+
// Calling GetCanonicalPath twice should return the same result
123+
var tempDir = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
124+
var first = PathUtil.GetCanonicalPath(tempDir);
125+
var second = PathUtil.GetCanonicalPath(first);
126+
Assert.Equal(first, second);
127+
}
128+
129+
[Fact]
130+
[Trait("Level", "L0")]
131+
[Trait("Category", "Common")]
132+
public void GetCanonicalPath_ReturnsSameResult_RegardlessOfInputCasing_OnWindows()
133+
{
134+
var tempDir = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
135+
if (tempDir.StartsWith(@"\\"))
136+
{
137+
return; // Skip UNC
138+
}
139+
140+
var upper = tempDir.ToUpperInvariant();
141+
var lower = tempDir.ToLowerInvariant();
142+
143+
var resultUpper = PathUtil.GetCanonicalPath(upper);
144+
var resultLower = PathUtil.GetCanonicalPath(lower);
145+
146+
// Both should resolve to the same canonical path
147+
Assert.Equal(resultUpper, resultLower);
148+
}
81149
#endif
82150
}
83151
}

0 commit comments

Comments
 (0)