From 1a0b0e014cf0e7b65268ccf97aca7045d8a63089 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 7 Sep 2026 18:16:36 +0200 Subject: [PATCH] =?UTF-8?q?fix(vtank):=20slice=207=20round=20E=20item=20D-?= =?UTF-8?q?5=20=E2=80=94=20refresh=20Advanced=20Options=20on=20open?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RefreshAdvancedOptions' own doc comment lists every real mutation site that must call it (category toggle, edit/apply, selection change, profile load) but ShowAdvancedOptions itself was missing — opening the popup only called LoadAdvancedOptionDraft. A setting changed while the popup was closed (/vt opt set, one of the Options tab's own direct checkboxes, or a profile load) left the cached AdvancedOptionNames/ AdvancedOptionValueColumn on whatever they held from construction or the popup's last open, until some in-popup interaction happened to refresh them. Mutation shown to fail first: reverting the source fix (git checkout, patch saved and reapplied) reproduced the stale column — toggling CombatEnabled then opening the popup still showed the pre-toggle value. MossTank suite 721 -> 722; App markup/plugin filter holds 244/244. Co-Authored-By: Claude Fable 5.1 --- src/AcDream.Plugins.MossTank/MossTankPanel.cs | 10 +++++++ .../MossTankPanelTests.cs | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/AcDream.Plugins.MossTank/MossTankPanel.cs b/src/AcDream.Plugins.MossTank/MossTankPanel.cs index 830b1a03..04a7a542 100644 --- a/src/AcDream.Plugins.MossTank/MossTankPanel.cs +++ b/src/AcDream.Plugins.MossTank/MossTankPanel.cs @@ -610,9 +610,19 @@ internal sealed partial class MossTankPanel return value.ToDisplayString(); } + // D-5 (round E architecture re-check): RefreshAdvancedOptions' own doc + // comment already lists every real mutation site that must call it — + // category toggle, edit/apply, selection change, and profile load — + // but opening the popup itself was missing, so a value changed + // between closes (/vt opt set, one of the Options tab's own direct + // checkboxes, or a profile load that happened while the popup was + // already closed) stayed on whatever _advancedOptionValueColumn held + // from construction or the popup's last open, until some in-popup + // interaction happened to refresh it. public Action ShowAdvancedOptions => () => { _advancedOptionsVisible = true; + RefreshAdvancedOptions(); LoadAdvancedOptionDraft(); }; public Action HideAdvancedOptions => () => _advancedOptionsVisible = false; diff --git a/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs b/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs index 3b74dd81..2edb95e2 100644 --- a/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs +++ b/tests/AcDream.Plugins.MossTank.Tests/MossTankPanelTests.cs @@ -1392,6 +1392,34 @@ public sealed class MossTankPanelTests Assert.Equal(panel.CombatEnabled ? "True" : "False", after); } + /// + /// D-5 (round E architecture re-check): RefreshAdvancedOptions' own + /// doc comment already lists every real mutation site that must call + /// it — category toggle, edit/apply, selection change, and profile + /// load — but opening the popup itself (ShowAdvancedOptions) was + /// missing. A setting changed via the Options tab (ToggleCombatEnabled, + /// the same mutator + /// exercises through a "selection change") while the popup was closed + /// must already read correctly the FIRST time it opens — not only + /// after some in-popup interaction happens to refresh it. + /// + [Fact] + public void ShowAdvancedOptionsRefreshesValuesChangedWhileThePopupWasClosed() + { + var panel = new MossTankPanel(new FakeHost(new FakeAutomation())); + int index = panel.AdvancedOptionNames.ToList().IndexOf("EnableCombat"); + Assert.True(index >= 0); + string before = panel.AdvancedOptionValueColumn[index]; + Assert.Equal(panel.CombatEnabled ? "True" : "False", before); + + panel.ToggleCombatEnabled(); + panel.ShowAdvancedOptions(); + + string after = panel.AdvancedOptionValueColumn[index]; + Assert.NotEqual(before, after); + Assert.Equal(panel.CombatEnabled ? "True" : "False", after); + } + [Fact] public void AdvancedOptionsPopupBindingsDoNotReallocateOnEveryRead() {