48a9c933af
Pixi режется по contentRect, пульт идёт в preview (12 FPS, 0.5 DPR), штампы тумана/огня/дождя прореживаются, draft темноты и маркера не чаще 20 Гц. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
/** Регресс: scheduleDraftRepaint бампил draftFxTick → полный ре-рендер ControlApp на кадр штриха. */
|
|
void test('ControlApp: draft кисти без корневого draftFxTick', () => {
|
|
const app = fs.readFileSync(path.join(here, 'ControlApp.tsx'), 'utf8');
|
|
const pixi = fs.readFileSync(
|
|
path.join(here, '../shared/effects/PxiEffectsOverlay.tsx'),
|
|
'utf8',
|
|
);
|
|
|
|
assert.doesNotMatch(app, /\bdraftFxTick\b/);
|
|
assert.doesNotMatch(app, /\bsetDraftFxTick\b/);
|
|
assert.doesNotMatch(app, /\bfxMergedState\b/);
|
|
|
|
assert.ok(app.includes('scheduleDraftRepaint'));
|
|
assert.ok(app.includes('pushDraftToPixi'));
|
|
assert.ok(app.includes('effectsOverlayRef'));
|
|
assert.match(app, /scheduleDraftRepaint[\s\S]*?pushDraftToPixi\(\)/);
|
|
assert.doesNotMatch(
|
|
app,
|
|
/scheduleDraftRepaint[\s\S]*?setDraftFxTick/,
|
|
'RAF draft не трогает React state корня',
|
|
);
|
|
|
|
assert.ok(pixi.includes('PixiEffectsOverlayHandle'));
|
|
assert.ok(pixi.includes('setDraft'));
|
|
assert.ok(pixi.includes('mergeDraftState'));
|
|
assert.ok(pixi.includes('forwardRef'));
|
|
assert.ok(app.includes('perfProfile="preview"'));
|
|
assert.ok(app.includes('OVERLAY_DRAFT_IPC_MS'));
|
|
});
|
|
|
|
void test('ControlApp: path playback не гоняет setState корня', () => {
|
|
const app = fs.readFileSync(path.join(here, 'ControlApp.tsx'), 'utf8');
|
|
const hook = fs.readFileSync(
|
|
path.join(here, '../shared/tokens/useTokenPathLivePoses.ts'),
|
|
'utf8',
|
|
);
|
|
assert.doesNotMatch(app, /\bpathLivePoses\b/);
|
|
assert.doesNotMatch(hook, /\bsetPoses\b/);
|
|
assert.ok(hook.includes('applyLivePathPose'));
|
|
assert.ok(hook.includes('requestAnimationFrame'));
|
|
});
|