test(documents): diagnose deletion recovery status

Refs #6

Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
Signed-off-by: James Maes <jmaes@dmdbrands.com>
This commit is contained in:
James MaesandCodex committed 2026-10-10 20:11:02 -05:00
1 parent 09d14e6b78
commit 665ece7fa4
4 files changed
+38 -7

No files matched your search

+11 -3
View File
@@ -25,11 +25,15 @@ native messaging stay disabled; fixed native queries check the current document
and results are validated finite fractions before numeric-only restoration.
Local evidence: zero-warning solution build; 82 core tests, zero skipped, 100% core
line coverage; 12 native filesystem/watcher tests passed. Browser replacement,
line coverage; 13 native filesystem/watcher tests passed, including loaded-file handle release and the
actual FileNotFoundException after deletion. Browser replacement,
deletion/recreation, editor lock, relative-scroll and remote-image denial tests have
been added but not run locally. Desktop reservation remains unanswered; do not drive
this desktop without availability. Hosted current-head acceptance will be the next
runtime proof. Issues #4 (reader boundary), #6 (reload) and #1 (full scope) remain open.
this desktop without availability. Reload head 09d14e6 hosted UI/published acceptance reproduced a deletion-status
timeout in both builds: 23 of 24 tests passed, including replacement, editor-lock,
scroll and remote-image denial. Diagnostics now preserve the exact assertion and
record observed status, exception type/HRESULT/thread access and app logs; root cause
is still unproven. Do not weaken or skip the deletion assertion. Issues #4 (reader boundary), #6 (reload) and #1 (full scope) remain open.
## Repository and authorization
@@ -51,3 +55,7 @@ frontmatter, editor, print, multiple windows, recents and Windows associations.
Original reference is pinned at 6d08bc9d27d7d7b2c2fa95bb282da330b8cf9021 under
AppKit/artifacts/markdownviewr-reference. No original code/resources copied yet;
retain Darin's MIT notices when adapting them. Full PRODUCT.md scope remains open.
Reference preparation: all 20 original JSON themes have been downloaded into
AppKit/artifacts/markdownviewr-reference/markdownViewr/Resources/themes and checked
against their Git blob hashes at the pinned commit. They are not yet in the app.
+2 -1
View File
@@ -161,13 +161,14 @@ public sealed partial class MainWindow : Window, IDisposable
}
catch(Exception exception) when(exception is IOException or UnauthorizedAccessException or ArgumentException or System.Runtime.InteropServices.COMException)
{
App.Log.Warning(FormattableString.Invariant($"Could not open a Markdown document. Reload={reload}; exception={exception.GetType().Name}; HRESULT=0x{exception.HResult:X8}; UIThread={DispatcherQueue.HasThreadAccess}."));
if(!_closed)
{
StatusText.Text = reload && exception is FileNotFoundException
? "The document is missing. Showing the last version; it will reload when restored."
: "Could not open this document: " + exception.Message;
}
App.Log.Warning("Could not open a Markdown document.");
}
finally
{
@@ -151,9 +151,17 @@ public class AppTests
session.WaitFor(() => session.FindInApp(cf => cf.ByName("Last readable version")), "the initial heading", TimeSpan.FromSeconds(30));
string path = Path.Combine(session.DataDirectory, "document.md");
File.Delete(path);
session.WaitFor(
() => session.FindInApp(cf => cf.ByName("The document is missing. Showing the last version; it will reload when restored.")),
"the missing-file status");
try
{
session.WaitFor(
() => session.FindInApp(cf => cf.ByName("The document is missing. Showing the last version; it will reload when restored.")),
"the missing-file status");
}
catch(TimeoutException exception)
{
AutomationElement? status = session.FindInApp(cf => cf.ByAutomationId("StatusText"));
throw new TimeoutException($"{exception.Message} Observed status: '{status?.Properties.Name.ValueOrDefault}'. Logs: {session.ReadLogs()}", exception);
}
Assert.NotNull(session.FindInApp(cf => cf.ByName("Last readable version")));
File.WriteAllText(path, "# Recovered document");
session.WaitFor(() => session.FindInApp(cf => cf.ByName("Recovered document")), "the recreated document heading");
@@ -37,6 +37,20 @@ public sealed class DocumentFilesTests : IDisposable
/// <summary>A loaded snapshot does not keep the source file open or hide its subsequent deletion.</summary>
[Fact]
public void Open_DeletedSource_ThrowsFileNotFound()
{
string path = Path.Combine(_root, "document", "read.md");
File.WriteAllText(path, "# Snapshot");
var files = DocumentFiles.Open(path);
File.Delete(path);
Assert.Equal("# Snapshot", files.Markdown);
Assert.Throws<FileNotFoundException>(() => DocumentFiles.Open(path));
}
/// <summary>Ordinary relative images inside the selected folder retain their exact bytes.</summary>
[Fact]
public void ReadImage_InsideDocumentFolder_ReturnsExactBytes()