import 'reflect-metadata'; import { requiredMocks, } from './../../../../test-mocks'; requiredMocks(jest); import { AutoNewLineService, } from './auto-new-line.service'; import * as mock from '../../../mocks/index'; const initMockDocument = mock.document(jest); const newLineChar = '\n'; const initAutoNewLineDirective = ( document?: Document, ) => { return new AutoNewLineService( document ? document : initMockDocument(), ); }; describe('getTextWidth', () => { // tslint:disable-next-line test('It set this.canvas to a new canvas if undefined', () => { const document = initMockDocument(); const canvas = {} as HTMLCanvasElement; const canvasContext = {} as CanvasRenderingContext2D; canvasContext.measureText = jest.fn() .mockReturnValue({}); canvas.getContext = jest.fn().mockReturnValue(canvasContext); document.createElement = jest.fn() .mockReturnValue(canvas); const autoNewLineDirective = initAutoNewLineDirective( document, ); autoNewLineDirective.canvas = undefined; autoNewLineDirective.getTextWidth('test', '1pt', 'family'); expect(autoNewLineDirective.canvas).toBe(canvas); }); // tslint:disable-next-line test('It correctly sets the font of the canvas context', () => { const autoNewLineDirective = initAutoNewLineDirective(); const canvasContext = {} as CanvasRenderingContext2D; canvasContext.measureText = jest.fn().mockReturnValue({}); const canvas = {} as HTMLCanvasElement; canvas.getContext = jest.fn().mockReturnValue(canvasContext); autoNewLineDirective.canvas = canvas; autoNewLineDirective.getTextWidth('test', '1pt', 'family'); expect(canvasContext.font).toBe( `1pt family`, ); }); // tslint:disable-next-line test('It calls context.measureText with the correct arguments', () => { const autoNewLineDirective = initAutoNewLineDirective(); const canvasContext = {} as CanvasRenderingContext2D; canvasContext.measureText = jest.fn().mockReturnValue({}); const canvas = {} as HTMLCanvasElement; canvas.getContext = jest.fn().mockReturnValue(canvasContext); autoNewLineDirective.canvas = canvas; autoNewLineDirective.getTextWidth('test', '1pt', 'family'); expect(canvasContext.measureText).toHaveBeenCalledWith( 'test', ); }); // tslint:disable-next-line test('It returns the width of context measureText', () => { const autoNewLineDirective = initAutoNewLineDirective(); const canvasContext = {} as CanvasRenderingContext2D; canvasContext.measureText = jest.fn() .mockReturnValue({ width: 10, }); const canvas = {} as HTMLCanvasElement; canvas.getContext = jest.fn().mockReturnValue(canvasContext); autoNewLineDirective.canvas = canvas; const result = autoNewLineDirective.getTextWidth('test', '1pt', 'family'); expect(result).toBe(10); }); }); describe('sortIntoLines', () => { // tslint:disable-next-line test('It does not effect the text when the lines have not exceeded the max text width', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = 'abcsdfsd tsdtsdt sfs'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValue(49); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 50, undefined, undefined, ); expect(sortedText).toBe(initialText); }); // tslint:disable-next-line test('It puts a newline character after the text which exceeds the maxChars', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '1234567890'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValueOnce(10) .mockReturnValue(9); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 9, undefined, undefined, ); expect(sortedText.charAt(9)).toBe(newLineChar); }); // tslint:disable-next-line test('It moves the characters that exceed the maxChars onto a new line', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '123456789'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValueOnce(10) .mockReturnValue(9); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 9, undefined, undefined, ); expect(sortedText).toBe('12345678\n9'); }); // tslint:disable-next-line test('If the characters moved onto the next line, cause that line to be too long, then the chars from that line should be moved to a third line', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '1234\n567'; autoNewLineDirective.getTextWidth = jest.fn() .mockImplementation((arg) => { return [ '1234', '4567', ].indexOf(arg) > -1 ? 2 : 1; }); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 1, undefined, undefined, ); expect(sortedText).toBe('123\n456\n7'); }); // tslint:disable-next-line test('It puts the whole word on the new text line if the new line falls in the middle of a word', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '1234 abc'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValueOnce(2) .mockReturnValue(1); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 1, undefined, undefined, ); expect(sortedText).toBe('1234\nabc'); }); // tslint:disable-next-line test('It adds a space between the words if a word is moved to new line', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '1234 abc\nover'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValueOnce(2) .mockReturnValue(1); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 1, undefined, undefined, ); expect(sortedText).toBe('1234\nabc over'); }); // tslint:disable-next-line test('If the text goes across multiple lines it handles this properly', () => { const autoNewLineDirective = initAutoNewLineDirective(); const initialText = '1234 abc over 1242'; autoNewLineDirective.getTextWidth = jest.fn() .mockReturnValueOnce(2) .mockReturnValueOnce(2) .mockReturnValueOnce(1) .mockReturnValueOnce(2) .mockReturnValueOnce(2) .mockReturnValue(1); const sortedText = autoNewLineDirective.sortIntoLines( initialText, 1, undefined, undefined, ); expect(sortedText).toBe('1234 abc\nover\n1242'); }); });