From f45e55c63281f8717c0c3b694fc7546d6d8e5fde Mon Sep 17 00:00:00 2001 From: Eugene Obrezkov Date: Sat, 4 Apr 2020 15:42:25 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20name=20to=20the=20?= =?UTF-8?q?slides,=20so=20you=20can=20reference=20them=20later?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each slide have a name now, that you can specify in SlideBuilder or SlideDeclaration when creating them in JSON. Having named slides not only allows to have a possibility to reference slides later but also make a more better error messaging, so it is easier to debug problems. --- packages/kittik-slide/spec/Slide.spec.ts | 25 ++++++++++--------- .../kittik-slide/spec/SlideBuilder.spec.ts | 2 ++ packages/kittik-slide/src/slide/Slide.ts | 21 +++++++++------- .../kittik-slide/src/slide/SlideBuilder.ts | 6 +++++ .../src/slide/SlideDeclaration.ts | 1 + 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/packages/kittik-slide/spec/Slide.spec.ts b/packages/kittik-slide/spec/Slide.spec.ts index 1931257..c1e5141 100644 --- a/packages/kittik-slide/spec/Slide.spec.ts +++ b/packages/kittik-slide/spec/Slide.spec.ts @@ -9,6 +9,7 @@ import { TextObject, Text } from 'kittik-shape-text'; import { Print } from 'kittik-animation-print'; const SLIDE_DECLARATION: SlideDeclaration = { + name: 'Testing Slide', shapes: [{ name: 'Hello', type: 'Text', @@ -71,6 +72,7 @@ const SERIALIZED_ORDER_DECLARATION: OrderDeclaration = { }; const SERIALIZED_SLIDE_DECLARATION: SlideDeclaration = { + name: 'Testing Slide', shapes: [SERIALIZED_TEXT_DECLARATION], animations: [SERIALIZED_ANIMATION_DECLARATION], order: [SERIALIZED_ORDER_DECLARATION] @@ -80,22 +82,22 @@ describe('Core::Slide', () => { it('Should properly throw an error if shape type is unknown', () => { const cursor = new Canvas(); - expect(() => new Slide(cursor, { shapes: [{ name: 'Test', type: 'unknown' }], order: [{ shape: 'Test' }] })) + expect(() => new Slide(cursor, { name: 'Test', shapes: [{ name: 'Test', type: 'unknown' }], order: [{ shape: 'Test' }] })) .toThrowError('Shape "Test" (unknown) is unknown for me, maybe you made a typo?'); }); it('Should properly throw an error if animation type is unknown', () => { const cursor = new Canvas(); - expect(() => new Slide(cursor, { shapes: [{ name: 'Test', type: 'Text' }], animations: [{ name: 'Test', type: 'unknown' }], order: [{ shape: 'Test' }] })) + expect(() => new Slide(cursor, { name: 'Test', shapes: [{ name: 'Test', type: 'Text' }], animations: [{ name: 'Test', type: 'unknown' }], order: [{ shape: 'Test' }] })) .toThrowError('Animation "Test" (unknown) is unknown for me, maybe you made a typo?'); }); it('Should properly throw an error if trying to use shape name in ordering that does not exist', async () => { const cursor = new Canvas(); - const slide = new Slide(cursor, { shapes: [], order: [{ shape: 'Not Exists' }] }); + const slide = new Slide(cursor, { name: 'Test', shapes: [], order: [{ shape: 'Not Exists' }] }); - await expect(slide.render()).rejects.toThrowError('You specified shape "Not Exists" as part of ordering, but it does not exist in shapes declaration.'); + await expect(slide.render()).rejects.toThrowError('You specified shape "Not Exists" in slide "Test" as part of ordering, but it does not exist in shapes declaration.'); }); it('Should properly render the whole slide', async () => { @@ -114,14 +116,14 @@ describe('Core::Slide', () => { it('Should render the slide without animations', async () => { const cursor = new Canvas(); - const slide = Slide.create(cursor, { shapes: [{ name: 'Test', type: 'Text' }], order: [{ shape: 'Test' }] }); + const slide = Slide.create(cursor, { name: 'Test', shapes: [{ name: 'Test', type: 'Text' }], order: [{ shape: 'Test' }] }); await expect(slide.render()).resolves.toBeUndefined(); }); it('Should render the slide with unknown animation in ordering', async () => { const cursor = new Canvas(); - const slide = Slide.create(cursor, { shapes: [{ name: 'Test', type: 'Text' }], order: [{ shape: 'Test', animations: ['Not Exists'] }] }); + const slide = Slide.create(cursor, { name: 'Test', shapes: [{ name: 'Test', type: 'Text' }], order: [{ shape: 'Test', animations: ['Not Exists'] }] }); await expect(slide.render()).resolves.toBeUndefined(); }); @@ -164,7 +166,7 @@ describe('Core::Slide', () => { }); it('Should properly instantiate an empty slide instance when nothing is passed but an empty arrays', () => { - const slide = new Slide(undefined, { order: [], shapes: [] }); + const slide = new Slide(undefined, { name: 'Test', order: [], shapes: [] }); expect(slide.cursor).toBeInstanceOf(Canvas); expect(slide.shapes.size).toBe(0); @@ -173,23 +175,22 @@ describe('Core::Slide', () => { }); it('Should properly throw an error when trying to add shape that is already added', () => { - const slide = new Slide(undefined, { shapes: [{ name: 'Test', type: 'Text' }], order: [] }); + const slide = new Slide(undefined, { name: 'Test', shapes: [{ name: 'Test', type: 'Text' }], order: [] }); expect(() => slide.addShape('Test', Text.create())).toThrowError('Shape "Test" already exists in slide'); }); it('Should properly throw an error when trying to add animation that is already added', () => { - const slide = new Slide(undefined, { shapes: [], order: [], animations: [{ name: 'Test', type: 'Print' }] }); + const slide = new Slide(undefined, { name: 'Test', shapes: [], order: [], animations: [{ name: 'Test', type: 'Print' }] }); expect(() => slide.addAnimation('Test', Print.create())).toThrowError('Animation "Test" already exists in slide'); }); it('Should properly throw an error when trying to add ordering for the shape that is already added', () => { - const slide = new Slide(undefined, { shapes: [], order: [{ shape: 'Test' }] }); + const slide = new Slide(undefined, { name: 'Test', shapes: [], order: [{ shape: 'Test' }] }); expect(() => slide.addOrder('Test')).toThrowError( - 'You already have an ordering for "Test"\n' + - 'Seems like it was defined somewhere before' + 'You already have an ordering for shape "Test" in slide "Test"' ); }); diff --git a/packages/kittik-slide/spec/SlideBuilder.spec.ts b/packages/kittik-slide/spec/SlideBuilder.spec.ts index e43ff7b..faa15ea 100644 --- a/packages/kittik-slide/spec/SlideBuilder.spec.ts +++ b/packages/kittik-slide/spec/SlideBuilder.spec.ts @@ -6,6 +6,7 @@ describe('SlideBuilder', () => { it('Should properly instantiate slide via builder', () => { const slide = SlideBuilder .start() + .withName('Hello, World') .withCursor(Canvas.create()) .withShape( 'Hello, World', @@ -26,6 +27,7 @@ describe('SlideBuilder', () => { .withOrder('Hello, World', ['Print']) .end(); + expect(slide.name).toBe('Hello, World'); expect(slide.shapes.size).toBe(1); expect(slide.shapes.get('Hello, World')?.toObject()).toEqual({ type: 'Text', diff --git a/packages/kittik-slide/src/slide/Slide.ts b/packages/kittik-slide/src/slide/Slide.ts index 03d1a6f..0e13f47 100644 --- a/packages/kittik-slide/src/slide/Slide.ts +++ b/packages/kittik-slide/src/slide/Slide.ts @@ -23,12 +23,17 @@ export class Slide { readonly animations: Map = new Map(); readonly order: OrderDeclaration[] = []; cursor: Canvas = Canvas.create(); + name = 'Untitled Slide' constructor (cursor?: Canvas, declaration?: SlideDeclaration) { if (cursor !== undefined) { this.cursor = cursor; } + if (declaration?.name !== undefined) { + this.name = declaration.name; + } + if (declaration?.shapes !== undefined) { this.initShapes(declaration.shapes); } @@ -74,7 +79,7 @@ export class Slide { addShape (name: string, shape: ShapeRenderable, toOverride = false): void { if (this.shapes.has(name) && !toOverride) { - throw new Error(`Shape "${name}" already exists in slide`); + throw new Error(`Shape "${name}" already exists in slide "${this.name}"`); } this.shapes.set(name, shape); @@ -82,18 +87,15 @@ export class Slide { addAnimation (name: string, animation: Animationable, toOverride = false): void { if (this.animations.has(name) && !toOverride) { - throw new Error(`Animation "${name}" already exists in slide`); + throw new Error(`Animation "${name}" already exists in slide "${this.name}"`); } this.animations.set(name, animation); } addOrder (shape: string, animations?: string[]): void { - if (this.order.findIndex(decl => decl.shape === shape) !== -1) { - throw new Error( - `You already have an ordering for "${shape}"\n` + - 'Seems like it was defined somewhere before' - ); + if (this.order.some(order => order.shape === shape)) { + throw new Error(`You already have an ordering for shape "${shape}" in slide "${this.name}"`); } this.order.push({ shape, animations }); @@ -114,7 +116,7 @@ export class Slide { const shapeToRender = shapes.get(order[i].shape); if (shapeToRender === undefined) { throw new Error( - `You specified shape "${order[i].shape}" as part of ordering, but it does not exist in shapes declaration.` + + `You specified shape "${order[i].shape}" in slide "${this.name}" as part of ordering, but it does not exist in shapes declaration.\n` + 'Maybe you forgot to create a shape you want to order or it is a typo in ordering itself.' ); } @@ -140,11 +142,12 @@ export class Slide { } toObject (): SlideDeclaration { + const name = this.name; const shapes = [...this.shapes.entries()].map(([name, shape]) => ({ ...shape.toObject(), name })); const animations = [...this.animations.entries()].map(([name, animation]) => ({ ...animation.toObject(), name })); const order = this.order; - return { shapes, animations, order }; + return { name, shapes, animations, order }; } toJSON (): string { diff --git a/packages/kittik-slide/src/slide/SlideBuilder.ts b/packages/kittik-slide/src/slide/SlideBuilder.ts index 484680a..bdc5bea 100644 --- a/packages/kittik-slide/src/slide/SlideBuilder.ts +++ b/packages/kittik-slide/src/slide/SlideBuilder.ts @@ -6,6 +6,12 @@ import { Slide } from './Slide'; export class SlideBuilder { private readonly slide: Slide = new Slide(); + withName (name: string): this { + this.slide.name = name; + + return this; + } + withCursor (cursor: Canvas): this { this.slide.cursor = cursor; diff --git a/packages/kittik-slide/src/slide/SlideDeclaration.ts b/packages/kittik-slide/src/slide/SlideDeclaration.ts index 7ad4a48..09cc0c6 100644 --- a/packages/kittik-slide/src/slide/SlideDeclaration.ts +++ b/packages/kittik-slide/src/slide/SlideDeclaration.ts @@ -3,6 +3,7 @@ import { OrderDeclaration } from './OrderDeclaration'; import { ShapeDeclaration } from '../shape/ShapeDeclaration'; export interface SlideDeclaration { + name: string shapes: ShapeDeclaration[] animations?: AnimationDeclaration[] order: OrderDeclaration[]