Skip to content

Commit 3aed1aa

Browse files
committed
Bring across all of GetDirectoryName and tests
1 parent 0207896 commit 3aed1aa

File tree

2 files changed

+402
-35
lines changed

2 files changed

+402
-35
lines changed

src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared.Test/PathUtilitiesTests.cs

Lines changed: 118 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,57 @@ public class PathUtilitiesTests
2828
{ " file.extension", ".extension"}
2929
};
3030

31+
public static TheoryData<string, string?> TestData_GetDirectoryName => new()
32+
{
33+
{ ".", "" },
34+
{ "..", "" },
35+
{ "baz", "" },
36+
{ Path.Combine("dir", "baz"), "dir" },
37+
{ "dir.foo" + Path.AltDirectorySeparatorChar + "baz.txt", "dir.foo" },
38+
{ Path.Combine("dir", "baz", "bar"), Path.Combine("dir", "baz") },
39+
{ Path.Combine("..", "..", "files.txt"), Path.Combine("..", "..") },
40+
{ Path.DirectorySeparatorChar + "foo", Path.DirectorySeparatorChar.ToString() },
41+
{ Path.DirectorySeparatorChar.ToString(), null }
42+
};
43+
44+
public static TheoryData<string, string?> TestData_GetDirectoryName_Windows => new()
45+
{
46+
{ @"C:\", null },
47+
{ @"C:/", null },
48+
{ @"C:", null },
49+
{ @"dir\\baz", "dir" },
50+
{ @"dir//baz", "dir" },
51+
{ @"C:\foo", @"C:\" },
52+
{ @"C:foo", "C:" }
53+
};
54+
55+
public static TheoryData<string> TestData_Spaces =>
56+
[
57+
" ",
58+
" "
59+
];
60+
61+
public static TheoryData<string> TestData_EmbeddedNull =>
62+
[
63+
"a\0b"
64+
];
65+
66+
public static TheoryData<string> TestData_ControlChars =>
67+
[
68+
"\t",
69+
"\r\n",
70+
"\b",
71+
"\v",
72+
"\n"
73+
];
74+
75+
public static TheoryData<string> TestData_UnicodeWhiteSpace =>
76+
[
77+
"\u00A0", // Non-breaking Space
78+
"\u2028", // Line separator
79+
"\u2029", // Paragraph separator
80+
];
81+
3182
[Theory, MemberData(nameof(TestData_GetExtension))]
3283
public void GetExtension(string path, string expected)
3384
{
@@ -121,57 +172,100 @@ public static void IsPathFullyQualified_Unix_Valid(string path)
121172
}
122173

123174
[Fact]
124-
public static void GetDirectoryName_EmptyString()
175+
public void GetDirectoryName_NullReturnsNull()
125176
{
126-
AssertEqual(@"", PathUtilities.GetDirectoryName(@""));
177+
Assert.Null(PathUtilities.GetDirectoryName(null));
178+
}
179+
180+
[Theory, MemberData(nameof(TestData_GetDirectoryName))]
181+
public void GetDirectoryName(string path, string? expected)
182+
{
183+
Assert.Equal(expected, PathUtilities.GetDirectoryName(path));
127184
}
128185

129186
[Fact]
130-
public static void GetDirectoryName_FilenameOnly()
187+
public void GetDirectoryName_CurrentDirectory()
131188
{
132-
AssertEqual(@"", PathUtilities.GetDirectoryName(@"Foo.txt"));
189+
var curDir = Directory.GetCurrentDirectory();
190+
Assert.Equal(curDir, PathUtilities.GetDirectoryName(Path.Combine(curDir, "baz")));
191+
192+
Assert.Null(PathUtilities.GetDirectoryName(Path.GetPathRoot(curDir)));
193+
Assert.True(PathUtilities.GetDirectoryName(Path.GetPathRoot(curDir).AsSpan()).IsEmpty);
133194
}
134195

135196
[Fact]
136-
public static void GetDirectoryName_NetworkPath_AlternateSeparator()
197+
public void GetDirectoryName_EmptyReturnsNull()
137198
{
138-
AssertEqual("//Server/Path", PathUtilities.GetDirectoryName("//Server/Path/Foo.txt"));
199+
// In .NET Framework this throws argument exception
200+
Assert.Null(PathUtilities.GetDirectoryName(string.Empty));
139201
}
140202

141-
[ConditionalFact(Is.AnyUnix)]
142-
public static void GetDirectoryName_FileAtRoot_Uni()
203+
[ConditionalTheory(Is.Windows)]
204+
[MemberData(nameof(TestData_Spaces))]
205+
public void GetDirectoryName_Spaces_Windows(string path)
143206
{
144-
AssertEqual(@"/", PathUtilities.GetDirectoryName(@"//Foo.txt"));
207+
// In Windows spaces are eaten by Win32, making them effectively empty
208+
Assert.Null(PathUtilities.GetDirectoryName(path));
145209
}
146210

147-
[ConditionalFact(Is.Windows)]
148-
public static void GetDirectoryName_FileAtRoot()
211+
[ConditionalTheory(Is.AnyUnix)]
212+
[MemberData(nameof(TestData_Spaces))]
213+
public void GetDirectoryName_Spaces_Unix(string path)
149214
{
150-
AssertEqual(@"", PathUtilities.GetDirectoryName(@"\\Foo.txt"));
215+
Assert.Empty(PathUtilities.GetDirectoryName(path));
151216
}
152217

153-
[ConditionalFact(Is.Windows)]
154-
public static void GetDirectoryName_FileAtRoot_AlternateSeparator()
218+
[Theory, MemberData(nameof(TestData_Spaces))]
219+
public void GetDirectoryName_Span_Spaces(string path)
155220
{
156-
AssertEqual(@"", PathUtilities.GetDirectoryName(@"//Foo.txt"));
221+
Assert.True(PathUtilities.GetDirectoryName(path.AsSpan()).IsEmpty);
157222
}
158223

159-
[ConditionalFact(Is.Windows)]
160-
public static void GetDirectoryName_Windows()
224+
[Theory]
225+
[MemberData(nameof(TestData_EmbeddedNull))]
226+
[MemberData(nameof(TestData_ControlChars))]
227+
[MemberData(nameof(TestData_UnicodeWhiteSpace))]
228+
public void GetDirectoryName_NetFxInvalid(string path)
161229
{
162-
AssertEqual(@"C:\Server", PathUtilities.GetDirectoryName(@"C:\Server\Foo.txt"));
230+
Assert.Empty(PathUtilities.GetDirectoryName(path));
231+
Assert.Equal(path, PathUtilities.GetDirectoryName(PathCombine(path, path)));
232+
Assert.True(PathUtilities.GetDirectoryName(path.AsSpan()).IsEmpty);
233+
AssertEqual(path, PathUtilities.GetDirectoryName(PathCombine(path, path).AsSpan()));
234+
235+
// Path.Combine on net472 throws on invalid path characters, so have to do this manually.
236+
static string PathCombine(string path1, string path2)
237+
{
238+
return $"""{path1}\{path2}""";
239+
}
163240
}
164241

165-
[ConditionalFact(Is.Windows)]
166-
public static void GetDirectoryName_LocalPath_DoubleSlash()
242+
[Theory, MemberData(nameof(TestData_GetDirectoryName))]
243+
public void GetDirectoryName_Span(string path, string? expected)
167244
{
168-
AssertEqual(@"C:\Server", PathUtilities.GetDirectoryName(@"C:\Server\\Foo.txt"));
245+
AssertEqual(expected ?? ReadOnlySpan<char>.Empty, PathUtilities.GetDirectoryName(path.AsSpan()));
169246
}
170247

171-
[ConditionalFact(Is.Windows)]
172-
public static void GetDirectoryName_NetworkPath()
248+
[Fact]
249+
public void GetDirectoryName_Span_CurrentDirectory()
250+
{
251+
var curDir = Directory.GetCurrentDirectory();
252+
AssertEqual(curDir, PathUtilities.GetDirectoryName(Path.Combine(curDir, "baz").AsSpan()));
253+
Assert.True(PathUtilities.GetDirectoryName(Path.GetPathRoot(curDir).AsSpan()).IsEmpty);
254+
}
255+
256+
[Theory]
257+
[InlineData(@" C:\dir/baz", @" C:\dir")]
258+
public void GetDirectoryName_SkipSpaces(string path, string expected)
259+
{
260+
// We no longer trim leading spaces for any path
261+
Assert.Equal(expected, PathUtilities.GetDirectoryName(path));
262+
}
263+
264+
[ConditionalTheory(Is.Windows)]
265+
[MemberData(nameof(TestData_GetDirectoryName_Windows))]
266+
public void GetDirectoryName_Windows(string path, string? expected)
173267
{
174-
AssertEqual(@"\\Server\Path", PathUtilities.GetDirectoryName(@"\\Server\Path\Foo.txt"));
268+
Assert.Equal(expected, Path.GetDirectoryName(path));
175269
}
176270

177271
private static void AssertEqual(ReadOnlySpan<char> expected, ReadOnlySpan<char> actual)

0 commit comments

Comments
 (0)