snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ICommandService, Injector, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { ICanvasPopupService } from '@univerjs/ui';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import {
|
||||
SlideCanvasPopMangerService,
|
||||
transformBound2OffsetBound,
|
||||
transformPosition2Offset,
|
||||
} from '../slide-popup-manager.service';
|
||||
|
||||
class TestCanvasPopupService {
|
||||
readonly addedPopups: unknown[] = [];
|
||||
readonly removedPopupIds: string[] = [];
|
||||
|
||||
addPopup(popup: unknown) {
|
||||
this.addedPopups.push(popup);
|
||||
return 'popup-1';
|
||||
}
|
||||
|
||||
removePopup(id: string) {
|
||||
this.removedPopupIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRenderManagerService {
|
||||
static hasRender = false;
|
||||
|
||||
static reset() {
|
||||
this.hasRender = false;
|
||||
}
|
||||
|
||||
getRenderUnitById(unitId: string) {
|
||||
if (!TestRenderManagerService.hasRender || unitId !== 'slide-1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const canvasElement = document.createElement('canvas');
|
||||
canvasElement.style.width = '200px';
|
||||
canvasElement.getBoundingClientRect = () => ({
|
||||
left: 10,
|
||||
top: 20,
|
||||
width: 400,
|
||||
height: 300,
|
||||
right: 410,
|
||||
bottom: 320,
|
||||
x: 10,
|
||||
y: 20,
|
||||
toJSON: () => ({}),
|
||||
});
|
||||
|
||||
return {
|
||||
mainComponent: { width: 300, height: 200 },
|
||||
engine: {
|
||||
getCanvasElement: () => canvasElement,
|
||||
},
|
||||
scene: {
|
||||
width: 500,
|
||||
height: 400,
|
||||
getAncestorScale: () => ({ scaleX: 2, scaleY: 3 }),
|
||||
getViewport: () => ({ viewportScrollX: 5, viewportScrollY: 10 }),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TestUniverInstanceService {
|
||||
getCurrentUnitOfType(type: UniverInstanceType) {
|
||||
return type === UniverInstanceType.UNIVER_SLIDE ? { getUnitId: () => 'slide-1' } : null;
|
||||
}
|
||||
}
|
||||
|
||||
class TestCommandService {}
|
||||
|
||||
describe('SlideCanvasPopMangerService', () => {
|
||||
let service: SlideCanvasPopMangerService;
|
||||
let popupService: TestCanvasPopupService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestRenderManagerService.reset();
|
||||
const injector = new Injector();
|
||||
injector.add([ICanvasPopupService, { useClass: TestCanvasPopupService as never }]);
|
||||
injector.add([IRenderManagerService, { useClass: TestRenderManagerService as never }]);
|
||||
injector.add([IUniverInstanceService, { useClass: TestUniverInstanceService as never }]);
|
||||
injector.add([ICommandService, { useClass: TestCommandService as never }]);
|
||||
injector.add([SlideCanvasPopMangerService]);
|
||||
popupService = injector.get(ICanvasPopupService) as unknown as TestCanvasPopupService;
|
||||
service = injector.get(SlideCanvasPopMangerService);
|
||||
});
|
||||
|
||||
it('does not create a canvas popup when the current slide has no renderer', () => {
|
||||
const disposable = service.attachPopupToObject({ left: 0, top: 0, width: 10, height: 10 } as never, { componentKey: 'slide-comment' });
|
||||
|
||||
disposable.dispose();
|
||||
|
||||
expect(popupService.addedPopups).toEqual([]);
|
||||
expect(popupService.removedPopupIds).toEqual([]);
|
||||
});
|
||||
|
||||
it('attaches a popup to the rendered slide object and removes it on dispose', () => {
|
||||
TestRenderManagerService.hasRender = true;
|
||||
|
||||
const disposable = service.attachPopupToObject({ left: 15, top: 20, width: 30, height: 10 } as never, {
|
||||
componentKey: 'slide-comment',
|
||||
direction: 'horizontal',
|
||||
});
|
||||
|
||||
expect(popupService.addedPopups).toHaveLength(1);
|
||||
expect(popupService.addedPopups[0]).toMatchObject({
|
||||
unitId: 'slide-1',
|
||||
subUnitId: 'default',
|
||||
componentKey: 'slide-comment',
|
||||
direction: 'horizontal',
|
||||
anchorRect: {
|
||||
left: 190,
|
||||
right: 430,
|
||||
top: 300,
|
||||
bottom: 480,
|
||||
},
|
||||
canvasElement: expect.any(HTMLCanvasElement),
|
||||
});
|
||||
|
||||
disposable.dispose();
|
||||
|
||||
expect(popupService.removedPopupIds).toEqual(['popup-1']);
|
||||
});
|
||||
|
||||
it('converts slide coordinates to viewport offsets with scroll and scale applied', () => {
|
||||
const scene = {
|
||||
getAncestorScale: () => ({ scaleX: 2, scaleY: 3 }),
|
||||
getViewport: () => ({ viewportScrollX: 5, viewportScrollY: 10 }),
|
||||
};
|
||||
|
||||
expect(transformPosition2Offset(15, 20, scene as never)).toEqual({ x: 20, y: 30 });
|
||||
expect(transformBound2OffsetBound({ left: 15, top: 20, right: 45, bottom: 30 }, scene as never)).toEqual({
|
||||
left: 20,
|
||||
top: 30,
|
||||
right: 80,
|
||||
bottom: 60,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user