mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-24 04:27:27 +08:00
test(editor): add tests for turbo renderer layout cache
This commit is contained in:
@@ -73,20 +73,16 @@ export const TurboRendererConfigFactory =
|
|||||||
export class ViewportTurboRendererExtension extends GfxExtension {
|
export class ViewportTurboRendererExtension extends GfxExtension {
|
||||||
static override key = 'viewportTurboRenderer';
|
static override key = 'viewportTurboRenderer';
|
||||||
|
|
||||||
private readonly state$ = new BehaviorSubject<RenderingState>('inactive');
|
public readonly state$ = new BehaviorSubject<RenderingState>('inactive');
|
||||||
public readonly canvas: HTMLCanvasElement = document.createElement('canvas');
|
public readonly canvas: HTMLCanvasElement = document.createElement('canvas');
|
||||||
|
public layoutCacheData: ViewportLayoutTree | null = null;
|
||||||
private readonly worker: Worker;
|
private readonly worker: Worker;
|
||||||
private readonly disposables = new DisposableGroup();
|
private readonly disposables = new DisposableGroup();
|
||||||
private layoutCacheData: ViewportLayoutTree | null = null;
|
|
||||||
private layoutVersion = 0;
|
private layoutVersion = 0;
|
||||||
private bitmap: ImageBitmap | null = null;
|
private bitmap: ImageBitmap | null = null;
|
||||||
private viewportElement: GfxViewportElement | null = null;
|
private viewportElement: GfxViewportElement | null = null;
|
||||||
private readonly refresh$ = new Subject<void>();
|
private readonly refresh$ = new Subject<void>();
|
||||||
|
|
||||||
public get currentState(): RenderingState {
|
|
||||||
return this.state$.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(gfx: GfxController) {
|
constructor(gfx: GfxController) {
|
||||||
super(gfx);
|
super(gfx);
|
||||||
|
|
||||||
|
|||||||
+41
-12
@@ -2,6 +2,7 @@
|
|||||||
* Please refer to integration-test/README.md for commands to run tests.
|
* Please refer to integration-test/README.md for commands to run tests.
|
||||||
*/
|
*/
|
||||||
import { ParagraphLayoutHandlerExtension } from '@blocksuite/affine/blocks/paragraph';
|
import { ParagraphLayoutHandlerExtension } from '@blocksuite/affine/blocks/paragraph';
|
||||||
|
import { noop } from '@blocksuite/affine/global/utils';
|
||||||
import {
|
import {
|
||||||
TurboRendererConfigFactory,
|
TurboRendererConfigFactory,
|
||||||
ViewportTurboRendererExtension,
|
ViewportTurboRendererExtension,
|
||||||
@@ -45,36 +46,64 @@ describe('viewport turbo renderer', () => {
|
|||||||
|
|
||||||
test('initial state should be pending', async () => {
|
test('initial state should be pending', async () => {
|
||||||
const renderer = getRenderer();
|
const renderer = getRenderer();
|
||||||
expect(renderer.currentState).toBe('pending');
|
expect(renderer.state$.value).toBe('pending');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('zooming should change state to zooming', async () => {
|
test('zooming should change state to zooming', async () => {
|
||||||
const renderer = getRenderer();
|
const renderer = getRenderer();
|
||||||
renderer.viewport.zooming$.next(true);
|
renderer.viewport.zooming$.next(true);
|
||||||
await wait();
|
await wait();
|
||||||
expect(renderer.currentState).toBe('zooming');
|
expect(renderer.state$.value).toBe('zooming');
|
||||||
renderer.viewport.zooming$.next(false);
|
renderer.viewport.zooming$.next(false);
|
||||||
await wait();
|
await wait();
|
||||||
expect(renderer.currentState).not.toBe('zooming');
|
expect(renderer.state$.value).not.toBe('zooming');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('state should become ready after rendering', async () => {
|
test('state transitions between pending and ready', async () => {
|
||||||
addSampleNotes(doc, 1);
|
|
||||||
await wait(100);
|
|
||||||
const renderer = getRenderer();
|
const renderer = getRenderer();
|
||||||
|
|
||||||
|
// Initial state should be pending after adding content
|
||||||
|
addSampleNotes(doc, 1);
|
||||||
|
await wait(100); // Short wait for initial processing
|
||||||
|
expect(renderer.state$.value).toBe('pending');
|
||||||
|
|
||||||
|
// Ensure zooming is off and wait for debounce + buffer
|
||||||
renderer.viewport.zooming$.next(false);
|
renderer.viewport.zooming$.next(false);
|
||||||
await wait(renderer.options.debounceTime + 500);
|
await wait(renderer.options.debounceTime + 500);
|
||||||
expect(renderer.currentState).toBe('ready');
|
expect(renderer.state$.value).toBe('ready');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('invalidation should reset state to pending', async () => {
|
test('initial layout cache data should be null', () => {
|
||||||
|
const renderer = getRenderer();
|
||||||
|
expect(renderer.layoutCacheData).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('invalidation should reset layout cache data to null', async () => {
|
||||||
const renderer = getRenderer();
|
const renderer = getRenderer();
|
||||||
addSampleNotes(doc, 1);
|
addSampleNotes(doc, 1);
|
||||||
expect(renderer.currentState).toBe('pending');
|
await wait(100);
|
||||||
await wait(renderer.options.debounceTime + 500);
|
|
||||||
expect(renderer.currentState).toBe('ready');
|
// Access getter to populate cache
|
||||||
|
const _cache = renderer.layoutCache;
|
||||||
|
noop(_cache);
|
||||||
|
expect(renderer.layoutCacheData).not.toBeNull();
|
||||||
|
|
||||||
|
// Invalidate
|
||||||
addSampleNotes(doc, 1);
|
addSampleNotes(doc, 1);
|
||||||
await wait(100);
|
await wait(100);
|
||||||
expect(renderer.currentState).toBe('pending');
|
|
||||||
|
expect(renderer.layoutCacheData).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('accessing layoutCache getter should populate cache data', async () => {
|
||||||
|
const renderer = getRenderer();
|
||||||
|
addSampleNotes(doc, 1);
|
||||||
|
await wait();
|
||||||
|
expect(renderer.layoutCacheData).toBeNull(); // Check internal state before access
|
||||||
|
|
||||||
|
const _cache = renderer.layoutCache; // Access getter to populate cache
|
||||||
|
noop(_cache);
|
||||||
|
expect(renderer.layoutCacheData).not.toBeNull(); // Check internal state after access
|
||||||
|
expect(renderer.layoutCache?.roots.length).toBeGreaterThan(0); // Check public getter result
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user