Skip to content

Commit a8a2fc7

Browse files
Aaronhaohaoclaude
andcommitted
fix(gui): clear stale result on successful run, not on mode switch (F10 vs #70)
The first F10 pass cleared the previous mode's result inside _on_mode_change, but that defeated release-gate contract #70 (test_run_validation_error_preserves_previous_valid_result_overview): switching mode then hitting a validation error left "No results" because the result was already wiped at switch time, so there was nothing to preserve. Reconcile by moving the clear off the switch: a successful run in the new mode replaces the result (so stale wrong-mode output is never shown/exported once you actually compute — F10's real intent, satisfied via the _on_calc_finished -> _show_*_results path), while a failed or validation-errored run returns early and keeps the last good result (#70). Rewrite F10's own test to assert the new timing (switch preserves; a successful run replaces). Both previously-conflicting tests pass; 221 neighborhood tests pass; ruff clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 08c56a8 commit a8a2fc7

2 files changed

Lines changed: 22 additions & 17 deletions

File tree

app_desktop/window.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,16 +2180,12 @@ def _update_theme_from_palette(self, *args):
21802180

21812181
def _on_mode_change(self):
21822182
mode = self.mode_combo.currentData()
2183-
# Clear the previous mode's result text / CSV / plot so a mode switch
2184-
# never shows (or exports) another mode's stale output (audit F10). Skip
2185-
# while restoring a workspace (the just-restored result must survive) or
2186-
# while a worker is running (don't wipe an in-flight run's state).
2187-
if (
2188-
not getattr(self, "_workspace_restoring", False)
2189-
and not self._has_running_worker()
2190-
and hasattr(self, "_reset_csv_data")
2191-
):
2192-
self._reset_csv_data(clear_non_tabular_result=True)
2183+
# Note: the previous mode's result is deliberately NOT cleared here.
2184+
# A successful run in the new mode replaces it (so stale wrong-mode
2185+
# output is never shown/exported once you actually compute — audit F10),
2186+
# while a failed or validation-errored run preserves the last good
2187+
# result (release-gate contract #70). Clearing at switch time would
2188+
# defeat that preserve-on-failure contract.
21932189
self._sync_manual_table_columns_for_mode(mode)
21942190
mode_indices = {
21952191
"extrapolation": 0,

tests/test_desktop_mode_stack.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,26 @@ def _set_combo_data(combo: Any, value: str) -> None:
3333
QApplication.processEvents()
3434

3535

36-
def test_mode_switch_clears_previous_mode_result(window: Any) -> None:
37-
"""Switching modes must clear the previous mode's result text and CSV export
38-
buffer so stale wrong-mode data is never shown or exported (audit F10)."""
36+
def test_mode_switch_preserves_result_until_a_successful_run_replaces_it(window: Any) -> None:
37+
"""A mode switch must NOT wipe the previous result: a successful run in the
38+
new mode replaces it (so stale wrong-mode output is never shown/exported once
39+
you actually compute — audit F10), while a failed/validation-errored run
40+
keeps the last good result (release-gate contract #70). Clearing at switch
41+
time would defeat that preserve-on-failure contract."""
3942
window._set_csv_data([{"x": "1", "y": "2"}], ["x", "y"])
40-
window.result_edit.setPlainText("stale fit result from a previous mode")
43+
window.result_edit.setPlainText("prior-mode result")
4144
assert window._csv_rows
4245

46+
# Switching mode alone preserves the prior result (nothing has recomputed).
4347
_set_combo_data(window.mode_combo, "statistics")
44-
45-
assert window._csv_rows == []
46-
assert window.result_edit.toPlainText() == ""
48+
assert window._csv_rows == [{"x": "1", "y": "2"}]
49+
assert window.result_edit.toPlainText() == "prior-mode result"
50+
51+
# A successful run in the new mode replaces the result with fresh output.
52+
window._set_csv_data([{"stat": "mean", "value": "3"}], ["stat", "value"])
53+
window._set_result_text("statistics result", final_result=True)
54+
assert window._csv_rows == [{"stat": "mean", "value": "3"}]
55+
assert "statistics result" in window.result_edit.toPlainText()
4756

4857

4958
def _measure_mode_stack_width(window: Any) -> int:

0 commit comments

Comments
 (0)