| 1 | using CascadeIDE.Features.UiChrome; |
| 2 | using CascadeIDE.Features.Workspace; |
| 3 | using CascadeIDE.Models; |
| 4 | using Xunit; |
| 5 | |
| 6 | namespace CascadeIDE.Tests; |
| 7 | |
| 8 | public sealed class UiWorkspaceTomlMergerTests |
| 9 | { |
| 10 | [Fact] |
| 11 | public void Merge_null_null_yields_null() |
| 12 | { |
| 13 | Assert.Null(RepositoryWorkspaceTomlMerger.Merge(null, null)); |
| 14 | } |
| 15 | |
| 16 | [Fact] |
| 17 | public void Merge_lower_only_round_trips_scalars() |
| 18 | { |
| 19 | var lower = new RepositoryWorkspaceToml |
| 20 | { |
| 21 | Chrome = new UiWorkspaceChromeToml |
| 22 | { |
| 23 | PfdRegionDefaultWidthPixels = 300, |
| 24 | BottomPanelMinRowPixels = 80 |
| 25 | } |
| 26 | }; |
| 27 | var m = RepositoryWorkspaceTomlMerger.Merge(lower, null); |
| 28 | Assert.NotNull(m); |
| 29 | Assert.Equal(300, m!.Chrome!.PfdRegionDefaultWidthPixels); |
| 30 | Assert.Equal(80, m.Chrome.BottomPanelMinRowPixels); |
| 31 | } |
| 32 | |
| 33 | [Fact] |
| 34 | public void Merge_higher_overrides_scalars() |
| 35 | { |
| 36 | var lower = new RepositoryWorkspaceToml |
| 37 | { |
| 38 | Chrome = new UiWorkspaceChromeToml { PfdRegionDefaultWidthPixels = 300 } |
| 39 | }; |
| 40 | var higher = new RepositoryWorkspaceToml |
| 41 | { |
| 42 | Chrome = new UiWorkspaceChromeToml { PfdRegionDefaultWidthPixels = 400 } |
| 43 | }; |
| 44 | var m = RepositoryWorkspaceTomlMerger.Merge(lower, higher); |
| 45 | Assert.Equal(400, m!.Chrome!.PfdRegionDefaultWidthPixels); |
| 46 | } |
| 47 | |
| 48 | [Fact] |
| 49 | public void Merge_higher_fills_missing_scalars_from_lower() |
| 50 | { |
| 51 | var lower = new RepositoryWorkspaceToml |
| 52 | { |
| 53 | Chrome = new UiWorkspaceChromeToml |
| 54 | { |
| 55 | PfdRegionDefaultWidthPixels = 300, |
| 56 | BottomPanelMinRowPixels = 90 |
| 57 | } |
| 58 | }; |
| 59 | var higher = new RepositoryWorkspaceToml |
| 60 | { |
| 61 | Chrome = new UiWorkspaceChromeToml { BottomPanelMinRowPixels = 100 } |
| 62 | }; |
| 63 | var m = RepositoryWorkspaceTomlMerger.Merge(lower, higher); |
| 64 | Assert.Equal(300, m!.Chrome!.PfdRegionDefaultWidthPixels); |
| 65 | Assert.Equal(100, m.Chrome.BottomPanelMinRowPixels); |
| 66 | } |
| 67 | |
| 68 | [Fact] |
| 69 | public void Merge_attention_routing_union_higher_wins_key() |
| 70 | { |
| 71 | var lower = new RepositoryWorkspaceToml |
| 72 | { |
| 73 | Routing = new UiWorkspaceRoutingToml |
| 74 | { |
| 75 | Attention = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 76 | { |
| 77 | ["solution_explorer"] = "pfd", |
| 78 | ["chat"] = "mfd" |
| 79 | } |
| 80 | } |
| 81 | }; |
| 82 | var higher = new RepositoryWorkspaceToml |
| 83 | { |
| 84 | Routing = new UiWorkspaceRoutingToml |
| 85 | { |
| 86 | Attention = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 87 | { |
| 88 | ["solution_explorer"] = "mfd", |
| 89 | ["git"] = "pfd" |
| 90 | } |
| 91 | } |
| 92 | }; |
| 93 | var m = RepositoryWorkspaceTomlMerger.Merge(lower, higher); |
| 94 | Assert.NotNull(m!.Routing?.Attention); |
| 95 | Assert.Equal("mfd", m.Routing.Attention!["solution_explorer"]); |
| 96 | Assert.Equal("mfd", m.Routing.Attention["chat"]); |
| 97 | Assert.Equal("pfd", m.Routing.Attention["git"]); |
| 98 | } |
| 99 | |
| 100 | [Fact] |
| 101 | public void Merge_instrument_routing_higher_wins_key_union() |
| 102 | { |
| 103 | var lower = new RepositoryWorkspaceToml |
| 104 | { |
| 105 | Routing = new UiWorkspaceRoutingToml |
| 106 | { |
| 107 | Instruments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 108 | { |
| 109 | [InstrumentRoutingSlotKeys.PfdPrimary] = "solution_explorer", |
| 110 | [InstrumentRoutingSlotKeys.MfdPrimary] = "workspace_map" |
| 111 | } |
| 112 | } |
| 113 | }; |
| 114 | var higher = new RepositoryWorkspaceToml |
| 115 | { |
| 116 | Routing = new UiWorkspaceRoutingToml |
| 117 | { |
| 118 | Instruments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 119 | { |
| 120 | [InstrumentRoutingSlotKeys.PfdPrimary] = "workspace_map" |
| 121 | } |
| 122 | } |
| 123 | }; |
| 124 | |
| 125 | var merged = RepositoryWorkspaceTomlMerger.Merge(lower, higher); |
| 126 | Assert.NotNull(merged?.Routing?.Instruments); |
| 127 | Assert.Equal("workspace_map", merged!.Routing!.Instruments![InstrumentRoutingSlotKeys.PfdPrimary]); |
| 128 | Assert.Equal("workspace_map", merged.Routing.Instruments[InstrumentRoutingSlotKeys.MfdPrimary]); |
| 129 | } |
| 130 | |
| 131 | [Fact] |
| 132 | public void Merge_loc_limits_higher_overrides_partial_scalars() |
| 133 | { |
| 134 | var lower = new RepositoryWorkspaceToml |
| 135 | { |
| 136 | LocLimits = new UiWorkspaceLocLimitsToml { MediumMin = 300, HighMin = 800 } |
| 137 | }; |
| 138 | var higher = new RepositoryWorkspaceToml |
| 139 | { |
| 140 | LocLimits = new UiWorkspaceLocLimitsToml { HighMin = 900 } |
| 141 | }; |
| 142 | var m = RepositoryWorkspaceTomlMerger.Merge(lower, higher); |
| 143 | Assert.NotNull(m?.LocLimits); |
| 144 | Assert.Equal(300, m!.LocLimits!.MediumMin); |
| 145 | Assert.Equal(900, m.LocLimits.HighMin); |
| 146 | } |
| 147 | } |
| 148 | |