Skip to content

Commit 2914bf3

Browse files
committed
add some test gaps
1 parent 71ba620 commit 2914bf3

8 files changed

Lines changed: 148 additions & 3 deletions

File tree

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/IO/FileExistStrategies/FileExistsStrategyTestBase.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ public void FileExists_PathResolvesToDirectory_ReturnsFalse(string input)
209209
Assert.False(exists);
210210
}
211211

212+
[Fact]
213+
public void FileExists_EmptyRelativePath_ReturnsFalse()
214+
{
215+
// After joining "" with the base directory, the dispatcher hands the strategy the bare
216+
// base directory. Every strategy must treat that as not-a-file rather than reporting the
217+
// directory itself as existing.
218+
var dir = NewTempDir();
219+
FileSystem.File.WriteAllText(FileSystem.Path.Combine(dir, "x.txt"), "x");
220+
221+
Assert.False(FileExists(string.Empty.AsSpan(), dir.AsSpan()));
222+
}
223+
212224
[Theory]
213225
[InlineData("test.txt", "TEST.txt")]
214226
[InlineData("dir/test.txt", "DIR/TEST.txt")]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Collections.Generic;
2+
using PG.StarWarsGame.Engine.IO.FileExistStrategies;
3+
using Xunit;
4+
5+
namespace PG.StarWarsGame.Engine.FileSystem.Test.IO.FileExistStrategies;
6+
7+
public class VirtualDirectoryTests
8+
{
9+
[Fact]
10+
public void Ctor_ExposesAssignedFields()
11+
{
12+
var files = new Dictionary<string, string> { ["foo.xml"] = "FOO.xml" };
13+
14+
var dir = new VirtualDirectory("/some/dir", files);
15+
16+
Assert.Equal("/some/dir", dir.OnDiskPath);
17+
Assert.Same(files, dir.Files);
18+
Assert.Equal("FOO.xml", dir.Files["foo.xml"]);
19+
}
20+
}

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/IO/PetroglyphFileSystemTests.CombineJoin.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
22
using System.IO;
3-
using AnakinRaW.CommonUtilities.FileSystem;
43
using PG.StarWarsGame.Engine.Utilities;
54
using Xunit;
5+
#if NETFRAMEWORK
6+
using AnakinRaW.CommonUtilities.FileSystem;
7+
#endif
68

79
namespace PG.StarWarsGame.Engine.FileSystem.Test.IO;
810

