System.IO.Abstractions icon indicating copy to clipboard operation
System.IO.Abstractions copied to clipboard

MockFileSystem.Directory.Move fails on Windows if destination has different case from source

Open El-Gor-do opened this issue 1 year ago • 2 comments

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"

El-Gor-do avatar Aug 07 '24 14:08 El-Gor-do

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).

vbreuss avatar Aug 08 '24 17:08 vbreuss

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.

El-Gor-do avatar Aug 08 '24 20:08 El-Gor-do

I am looking into it.

oni-shiro avatar Mar 22 '25 13:03 oni-shiro

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.

oni-shiro avatar Mar 22 '25 14:03 oni-shiro

This is addressed in release v22.0.14.

github-actions[bot] avatar Apr 18 '25 20:04 github-actions[bot]