Skip to content

Commit c317a93

Browse files
KaliVifgreinacher
authored andcommitted
fix(439): Pattern "*." returns only files with no extension (#516)
* fix(439): Add special case to Directory.GetFilesInternal to return only files without extensions when search pattern is "*." * Added files with no extension to the existing tests in MockDirectoryTests. * fix(439): Pattern *. works as System.Directory. * Fix for case sensitive paths.
1 parent 00e7431 commit c317a93

2 files changed

Lines changed: 186 additions & 7 deletions

File tree

System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryTests.cs

Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ public void MockDirectory_GetFiles_ShouldReturnAllFilesBelowPathWhenPatternIsWil
2020
XFS.Path(@"c:\a\a.txt"),
2121
XFS.Path(@"c:\a\b.gif"),
2222
XFS.Path(@"c:\a\c.txt"),
23+
XFS.Path(@"c:\a\d"),
2324
XFS.Path(@"c:\a\a\a.txt"),
2425
XFS.Path(@"c:\a\a\b.txt"),
25-
XFS.Path(@"c:\a\a\c.gif")
26+
XFS.Path(@"c:\a\a\c.gif"),
27+
XFS.Path(@"c:\a\a\d")
2628
};
2729

2830
// Act
@@ -39,12 +41,15 @@ private MockFileSystem SetupFileSystem()
3941
{ XFS.Path(@"c:\a.gif"), new MockFileData("Demo text content") },
4042
{ XFS.Path(@"c:\b.txt"), new MockFileData("Demo text content") },
4143
{ XFS.Path(@"c:\c.txt"), new MockFileData("Demo text content") },
44+
{ XFS.Path(@"c:\d"), new MockFileData("Demo text content") },
4245
{ XFS.Path(@"c:\a\a.txt"), new MockFileData("Demo text content") },
4346
{ XFS.Path(@"c:\a\b.gif"), new MockFileData("Demo text content") },
4447
{ XFS.Path(@"c:\a\c.txt"), new MockFileData("Demo text content") },
48+
{ XFS.Path(@"c:\a\d"), new MockFileData("Demo text content") },
4549
{ XFS.Path(@"c:\a\a\a.txt"), new MockFileData("Demo text content") },
4650
{ XFS.Path(@"c:\a\a\b.txt"), new MockFileData("Demo text content") },
4751
{ XFS.Path(@"c:\a\a\c.gif"), new MockFileData("Demo text content") },
52+
{ XFS.Path(@"c:\a\a\d"), new MockFileData("Demo text content") }
4853
});
4954

5055
}
@@ -58,7 +63,8 @@ public void MockDirectory_GetFiles_ShouldReturnFilesDirectlyBelowPathWhenPattern
5863
{
5964
XFS.Path(@"c:\a\a.txt"),
6065
XFS.Path(@"c:\a\b.gif"),
61-
XFS.Path(@"c:\a\c.txt")
66+
XFS.Path(@"c:\a\c.txt"),
67+
XFS.Path(@"c:\a\d")
6268
};
6369

6470
// Act
@@ -221,6 +227,145 @@ public void MockDirectory_GetFiles_ShouldFilterByExtensionBasedSearchPatternAndS
221227
Assert.That(result, Is.EquivalentTo(expected));
222228
}
223229