@@ -86,4 +88,32 @@ public void JoinPath(string path1, string path2, string expected)
8688
vsb.Dispose();
8789
}
8890
}
91+
92+
[Fact]
93+
public void CombinePath_FirstArgNull_Throws()
94+
{
95+
Assert.Throws<ArgumentNullException>(() => _pgFileSystem.CombinePath(null!, "b"));
96+
}
97+
98+
[Fact]
99+
public void CombinePath_SecondArgNull_Throws()
100+
{
101+
Assert.Throws<ArgumentNullException>(() => _pgFileSystem.CombinePath("a", null!));
102+
}
103+
104+
[Fact]
105+
public void JoinPath_BothEmpty_LeavesBufferUntouched()
106+
{
107+
var vsb = new ValueStringBuilder();
108+
try
109+
{
110+
vsb.Append("preexisting");
111+
_pgFileSystem.JoinPath(ReadOnlySpan<char>.Empty, ReadOnlySpan<char>.Empty, ref vsb);
112+
Assert.Equal("preexisting", vsb.ToString());
113+
}
114+
finally
115+
{
116+
vsb.Dispose();
117+
}
118+
}
89119
}

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/IO/PetroglyphFileSystemTests.Exist.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@ public partial class PetroglyphFileSystemTests
88
[Theory]
99
#if Windows
1010
[InlineData("C:\\test.txt", true)]
11+
[InlineData("C:/test.txt", true)]
12+
[InlineData("D:\\path\\to\\file", true)]
1113
[InlineData("/test.txt", false)]
1214
[InlineData("\\test.txt", false)]
1315
#else
1416
[InlineData("/test.txt", true)]
17+
[InlineData("/", true)]
18+
[InlineData("/a/b/c", true)]
19+
[InlineData("\\test.txt", false)]
1520
[InlineData("C:\\test.txt", false)]
1621
#endif
1722
[InlineData("test.txt", false)]
23+
[InlineData("a/b/c", false)]
24+
[InlineData("./file.txt", false)]
25+
[InlineData("../file.txt", false)]
1826
[InlineData("", false)]
1927
public void IsPathFullyQualified_Exists(string path, bool expected)
2028
{

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/IO/PetroglyphFileSystemTests.PathEqual.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ public partial class PetroglyphFileSystemTests
99
[InlineData("dir/file.txt", "DIR\\FILE.TXT", true)]
1010
[InlineData("dir/file.txt", "dir/other.txt", false)]
1111
[InlineData("a/b/c", "a\\b\\c", true)]
12+
[InlineData("a/b/c", "a/b/c", true)]
13+
[InlineData("a/b/c", "A/B/C", true)]
14+
[InlineData("a/b/c", "a/b/c/d", false)]
15+
[InlineData("a/b/c/d", "a/b/c", false)]
16+
[InlineData("Mods/Test/Data/foo.xml", "MODS\\TEST\\DATA\\FOO.XML", true)]
17+
[InlineData("a//b", "a\\b", true)]
18+
[InlineData("a/b/", "a\\b\\", true)]
1219
public void PathsAreEqual(string pathA, string pathB, bool expected)
1320
{
1421
Assert.Equal(expected, _pgFileSystem.PathsAreEqual(pathA, pathB));

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/IO/PetroglyphFileSystemTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,47 @@ public void UnderlyingFileSystem_ReturnsCorrectInstance()
3939
[InlineData("dir/file.txt", false)]
4040
[InlineData("file.txt", false)]
4141
[InlineData("", false)]
42+
[InlineData("/", true)]
43+
[InlineData("\\", true)]
44+
[InlineData("a", false)]
45+
[InlineData(".", false)]
46+
[InlineData("..", false)]
47+
[InlineData("dir//", true)]
48+
[InlineData("dir\\\\", true)]
4249
public void HasTrailingDirectorySeparator(string path, bool expected)
4350
{
4451
Assert.Equal(expected, _pgFileSystem.HasTrailingDirectorySeparator(path.AsSpan()));
4552
}
53+
54+
[Fact]
55+
public void OpenRead_ExistingFile_ReturnsReadableStream()
56+
{
57+
var dir = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), Guid.NewGuid().ToString());
58+
_fileSystem.Directory.CreateDirectory(dir);
59+
try
60+
{
61+
var file = _fileSystem.Path.Combine(dir, "openread.bin");
62+
_fileSystem.File.WriteAllBytes(file, new byte[] { 1, 2, 3, 4 });
63+
64+
using var stream = _pgFileSystem.OpenRead(file);
65+
66+
Assert.True(stream.CanRead);
67+
Assert.False(stream.CanWrite);
68+
Assert.Equal(4, stream.Length);
69+
var buf = new byte[4];
70+
Assert.Equal(4, stream.Read(buf, 0, 4));
71+
Assert.Equal(new byte[] { 1, 2, 3, 4 }, buf);
72+
}
73+
finally
74+
{
75+
_fileSystem.Directory.Delete(dir, recursive: true);
76+
}
77+
}
78+
79+
[Fact]
80+
public void OpenRead_MissingFile_Throws()
81+
{
82+
var missing = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), Guid.NewGuid() + ".missing");
83+
Assert.ThrowsAny<System.IO.IOException>(() => _pgFileSystem.OpenRead(missing));
84+
}
4685
}

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem.Test/Utilities/LowLevelPathTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,33 @@ public void GetCommonDirectoryPrefixLength_CaseInsensitive_Windows(string path,
3737
{
3838
Assert.Equal(expected, LowLevelPath.GetCommonDirectoryPrefixLength(path.AsSpan(), directory.AsSpan()));
3939
}
40+
41+
[PlatformSpecificFact(TestPlatformIdentifier.Windows)]
42+
public void IsHostFileSystemCaseSensitive_Windows_IsFalse()
43+
{
44+
Assert.False(LowLevelPath.IsHostFileSystemCaseSensitive);
45+
}
46+
47+
[PlatformSpecificFact(TestPlatformIdentifier.Linux)]
48+
public void IsHostFileSystemCaseSensitive_Linux_IsTrue()
49+
{
50+
Assert.True(LowLevelPath.IsHostFileSystemCaseSensitive);
51+
}
52+
53+
[Theory]
54+
// Sibling at root level: path and directory diverge before any separator → no shared prefix.
55+
[InlineData("foo/bar", "baz/qux", 0)]
56+
// Trailing separator on path side, directory does not have one — must match the no-trailing form.
57+
[InlineData("a/b/", "a/b", 3)]
58+
[InlineData("a/b", "a/b/", 3)]
59+
// Sibling whose name is a prefix of the other — shared prefix is the parent dir, not the
60+
// longest character match. "a/b" vs "a/ba" must NOT be reported as 3 chars in common.
61+
[InlineData("a/b", "a/ba", 2)]
62+
[InlineData("a/ba", "a/b", 2)]
63+
[InlineData("a/foo", "a/foobar", 2)]
64+
[InlineData("a/foobar", "a/foo", 2)]
65+
public void GetCommonDirectoryPrefixLength_BoundaryCases(string path, string directory, int expected)
66+
{
67+
Assert.Equal(expected, LowLevelPath.GetCommonDirectoryPrefixLength(path.AsSpan(), directory.AsSpan()));
68+
}
4069
}

src/PetroglyphTools/PG.StarWarsGame.Engine.FileSystem/Utilities/LowLevelPath.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ public static int GetCommonDirectoryPrefixLength(ReadOnlySpan<char> path, ReadOn
4141
if (i == minLen)
4242
{
4343
if (path.Length == directory.Length
44-
|| i == directory.Length && IsDirectorySeparator(path[i])
45-
|| i == path.Length && IsDirectorySeparator(directory[i]))
44+
|| (i == directory.Length && IsDirectorySeparator(path[i]))
45+
|| (i == path.Length && IsDirectorySeparator(directory[i])))
4646
return i;
4747
}
4848

0 commit comments

Comments
 (0)