mirror of
https://github.com/igorski/bitmappery.git
synced 2026-06-16 19:25:38 +02:00
Split `definitions/document.ts` into unique files per actor type. Create `model` folder to store the above types, their factories and the state changing actions.
131 lines
6.0 KiB
TypeScript
131 lines
6.0 KiB
TypeScript
import { it, describe, expect, beforeEach, vi } from "vitest";
|
|
import { createMockCanvasElement, mockZCanvas } from "../mocks";
|
|
import type { Document } from "@/model/types/document";
|
|
import type { Layer } from "@/model/types/layer";
|
|
import DocumentFactory from "@/model/factories/document-factory";
|
|
import LayerFactory from "@/model/factories/layer-factory";
|
|
import TextFactory from "@/model/factories/text-factory";
|
|
import { cloneLayers, getAlignableObjects, restoreFromClone } from "@/utils/document-util";
|
|
|
|
mockZCanvas();
|
|
|
|
vi.mock( "@/utils/canvas-util", () => ({
|
|
createCanvas : vi.fn().mockReturnValue({ cvs: {}, ctx: {}}),
|
|
cloneCanvas: ( cvs: HTMLCanvasElement ): HTMLCanvasElement => cvs
|
|
}));
|
|
|
|
describe( "Document utilities", () => {
|
|
describe( "When calculating the alignable objects within a document", () => {
|
|
let document: Document;
|
|
let width: number;
|
|
let height: number;
|
|
|
|
beforeEach(() => {
|
|
document = DocumentFactory.create();
|
|
({ width, height } = document );
|
|
});
|
|
|
|
it( "should be able to calculate the documents horizontal and vertical center", () => {
|
|
const alignableObjects = getAlignableObjects( document );
|
|
expect( alignableObjects ).toEqual([
|
|
{ left: 0, top: height / 2, width, height: 0 }, // vertical document center
|
|
{ left: width / 2, top: 0, width: 0, height } // horizontal document center
|
|
]);
|
|
});
|
|
|
|
it( "should ignore layers that are currently invisible", () => {
|
|
const layer = LayerFactory.create({ left: 10, top: 10, width: width / 2, height: height / 2, visible: false });
|
|
document.layers.push( layer );
|
|
const alignableObjects = getAlignableObjects( document );
|
|
expect( alignableObjects ).toEqual([
|
|
{ left: 0, top: height / 2, width, height: 0 }, // vertical document center
|
|
{ left: width / 2, top: 0, width: 0, height } // horizontal document center
|
|
]);
|
|
});
|
|
|
|
it( "should ignore layers that occupy the same bounding box as the document to prevent duplicates", () => {
|
|
document.layers.push( LayerFactory.create({ left: 0, top: 0, width, height }));
|
|
const alignableObjects = getAlignableObjects( document );
|
|
expect( alignableObjects ).toEqual([
|
|
{ left: 0, top: height / 2, width, height: 0 }, // vertical document center
|
|
{ left: width / 2, top: 0, width: 0, height } // horizontal document center
|
|
]);
|
|
});
|
|
|
|
it( "should be able to calculate the horizontal and vertical center for each additional layer", () => {
|
|
document.layers.push( LayerFactory.create({ left: 10, top: 10, width: width / 2, height: height / 2 }));
|
|
const alignableObjects = getAlignableObjects( document );
|
|
expect( alignableObjects ).toEqual([
|
|
{ left: 0, top: height / 2, width, height: 0 }, // vertical document center
|
|
{ left: width / 2, top: 0, width: 0, height }, // horizontal document center
|
|
// added layer
|
|
{ left: 0, top: 10, width, height: 0 }, // vertical layer top
|
|
{ left: 0, top: 260, width, height: 0 }, // vertical layer center
|
|
{ left: 0, top: 510, width, height: 0 }, // vertical layer bottom
|
|
{ left: 10, top: 0, width: 0, height }, // horizontal layer left
|
|
{ left: 260, top: 0, width: 0, height }, // horizontal layer center
|
|
{ left: 510, top: 0, width: 0, height }, // horizontal layer right
|
|
]);
|
|
});
|
|
|
|
it( "should ignore the optionally provided layer to exclude", () => {
|
|
const layer = LayerFactory.create({ left: 10, top: 10, width: width / 2, height: height / 2 });
|
|
document.layers.push( layer );
|
|
const alignableObjects = getAlignableObjects( document, layer );
|
|
expect( alignableObjects ).toEqual([
|
|
{ left: 0, top: height / 2, width, height: 0 }, // vertical document center
|
|
{ left: width / 2, top: 0, width: 0, height } // horizontal document center
|
|
]);
|
|
});
|
|
});
|
|
|
|
it( "Should be able to clone and restore a Documents Layers contents", () => {
|
|
const layer1mask = createMockCanvasElement();
|
|
const layer1source = createMockCanvasElement();
|
|
const layer1props = {
|
|
left: 1, top: 2, width: 3, height: 4, maskX: 5, maskY: 6, mask: layer1mask, source: layer1source,
|
|
text: TextFactory.create({ value: "foo bar" }),
|
|
};
|
|
const layer2mask = createMockCanvasElement();
|
|
const layer2source = createMockCanvasElement();
|
|
const layer2props = {
|
|
left: -5, top: -5, width: 10, height: 15, maskX: 0, maskY: 0, mask: layer2mask, source: layer2source
|
|
};
|
|
|
|
const layer1 = LayerFactory.create( layer1props );
|
|
const layer2 = LayerFactory.create( layer2props );
|
|
|
|
// create document
|
|
const document = DocumentFactory.create({ layers: [ layer1, layer2 ]});
|
|
|
|
// clone document content
|
|
const clonedLayers = cloneLayers( document );
|
|
|
|
// adjust document data
|
|
for ( const layer of document.layers ) {
|
|
layer.left = 10;
|
|
layer.top = 10;
|
|
layer.width = 30;
|
|
layer.height = 40;
|
|
layer.maskX = 100;
|
|
layer.maskY = 100;
|
|
layer.text = TextFactory.create({ value: "baz qux" });
|
|
layer.source = createMockCanvasElement();
|
|
layer.mask = createMockCanvasElement();
|
|
}
|
|
|
|
// restore clone
|
|
restoreFromClone( document, clonedLayers );
|
|
|
|
// assert properties have been restored
|
|
|
|
Object.entries( layer1props ).forEach(([ key, value ]) => {
|
|
expect( layer1[ key as keyof Layer ]).toEqual( value );
|
|
});
|
|
|
|
Object.entries( layer2props ).forEach(([ key, value ]) => {
|
|
expect( layer2[ key as keyof Layer ]).toEqual( value );
|
|
});
|
|
});
|
|
});
|