diff --git a/StarterNG.Tests/TextureFolderTests.cs b/StarterNG.Tests/TextureFolderTests.cs new file mode 100644 index 0000000..2384c37 --- /dev/null +++ b/StarterNG.Tests/TextureFolderTests.cs @@ -0,0 +1,22 @@ +using StarterNG.Domain.Vehicles; +using StarterNG.Infrastructure.Vehicles; +using StarterNG.Tests.Fakes; + +namespace StarterNG.Tests; + +public class TextureFolderTests +{ + private static readonly TestInstallation Installation = new(new InMemoryFileSystem(caseSensitive: true) + .WithFile("game/dynamic/PKP/EP09_v1/textures.txt", "") + .WithDirectory("game/Other/Folder")); + + [Theory] + [InlineData("pkp/ep09_v1/", "dynamic/PKP/EP09_v1")] + [InlineData(@"PKP\EP09_V1", "dynamic/PKP/EP09_v1")] + [InlineData("other/folder/", "Other/Folder")] + [InlineData("pkp/brak/", "pkp/brak")] + public void A_liverys_folder_is_found_as_it_is_named_on_disk(string named, string onDisk) => + Assert.Equal(Path.GetFullPath(Path.Combine("game", onDisk)), + Path.GetFullPath(TextureFolder.Of(Installation.Files, Installation.Paths, + new VehicleTexture { Directory = named }))); +} diff --git a/StarterNG/Infrastructure/Vehicles/TextureFolder.cs b/StarterNG/Infrastructure/Vehicles/TextureFolder.cs new file mode 100644 index 0000000..530d5bb --- /dev/null +++ b/StarterNG/Infrastructure/Vehicles/TextureFolder.cs @@ -0,0 +1,24 @@ +using System.IO; +using StarterNG.Application.Abstractions; +using StarterNG.Domain.Vehicles; + +namespace StarterNG.Infrastructure.Vehicles; + +public static class TextureFolder +{ + /// + /// A livery's folder as it is named on disk: under dynamic, or from the game's folder + /// when its name starts there, in any letter case. Where it would be when it is not there. + /// + public static string Of(IFileSystem files, IGamePaths paths, VehicleTexture texture) + { + string directory = texture.Directory.Replace('\\', '/').TrimEnd('/'); + if (directory.Length == 0) + return paths.Dynamic; + + var names = new CaseInsensitivePaths(files); + return names.Find(paths.Dynamic, directory, directory: true) ?? + names.Find(paths.Root, directory, directory: true) ?? + Path.Combine(paths.Root, directory.Replace('/', Path.DirectorySeparatorChar)); + } +} diff --git a/StarterNG/Views/Depot/TextureMenuItems.cs b/StarterNG/Views/Depot/TextureMenuItems.cs index b54810e..0461a99 100644 --- a/StarterNG/Views/Depot/TextureMenuItems.cs +++ b/StarterNG/Views/Depot/TextureMenuItems.cs @@ -1,8 +1,10 @@ using System.IO; using Avalonia.Controls; using Avalonia.Input.Platform; +using StarterNG.Application; using StarterNG.Domain; using StarterNG.Domain.Vehicles; +using StarterNG.Infrastructure.Vehicles; namespace StarterNG.Views; @@ -17,13 +19,7 @@ internal static class TextureMenuItems if (TopLevel.GetTopLevel(owner)?.Clipboard is { } clipboard) await clipboard.SetTextAsync(Consist.Base(texture.Skinfile)); }); - menu.AddItem(App.Loc["OpenTextureFolder"], () => Infrastructure.Diagnostics.OpenOrReport(FolderOf(texture))); - } - - private static string FolderOf(VehicleTexture texture) - { - string dir = Path.Combine(Directory.GetCurrentDirectory(), "dynamic", - texture.Directory.Replace('/', Path.DirectorySeparatorChar).TrimEnd('\\', '/')); - return Directory.Exists(dir) ? dir : Path.Combine(Directory.GetCurrentDirectory(), texture.Directory); + menu.AddItem(App.Loc["OpenTextureFolder"], () => Infrastructure.Diagnostics.OpenOrReport( + Path.GetFullPath(TextureFolder.Of(AppServices.Current.Files, AppServices.Current.Paths, texture)))); } }