230+
[Test]
231+
public void MockDirectory_GetFiles_ShouldFilterForAllFilesWithNoExtensionsAndSearchOptionTopDirectoryOnly()
232+
{
233+
// Arrange
234+
var fileSystem = SetupFileSystem();
235+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename"), new MockFileData("some content"));
236+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename."), new MockFileData("some content"));
237+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name"), new MockFileData("some content"));
238+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name."), new MockFileData("some content"));
239+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again"), new MockFileData("some content"));
240+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again."), new MockFileData("some content"));
241+
242+
var expected = new[]
243+
{
244+
XFS.Path(@"c:\d"),
245+
XFS.Path(@"C:\mytestfilename"),
246+
XFS.Path(@"C:\mytestfilename."),
247+
XFS.Path(@"C:\mytestfile.name."),
248+
XFS.Path(@"C:\mytestfile.name.again.")
249+
};
250+
251+
// Act
252+
var result = fileSystem.Directory.GetFiles(XFS.Path(@"C:\"), "*.", SearchOption.TopDirectoryOnly);
253+
254+
// Assert
255+
Assert.That(result, Is.EquivalentTo(expected));
256+
}
257+
258+
[Test]
259+
public void MockDirectory_GetFiles_ShouldFilterForAllFilesWithNoExtensionsAndSearchOptionAllDirectories()
260+
{
261+
// Arrange
262+
var fileSystem = SetupFileSystem();
263+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfilename"), new MockFileData("some content"));
264+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfilename."), new MockFileData("some content"));
265+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfile.name"), new MockFileData("some content"));
266+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfile.name."), new MockFileData("some content"));
267+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfile.name.again"), new MockFileData("some content"));
268+
fileSystem.AddFile(XFS.Path(@"C:\specialNameFormats\mytestfile.name.again."), new MockFileData("some content"));
269+
270+
var expected = new[]
271+
{
272+
XFS.Path(@"c:\d"),
273+
XFS.Path(@"c:\a\d"),
274+
XFS.Path(@"c:\a\a\d"),
275+
XFS.Path(@"C:\specialNameFormats\mytestfilename"),
276+
XFS.Path(@"C:\specialNameFormats\mytestfilename."),
277+
XFS.Path(@"C:\specialNameFormats\mytestfile.name."),
278+
XFS.Path(@"C:\specialNameFormats\mytestfile.name.again.")
279+
};
280+
281+
// Act
282+
var result = fileSystem.Directory.GetFiles(XFS.Path(@"c:\"), "*.", SearchOption.AllDirectories);
283+
284+
// Assert
285+
Assert.That(result, Is.EquivalentTo(expected));
286+
}
287+
288+
[Test]
289+
public void MockDirectory_GetFiles_ShouldFilterForFilesWithNoExtensionsAndNonTrivialFilterAndSearchOptionTopDirectoryOnly()
290+
{
291+
// Arrange
292+
var fileSystem = SetupFileSystem();
293+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename"), new MockFileData("some content"));
294+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename."), new MockFileData("some content"));
295+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name"), new MockFileData("some content"));
296+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name."), new MockFileData("some content"));
297+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again"), new MockFileData("some content"));
298+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again."), new MockFileData("some content"));
299+
300+
var expected = new[]
301+
{
302+
XFS.Path(@"C:\mytestfilename"),
303+
XFS.Path(@"C:\mytestfilename."),
304+
XFS.Path(@"C:\mytestfile.name."),
305+
XFS.Path(@"C:\mytestfile.name.again.")
306+
307+
};
308+
309+
// Act
310+
var result = fileSystem.Directory.GetFiles(XFS.Path(@"C:\"), "my??s*.", SearchOption.TopDirectoryOnly);
311+
312+
// Assert
313+
Assert.That(result, Is.EquivalentTo(expected));
314+
}
315+
316+
[Test]
317+
public void MockDirectory_GetFiles_ShouldFilterForFilesWithNoExtensionsAndNonTrivialFilter2AndSearchOptionTopDirectoryOnly()
318+
{
319+
// Arrange
320+
var fileSystem = SetupFileSystem();
321+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename"), new MockFileData("some content"));
322+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename."), new MockFileData("some content"));
323+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name"), new MockFileData("some content"));
324+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name."), new MockFileData("some content"));
325+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again"), new MockFileData("some content"));
326+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again."), new MockFileData("some content"));
327+
328+
var expected = new[]
329+
{
330+
XFS.Path(@"C:\mytestfile.name"),
331+
XFS.Path(@"C:\mytestfile.name."),
332+
XFS.Path(@"C:\mytestfile.name.again.")
333+
334+
};
335+
336+
// Act
337+
var result = fileSystem.Directory.GetFiles(XFS.Path(@"C:\"), "my*.n*.", SearchOption.TopDirectoryOnly);
338+
339+
// Assert
340+
Assert.That(result, Is.EquivalentTo(expected));
341+
}
342+
343+
[Test]
344+
public void MockDirectory_GetFiles_ShouldFilterForFilesWithNoExtensionsAndFilterThatIncludesDotAndSearchOptionTopDirectoryOnly()
345+
{
346+
// Arrange
347+
var fileSystem = SetupFileSystem();
348+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename"), new MockFileData("some content"));
349+
fileSystem.AddFile(XFS.Path(@"C:\mytestfilename."), new MockFileData("some content"));
350+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name"), new MockFileData("some content"));
351+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name."), new MockFileData("some content"));
352+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again"), new MockFileData("some content"));
353+
fileSystem.AddFile(XFS.Path(@"C:\mytestfile.name.again."), new MockFileData("some content"));
354+
355+
var expected = new[]
356+
{
357+
XFS.Path(@"C:\mytestfile.name"),
358+
XFS.Path(@"C:\mytestfile.name."),
359+
XFS.Path(@"C:\mytestfile.name.again.")
360+
};
361+
362+
// Act
363+
var result = fileSystem.Directory.GetFiles(XFS.Path(@"C:\"), "my*.n*.", SearchOption.TopDirectoryOnly);
364+
365+
// Assert
366+
Assert.That(result, Is.EquivalentTo(expected));
367+
}
368+
224369
private void ExecuteTimeAttributeTest(Action<IFileSystem, string, DateTime> setter, Func<IFileSystem, string, DateTime> getter)
225370
{
226371
string path = XFS.Path(@"c:\something\demo.txt");
@@ -1215,7 +1360,7 @@ public void MockDirectory_Move_ShouldMoveFiles()
12151360
{
12161361
string sourceFilePath = XFS.Path(@"c:\demo.txt");
12171362
string sourceFileContent = "this is some content";
1218-
1363+
12191364
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
12201365
{
12211366
{ sourceFilePath, new MockFileData(sourceFileContent) }
@@ -1497,9 +1642,11 @@ public void MockDirectory_EnumerateFiles_ShouldReturnAllFilesBelowPathWhenPatter
14971642
XFS.Path(@"c:\a\a.txt"),
14981643
XFS.Path(@"c:\a\b.gif"),
14991644
XFS.Path(@"c:\a\c.txt"),
1645+
XFS.Path(@"c:\a\d"),
15001646
XFS.Path(@"c:\a\a\a.txt"),
15011647
XFS.Path(@"c:\a\a\b.txt"),
1502-
XFS.Path(@"c:\a\a\c.gif")
1648+
XFS.Path(@"c:\a\a\c.gif"),
1649+
XFS.Path(@"c:\a\a\d")
15031650
};
15041651

15051652
// Act
@@ -1589,9 +1736,11 @@ public void MockDirectory_EnumerateFileSystemEntries_ShouldReturnAllFilesBelowPa
15891736
XFS.Path(@"c:\a\a.txt"),
15901737
XFS.Path(@"c:\a\b.gif"),
15911738
XFS.Path(@"c:\a\c.txt"),
1739+
XFS.Path(@"c:\a\d"),
15921740
XFS.Path(@"c:\a\a\a.txt"),
15931741
XFS.Path(@"c:\a\a\b.txt"),
15941742
XFS.Path(@"c:\a\a\c.gif"),
1743+
XFS.Path(@"c:\a\a\d"),
15951744
XFS.Path(@"c:\a\a")
15961745
};
15971746

System.IO.Abstractions.TestingHelpers/MockDirectory.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,11 @@ private string[] GetFilesInternal(
230230
? @"([^<>:""/|?*]*/)*"
231231
: @"([^<>:""/\\|?*]*\\)*";
232232

233+
var searchEndInStarDot = searchPattern.EndsWith(@"*.");
234+
233235
string fileNamePattern;
236+
string pathPatternNoExtension = string.Empty;
237+
string pathPatternEndsInDot = string.Empty;
234238
string pathPatternSpecial = null;
235239

236240
if (searchPattern == "*")
@@ -264,9 +268,17 @@ private string[] GetFilesInternal(
264268
searchOption == SearchOption.AllDirectories ? allDirectoriesPattern : string.Empty,
265269
fileNamePattern);
266270

267-
return files
268-
.Where(p => Regex.IsMatch(p, pathPattern)
269-
|| (pathPatternSpecial != null && Regex.IsMatch(p, pathPatternSpecial)))
271+
if (searchEndInStarDot)
272+
{
273+
pathPatternNoExtension = ReplaceLastOccurrence(pathPattern, @"]*?\.", @"\.]*?[.]*");
274+
pathPatternEndsInDot = ReplaceLastOccurrence(pathPattern, @"]*?\.", @"]*?[.]{1,}");
275+
}
276+
277+
return files.Where(p =>
278+
!searchEndInStarDot ?
279+
(Regex.IsMatch(p, pathPattern) || (pathPatternSpecial != null && Regex.IsMatch(p, pathPatternSpecial)))
280+
: (Regex.IsMatch(p, pathPatternNoExtension) || Regex.IsMatch(p, pathPatternEndsInDot))
281+
)
270282
.ToArray();
271283
}
272284

@@ -558,5 +570,23 @@ private void CheckSearchPattern(string searchPattern)
558570
throw CommonExceptions.IllegalCharactersInPath(nameof(searchPattern));
559571
}
560572
}
573+
574+
private string ReplaceLastOccurrence(string source, string find, string replace)
575+
{
576+
if (source == null)
577+
{
578+
return source;
579+
}
580+
581+
var place = source.LastIndexOf(find);
582+
583+
if (place == -1)
584+
{
585+
return source;
586+
}
587+
588+
var result = source.Remove(place, find.Length).Insert(place, replace);
589+
return result;
590+
}
561591
}
562592
}

0 commit comments

Comments
 (0)