From 8c8ce9e5c1e203abb8d4c37d57bffe601c5dca1a Mon Sep 17 00:00:00 2001 From: erri120 Date: Thu, 14 Dec 2023 15:05:50 +0100 Subject: [PATCH] Workspace Icon Test update (#815) * Add Verify * Update tests * Use WorkspaceGridState --- .editorconfig | 10 +++ .gitattributes | 5 ++ .gitignore | 5 +- Directory.Packages.props | 14 +-- NexusMods.App.sln | 2 + .../AddPanelButtonDesignViewModel.cs | 14 +-- .../AddPanelButton/AddPanelButtonViewModel.cs | 6 +- .../IAddPanelButtonViewModel.cs | 5 +- .../WorkspaceSystem/IconUtils.cs | 8 +- .../Workspace/IWorkspaceViewModel.cs | 4 +- .../Workspace/WorkspacePlaygroundViewModel.cs | 10 +-- .../Workspace/WorkspaceViewModel.cs | 14 ++- .../WorkspaceSystem/WorkspaceGridState.cs | 10 +++ tests/NexusMods.UI.Tests/ModuleInitializer.cs | 20 +++++ .../NexusMods.UI.Tests.csproj | 6 ++ ...Test_StateToBitmap_FourPanels.verified.png | Bin 0 -> 1411 bytes ...ap_ThreePanels_OneLargeColumn.verified.png | Bin 0 -> 1686 bytes ...itmap_ThreePanels_OneLargeRow.verified.png | Bin 0 -> 1568 bytes ...Test_StateToBitmap_TwoColumns.verified.png | Bin 0 -> 1012 bytes ...ts.Test_StateToBitmap_TwoRows.verified.png | Bin 0 -> 1452 bytes .../WorkspaceSystem/IconUtilsTests.cs | 83 +++++++++++++++--- 21 files changed, 166 insertions(+), 50 deletions(-) create mode 100644 tests/NexusMods.UI.Tests/ModuleInitializer.cs create mode 100644 tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_FourPanels.verified.png create mode 100644 tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_ThreePanels_OneLargeColumn.verified.png create mode 100644 tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_ThreePanels_OneLargeRow.verified.png create mode 100644 tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_TwoColumns.verified.png create mode 100644 tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_TwoRows.verified.png diff --git a/.editorconfig b/.editorconfig index f0d77090f8..841ef755bf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -75,3 +75,13 @@ indent_size = 2 [*.csproj] indent_size = 4 + +# Verify settings +[*.{received,verified}.{txt,xml,json}] +charset = "utf-8-bom" +end_of_line = lf +indent_size = unset +indent_style = unset +insert_final_newline = false +tab_width = unset +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes index 10a3cece82..56f19b4302 100644 --- a/.gitattributes +++ b/.gitattributes @@ -59,3 +59,8 @@ .gitattributes export-ignore .gitignore export-ignore .gitkeep export-ignore + +# Verify +*.verified.txt text eol=lf working-tree-encoding=UTF-8 +*.verified.xml text eol=lf working-tree-encoding=UTF-8 +*.verified.json text eol=lf working-tree-encoding=UTF-8 diff --git a/.gitignore b/.gitignore index 3b85a8161a..7446eaed8e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,7 @@ Thumbs.db Desktop.ini .DS_Store -coverage.json \ No newline at end of file +coverage.json + +# Verify +*.received.* diff --git a/Directory.Packages.props b/Directory.Packages.props index 23f055cbd1..18dc6b9be1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -58,8 +58,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -80,12 +80,14 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/NexusMods.App.sln b/NexusMods.App.sln index cfcf80f583..9702dc425d 100644 --- a/NexusMods.App.sln +++ b/NexusMods.App.sln @@ -64,6 +64,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".solutionItems", ".solution NuGet.Build.props = NuGet.Build.props README.md = README.md Directory.Packages.props = Directory.Packages.props + .gitignore = .gitignore EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NexusMods.Games.FOMOD", "src\Games\NexusMods.Games.FOMOD\NexusMods.Games.FOMOD.csproj", "{B43A31B2-1F08-4D8E-9C45-48015FBA983E}" @@ -129,6 +130,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Games.BladeAndSorcery", "src\Games\NexusMods.Games.BladeAndSorcery\NexusMods.Games.BladeAndSorcery.csproj", "{81F23A27-F517-41AD-B86E-6DCE7B4CCE93}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Games.BladeAndSorcery.Tests", "tests\Games\NexusMods.Games.BladeAndSorcery.Tests\NexusMods.Games.BladeAndSorcery.Tests.csproj", "{C2F6C9E5-CC53-44B7-994C-5B9287408263}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Games.AdvancedInstaller.UI", "src\Games\NexusMods.Games.AdvancedInstaller.UI\NexusMods.Games.AdvancedInstaller.UI.csproj", "{07B8ACA6-CE4B-496D-B183-63A57C5F08E1}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Games.AdvancedInstaller.UI.Tests", "tests\Games\NexusMods.Games.AdvancedInstaller.UI.Tests\NexusMods.Games.AdvancedInstaller.UI.Tests.csproj", "{2BFAAE53-AFFF-4F0B-AD76-67918665F298}" diff --git a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonDesignViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonDesignViewModel.cs index 7b0b96d1f0..25e7422bcf 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonDesignViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonDesignViewModel.cs @@ -6,11 +6,11 @@ public class AddPanelButtonDesignViewModel : AddPanelButtonViewModel { public AddPanelButtonDesignViewModel() : base(DummyState, IconUtils.StateToBitmap(DummyState)) { } - private static readonly IReadOnlyDictionary DummyState = new Dictionary - { - { PanelId.NewId(), new Rect(0, 0, 0.5, 0.5) }, - { PanelId.DefaultValue, new Rect(0.5, 0, 0.5, 0.5) }, - { PanelId.NewId(), new Rect(0, 0.5, 0.5, 0.5) }, - { PanelId.NewId(), new Rect(0.5, 0.5, 0.5, 0.5) }, - }; + private static readonly WorkspaceGridState DummyState = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(), new Rect(0, 0, 0.5, 0.5)), + new PanelGridState(PanelId.NewId(), new Rect(0, 0.5, 0.5, 0.5)), + new PanelGridState(PanelId.NewId(), new Rect(0.5, 0, 0.5, 0.5)), + new PanelGridState(PanelId.DefaultValue, new Rect(0.5, 0.5, 0.5, 0.5)) + ); } diff --git a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonViewModel.cs index 249e64d88d..2d7a565522 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/AddPanelButtonViewModel.cs @@ -7,12 +7,12 @@ namespace NexusMods.App.UI.WorkspaceSystem; public class AddPanelButtonViewModel : AViewModel, IAddPanelButtonViewModel { - public IReadOnlyDictionary NewLayoutState { get; } + public WorkspaceGridState NewLayoutState { get; } public IImage ButtonImage { get; } - public ReactiveCommand> AddPanelCommand { get; } + public ReactiveCommand AddPanelCommand { get; } public AddPanelButtonViewModel( - IReadOnlyDictionary newLayoutState, + WorkspaceGridState newLayoutState, IImage buttonImage) { NewLayoutState = newLayoutState; diff --git a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/IAddPanelButtonViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/IAddPanelButtonViewModel.cs index 078244f87b..f078f62eea 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/IAddPanelButtonViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/AddPanelButton/IAddPanelButtonViewModel.cs @@ -1,5 +1,4 @@ using System.Reactive; -using Avalonia; using Avalonia.Media; using ReactiveUI; @@ -7,9 +6,9 @@ namespace NexusMods.App.UI.WorkspaceSystem; public interface IAddPanelButtonViewModel : IViewModelInterface { - public IReadOnlyDictionary NewLayoutState { get; } + public WorkspaceGridState NewLayoutState { get; } public IImage ButtonImage { get; } - public ReactiveCommand> AddPanelCommand { get; } + public ReactiveCommand AddPanelCommand { get; } } diff --git a/src/NexusMods.App.UI/WorkspaceSystem/IconUtils.cs b/src/NexusMods.App.UI/WorkspaceSystem/IconUtils.cs index 877962502e..0ba74d07aa 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/IconUtils.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/IconUtils.cs @@ -23,7 +23,7 @@ internal static class IconUtils /// /// Generates a for the given state. /// - internal static Bitmap StateToBitmap(IReadOnlyDictionary state) + internal static Bitmap StateToBitmap(WorkspaceGridState state) { using var skPicture = GeneratePicture(state); using var skBitmap = skPicture.ToBitmap( @@ -39,7 +39,7 @@ internal static Bitmap StateToBitmap(IReadOnlyDictionary state) return skBitmap.ToAvaloniaImage(); } - private static SKPicture GeneratePicture(IReadOnlyDictionary state) + private static SKPicture GeneratePicture(WorkspaceGridState state) { using var skPictureRecorder = new SKPictureRecorder(); using var skCanvas = skPictureRecorder.BeginRecording(new SKRect(0f, 0f, IconSize, IconSize)); @@ -52,9 +52,9 @@ private static SKPicture GeneratePicture(IReadOnlyDictionary stat using var skPathFilled = new SKPath(); using var skPathHollow = new SKPath(); - foreach (var kv in state) + foreach (var panel in state) { - var (panelId, rect) = kv; + var (panelId, rect) = panel; DrawRect(skPathFilled, skPathHollow, rect, isHollow: panelId != PanelId.DefaultValue); } diff --git a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/IWorkspaceViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/IWorkspaceViewModel.cs index 49dd636afb..cb53e76664 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/IWorkspaceViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/IWorkspaceViewModel.cs @@ -11,6 +11,8 @@ public interface IWorkspaceViewModel : IViewModelInterface public ReadOnlyObservableCollection AddPanelButtonViewModels { get; } + public bool IsHorizontal { get; } + /// /// Called by the View to notify the VM about the new size of the control. /// @@ -20,7 +22,7 @@ public interface IWorkspaceViewModel : IViewModelInterface /// Add a new panel to the workspace. /// /// The newly created . - public IPanelViewModel AddPanel(IReadOnlyDictionary state); + public IPanelViewModel AddPanel(WorkspaceGridState state); /// /// Transforms the current state of the workspace into a serializable data format. diff --git a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspacePlaygroundViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspacePlaygroundViewModel.cs index 19a1714895..19ec57fbc0 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspacePlaygroundViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspacePlaygroundViewModel.cs @@ -2,11 +2,7 @@ using System.Reactive.Disposables; using System.Reactive.Linq; using System.Text.Json; -using Avalonia; using Microsoft.Extensions.DependencyInjection; -using NexusMods.App.UI.RightContent.LoadoutGrid; -using NexusMods.Common; -using NexusMods.DataModel.Loadouts; using ReactiveUI; using ReactiveUI.Fody.Helpers; @@ -63,10 +59,10 @@ public WorkspacePlaygroundViewModel() this.WhenActivated(disposables => { - WorkspaceViewModel.AddPanel(new Dictionary + WorkspaceViewModel.AddPanel(WorkspaceGridState.From(new[] { - { PanelId.DefaultValue, MathUtils.One } - }); + new PanelGridState(PanelId.DefaultValue, MathUtils.One) + }, isHorizontal: WorkspaceViewModel.IsHorizontal)); Disposable.Create(() => { }).DisposeWith(disposables); }); diff --git a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspaceViewModel.cs b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspaceViewModel.cs index cb71465e35..511b04d325 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspaceViewModel.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/Workspace/WorkspaceViewModel.cs @@ -206,7 +206,7 @@ public WorkspaceViewModel(PageFactoryController factoryController) private Size _lastWorkspaceSize; - [Reactive] private bool IsHorizontal { get; set; } + [Reactive] public bool IsHorizontal { get; private set; } /// public void Arrange(Size workspaceSize) @@ -244,10 +244,8 @@ private void UpdateStates() foreach (var state in newStates) { - var dict = state.ToDictionary(); - - var image = IconUtils.StateToBitmap(dict); - updater.Add(new AddPanelButtonViewModel(dict, image)); + var image = IconUtils.StateToBitmap(state); + updater.Add(new AddPanelButtonViewModel(state, image)); } }); } @@ -271,14 +269,14 @@ private void UpdateResizers() } /// - public IPanelViewModel AddPanel(IReadOnlyDictionary state) + public IPanelViewModel AddPanel(WorkspaceGridState state) { IPanelViewModel panelViewModel = null!; _panelSource.Edit(updater => { - foreach (var kv in state) + foreach (var panel in state) { - var (panelId, logicalBounds) = kv; + var (panelId, logicalBounds) = panel; if (panelId == PanelId.DefaultValue) { panelViewModel = new PanelViewModel(_factoryController) diff --git a/src/NexusMods.App.UI/WorkspaceSystem/WorkspaceGridState.cs b/src/NexusMods.App.UI/WorkspaceSystem/WorkspaceGridState.cs index f345890127..467bb04917 100644 --- a/src/NexusMods.App.UI/WorkspaceSystem/WorkspaceGridState.cs +++ b/src/NexusMods.App.UI/WorkspaceSystem/WorkspaceGridState.cs @@ -44,6 +44,16 @@ public static WorkspaceGridState From(IEnumerable panels, bool i ); } + public static WorkspaceGridState From(bool isHorizontal, params PanelGridState[] panels) => From(panels, isHorizontal); + + public static WorkspaceGridState From(IReadOnlyDictionary panels, bool isHorizontal) + { + return new WorkspaceGridState( + inner: panels.Select(kv => new PanelGridState(kv.Key, kv.Value)).ToImmutableSortedSet(PanelGridStateComparer.Instance), + isHorizontal + ); + } + public static WorkspaceGridState Empty(bool isHorizontal) => new(ImmutableSortedSet.Empty, isHorizontal); private WorkspaceGridState WithInner(ImmutableSortedSet inner) diff --git a/tests/NexusMods.UI.Tests/ModuleInitializer.cs b/tests/NexusMods.UI.Tests/ModuleInitializer.cs new file mode 100644 index 0000000000..45105a1484 --- /dev/null +++ b/tests/NexusMods.UI.Tests/ModuleInitializer.cs @@ -0,0 +1,20 @@ +using System.Runtime.CompilerServices; +using ImageMagick; + +namespace NexusMods.UI.Tests; + +public static class ModuleInitializer +{ + [ModuleInitializer] + public static void Init() + { + VerifyImageMagick.Initialize(); + VerifyImageMagick.RegisterComparers(threshold: 0.005D, metric: ErrorMetric.Fuzz); + } + + [ModuleInitializer] + public static void InitOther() + { + VerifierSettings.InitializePlugins(); + } +} diff --git a/tests/NexusMods.UI.Tests/NexusMods.UI.Tests.csproj b/tests/NexusMods.UI.Tests/NexusMods.UI.Tests.csproj index 18830ab43c..968b07dbab 100644 --- a/tests/NexusMods.UI.Tests/NexusMods.UI.Tests.csproj +++ b/tests/NexusMods.UI.Tests/NexusMods.UI.Tests.csproj @@ -8,6 +8,8 @@ + + @@ -23,5 +25,9 @@ PreserveNewest + + IconUtilsTests + IconUtilsTests.cs + diff --git a/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_FourPanels.verified.png b/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_FourPanels.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9ec769093fb9be682d68fb5632c4ea9d504d3a GIT binary patch literal 1411 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}EX7WqAsj$Z!;#X#z`$zd>Eakt zG3V`F+n~o@B5e;3&y{Xa4)49}chM=J$~aSjr7vOGp{2y-#jDM-74yOF}vAv)$3bv@$qjTKUO|jb>`Lf=ESpU#?=)S z5=U(FrwcUQy?;NNW8rnHGg)sRO#Xf}$?%2a%$dGw!n=3xe!Z7(bJT6=u*hl6HcS8e z28x7DOa1b8=GA3;6Yt);r*=2s-7gva&9}A~uUVwQRv-00$7rU@+|n6Wx6Mtoe6AvW zD)vmF@#@@`ubhdp`dVw&f6*%RGCY2E&9;wmiYkllY5$om&{X+8Sa*6)vEFX=YsoW0 zH*MJS{o9u>Q?hoZOgo)gwqCzCG0aB92_7;6Vk#WmLM^PEhniTB0*orcD!X^AEj|ad zcGc5KCqF*=2X;=<{`RzZE>TicA+$n3X#D3jDTJ2F>! zjX%fhionFHrMa=!J)`2Bmg z<#V>5zKeV>-+26ZajQVp`lD;E=`Fkb@_e$m-swxvKJSc;js1Enfp6Ek&8t>b+5UNJ z{4H{>$TfM_z!}BwPTw`Yz0LIf-pcoj|NZJVycX%&$|`fHx)qevaEIKYf9pT|`t|Gd z{*6`Z_@DNchN-uf78fUf{&`1j^2w9?HOv)RRg) z{{6Mm-1Y0%fBX1xVv23r*V_j-q-~yQYh%OnXx?^jj)U*szpt+Eni9EIw&v5m2pu+C zjm`J32kjs|wds8O(ynT%`EUnJnq|qE1RT zO+B1BBIDFgS(@)szh>znHtqYpdGqE4=}tdWv{UBnYj4Yk3k7JDtWZN(>E_Ygxy9RJ z^nj`UOoaZs|Law`wZBzo82A8_c~W{r?(KQS@;5sy^U}8Frbk%Toj!uch#yV(x)QlKTZvs{jF_l)Y>(fvzADo3cYNyEo$we{PSzf zWNUUleEKx?!}6c&UcdSIbLV$ZcEA1f>C^sNdjY2n-@lg^pX2>B+hz8$jmM9>b1Qy{ z>yBI->$Cjw{Ns8t)0UonUc7tPu2)+R%9O;WhlYNw`f)q`&1NgjHTGSL44&VazB_$e zZuY(E&-dK_eict%v$>0l+oI(=mm;J*g9O2ThQ2m`_l$L4;(?_qgQu&X%Q~loCIG1i BrmO$} literal 0 HcmV?d00001 diff --git a/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_ThreePanels_OneLargeColumn.verified.png b/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_ThreePanels_OneLargeColumn.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea9cd8794a8a1350874d9f4d6a4985c3fe3c6aa GIT binary patch literal 1686 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 I>zopr0AhrsssI20 literal 0 HcmV?d00001 diff --git a/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_TwoRows.verified.png b/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.Test_StateToBitmap_TwoRows.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..802e6f18d1664e67bf63b1852ee563e4776e4e57 GIT binary patch literal 1452 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}EX7WqAsj$Z!;#X#z`&a9>Eakt zG3V{wjb5*FWR8EVe=54AaD|h&>B7nBTl8GlJLo&Ito;7q-J=?_!s|=B?={9bsDEU; zvcyj;M8H_YQo54_{cMu}PzA&E34{#TNt4w8>9Oo!NUl*?ZEFM;6-#fYLb#!$j_uoH% z_c?ENaq;C{ck?ox7s~CryY6e1?R&ZW2y1KWrF<>FZrr=~ZJqUDuBHRircd{l=lHr| z*RHJM;^K3q=@I+u{!Zd)smd^sy5}}0aqZf*o@`FFKcouVwr<*_B+2$wux(-SSxK?& znG@2}j{Uv4{=;6U=_bCpCQ?&Nt^PC^@T|R=Gp%Udr9)D^Zr^@?f4|AEUA~~ABH~uN z**-I7&O=QsNWmr`rozE3)WS+#;lNw{x7!jk+S}Vx=knPf_`dtC>r}C@%{QMIYW_I< zbGgCkWp#`6{{`*?dJh;kCkvD`{T3p{N?xC-zr_=ZNQoGaEyLa#2eEM{0dB6FZ{(gRIOUsSd zuU`*hcP`z#XU~n7FIU#q)m42r1*V*LtgF*DXI58NUwi%4OIqNnu?%0XfkectWjm{v zbG<(O>(?$>8JP$HmU>f#RZri(J$vr_`M2M`mAy*lYW=$O^2-Pj*K03JfNAUVjQg`r zZaOn>-aMT?P}-7{ljEBII69HB^2aS6ydm0o=zq9{wRLu)M3jiDn5&@q!fcJxM$-Mq zr>S%vEzJ4;{d?>Az!z#?u3ek<_T9T%fBw`w6n83Jnwiyn@Ic$)hgXjKh+aE%sOjzd z_qUH7I~LE|k+pm0&W)QlZ!X&RLY$>hR#x`rqen@Z%!_u-n?L{Uj~_Sg-M_#0chUVl z-+$LGIwbGy?S1Y2_u}uBhi~1vvn6kP^sRsu?Rnd0|NhT^Z$nvGnU^fb*NuDkzKtz! z6J=@C)z_bHC-5qlu6M33{ zefYa&iLp-JWrg!+dVX(~H(#g-$(yuEWZ29;BpEi%_peL*pT!_&N%bF}lo%inPG)Y( zz+~31;yEX~r8WO|Sj4{O2A$JyK7PEo^BqsN(aalPziv&@2)Tdt>QrAf;pe-)7acx& zwDo9V%&&kI+jj4^-o0nfmvY-OsA@aBke7|w`?5*-`;f%i$oTl}&CSf*O%K+yxoq9Dckj)g zKX=}}ch9fZXW@o@C04TCi%wY0?b~`gSMGDPapbg{moHBSCJE0;Hx3_meppzopr06<%@C;$Ke literal 0 HcmV?d00001 diff --git a/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.cs b/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.cs index d3dfaaeb75..8d5619cf40 100644 --- a/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.cs +++ b/tests/NexusMods.UI.Tests/WorkspaceSystem/IconUtilsTests.cs @@ -1,23 +1,86 @@ +using System.Runtime.CompilerServices; using Avalonia; -using FluentAssertions; using NexusMods.App.UI.WorkspaceSystem; namespace NexusMods.UI.Tests.WorkspaceSystem; -public class IconUtilsTests : AUiTest +[UsesVerify] +public class IconUtilsTests(IServiceProvider provider) : AUiTest(provider) { - public IconUtilsTests(IServiceProvider provider) : base(provider) { } + [Fact] + public Task Test_StateToBitmap_TwoColumns() + { + var state = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(),new Rect(0, 0, 0.5, 1)), + new PanelGridState(PanelId.DefaultValue, new Rect(0.5, 0, 0.5, 1)) + ); + + return RunVerify(state); + } + + [Fact] + public Task Test_StateToBitmap_TwoRows() + { + var state = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(), new Rect(0, 0, 1, 0.5)), + new PanelGridState(PanelId.DefaultValue, new Rect(0, 0.5, 1, 0.5)) + ); + + return RunVerify(state); + } [Fact] - public void Test_StateToBitmap() + public Task Test_StateToBitmap_ThreePanels_OneLargeColumn() + { + var state = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(),new Rect(0, 0, 0.5, 0.5)), + new PanelGridState(PanelId.DefaultValue, new Rect(0.5, 0, 0.5, 1)), + new PanelGridState(PanelId.NewId(), new Rect(0, 0.5, 0.5, 0.5)) + ); + + return RunVerify(state); + } + + [Fact] + public Task Test_StateToBitmap_ThreePanels_OneLargeRow() + { + var state = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(), new Rect(0, 0, 0.5, 0.5)), + new PanelGridState(PanelId.NewId(), new Rect(0.5, 0, 0.5, 0.5)), + new PanelGridState(PanelId.DefaultValue,new Rect(0, 0.5, 1, 0.5)) + ); + + return RunVerify(state); + } + + [Fact] + public Task Test_StateToBitmap_FourPanels() + { + var state = WorkspaceGridState.From( + isHorizontal: true, + new PanelGridState(PanelId.NewId(), new Rect(0, 0, 0.5, 0.5)), + new PanelGridState(PanelId.NewId(), new Rect(0, 0.5, 0.5, 0.5)), + new PanelGridState(PanelId.NewId(), new Rect(0.5, 0, 0.5, 0.5)), + new PanelGridState(PanelId.DefaultValue, new Rect(0.5, 0.5, 0.5, 0.5)) + ); + + return RunVerify(state); + } + + private static Task RunVerify(WorkspaceGridState state, [CallerFilePath] string sourceFile = "") { - var state = new Dictionary + using var stream = new MemoryStream(); + using (var bitmap = IconUtils.StateToBitmap(state)) { - { PanelId.NewId(), new Rect(0, 0, 0.5, 1) }, - { PanelId.DefaultValue, new Rect(0.5, 0, 0.5, 1) } - }; + bitmap.Save(stream); + stream.Position = 0; + } - var bitmap = IconUtils.StateToBitmap(state); - bitmap.Size.Should().Be(new Size(150, 150)); + // ReSharper disable once ExplicitCallerInfoArgument + return Verify(stream, extension: "png", sourceFile: sourceFile).DisableDiff(); } }