From a538980c9b8ad438ab4a4a61ba10b46907191ccd Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Tue, 5 Nov 2024 16:48:17 +0100 Subject: [PATCH] More tests --- src/wireframes/model/constraints.spec.ts | 160 ++++++++++++++++++++++- src/wireframes/model/constraints.ts | 2 +- 2 files changed, 159 insertions(+), 3 deletions(-) diff --git a/src/wireframes/model/constraints.spec.ts b/src/wireframes/model/constraints.spec.ts index 214cebe..f1ecbb4 100644 --- a/src/wireframes/model/constraints.spec.ts +++ b/src/wireframes/model/constraints.spec.ts @@ -5,9 +5,9 @@ * Copyright (c) Sebastian Stehle. All rights reserved. */ -import { Vec2 } from '@app/core/utils'; +import { TextMeasurer, Vec2 } from '@app/core/utils'; import { DefaultAppearance } from '@app/wireframes/interface'; -import { DiagramItem, MinSizeConstraint, SizeConstraint, TextHeightConstraint } from '@app/wireframes/model'; +import { DiagramItem, MinSizeConstraint, SizeConstraint, TextHeightConstraint, TextSizeConstraint } from '@app/wireframes/model'; const shape = DiagramItem.createShape({ id: '1', @@ -72,3 +72,159 @@ describe('SizeConstraint', () => { expect(constraint.calculateSizeY()).toBeTruthy(); }); }); + + +describe('TextSizeConstraint', () => { + let measured = 0; + + const measurer: TextMeasurer = { + getTextWidth(text, fontSize) { + measured++; + return text.length * fontSize * 1.5; + }, + }; + + beforeEach(() => { + measured = 0; + }); + + it('should only calculate width when width cannot be resized', () => { + const constraint1 = new TextSizeConstraint(measurer, 5, 5, 1.2, true, 10); + const constraint2 = new TextSizeConstraint(measurer, 5, 5, 1.2, false, 10); + + expect(constraint1.calculateSizeX()).toBeFalsy(); + expect(constraint1.calculateSizeY()).toBeTruthy(); + + expect(constraint2.calculateSizeX()).toBeTruthy(); + expect(constraint2.calculateSizeY()).toBeTruthy(); + }); + + it('should calculate size from measurer without padding', () => { + const constraint2 = new TextSizeConstraint(measurer, 0, 0, 1.5, true, 10); + + const newShape: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const size = constraint2.updateSize(newShape, Vec2.ZERO, null!); + + expect(size.x).toBe(120); + expect(size.y).toBe(24); + }); + + it('should calculate size from measurer with padding', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 10); + + const newShape: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const size = constraint2.updateSize(newShape, Vec2.ZERO); + + expect(size.x).toBe(126); + expect(size.y).toBe(32); + }); + + it('should calculate size from measurer min width', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 200); + + const newShape: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const size = constraint2.updateSize(newShape, Vec2.ZERO); + + expect(size.x).toBe(200); + expect(size.y).toBe(32); + }); + + it('should cache font size', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 200); + + const shape1: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const shape2: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + constraint2.updateSize(shape1, Vec2.ZERO); + constraint2.updateSize(shape2, Vec2.ZERO, shape1); + + expect(measured).toBe(1); + }); + + it('should recompute font width if text changed', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 200); + + const shape1: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const shape2: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'World', + } as any; + + constraint2.updateSize(shape1, Vec2.ZERO); + constraint2.updateSize(shape2, Vec2.ZERO, shape1); + + expect(measured).toBe(2); + }); + + it('should recompute font width if font family changed', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 200); + + const shape1: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const shape2: DiagramItem = { + fontSize: 16, + fontFamily: 'Aria', + text: 'Hello', + } as any; + + constraint2.updateSize(shape1, Vec2.ZERO); + constraint2.updateSize(shape2, Vec2.ZERO, shape1); + + expect(measured).toBe(2); + }); + + it('should recompute font width if font size changed', () => { + const constraint2 = new TextSizeConstraint(measurer, 3, 4, 1.5, true, 200); + + const shape1: DiagramItem = { + fontSize: 16, + fontFamily: 'monospace', + text: 'Hello', + } as any; + + const shape2: DiagramItem = { + fontSize: 18, + fontFamily: 'Aria', + text: 'Hello', + } as any; + + constraint2.updateSize(shape1, Vec2.ZERO); + constraint2.updateSize(shape2, Vec2.ZERO, shape1); + + expect(measured).toBe(2); + }); +}); diff --git a/src/wireframes/model/constraints.ts b/src/wireframes/model/constraints.ts index 5d8859a..d36155c 100644 --- a/src/wireframes/model/constraints.ts +++ b/src/wireframes/model/constraints.ts @@ -101,7 +101,7 @@ export class TextSizeConstraint implements Constraint { private readonly minWidth = 0, ) { } - public updateSize(shape: Shape, size: Vec2, prev: DiagramItem): Vec2 { + public updateSize(shape: Shape, size: Vec2, prev?: DiagramItem): Vec2 { const fontSize = shape.fontSize; const fontFamily = shape.fontFamily;