102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
/**
|
||
* Task D4 – MTEXT-Tool: Mehrzeiliger Text mit/ohne Rahmen.
|
||
*
|
||
* Klick platziert mehrzeiligen Text (Inhalt aus Options, Zeilen-
|
||
* umbrueche), fontSize-Option, optionale Rahmen-Option erzeugt ein
|
||
* rect-Element in derselben Transaktion (1 Undo-Schritt).
|
||
*/
|
||
import { describe, it, expect } from 'vitest';
|
||
import { mtextTool } from '../src/plugins/builtin/core-annotate';
|
||
import { CADDocument } from '../src/kernel/document/CADDocument';
|
||
import { createInMemoryDoc } from './helpers/inMemoryDoc';
|
||
import type { CADElement, Pt } from '../src/types/cad.types';
|
||
|
||
function mkCtx(options: Record<string, unknown> = {}) {
|
||
const { ydoc } = createInMemoryDoc();
|
||
const doc = new CADDocument(ydoc);
|
||
const statuses: string[] = [];
|
||
const ctx: any = {
|
||
doc,
|
||
options,
|
||
setStatus: (m: string) => statuses.push(m),
|
||
setPreview: (_el: CADElement | null) => {},
|
||
};
|
||
return { ctx, doc, statuses };
|
||
}
|
||
|
||
function pe(x: number, y: number): { world: Pt } {
|
||
return { world: { x, y } } as never;
|
||
}
|
||
|
||
describe('D4: mtextTool', () => {
|
||
it('platziert mehrzeiligen Text mit Zeilenumbruechen aus den Options', () => {
|
||
const { ctx, doc } = mkCtx({ text: 'Zeile 1\nZeile 2\nZeile 3', fontSize: 14 });
|
||
mtextTool.handlers.down!(pe(100, 50), ctx);
|
||
const els = doc.getAllElements();
|
||
expect(els).toHaveLength(1);
|
||
const el = els[0];
|
||
expect(el.type).toBe('text');
|
||
expect(el.x).toBe(100);
|
||
expect(el.y).toBe(50);
|
||
expect(el.properties.text).toBe('Zeile 1\nZeile 2\nZeile 3');
|
||
expect(el.properties.fontSize).toBe(14);
|
||
expect(el.properties.mtext).toBe(true);
|
||
});
|
||
|
||
it('Rahmen-Option erzeugt zusaetzliches rect in derselben Transaktion (1 Undo)', () => {
|
||
const { ctx, doc } = mkCtx({ text: 'Mit Rahmen', frame: true });
|
||
mtextTool.handlers.down!(pe(0, 0), ctx);
|
||
const els = doc.getAllElements();
|
||
expect(els).toHaveLength(2);
|
||
const texts = els.filter((e) => e.type === 'text');
|
||
const rects = els.filter((e) => e.type === 'rect');
|
||
expect(texts).toHaveLength(1);
|
||
expect(rects).toHaveLength(1);
|
||
expect(rects[0].x).toBeCloseTo(0, 5);
|
||
expect(rects[0].y).toBeCloseTo(0, 5);
|
||
doc.undo();
|
||
expect(doc.getAllElements()).toHaveLength(0);
|
||
});
|
||
|
||
it('ohne frame-Option: nur Text, kein rect', () => {
|
||
const { ctx, doc } = mkCtx({ text: 'Ohne Rahmen' });
|
||
mtextTool.handlers.down!(pe(0, 0), ctx);
|
||
expect(doc.getAllElements().filter((e) => e.type === 'rect')).toHaveLength(0);
|
||
});
|
||
|
||
it('Standard-Text wenn Options leer: MTEXT-Platzhalter leer (Editor bearbeitet spaeter)', () => {
|
||
const { ctx, doc } = mkCtx({});
|
||
mtextTool.handlers.down!(pe(10, 10), ctx);
|
||
const el = doc.getAllElements()[0];
|
||
expect(el.properties.text).toBe('');
|
||
expect(el.properties.fontSize).toBe(12); // Default
|
||
});
|
||
|
||
it('OptionsSchema: text/number/checkbox-Felder', () => {
|
||
const schema = mtextTool.optionsSchema ?? [];
|
||
const keys = schema.map((f) => f.key);
|
||
expect(keys).toContain('text');
|
||
expect(keys).toContain('fontSize');
|
||
expect(keys).toContain('frame');
|
||
const textField = schema.find((f) => f.key === 'text');
|
||
expect(textField!.type).toBe('text');
|
||
const frameField = schema.find((f) => f.key === 'frame');
|
||
expect(frameField!.type).toBe('checkbox');
|
||
});
|
||
|
||
it('Rahmenhoehe waechst mit Zeilenzahl', () => {
|
||
const { ctx: ctx1, doc: doc1 } = mkCtx({ text: 'eine Zeile', frame: true });
|
||
mtextTool.handlers.down!(pe(0, 0), ctx1);
|
||
const { ctx: ctx3, doc: doc3 } = mkCtx({ text: 'eins\nzwei\ndrei', frame: true });
|
||
mtextTool.handlers.down!(pe(0, 0), ctx3);
|
||
const rect1 = doc1.getAllElements().find((e) => e.type === 'rect')!;
|
||
const rect3 = doc3.getAllElements().find((e) => e.type === 'rect')!;
|
||
expect(rect3.height).toBeGreaterThan(rect1.height);
|
||
});
|
||
|
||
it('Manifest: id=mtext, tags basic', () => {
|
||
expect(mtextTool.manifest.id).toBe('mtext');
|
||
expect((mtextTool.manifest.tags ?? [])).toContain('basic');
|
||
});
|
||
});
|