feat(presentation): wire platform scenes and UI commands

This commit is contained in:
2026-09-05 12:47:15 +08:00
parent 8b7efa7de0
commit d29a659541
4 changed files with 860 additions and 16 deletions
@@ -261,3 +261,106 @@ test('does not swallow an onFault callback error', () => {
renderer.request();
assert.equal(callbacks.length, 1);
});
test('registration reentering flush cancels the superseded handle without blocking the next frame', () => {
const callbacks: (() => void)[] = [];
let cancelled = 0;
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
callbacks.push(callback);
if (callbacks.length === 1) renderer.flush();
return () => { cancelled += 1; };
} }, () => { rendered += 1; }, error => { throw error; });
renderer.request();
assert.equal(rendered, 1);
assert.equal(cancelled, 1);
callbacks[0](); assert.equal(rendered, 1);
renderer.request();
assert.equal(callbacks.length, 2);
callbacks[1](); assert.equal(rendered, 2);
});
test('registration reentering dispose immediately cancels its returned handle once', () => {
const callbacks: (() => void)[] = [];
let cancelled = 0;
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
callbacks.push(callback); renderer.dispose();
return () => { cancelled += 1; };
} }, () => { rendered += 1; }, error => { throw error; });
renderer.request(); renderer.dispose();
assert.equal(cancelled, 1);
callbacks[0]();
assert.equal(rendered, 0);
renderer.request(); assert.equal(callbacks.length, 1);
});
test('a reentrant request during registration coalesces with the acquiring frame', () => {
const callbacks: (() => void)[] = [];
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
callbacks.push(callback);
if (callbacks.length === 1) renderer.request();
return () => {};
} }, () => { rendered += 1; }, error => { throw error; });
renderer.request();
assert.equal(callbacks.length, 1);
callbacks[0](); assert.equal(rendered, 1);
});
test('registration failure releases the reservation and invalidates its captured callback', () => {
const failure = new Error('request failed');
const callbacks: (() => void)[] = [];
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
callbacks.push(callback);
if (callbacks.length === 1) throw failure;
return () => {};
} }, () => { rendered += 1; }, error => { throw error; });
assert.throws(() => renderer.request(), error => error === failure);
renderer.request(); assert.equal(callbacks.length, 2);
callbacks[0](); assert.equal(rendered, 0);
callbacks[1](); assert.equal(rendered, 1);
});
test('superseded registration preserves the successor scheduled by its synchronous flush', () => {
const callbacks: (() => void)[] = [];
const cancelled: number[] = [];
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
const index = callbacks.length;
callbacks.push(callback);
if (index === 0) renderer.flush();
return () => { cancelled.push(index); };
} }, () => {
rendered += 1;
if (rendered === 1) renderer.request();
}, error => { throw error; });
renderer.request();
assert.deepEqual(cancelled, [0]);
assert.equal(callbacks.length, 2);
callbacks[0](); assert.equal(rendered, 1);
renderer.flush();
assert.deepEqual(cancelled, [0, 1]);
assert.equal(rendered, 2);
callbacks[1](); assert.equal(rendered, 2);
});
test('superseded handle cancellation errors propagate without reviving stale callbacks', () => {
const failure = new Error('late handle cancellation');
const callbacks: (() => void)[] = [];
let rendered = 0;
const renderer = new FrameRenderer({ request(callback) {
callbacks.push(callback); renderer.dispose();
return () => { throw failure; };
} }, () => { rendered += 1; }, error => { throw error; });
assert.throws(() => renderer.request(), error => error === failure);
callbacks[0](); renderer.dispose(); renderer.request();
assert.equal(rendered, 0);
assert.equal(callbacks.length, 1);
});