docs 22 D-on probe + app-quit teardown spec; bump wx (alignment) + kicad (root identity)
The D-on probe (wxWASM_STAR_DISPATCH=1 on top of D5) is measured and recorded in doc 22 §10: the week's 'environmental cliff' was adopted-fiber- stack alignment (trap 1, fixed in wx - retires the D5 entry's findings 2-3 with a mechanism); with it fixed D5+D reached 388 passed; the remaining reds decompose into three named Phase B gaps (wake ordering on a running context, finished-coroutine transfer livelock, invocation-aware root routing), each with a deterministic repro suite. D parks again behind the switch until Phase B owns coroutine lifetimes. app-quit.spec.ts + a wx_test_quit hook in minimal_test drive a real File->Quit-shaped exit through D5's detached teardown (loop exits on its context, S6 latch 'clean', OnExit + wxUninitialize there) - green in the D-on probe, closing the D5 teardown-gate open item. Landing state (D off): coroutine + coroutine-pthread + app-quit green; nested red at case 3 in the pre-existing doc-19 wake-window family (cases 1-2, yesterday's blockers, now pass); races wakeup_during_transition stays layout-sensitive. Both are the class the C+B+E flip removes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LBjomQfKyRa3jBdeAKpmTw
This commit is contained in:
parent
801aff6649
commit
7dfd4f1834
5 changed files with 148 additions and 9 deletions
|
|
@ -20,8 +20,19 @@
|
|||
#include "wx/spinctrl.h"
|
||||
#include "wx/srchctrl.h"
|
||||
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Quit hook for the app-quit teardown spec (docs/features/async/22 D5): close
|
||||
// the main frame exactly as File->Quit would, so the spec can drive a real
|
||||
// app exit through the detached main-loop teardown path from JS.
|
||||
extern "C" void EMSCRIPTEN_KEEPALIVE wx_test_quit()
|
||||
{
|
||||
if (wxTheApp && wxTheApp->GetTopWindow())
|
||||
wxTheApp->GetTopWindow()->Close(true);
|
||||
}
|
||||
|
||||
// Control IDs
|
||||
enum {
|
||||
ID_BTN_TEST = wxID_HIGHEST + 1,
|
||||
|
|
|
|||
43
tests/e2e/app-quit.spec.ts
Normal file
43
tests/e2e/app-quit.spec.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { test, expect, waitForApp } from './utils/fixtures';
|
||||
|
||||
// D5 (docs/features/async/22): the main loop runs on a scheduler context and
|
||||
// OnRun/main() return at startup, so a real app quit must travel the DETACHED
|
||||
// teardown path — the loop exits on its context, latches the shim DEAD ("main
|
||||
// loop exited"), and runs OnExit + wxUninitialize there. Nothing else in the
|
||||
// battery drives an app exit, so this spec is the teardown gate doc 22's D5
|
||||
// entry asks for. Intentionally takes no screenshots.
|
||||
test.describe('App quit (detached main-loop teardown)', () => {
|
||||
test('quit runs the detached teardown cleanly', async ({ page, testLogger }) => {
|
||||
const fatal: string[] = [];
|
||||
page.on('pageerror', (err) => fatal.push(String(err)));
|
||||
|
||||
await page.goto('/minimal_test.html');
|
||||
await waitForApp(page);
|
||||
|
||||
// Close the main frame exactly as File->Quit would (wx_test_quit is the
|
||||
// app's EMSCRIPTEN_KEEPALIVE hook). The frame's pending-delete drains on a
|
||||
// later idle tick, the last top-level window's destruction ends the main
|
||||
// loop, and the loop context runs the teardown.
|
||||
await page.evaluate(() => (window as any).Module._wx_test_quit());
|
||||
|
||||
// The S6 latch names the exit; "clean" means no queued work was stranded.
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
testLogger.consoleLogs.find((l) =>
|
||||
l.includes('[wx-scheduler] shutdown (main loop exited)')
|
||||
) ?? null,
|
||||
{ timeout: 20000 }
|
||||
)
|
||||
.not.toBeNull();
|
||||
|
||||
const all = testLogger.consoleLogs.join('\n');
|
||||
expect(all).toContain('shutdown (main loop exited) clean');
|
||||
|
||||
// The teardown itself must not trap or trip the scheduler's guards.
|
||||
expect(all).not.toContain('Aborted');
|
||||
expect(all).not.toContain('unreachable executed');
|
||||
expect(all).not.toContain('[sched-ctx] REFUSED');
|
||||
expect(fatal, `page errors: ${fatal.join('\n')}`).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue