diff --git a/src/DocumentContext.js b/src/DocumentContext.js index 8329d002e..dfa774a5c 100644 --- a/src/DocumentContext.js +++ b/src/DocumentContext.js @@ -1,4 +1,5 @@ import { isString } from './helpers/variableType'; +import { functionalizePageMargin } from './PageSize'; import { EventEmitter } from 'events'; /** @@ -10,10 +11,10 @@ class DocumentContext extends EventEmitter { super(); this.pages = []; - this.pageMargins = pageMargins; + this.pageMargins = functionalizePageMargin(pageMargins); - this.x = pageMargins.left; - this.availableWidth = pageSize.width - pageMargins.left - pageMargins.right; + this.x = this.pageMargins(1).left; + this.availableWidth = pageSize.width - this.pageMargins(1).left - this.pageMargins(1).right; this.availableHeight = 0; this.page = -1; @@ -131,9 +132,13 @@ class DocumentContext extends EventEmitter { } initializePage() { - this.y = this.pageMargins.top; - this.availableHeight = this.getCurrentPage().pageSize.height - this.pageMargins.top - this.pageMargins.bottom; - this.pageSnapshot().availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right; + this.y = this.getCurrentPage().pageMargins.top; + this.availableHeight = this.getCurrentPage().pageSize.height + - this.getCurrentPage().pageMargins.top + - this.getCurrentPage().pageMargins.bottom; + this.pageSnapshot().availableWidth = this.getCurrentPage().pageSize.width + - this.getCurrentPage().pageMargins.left + - this.getCurrentPage().pageMargins.right; } pageSnapshot() { @@ -147,11 +152,11 @@ class DocumentContext extends EventEmitter { moveTo(x, y) { if (x !== undefined && x !== null) { this.x = x; - this.availableWidth = this.getCurrentPage().pageSize.width - this.x - this.pageMargins.right; + this.availableWidth = this.getCurrentPage().pageSize.width - this.x - this.getCurrentPage().pageMargins.right; } if (y !== undefined && y !== null) { this.y = y; - this.availableHeight = this.getCurrentPage().pageSize.height - this.y - this.pageMargins.bottom; + this.availableHeight = this.getCurrentPage().pageSize.height - this.y - this.getCurrentPage().pageMargins.bottom; } } @@ -218,7 +223,11 @@ class DocumentContext extends EventEmitter { } addPage(pageSize) { - let page = { items: [], pageSize: pageSize }; + let page = { + items: [], + pageSize: pageSize, + pageMargins: this.pageMargins(this.pages.length + 1), + }; this.pages.push(page); this.backgroundLength.push(0); this.page = this.pages.length - 1; @@ -239,8 +248,12 @@ class DocumentContext extends EventEmitter { getCurrentPosition() { let pageSize = this.getCurrentPage().pageSize; - let innerHeight = pageSize.height - this.pageMargins.top - this.pageMargins.bottom; - let innerWidth = pageSize.width - this.pageMargins.left - this.pageMargins.right; + let innerHeight = pageSize.height + - this.getCurrentPage().pageMargins.top + - this.getCurrentPage().pageMargins.bottom; + let innerWidth = pageSize.width + - this.getCurrentPage().pageMargins.left + - this.getCurrentPage().pageMargins.right; return { pageNumber: this.page + 1, @@ -249,8 +262,9 @@ class DocumentContext extends EventEmitter { pageInnerWidth: innerWidth, left: this.x, top: this.y, - verticalRatio: ((this.y - this.pageMargins.top) / innerHeight), - horizontalRatio: ((this.x - this.pageMargins.left) / innerWidth) + verticalRatio: ((this.y - this.getCurrentPage().pageMargins.top) / innerHeight), + horizontalRatio: ((this.x - this.getCurrentPage().pageMargins.left) / innerWidth), + pageMargins: this.getCurrentPage().pageMargins, }; } } diff --git a/src/ElementWriter.js b/src/ElementWriter.js index 94cc42033..7c86d586f 100644 --- a/src/ElementWriter.js +++ b/src/ElementWriter.js @@ -362,7 +362,9 @@ class ElementWriter extends EventEmitter { */ pushContext(contextOrWidth, height) { if (contextOrWidth === undefined) { - height = this.context().getCurrentPage().height - this.context().pageMargins.top - this.context().pageMargins.bottom; + height = this.context().getCurrentPage().height + - this.context().getCurrentPage().pageMargins.top + - this.context().getCurrentPage().pageMargins.bottom; contextOrWidth = this.context().availableWidth; } diff --git a/src/LayoutBuilder.js b/src/LayoutBuilder.js index 38560f8d3..e88039bad 100644 --- a/src/LayoutBuilder.js +++ b/src/LayoutBuilder.js @@ -219,7 +219,7 @@ class LayoutBuilder { let node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize); if (node) { - let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.pageMargins); + let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.writer.context().getCurrentPage().pageMargins); this.writer.beginUnbreakableBlock(sizes.width, sizes.height); node = this.docPreprocessor.preprocessDocument(node); this.processNode(this.docMeasure.measureDocument(node)); diff --git a/src/PageSize.js b/src/PageSize.js index f362f3fc8..55eb52881 100644 --- a/src/PageSize.js +++ b/src/PageSize.js @@ -1,5 +1,5 @@ import sizes from './standardPageSizes'; -import { isString, isNumber } from './helpers/variableType'; +import { isString, isNumber, isFunction, isObject, isValue } from './helpers/variableType'; export function normalizePageSize(pageSize, pageOrientation) { function isNeedSwapPageSizes(pageOrientation) { @@ -36,6 +36,27 @@ export function normalizePageSize(pageSize, pageOrientation) { return size; } +function isPageMarginObject(margin) { + if (isObject(margin)) { + const { left, top, right, bottom } = margin; + + if (isValue(left) && isValue(top) && isValue(right) && isValue(bottom)) { + return true; + } + } + return false; +} + + +/* + * Accepts margin definition as being: + * * a number to set same margin size on all margins + * * a function which will receive pageNumber as argument + * * an array with two numbers to set horizontal and vertical margin respectively + * * an array with four numbers to set left, top, right and bottom margin respectively + * + * Normalized value is an object with the four margins as property. + * */ export function normalizePageMargin(margin) { if (isNumber(margin)) { margin = { left: margin, right: margin, top: margin, bottom: margin }; @@ -49,5 +70,43 @@ export function normalizePageMargin(margin) { } } + if (!isFunction(margin) && !isPageMarginObject(margin)) { + throw new Error('Invalid pageMargins definition'); + } + return margin; } + +/* + * Returns a function accepting pageNumber as argument and returning + * a normalized page margin object + * */ +export function functionalizePageMargin(margin) { + let marginFn; + if (isFunction(margin)) { + marginFn = function (pageNumber) { + return normalizePageMargin(margin(pageNumber)); + }; + } else { + if (!isPageMarginObject(margin)) { + margin = normalizePageMargin(margin); + } + + const { left, top, right, bottom } = margin; + marginFn = function () { + return { + left, + top, + right, + bottom, + }; + }; + + } + + if (!isFunction(marginFn)) { + throw new Error(`Unable to functionalize pageMargin: ${margin}`); + } + + return marginFn; +} diff --git a/src/helpers/variableType.js b/src/helpers/variableType.js index 6d6ee8a91..e5d4ac7ad 100644 --- a/src/helpers/variableType.js +++ b/src/helpers/variableType.js @@ -14,6 +14,14 @@ export function isNumber(variable) { return (typeof variable === 'number') || (variable instanceof Number); } +/** + * @param {any} variable + * @returns {boolean} + */ +export function isFunction(variable) { + return (typeof variable === 'function') || (variable instanceof Function); +} + /** * @param {any} variable * @returns {boolean} diff --git a/tests/integration/integrationTestHelper.js b/tests/integration/integrationTestHelper.js index 05c5f44fd..122ec6fbe 100644 --- a/tests/integration/integrationTestHelper.js +++ b/tests/integration/integrationTestHelper.js @@ -6,8 +6,8 @@ var LayoutBuilder = require('../../js/LayoutBuilder').default; var SVGMeasure = require('../../js/SVGMeasure').default; class IntegrationTestHelper { - constructor() { - this.MARGINS = { top: 40, left: 40, right: 40, bottom: 40 }; + constructor(options = {}) { + this.MARGINS = options.margins || { top: 40, left: 40, right: 40, bottom: 40 }; this.LINE_HEIGHT = 14.0625; this.DEFAULT_BULLET_SPACER = '9. '; } @@ -28,7 +28,7 @@ class IntegrationTestHelper { var pageSize = { width: size[0], height: size[1], orientation: 'portrait' }; this.pdfDocument = new PDFDocument(fontDescriptors, docDefinition.images, docDefinition.attachments, { size: [pageSize.width, pageSize.height], compress: false }); - var builder = new LayoutBuilder(pageSize, { left: this.MARGINS.left, right: this.MARGINS.right, top: this.MARGINS.top, bottom: this.MARGINS.bottom }, new SVGMeasure()); + var builder = new LayoutBuilder(pageSize, this.MARGINS, new SVGMeasure()); return builder.layoutDocument( docDefinition.content, diff --git a/tests/integration/pageMargins.spec.js b/tests/integration/pageMargins.spec.js new file mode 100644 index 000000000..cffd5fa78 --- /dev/null +++ b/tests/integration/pageMargins.spec.js @@ -0,0 +1,125 @@ +'use strict'; + +var assert = require('assert'); + +var integrationTestHelper = require('./integrationTestHelper'); + +describe('Integration test: pageMargins', function () { + it('margins values with function using different values for even and odd pages', function () { + function marginFn(pageNumber) { + if (pageNumber % 2 === 0) { + return 10; + } + return [20, 30]; + } + + var testHelper = new integrationTestHelper({ margins: marginFn }); + + var pages = testHelper.renderPages('A7', { + content: [ + { text: 'First page', pageBreak: 'after' }, + { text: 'Second page', pageBreak: 'after' }, + { text: 'Third page', pageBreak: 'after' }, + { text: 'Fourth page'}, + ] + }); + + assert.equal(pages.length, 4); + assert.deepEqual(pages[0].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[1].pageMargins, { left: 10, right: 10, top: 10, bottom: 10 }); + assert.deepEqual(pages[2].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[3].pageMargins, { left: 10, right: 10, top: 10, bottom: 10 }); + }); + + it('margins values when function use dynamic left value', function () { + function marginFn(pageNumber) { + return [(pageNumber %2 === 0) ? 0 : 20, 30, 30, 30]; + } + + var testHelper = new integrationTestHelper({ margins: marginFn }); + + var pages = testHelper.renderPages('A7', { + content: [ + { text: 'First page', pageBreak: 'after' }, + { text: 'Second page', pageBreak: 'after' }, + { text: 'Third page', pageBreak: 'after' }, + { text: 'Fourth page'}, + ] + }); + + assert.equal(pages.length, 4); + assert.deepEqual(pages[0].pageMargins, { left: 20, right: 30, top: 30, bottom: 30 }); + assert.deepEqual(pages[1].pageMargins, { left: 0, right: 30, top: 30, bottom: 30 }); + assert.deepEqual(pages[2].pageMargins, { left: 20, right: 30, top: 30, bottom: 30 }); + assert.deepEqual(pages[3].pageMargins, { left: 0, right: 30, top: 30, bottom: 30 }); + }); + + it('margins values when function use dynamic top value', function () { + function marginFn(pageNumber) { + return [30, (pageNumber % 2 === 0) ? 0 : 20, 30, 30]; + } + + var testHelper = new integrationTestHelper({ margins: marginFn }); + + var pages = testHelper.renderPages('A7', { + content: [ + { text: 'First page', pageBreak: 'after' }, + { text: 'Second page', pageBreak: 'after' }, + { text: 'Third page', pageBreak: 'after' }, + { text: 'Fourth page'}, + ] + }); + + assert.equal(pages.length, 4); + assert.deepEqual(pages[0].pageMargins, { left: 30, right: 30, top: 20, bottom: 30 }); + assert.deepEqual(pages[1].pageMargins, { left: 30, right: 30, top: 0, bottom: 30 }); + assert.deepEqual(pages[2].pageMargins, { left: 30, right: 30, top: 20, bottom: 30 }); + assert.deepEqual(pages[3].pageMargins, { left: 30, right: 30, top: 0, bottom: 30 }); + }); + + it('margins values when function use dynamic horizontal value', function () { + function marginFn(pageNumber) { + return [(pageNumber %2 === 0) ? 0 : 20, 30]; + } + + var testHelper = new integrationTestHelper({ margins: marginFn }); + + var pages = testHelper.renderPages('A7', { + content: [ + { text: 'First page', pageBreak: 'after' }, + { text: 'Second page', pageBreak: 'after' }, + { text: 'Third page', pageBreak: 'after' }, + { text: 'Fourth page'}, + ] + }); + + assert.equal(pages.length, 4); + assert.deepEqual(pages[0].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[1].pageMargins, { left: 0, right: 0, top: 30, bottom: 30 }); + assert.deepEqual(pages[2].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[3].pageMargins, { left: 0, right: 0, top: 30, bottom: 30 }); + }); + + it('margins values when function use dynamic vertical value', function () { + function marginFn(pageNumber) { + return [20, (pageNumber %2 === 0) ? 0 : 30]; + } + + var testHelper = new integrationTestHelper({ margins: marginFn }); + + var pages = testHelper.renderPages('A7', { + content: [ + { text: 'First page', pageBreak: 'after' }, + { text: 'Second page', pageBreak: 'after' }, + { text: 'Third page', pageBreak: 'after' }, + { text: 'Fourth page'}, + ] + }); + + assert.equal(pages.length, 4); + assert.deepEqual(pages[0].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[1].pageMargins, { left: 20, right: 20, top: 0, bottom: 0 }); + assert.deepEqual(pages[2].pageMargins, { left: 20, right: 20, top: 30, bottom: 30 }); + assert.deepEqual(pages[3].pageMargins, { left: 20, right: 20, top: 0, bottom: 0 }); + }); +}); diff --git a/tests/unit/LayoutBuilder.spec.js b/tests/unit/LayoutBuilder.spec.js index c98a7f21c..2295343e6 100644 --- a/tests/unit/LayoutBuilder.spec.js +++ b/tests/unit/LayoutBuilder.spec.js @@ -1910,7 +1910,7 @@ describe('LayoutBuilder', function () { builder.layoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark, pageBreakBeforeFunction); - assert.deepEqual(pageBreakBeforeFunction.getCall(0).args[0].startPosition, { pageNumber: 1, left: 40, top: 40, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 720, pageInnerWidth: 320 }); + assert.deepEqual(pageBreakBeforeFunction.getCall(0).args[0].startPosition, { pageNumber: 1, left: 40, top: 40, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 720, pageInnerWidth: 320, pageMargins: { left: 40, top: 40, right: 40, bottom: 40 } }); }); it('should provide the pageOrientation of the node', function () { diff --git a/tests/unit/PageElementWriter.spec.js b/tests/unit/PageElementWriter.spec.js index f625039e0..8a28ae4d9 100644 --- a/tests/unit/PageElementWriter.spec.js +++ b/tests/unit/PageElementWriter.spec.js @@ -112,7 +112,22 @@ describe('PageElementWriter', function () { var position = addOneTenthLines(10); assert.equal(ctx.pages.length, 1); - assert.deepEqual(position, { pageNumber: 1, left: MARGINS.left, top: (9 / 10 * AVAILABLE_HEIGHT) + MARGINS.top, verticalRatio: 0.9, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 1, + left: MARGINS.left, + top: (9 / 10 * AVAILABLE_HEIGHT) + MARGINS.top, + verticalRatio: 0.9, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); it('should add new pages if there\'s not enough space left', function () { @@ -121,7 +136,22 @@ describe('PageElementWriter', function () { assert.equal(ctx.pages.length, 2); assert.equal(ctx.pages[0].items.length, 10); assert.equal(ctx.pages[1].items.length, 1); - assert.deepEqual(position, { pageNumber: 2, left: MARGINS.left, top: MARGINS.top, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 2, + left: MARGINS.left, + top: MARGINS.top, + verticalRatio: 0, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); it('should subtract line height from availableHeight when adding a line and update current y position', function () { @@ -157,7 +187,22 @@ describe('PageElementWriter', function () { var position = pew.addImage(buildImage(300)); assert.equal(ctx.pages.length, 1); - assert.deepEqual(position, { pageNumber: 1, left: MARGINS.left, top: lineHeight + MARGINS.top, verticalRatio: 0.4, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 1, + left: MARGINS.left, + top: lineHeight + MARGINS.top, + verticalRatio: 0.4, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); it('should add a new page if something else exists on the page and there\'s not enough space left', function () { @@ -169,7 +214,22 @@ describe('PageElementWriter', function () { assert.equal(ctx.pages.length, 2); assert.equal(ctx.pages[0].items.length, 1); assert.equal(ctx.pages[1].items.length, 1); - assert.deepEqual(position, { pageNumber: 2, left: MARGINS.left, top: MARGINS.top, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 2, + left: MARGINS.left, + top: MARGINS.top, + verticalRatio: 0, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); it('should write into the current page if it\'s a large image and nothing else exists on the page', function () { @@ -177,7 +237,22 @@ describe('PageElementWriter', function () { assert.equal(ctx.pages.length, 1); assert.equal(ctx.pages[0].items.length, 1); - assert.deepEqual(position, { pageNumber: 1, left: MARGINS.left, top: MARGINS.top, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 1, + left: MARGINS.left, + top: MARGINS.top, + verticalRatio: 0, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); it('should write into the a new page page if it\'s a large image and something else does exist on the page', function () { @@ -187,7 +262,22 @@ describe('PageElementWriter', function () { assert.equal(ctx.pages.length, 2); assert.equal(ctx.pages[0].items.length, 1); assert.equal(ctx.pages[1].items.length, 1); - assert.deepEqual(position, { pageNumber: 2, left: MARGINS.left, top: MARGINS.top, verticalRatio: 0, horizontalRatio: 0, pageOrientation: 'portrait', pageInnerHeight: 1000, pageInnerWidth: 500 }); + assert.deepEqual(position, { + pageNumber: 2, + left: MARGINS.left, + top: MARGINS.top, + verticalRatio: 0, + horizontalRatio: 0, + pageOrientation: 'portrait', + pageInnerHeight: 1000, + pageInnerWidth: 500, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom, + }, + }); }); }); @@ -420,7 +510,16 @@ describe('PageElementWriter', function () { it('should use existing page', function () { addOneTenthLines(1); - ctx.pages.push({ items: [], pageSize: pageSize }); + ctx.pages.push({ + items: [], + pageSize: pageSize, + pageMargins: { + left: MARGINS.left, + right: MARGINS.right, + top: MARGINS.top, + bottom: MARGINS.bottom + }, + }); ctx.availableWidth = 'garbage'; ctx.availableHeight = 'garbage'; diff --git a/tests/unit/PageSize.spec.js b/tests/unit/PageSize.spec.js new file mode 100644 index 000000000..f3981998b --- /dev/null +++ b/tests/unit/PageSize.spec.js @@ -0,0 +1,141 @@ +const assert = require('assert'); + +const { isFunction } = require('../../js/helpers/variableType'); +const { normalizePageMargin, functionalizePageMargin } = require('../../js/PageSize'); + +describe('PageSize normalizePageMargin', function () { + describe('normalizePageMargin', function () { + it('should accept pageMargin as number', function () { + const margin = normalizePageMargin(10); + assert.deepEqual(margin, { + left: 10, + top: 10, + right: 10, + bottom: 10, + }); + }); + + it('should accept pageMargin as Array of two numbers', function () { + const margin = normalizePageMargin([10, 20]); + assert.deepEqual(margin, { + left: 10, + top: 20, + right: 10, + bottom: 20, + }); + }); + + it('should throw Error for pageMargin as Array of three numbers', function () { + assert.throws(() => normalizePageMargin([10, 20, 30]), Error); + }); + + it('should accept pageMargin as Array of four numbers', function () { + const margin = normalizePageMargin([10, 20, 30, 40]); + assert.deepEqual(margin, { + left: 10, + top: 20, + right: 30, + bottom: 40, + }); + }); + + it('should throw Error for pageMargin as Array of five numbers', function () { + assert.throws(() => normalizePageMargin([10, 20, 30, 40, 50]), Error); + }); + + it('should accept pageMargin as Object with all properties', function () { + const marginObject = { + left: 10, + top: 20, + right: 30, + bottom: 40, + }; + const margin = normalizePageMargin(marginObject); + assert.deepEqual(margin, marginObject); + }); + + it('should refuse pageMargin as Object missing left property', function () { + const marginObject = { + top: 20, + right: 30, + bottom: 40, + }; + assert.throws(() => normalizePageMargin(marginObject), Error); + }); + + it('should refuse pageMargin as Object missing top property', function () { + const marginObject = { + left: 10, + right: 30, + bottom: 40, + }; + assert.throws(() => normalizePageMargin(marginObject), Error); + }); + + it('should refuse pageMargin as Object missing right property', function () { + const marginObject = { + left: 10, + top: 20, + bottom: 40, + }; + assert.throws(() => normalizePageMargin(marginObject), Error); + }); + + it('should refuse pageMargin as Object missing bottom property', function () { + const marginObject = { + left: 10, + top: 20, + right: 30, + }; + assert.throws(() => normalizePageMargin(marginObject), Error); + }); + + it('should accept pageMargin as Function', function () { + const margin = normalizePageMargin(() => [10, 20]); + assert.ok(isFunction(margin)); + assert.deepEqual(margin(), [10, 20]); + }); + }); + + describe('functionalizePageMargin', function () { + it('should transform when pageMargin is a Number', function () { + const marginFn = functionalizePageMargin(10); + assert.ok(isFunction(marginFn)); + assert.deepEqual(marginFn(1), { + left: 10, + top: 10, + right: 10, + bottom: 10, + }); + }); + + it('should transform when pageMargin is an Array', function () { + const marginFn = functionalizePageMargin([10, 20]); + assert.ok(isFunction(marginFn)); + assert.deepEqual(marginFn(1), { + left: 10, + top: 20, + right: 10, + bottom: 20, + }); + }); + + it('should transform when pageMargin is an Object', function () { + const marginObject = { left: 10, top: 20, right: 30, bottom: 40 }; + const marginFn = functionalizePageMargin(marginObject); + assert.ok(isFunction(marginFn)); + assert.deepEqual(marginFn(1), marginObject); + }); + + it('should transform when pageMargin is a Function', function () { + const marginObject = { left: 10, top: 20, right: 30, bottom: 40 }; + function userMarginFn() { + return marginObject; + } + + const marginFn = functionalizePageMargin(userMarginFn); + assert.ok(isFunction(marginFn)); + assert.deepEqual(marginFn(1), marginObject); + }); + }); +}); diff --git a/tests/unit/helpers/variableType.spec.js b/tests/unit/helpers/variableType.spec.js index c94c51d35..02aac213a 100644 --- a/tests/unit/helpers/variableType.spec.js +++ b/tests/unit/helpers/variableType.spec.js @@ -1,7 +1,7 @@ const assert = require('assert'); const util = require('util'); -const { isString, isNumber, isObject, isEmptyObject, isValue } = require('../../../js/helpers/variableType'); +const { isString, isNumber, isObject, isEmptyObject, isValue, isFunction } = require('../../../js/helpers/variableType'); const variableCheckMap = [ { @@ -75,7 +75,7 @@ const variableCheckMap = [ { value: () => { }, - type: [isValue] + type: [isFunction, isValue] }, { value: { dummyObject: 0 }, @@ -125,4 +125,8 @@ describe('helpers/variableType', function () { checkVariables(isValue); }); + it('should be correctly specify variable with function', function () { + checkVariables(isValue); + }); + });