MockFileSystem.Directory.Move fails on Windows if destination has different case from source
Describe the bug
On Windows, FileSystem.Directory.Move is successful when the destination has a different case than source but MockFileSystem.Directory.Move throws System.IO.IOException: Source and destination path must be different.
To Reproduce
Steps to reproduce the behavior:
Using System.IO.Abstractions.TestingHelpers 21.0.29
static void Test()
{
FileSystem fs = new FileSystem();
MockFileSystem mockFs = new MockFileSystem();
Console.WriteLine("Real file system");
MoveDir(fs);
Console.WriteLine("Mock file system");
MoveDir(mockFs);
}
static void MoveDir(IFileSystem fileSystem)
{
string tempDir = fileSystem.Path.GetTempPath();
string src = fileSystem.Path.Combine(tempDir, "src");
string dest = fileSystem.Path.Combine(tempDir, "SRC"); // different case
try
{
// create source directory
IDirectoryInfo srcDir = fileSystem.DirectoryInfo.New(src);
srcDir.Create();
// move directory
fileSystem.Directory.Move(src, dest);
Console.WriteLine($"Successfully moved \"{src}\" to \"{dest}\"");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
if (fileSystem.Directory.Exists(src))
fileSystem.Directory.Delete(src);
if (fileSystem.Directory.Exists(dest))
fileSystem.Directory.Delete(dest);
}
}
Actual output
Real file system
Successfully moved "C:\Users\El-Gor-do\AppData\Local\Temp\src" to "C:\Users\El-Gor-do\AppData\Local\Temp\SRC"
Mock file system
System.IO.IOException: Source and destination path must be different.
at System.IO.Abstractions.TestingHelpers.MockDirectory.Move(String sourceDirName, String destDirName)
at IDirectoryInfoMove.Program.MoveDir(IFileSystem fileSystem) in D:\dev\bugs\IDirectoryInfoMove\IDirectoryInfoMove\Program.cs:line 33
Expected behavior MockFileSystem.Directory.Move should successfully move the directory.
Real file system
Successfully moved "C:\Users\El-Gor-do\AppData\Local\Temp\src" to "C:\Users\El-Gor-do\AppData\Local\Temp\SRC"
Mock file system
Successfully moved "C:\Users\El-Gor-do\AppData\Local\Temp\src" to "C:\Users\El-Gor-do\AppData\Local\Temp\SRC"
Thanks for reporting. This behaviour is probably due to a different behaviour on Linux between .NET Framework and .NET Core. On .NET Framework also the real file system throws an IOException (see here).
I forgot to mention that I am running on .Net 8 only, not .Net Framework. My applications work fine because I use FileSystem as my IFileSystem implementation, it's only my tests that fail because I replace FileSystem with MockFileSystem.
I am looking into it.
For the mentioned exception we have a condition check, to throw that custom IO exception, it can be resolved by removing that if condition.
if (mockFileDataAccessor.StringOperations.Equals(fullSourcePath, fullDestPath))
{
throw new IOException("Source and destination path must be different.");
}
But without that check it still throws IO Exception. Sharing the trace below:
Mock FileSystem
System.IO.IOException: Cannot create 'C:\temp\SRC' because a file or directory with the same name already exists.
at System.IO.Abstractions.TestingHelpers.MockDirectory.Move(String sourceDirName, String destDirName) in C:\Dev\forked-projects\System.IO.Abstractions\src\TestableIO.System.IO.Abstractions.TestingHelpers\MockDirectory.cs:line 540
at System.IO.Abstractions.TestingHelpers.Tests.MockFileCopyTests.MoveDir(IFileSystem fileSystem) in C:\Dev\forked-projects\System.IO.Abstractions\tests\TestableIO.System.IO.Abstractions.TestingHelpers.Tests\MockFileCopyTests.cs:line 438
Looking further into it.
This is addressed in release v22.0.14.