using System; using LibHac.Tools.FsSystem.RomFs; using Xunit; namespace LibHac.Tests; public class RomFsTests { [Fact] public void SimpleAddAndRead() { const string path = "/a/b"; var table = new HierarchicalRomFileTable(); var item = new RomFileInfo { Length = 1, Offset = 1 }; table.AddFile(path, ref item); bool success = table.TryOpenFile(path, out RomFileInfo readItem); Assert.True(success, "Table read failed"); Assert.Equal(item, readItem); } [Fact] public void UpdateExistingFile() { const string path = "/a/b"; var table = new HierarchicalRomFileTable(); var originalItem = new RomFileInfo { Length = 1, Offset = 1 }; var newItem = new RomFileInfo { Length = 1, Offset = 1 }; table.AddFile(path, ref originalItem); table.AddFile(path, ref newItem); bool success = table.TryOpenFile(path, out RomFileInfo readItem); Assert.True(success, "Table read failed"); Assert.Equal(newItem, readItem); } [Fact] public void AddingDirectory() { var table = new HierarchicalRomFileTable(); var expectedPosition = new FindPosition { NextDirectory = -1, NextFile = -1 }; table.AddDirectory("/dir"); bool success = table.TryOpenDirectory("/dir", out FindPosition position); Assert.True(success, "Opening directory failed"); Assert.Equal(expectedPosition, position); } [Fact] public void AddingEmptyPathThrows() { var table = new HierarchicalRomFileTable(); var item = new RomFileInfo(); Assert.Throws(() => table.AddFile("", ref item)); } [Fact] public void OpeningNonexistentFileFails() { var table = new HierarchicalRomFileTable(); bool success = table.TryOpenFile("/foo", out _); Assert.False(success); } [Fact] public void OpeningNonexistentDirectoryFails() { var table = new HierarchicalRomFileTable(); bool success = table.TryOpenDirectory("/foo", out _); Assert.False(success); } [Fact] public void OpeningFileAsDirectoryFails() { var table = new HierarchicalRomFileTable(); var fileInfo = new RomFileInfo(); table.AddFile("/file", ref fileInfo); bool success = table.TryOpenDirectory("/file", out _); Assert.False(success); } [Fact] public void OpeningDirectoryAsFileFails() { var table = new HierarchicalRomFileTable(); table.AddDirectory("/dir"); bool success = table.TryOpenFile("/dir", out _); Assert.False(success); } [Fact] public void ChildFileIteration() { const int fileCount = 10; var table = new HierarchicalRomFileTable(); for (int i = 0; i < fileCount; i++) { var item = new RomFileInfo { Length = i, Offset = i }; table.AddFile($"/a/{i}", ref item); } bool openDirSuccess = table.TryOpenDirectory("/a", out FindPosition position); Assert.True(openDirSuccess, "Error opening directory"); for (int i = 0; i < fileCount; i++) { var expectedItem = new RomFileInfo { Length = i, Offset = i }; string expectedName = i.ToString(); bool success = table.FindNextFile(ref position, out RomFileInfo actualItem, out string actualName); Assert.True(success, $"Failed reading file {i}"); Assert.Equal(expectedItem, actualItem); Assert.Equal(expectedName, actualName); } bool endOfFilesSuccess = table.FindNextFile(ref position, out _, out _); Assert.False(endOfFilesSuccess, "Table returned more files than it should"); } [Fact] public void ChildFileIterationPeek() { var table = new HierarchicalRomFileTable(); var itemA = new RomFileInfo { Length = 1, Offset = 1 }; var itemB = new RomFileInfo { Length = 2, Offset = 2 }; table.AddFile("/a/a", ref itemA); table.AddFile("/a/b", ref itemB); table.TryOpenDirectory("/a", out FindPosition position); table.TryOpenFile(position.NextFile, out RomFileInfo peekItemA); Assert.Equal(itemA, peekItemA); table.FindNextFile(ref position, out RomFileInfo iterateItemA, out _); Assert.Equal(itemA, iterateItemA); table.TryOpenFile(position.NextFile, out RomFileInfo peekItemB); Assert.Equal(itemB, peekItemB); table.FindNextFile(ref position, out RomFileInfo iterateItemB, out _); Assert.Equal(itemB, iterateItemB); } [Fact] public void AddingCousinFiles() { var table = new HierarchicalRomFileTable(); var itemB1 = new RomFileInfo { Length = 1, Offset = 1 }; var itemB2 = new RomFileInfo { Length = 2, Offset = 2 }; var itemB3 = new RomFileInfo { Length = 3, Offset = 3 }; table.AddFile("/a/b1/c", ref itemB1); table.AddFile("/a/b2/c", ref itemB2); table.AddFile("/a/b3/c", ref itemB3); table.TryOpenFile("/a/b1/c", out RomFileInfo actualItemB1); table.TryOpenFile("/a/b2/c", out RomFileInfo actualItemB2); table.TryOpenFile("/a/b3/c", out RomFileInfo actualItemB3); Assert.Equal(itemB1, actualItemB1); Assert.Equal(itemB2, actualItemB2); Assert.Equal(itemB3, actualItemB3); } [Fact] public void AddingSiblingFiles() { var table = new HierarchicalRomFileTable(); var itemC1 = new RomFileInfo { Length = 1, Offset = 1 }; var itemC2 = new RomFileInfo { Length = 2, Offset = 2 }; var itemC3 = new RomFileInfo { Length = 3, Offset = 3 }; table.AddFile("/a/b/c1", ref itemC1); table.AddFile("/a/b/c2", ref itemC2); table.AddFile("/a/b/c3", ref itemC3); table.TryOpenFile("/a/b/c1", out RomFileInfo actualItemC1); table.TryOpenFile("/a/b/c2", out RomFileInfo actualItemC2); table.TryOpenFile("/a/b/c3", out RomFileInfo actualItemC3); Assert.Equal(itemC1, actualItemC1); Assert.Equal(itemC2, actualItemC2); Assert.Equal(itemC3, actualItemC3); } }