Skip to content

Possible to create file and directory with the same name #318

@rkoeninger

Description

@rkoeninger

Main Issue

This test passes, and it really shouldn't:

[Test]
public void CreateSamePathAsDirectoryAndFile()
{
    var fileSystem = new MockFileSystem();
    fileSystem.AddDirectory(@"C:\");
    var path = @"C:\path";
    fileSystem.File.Create(path); // Create path as File
    Console.WriteLine(fileSystem.File.Exists(path)); // True
    fileSystem.Directory.CreateDirectory(path); // Create path as Directory
    Console.WriteLine(fileSystem.Directory.Exists(path)); // True
    Console.WriteLine(fileSystem.Path.GetFullPath(path)); // C:\path
}

You can't create a directory and a file with the same name in the same parent on either Windows or Unix (and probably most other OS/file systems), but MockFileSystem allows it.

MockFileSystem contains a IDictionary<string, MockFileData> with all the file system entries. It uses a trailing slash on all directories, so they have distinct keys from files. Should probably remove trailing slashes from all keys and do a check if a file system entry is a file or directory before doing a file overwrite or directory move operation.

The AllFiles and AllDirectories properties on MockFileSystem don't actually depend on the trailing slash, they filter using the IsDirectory property on the MockFileData.


Secondary Issue

(This is what I was originally going to report, less of an issue, and might be resolved just by fixing the above)

While working on what turned out to be a redundant PR ( #316 ), I discovered this:

The test MockDirectoryInfo_CreationTime_ShouldWorkIfPathIsActuallyAFile (EDIT: a test that was part of that PR) is currently failing. In the BCL, it is possible to create a new DirectoryInfo for a path to a file and the CreationTime is accessible and accurate, even though it's a DirectoryInfo pointing to a file (on Windows in .NET Framework anyway).

I wrote a sanity test to confirm the BCL exhibits this behavior:

[Test]
public void WorksInBCL()
{
    var temp = Path.GetTempFileName();
    Console.WriteLine(temp); // "C:\Users\username\AppData\Local\Temp\tmpE451.tmp"
    var dir = new DirectoryInfo(temp);
    Console.WriteLine(dir.FullName); // "C:\Users\username\AppData\Local\Temp\tmpE451.tmp"
    Console.WriteLine(dir.CreationTime); // shows the time the test was run
}

This doesn't work in System.IO.Abstractions because the IDictionary<string, MockFileData> in MockFileSystem uses the path strings as keys, with trailing slashes on the directories, no trailing slashes on files. MockDirectory and MockDirectoryInfo ensure there is a trailing slash on the path. If you try to create a MockDirectoryInfo pointing at a file, the trailing slash is added and it no longer points at the file.

Metadata

Metadata

Assignees

Labels

state: in workIssues that are currently worked ontype: bugIssues that describe misbehaving functionality

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions