diff --git a/test/lib/helpers.js b/test/lib/helpers.js index 7255e892..965167ca 100644 --- a/test/lib/helpers.js +++ b/test/lib/helpers.js @@ -27,42 +27,70 @@ QUnit.jsDump.setParser('object', function (obj, stack) { : objectParser).call(this, obj, stack); }); -function getFunctionBody(func) { - return func.toString().match( +var comparators = { + Number: function(actual, expected, message, options) { + // Compare with a default tolerance of Numerical.TOLERANCE: + var ok = Math.abs(actual - expected) + <= Base.pick(options && options.tolerance, Numerical.TOLERANCE); + QUnit.push(ok, ok ? expected : actual, expected, message); + }, + + Array: function(actual, expected, message, options) { + equals(actual.length, expected.length, (message || '') + ' length', + options); + for (var i = 0, l = actual.length; i < l; i++) { + equals(actual[i], expected[i], (message || '') + ' [' + i + ']', + options); + } + } +}; + +function getClass(object) { + return typeof object === 'number' && 'Number' + || Array.isArray(object) && 'Array' + || object && object._class; +} + +function getFunctionMessage(func) { + var message = func.toString().match( /^\s*function[^\{]*\{([\s\S]*)\}\s*$/)[1] .replace(/ /g, '') .replace(/^\s+|\s+$/g, ''); + if (/^return /.test(message)) { + message = message + .replace(/^return /, '') + .replace(/;$/, ''); + } + return message; } // Override equals to convert functions to message and execute them as tests() -function equals(actual, expected, message, tolerance) { +function equals(actual, expected, message, options) { // Allow the use of functions for actual, which will get called and their // source content extracted for readable reports. if (typeof actual === 'function') { - if (!message) { - message = getFunctionBody(actual); - if (/^return /.test(message)) { - message = message - .replace(/^return /, '') - .replace(/;$/, ''); - } - } + if (!message) + message = getFunctionMessage(actual); actual = actual(); } - if (typeof expected === 'number') { - // Compare with a default tolerance of Numerical.TOLERANCE: - var ok = Math.abs(actual - expected) - <= Base.pick(tolerance, Numerical.TOLERANCE); - return QUnit.push(ok, ok ? expected : actual, expected, message); - } else if (actual && actual.equals) { - // Support calling of #equals() on the actual or expected value, and - // automatically convert displayed values to strings. - return QUnit.push(actual.equals(expected), actual, expected, message); - } else if (expected && expected.equals) { - return QUnit.push(expected.equals(actual), actual, expected, message); + if (actual != null) { + var comparator = comparators[getClass(actual)]; + if (comparator) + return comparator(actual, expected, message, options); + // Support calling of #equals() on the actual or expected value. + if (actual.equals) + return QUnit.push(actual.equals(expected), + actual, expected, message); } - // Let's be strict - return strictEqual(actual, expected, message); + if (expected != null) { + var comparator = comparators[getClass(expected)]; + if (comparator) + return comparator(actual, expected, message, options); + if (expected.equals) + return QUnit.push(expected.equals(actual), + actual, expected, message); + } + QUnit.push(actual === expected, actual, expected, message); } function test(testName, expected) { @@ -83,42 +111,36 @@ function asyncTest(testName, expected) { }); } -function compareArrays(array1, array2, message, tolerance) { - equals(array1.length, array2.length, (message || '') + ' length'); - for (var i = 0, l = array1.length; i < l; i++) { - equals(array1[i], array2[i], (message || '') + ' [' + i + ']', - tolerance); - } +function comparePoints(point1, point2, message, options) { + equals(point1.x, point2.x, (message || '') + ' x', options); + equals(point1.y, point2.y, (message || '') + ' y', options); } -function comparePoints(point1, point2, message, tolerance) { - equals(point1.x, point2.x, (message || '') + ' x', tolerance); - equals(point1.y, point2.y, (message || '') + ' y', tolerance); +function compareSize(size1, size2, message, options) { + equals(size1.width, size2.width, (message || '') + ' width', options); + equals(size1.height, size2.height, (message || '') + ' height', options); } -function compareSize(size1, size2, message, tolerance) { - equals(size1.width, size2.width, (message || '') + ' width', tolerance); - equals(size1.height, size2.height, (message || '') + ' height', tolerance); +function compareRectangles(rect1, rect2, message, options) { + comparePoints(rect1, rect2, message, options); + compareSize(rect1, rect2, message, options); } -function compareRectangles(rect1, rect2, message, tolerance) { - comparePoints(rect1, rect2, message, tolerance); - compareSize(rect1, rect2, message, tolerance); -} - -function compareColors(color1, color2, message, tolerance) { +function compareColors(color1, color2, message, options) { color1 = color1 && new Color(color1); color2 = color2 && new Color(color2); if (color1 && color2) { - equals(color1.type, color2.type, (message || '') + ' type'); - compareArrays(color1.components, color2.components, - (message || '') + ' components', tolerance); + equals(color1.type, color2.type, + (message || '') + ' type', options); + equals(color1.components, color2.components, + (message || '') + ' components', options); } else { - equals(color1, color2, message, tolerance); + equals(color1, color2, message, options); } } -function compareStyles(style, style2, checkIdentity) { +function compareStyles(style, style2, options) { + var checkIdentity = options && options.checkIdentity; if (checkIdentity) { equals(function() { return style !== style2; @@ -150,38 +172,30 @@ function compareStyles(style, style2, checkIdentity) { } }); - compareObjects('Style', ['strokeCap', 'strokeJoin', 'dashArray', - 'dashOffset', 'miterLimit', 'strokeOverprint', 'fillOverprint', + compareObjects(['strokeCap', 'strokeJoin', 'dashArray', 'dashOffset', + 'miterLimit', 'strokeOverprint', 'fillOverprint', 'fontSize', 'font', 'leading', 'justification'], - style, style2, checkIdentity); + style, style2, 'Compare Style', options); } -function compareObjects(name, keys, obj, obj2, checkIdentity) { - if (checkIdentity) { +function compareObjects(keys, obj, obj2, message, options) { + if (options && options.checkIdentity) { equals(function() { return obj !== obj2; }, true); } Base.each(keys, function(key) { - var val = obj[key], val2 = obj2[key], - message = 'Compare ' + name + '#' + key; - if (typeof val === 'number') { - equals(val, val2, message); - } else if (Array.isArray(val)) { - compareArrays(val, val2, message); - } else { - equals(val, val2, message); - } + equals(obj[key], obj2[key], message + '#' + key, options); }); } -function compareSegmentPoints(segmentPoint, segmentPoint2, checkIdentity) { - compareObjects('SegmentPoint', ['x', 'y', 'selected'], - segmentPoint, segmentPoint2, checkIdentity); +function compareSegmentPoints(segmentPoint, segmentPoint2, options) { + compareObjects(['x', 'y', 'selected'], segmentPoint, segmentPoint2, + 'Compare SegmentPoint', options); } -function compareSegments(segment, segment2, checkIdentity) { - if (checkIdentity) { +function compareSegments(segment, segment2, options) { + if (options.checkIdentity) { equals(function() { return segment !== segment2; }, true); @@ -194,7 +208,8 @@ function compareSegments(segment, segment2, checkIdentity) { }); } -function compareSegmentLists(segmentList, segmentList2, checkIdentity) { +function compareSegmentLists(segmentList, segmentList2, options) { + var checkIdentity = options && options.checkIdentity; if (checkIdentity) { equals(function() { return segmentList !== segmentList2; @@ -206,12 +221,13 @@ function compareSegmentLists(segmentList, segmentList2, checkIdentity) { for (var i = 0, l = segmentList.length; i < l; i++) { var segment = segmentList[i], segment2 = segmentList2[i]; - compareSegments(segment, segment2, checkIdentity); + compareSegments(segment, segment2, options); } } } -function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { +function compareItems(item, item2, options) { + var checkIdentity = options && options.checkIdentity; if (checkIdentity) { equals(function() { return item !== item2; @@ -232,7 +248,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { var value = item[key]; // When item was cloned and had a name, the name will be versioned equals( - key == 'name' && cloned && value + key == 'name' && options && options.cloned && value ? value + ' 1' : value, item2[key], @@ -279,7 +295,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { equals(item[key], item2[key], 'Compare Path#' + key); } equals(item.length, item2.length, 'Compare Path#length'); - compareSegmentLists(item.segments, item2.segments, checkIdentity); + compareSegmentLists(item.segments, item2.segments, options); } // Shape specific @@ -301,7 +317,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { // Layer specific if (item instanceof Layer) { equals(function() { - return dontShareProject + return options && options.dontShareProject ? item.project != item2.project : item.project == item2.project; }, true); @@ -309,9 +325,9 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { // PlacedSymbol specific if (item instanceof PlacedSymbol) { - if (dontShareProject) { + if (options.dontShareProject) { compareItems(item.symbol.definition, item2.symbol.definition, - cloned, checkIdentity, dontShareProject, + options, 'Compare Symbol#definition'); } else { equals(function() { @@ -331,7 +347,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { 'Compare Raster#ppi'); equals(item.source, item2.source, 'Compare Raster#source'); - if (checkIdentity) { + if (options.checkIdentity) { equals(item.image, item2.image, 'Compare Raster#image'); } equals(item.size.toString(), item2.size.toString(), @@ -347,7 +363,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { // PointText specific: if (item instanceof PointText) { - if (checkIdentity) { + if (options.checkIdentity) { equals(function() { return item.point !== item2.point; }, true); @@ -358,7 +374,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { if (item.style) { // Style - compareStyles(item.style, item2.style, checkIdentity); + compareStyles(item.style, item2.style, options); } // Check length of children and recursively compare them: @@ -367,8 +383,7 @@ function compareItems(item, item2, cloned, checkIdentity, dontShareProject) { return item.children.length == item2.children.length; }, true); for (var i = 0, l = item.children.length; i < l; i++) { - compareItems(item.children[i], item2.children[i], cloned, - checkIdentity, dontShareProject); + compareItems(item.children[i], item2.children[i], options); } } } @@ -381,7 +396,7 @@ function compareProjects(project, project2) { for (var i = 0, l = project.symbols.length; i < l; i++) { var definition1 = project.symbols[i].definition; var definition2 = project2.symbols[i].definition; - compareItems(definition1, definition2, false, false, true, + compareItems(definition1, definition2, { dontShareProject: true }, 'Compare Symbol#definition'); } @@ -390,7 +405,8 @@ function compareProjects(project, project2) { return project.layers.length == project2.layers.length; }, true); for (var i = 0, l = project.layers.length; i < l; i++) { - compareItems(project.layers[i], project2.layers[i], false, false, true); + compareItems(project.layers[i], project2.layers[i], + { dontShareProject: true }); } } diff --git a/test/tests/Item_Bounds.js b/test/tests/Item_Bounds.js index 0330ac5a..e8061dcc 100644 --- a/test/tests/Item_Bounds.js +++ b/test/tests/Item_Bounds.js @@ -71,5 +71,5 @@ test('text.bounds', function() { var text = new PointText(new Point(50, 100)); text.fillColor = 'black'; text.content = 'This is a test'; - compareRectangles(text.bounds, { x: 50, y: 89.2, width: 67, height: 14.4 } , 'text.bounds', 0.5); + compareRectangles(text.bounds, { x: 50, y: 89.2, width: 67, height: 14.4 } , 'text.bounds', { tolerance: 0.5 }); }); diff --git a/test/tests/Item_Cloning.js b/test/tests/Item_Cloning.js index 26e2bbc8..4a28ec50 100644 --- a/test/tests/Item_Cloning.js +++ b/test/tests/Item_Cloning.js @@ -24,7 +24,7 @@ function cloneAndCompare(item) { return copy.parent.children[copy.name] == copy; }, true); } - compareItems(item, copy, true, true); + compareItems(item, copy, { cloned: true, checkIdentity: true }); // Remove the cloned item to restore the document: copy.remove(); } diff --git a/test/tests/Item_Order.js b/test/tests/Item_Order.js index 9c1498e0..1a25d2f4 100644 --- a/test/tests/Item_Order.js +++ b/test/tests/Item_Order.js @@ -64,30 +64,30 @@ test('Item#insertAbove(item) / Item#insertBelow(item)', function() { item1 = new Group(); item2 = new Group(); command(); - var str = getFunctionBody(command); + var str = getFunctionMessage(command); equals(item0.index, indexes[0], str + ': item0.index'); equals(item1.index, indexes[1], str + ': item1.index'); equals(item2.index, indexes[2], str + ': item2.index'); } - testMove(function() { item0.insertBelow(item0) }, [0,1,2]); - testMove(function() { item0.insertBelow(item1) }, [0,1,2]); - testMove(function() { item0.insertBelow(item2) }, [1,0,2]); - testMove(function() { item1.insertBelow(item0) }, [1,0,2]); - testMove(function() { item1.insertBelow(item1) }, [0,1,2]); - testMove(function() { item1.insertBelow(item2) }, [0,1,2]); + testMove(function() { item0.insertBelow(item0); }, [0,1,2]); + testMove(function() { item0.insertBelow(item1); }, [0,1,2]); + testMove(function() { item0.insertBelow(item2); }, [1,0,2]); + testMove(function() { item1.insertBelow(item0); }, [1,0,2]); + testMove(function() { item1.insertBelow(item1); }, [0,1,2]); + testMove(function() { item1.insertBelow(item2); }, [0,1,2]); - testMove(function() { item2.insertBelow(item0) }, [1,2,0]); - testMove(function() { item2.insertBelow(item1) }, [0,2,1]); - testMove(function() { item2.insertBelow(item2) }, [0,1,2]); + testMove(function() { item2.insertBelow(item0); }, [1,2,0]); + testMove(function() { item2.insertBelow(item1); }, [0,2,1]); + testMove(function() { item2.insertBelow(item2); }, [0,1,2]); - testMove(function() { item0.insertAbove(item0) }, [0,1,2]); - testMove(function() { item0.insertAbove(item1) }, [1,0,2]); - testMove(function() { item0.insertAbove(item2) }, [2,0,1]); - testMove(function() { item1.insertAbove(item0) }, [0,1,2]); - testMove(function() { item1.insertAbove(item1) }, [0,1,2]); - testMove(function() { item1.insertAbove(item2) }, [0,2,1]); - testMove(function() { item2.insertAbove(item0) }, [0,2,1]); - testMove(function() { item2.insertAbove(item1) }, [0,1,2]); - testMove(function() { item2.insertAbove(item2) }, [0,1,2]); + testMove(function() { item0.insertAbove(item0); }, [0,1,2]); + testMove(function() { item0.insertAbove(item1); }, [1,0,2]); + testMove(function() { item0.insertAbove(item2); }, [2,0,1]); + testMove(function() { item1.insertAbove(item0); }, [0,1,2]); + testMove(function() { item1.insertAbove(item1); }, [0,1,2]); + testMove(function() { item1.insertAbove(item2); }, [0,2,1]); + testMove(function() { item2.insertAbove(item0); }, [0,2,1]); + testMove(function() { item2.insertAbove(item1); }, [0,1,2]); + testMove(function() { item2.insertAbove(item2); }, [0,1,2]); }); diff --git a/test/tests/Raster.js b/test/tests/Raster.js index 48dc6831..1e81541d 100644 --- a/test/tests/Raster.js +++ b/test/tests/Raster.js @@ -131,7 +131,7 @@ test('Raster#getAverageColor(path)', function() { }); var raster = paper.project.activeLayer.rasterize(72); circle.scale(0.9); - compareColors(raster.getAverageColor(circle), circle.fillColor, null, 3); + compareColors(raster.getAverageColor(circle), circle.fillColor); }); test('Raster#getAverageColor(path) with compound path', function() { @@ -153,5 +153,5 @@ test('Raster#getAverageColor(path) with compound path', function() { var raster = paper.project.activeLayer.rasterize(72); path.scale(0.9); path2.scale(1.1); - compareColors(raster.getAverageColor(compoundPath), new Color(1, 0, 0), null, 3); + compareColors(raster.getAverageColor(compoundPath), new Color(1, 0, 0), null, { tolerance: 10e-4 }); }); diff --git a/test/tests/SVGImport.js b/test/tests/SVGImport.js index 737bc503..da04ebf0 100644 --- a/test/tests/SVGImport.js +++ b/test/tests/SVGImport.js @@ -15,7 +15,7 @@ module('SVGImport'); test('Import complex CompoundPath and clone', function() { var svg = createSVG(';'); var item = paper.project.importSVG(svg.getElementById('path')); - compareItems(item, item.clone(), true, true); + compareItems(item, item.clone(), { cloned: true, checkIdentity: true }); }); test('make an svg line', function() { diff --git a/test/tests/TextItem.js b/test/tests/TextItem.js index 141dfcbe..4464eedd 100644 --- a/test/tests/TextItem.js +++ b/test/tests/TextItem.js @@ -22,7 +22,7 @@ test('PointText', function() { compareColors(text.fillColor, new Color(0, 0, 0), 'text.fillColor should be black by default'); comparePoints(text.point, { x: 100, y: 100 }, 'text.point'); comparePoints(text.bounds.point, { x: 100, y: 87.4 }, 'text.bounds.point'); - compareSize(text.bounds.size, { width: 77, height: 16.8 }, 'text.bounds.size', 1.0); + compareSize(text.bounds.size, { width: 77, height: 16.8 }, 'text.bounds.size', { tolerance: 1.0 }); equals(function() { return text.hitTest(text.bounds.center) != null; }, true);