From 644fb71dc17a8e36d4eea007beee6e6181c7f2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=88rg=20Lehni?= Date: Sun, 28 Dec 2014 18:10:53 +0100 Subject: [PATCH] Implement unit test comparator for Item & co + Project, and further improve new comparator code. --- test/lib/helpers.js | 256 ++++++++++++++++--------------------- test/tests/Item_Cloning.js | 4 +- test/tests/JSON.js | 2 +- test/tests/SVGImport.js | 38 +++--- 4 files changed, 132 insertions(+), 168 deletions(-) diff --git a/test/lib/helpers.js b/test/lib/helpers.js index 8219be1b..159c0a55 100644 --- a/test/lib/helpers.js +++ b/test/lib/helpers.js @@ -27,6 +27,34 @@ QUnit.jsDump.setParser('object', function (obj, stack) { : objectParser).call(this, obj, stack); }); +function compareProperties(actual, expected, properties, message, options) { + Base.each(properties, function(key) { + equals(actual[key], expected[key], message + '.' + key, options); + }); +} + +function compareItem(actual, expected, message, options, properties) { + if (options && options.cloned) + QUnit.notStrictEqual(actual.id, 'not ' + expected.id, message + '.id'); + QUnit.strictEqual(actual.constructor, expected.constructor, + message + '.constructor'); + // When item was cloned and had a name, the name will be versioned + equals(options && options.cloned && actual.name ? actual.name + ' 1' + : actual.name, expected.name, + message + '.name'); + compareProperties(actual, expected, ['children', 'bounds', 'position', + 'matrix', 'data', 'opacity', 'locked', 'visible', 'blendMode', + 'selected', 'fullySelected', 'clipMask', 'guide'], + message, options); + if (properties) + compareProperties(actual, expected, properties, message, options); + // Style + compareProperties(actual.style, expected.style, ['fillColor', 'strokeColor', + 'strokeCap', 'strokeJoin', 'dashArray', 'dashOffset', 'miterLimit', + 'fontSize', 'font', 'leading', 'justification'], + message + '.style', options); +} + var comparators = { Null: QUnit.strictEqual, Undefined: QUnit.strictEqual, @@ -48,26 +76,23 @@ var comparators = { }, Array: function(actual, expected, message, options) { - QUnit.strictEqual(actual.length, expected.length, - (message || '') + ' length'); + QUnit.strictEqual(actual.length, expected.length, message + '.length'); for (var i = 0, l = actual.length; i < l; i++) { - equals(actual[i], expected[i], (message || '') + ' [' + i + ']', + equals(actual[i], expected[i], (message || '') + '[' + i + ']', options); } }, Point: function(actual, expected, message, options) { - comparators.Number(actual.x, expected.x, (message || '') + ' x', - options); - comparators.Number(actual.y, expected.y, (message || '') + ' y', - options); + comparators.Number(actual.x, expected.x, message + '.x', options); + comparators.Number(actual.y, expected.y, message + '.y', options); }, Size: function(actual, expected, message, options) { - comparators.Number(actual.width, expected.width, - (message || '') + ' width', options); - comparators.Number(actual.height, expected.height, - (message || '') + ' height', options); + comparators.Number(actual.width, expected.width, message + '.width', + options); + comparators.Number(actual.height, expected.height, message + '.height', + options); }, Rectangle: function(actual, expected, message, options) { @@ -81,20 +106,24 @@ var comparators = { Color: function(actual, expected, message, options) { if (actual && expected) { - equals(actual.type, expected.type, - (message || '') + ' type', options); + equals(actual.type, expected.type, message + '.type', options); // NOTE: This also compares gradients, with identity checks and all. equals(actual.components, expected.components, - (message || '') + ' components', options); + message + '.components', options); } else { - equals(actual, expected, message, options); + QUnit.strictEqual(actual, expected, message); } }, + Symbol: function(actual, expected, message, options) { + equals(actual.definition, expected.definition, message + '.definition', + options); + }, + Segment: function(actual, expected, message, options) { Base.each(['handleIn', 'handleOut', 'point', 'selected'], function(key) { - equals(actual[key], expected[key], (message || '') + ' ' + key); + equals(actual[key], expected[key], message + '.' + key); } ); }, @@ -102,11 +131,67 @@ var comparators = { SegmentPoint: function(actual, expected, message, options) { comparators.Point(actual, expected, message, options); comparators.Boolean(actual.selected, expected.selected, - (message || '') + ' selected', options); + message + '.selected', options); + }, + + Item: compareItem, + + Group: function(actual, expected, message, options) { + compareItem(actual, expected, message, options, + ['clipped']); + }, + + Layer: function(actual, expected, message, options) { + compareItem(actual, expected, message, options); + equals(function() { + return options && options.dontShareProject + ? actual.project !== expected.project + : actual.project === expected.project; + }, true); + }, + + Path: function(actual, expected, message, options) { + compareItem(actual, expected, message, options, + ['segments', 'closed', 'clockwise', 'length']); + }, + + CompoundPath: function(actual, expected, message, options) { + compareItem(actual, expected, message, options); + }, + + Raster: function(actual, expected, message, options) { + compareItem(actual, expected, message, options, + ['size', 'width', 'height', 'ppi', 'source', 'image']); + equals(actual.toDataURL(), expected.toDataURL(), + message + '.toDataUrl()'); + }, + + Shape: function(actual, expected, message, options) { + compareItem(actual, expected, message, options, + ['shape', 'size', 'radius']); + }, + + PlacedSymbol: function(actual, expected, message, options) { + compareItem(actual, expected, message, + // Cloning PlacedSymbols does not result in cloned Symbols + options && options.cloned + ? new Base(options, { cloned: false }) + : options, + ['symbol']); + }, + + PointText: function(actual, expected, message, options) { + compareItem(actual, expected, message, options, + ['content', 'point']); + }, + + Project: function(actual, expected, message, options) { + compareProperties(actual, expected, ['symbols', 'layers'], + message, options); } }; -var identicalAfterClone = { +var strictIdenticalAfterCloning = { Gradient: true, Symbol: true }; @@ -145,6 +230,11 @@ function equals(actual, expected, message, options) { || (cls = expected && expected._class) || type === 'object' && 'Object'; var comparator = type && comparators[type]; + if (!message) { + message = type + ? type.charAt(0).toLowerCase() + type.substring(1) + : 'value'; + } if (comparator) { comparator(actual, expected, message, options); } else if (expected && expected.equals) { @@ -155,10 +245,10 @@ function equals(actual, expected, message, options) { QUnit.push(actual === expected, actual, expected, message); } if (options && options.cloned && cls) { - var identical = identicalAfterClone[cls]; + var identical = strictIdenticalAfterCloning[cls]; QUnit.push(identical ? actual === expected : actual !== expected, actual, identical ? expected : 'not ' + expected, - (message || '') + ' identity'); + message + ': identical after cloning'); } } @@ -180,132 +270,6 @@ function asyncTest(testName, expected) { }); } -function compareItems(item, item2, options) { - if (options && options.cloned) - QUnit.notStrictEqual(item.id, item2.id, 'Compare Item#id'); - - QUnit.strictEqual(item.constructor, item2.constructor, - 'Compare Item#constructor'); - // When item was cloned and had a name, the name will be versioned - equals(options && options.cloned && item.name ? item.name + ' 1' - : item.name, item2.name, 'Compare Item#name'); - Base.each(['bounds', 'position', 'data', 'matrix', 'opacity', 'locked', - 'visible', 'blendMode', 'selected', 'fullySelected', 'clipMask', - 'guide'], - function(key) { - equals(item[key], item2[key], 'Compare Item#' + key, options); - } - ); - - // Style - Base.each(['fillColor', 'strokeColor', 'strokeCap', 'strokeJoin', - 'dashArray', 'dashOffset', 'miterLimit', - 'fontSize', 'font', 'leading', 'justification'], - function(key) { - equals(item.style[key], item2.style[key], 'Compare Style#' + key, - options); - } - ); - - // Path specific - if (item instanceof Path) { - Base.each(['segments', 'closed', 'clockwise', 'length'], - function(key) { - equals(item[key], item2[key], 'Compare Path#' + key, options); - } - ); - } - - // Shape specific - if (item instanceof Shape) { - Base.each(['shape', 'size', 'radius'], - function(key) { - equals(item[key], item2[key], 'Compare Shape#' + key, options); - } - ); - } - - // Group specific - if (item instanceof Group) { - equals(item.clipped, item2.clipped, 'Compare Group#clipped', options); - } - - // Layer specific - if (item instanceof Layer) { - equals(function() { - return options && options.dontShareProject - ? item.project != item2.project - : item.project == item2.project; - }, true); - } - - // PlacedSymbol specific - if (item instanceof PlacedSymbol) { - if (options.dontShareProject) { - compareItems(item.symbol.definition, item2.symbol.definition, - options, - 'Compare Symbol#definition'); - } else { - equals(item.symbol, item2.symbol, 'Compare PlacedSymbol#symbol', - options); - } - } - - // Raster specific - if (item instanceof Raster) { - equals(item.size, item2.size, 'Compare Raster#size'); - equals(item.width, item2.width, 'Compare Raster#width'); - equals(item.height, item2.height, 'Compare Raster#height'); - equals(item.ppi, item2.ppi, 'Compare Raster#ppi'); - equals(item.source, item2.source, 'Compare Raster#source'); - equals(item.image, item2.image, 'Compare Raster#image'); - equals(item.toDataURL(), item2.toDataURL(), - 'Compare Raster#toDataUrl()'); - } - - // TextItem specific: - if (item instanceof TextItem) { - equals(item.content, item2.content, 'Compare Item#content'); - } - - // PointText specific: - if (item instanceof PointText) { - equals(item.point, item2.point, 'Compare Item#point'); - } - - // Check length of children and recursively compare them: - if (item.children) { - equals(function() { - 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], options); - } - } -} - -function compareProjects(project, project2) { - // Compare Project#symbols: - equals(function() { - return project.symbols.length == project2.symbols.length; - }, true); - 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, { dontShareProject: true }, - 'Compare Symbol#definition'); - } - - // Compare Project#layers: - equals(function() { - 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], - { dontShareProject: true }); - } -} - // SVG function createSVG(xml) { diff --git a/test/tests/Item_Cloning.js b/test/tests/Item_Cloning.js index 884a08e2..d2076126 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, { cloned: true }); + equals(item, copy, 'item.clone()', { cloned: true }); // Remove the cloned item to restore the document: copy.remove(); } @@ -134,7 +134,7 @@ test('Symbol#clone()', function() { path.selected = true; var symbol = new Symbol(path); var copy = symbol.clone(); - compareItems(symbol.definition, copy.definition); + equals(symbol.definition, copy.definition, 'symbol.definition'); equals(function() { return symbol.project == copy.project; }, true); diff --git a/test/tests/JSON.js b/test/tests/JSON.js index 7ec2eebd..00712cba 100644 --- a/test/tests/JSON.js +++ b/test/tests/JSON.js @@ -17,7 +17,7 @@ function testExportImportJSON(project) { var json = project.exportJSON({ precision: 8 }); var project2 = new Project(); project2.importJSON(json); - compareProjects(project2, project); + equals(project, project2, null, { dontShareProject: true }); } test('Circles', function() { diff --git a/test/tests/SVGImport.js b/test/tests/SVGImport.js index 9d6f3dcc..52a43b47 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(), { cloned: true }); + equals(item, item.clone(), null, { cloned: true }); }); test('make an svg line', function() { @@ -34,7 +34,7 @@ test('make an svg line', function() { var line = new Path.Line([x1, y1], [x2, y2]); - compareItems(importedLine, line); + equals(importedLine, line); }); test('make an svg line with invalid values', function() { @@ -49,7 +49,7 @@ test('make an svg line with invalid values', function() { var line = new Path.Line([0, 0], [0, 0]); - compareItems(importedLine, line); + equals(importedLine, line); }); test('compare rectangle values', function() { @@ -71,7 +71,7 @@ test('compare rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var realRectangle = new Shape.Rectangle(rectangle); - compareItems(importedRectangle, realRectangle); + equals(importedRectangle, realRectangle); }); @@ -93,7 +93,7 @@ test('compare negative rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var realRectangle = new Shape.Rectangle(rectangle); - compareItems(importedRectangle, realRectangle); + equals(importedRectangle, realRectangle); }); @@ -113,7 +113,7 @@ test('compare invalid rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var realRectangle = new Shape.Rectangle(rectangle); - compareItems(importedRectangle, realRectangle); + equals(importedRectangle, realRectangle); }); test('compare round rectangle values', function() { @@ -140,7 +140,7 @@ test('compare round rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var roundRect = new Shape.Rectangle(rectangle, cornerSize); - compareItems(importedRectangle, roundRect); + equals(importedRectangle, roundRect); }); test('compare negative round rectangle values', function() { @@ -167,7 +167,7 @@ test('compare negative round rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var roundRect = new Shape.Rectangle(rectangle, cornerSize); - compareItems(importedRectangle, roundRect); + equals(importedRectangle, roundRect); }); test('compare invalid round rectangle values', function() { @@ -194,7 +194,7 @@ test('compare invalid round rectangle values', function() { var rectangle = new Rectangle(topLeft, size); var roundRect = new Shape.Rectangle(rectangle, cornerSize); - compareItems(importedRectangle, roundRect); + equals(importedRectangle, roundRect); }); test('compare ellipse values', function() { @@ -216,7 +216,7 @@ test('compare ellipse values', function() { radius: new Point(rx, ry) }); - compareItems(importedEllipse, ellipse); + equals(importedEllipse, ellipse); }); test('compare negative ellipse values', function() { @@ -238,7 +238,7 @@ test('compare negative ellipse values', function() { radius: new Point(rx, ry) }); - compareItems(importedEllipse, ellipse); + equals(importedEllipse, ellipse); }); test('compare invalid ellipse values', function() { @@ -256,7 +256,7 @@ test('compare invalid ellipse values', function() { radius: new Point(0, 0) }); - compareItems(importedEllipse, ellipse); + equals(importedEllipse, ellipse); }); test('compare circle values', function() { @@ -274,7 +274,7 @@ test('compare circle values', function() { var center = new Point(cx, cy); var circle = new Shape.Circle(center, r); - compareItems(importedCircle, circle); + equals(importedCircle, circle); }); test('compare negative circle values', function() { @@ -292,7 +292,7 @@ test('compare negative circle values', function() { var center = new Point(cx, cy); var circle = new Shape.Circle(center, r); - compareItems(importedCircle, circle); + equals(importedCircle, circle); }); @@ -308,7 +308,7 @@ test('compare invalid circle values', function() { var center = new Point(0, 0); var circle = new Shape.Circle(center, 0); - compareItems(importedCircle, circle); + equals(importedCircle, circle); }); @@ -330,7 +330,7 @@ test('compare polygon values', function() { poly.closePath(); } - compareItems(importedPolygon, poly); + equals(importedPolygon, poly); }); test('compare negative polygon values', function() { @@ -351,7 +351,7 @@ test('compare negative polygon values', function() { poly.closePath(); } - compareItems(importedPolygon, poly); + equals(importedPolygon, poly); }); test('compare polyline values', function() { @@ -372,7 +372,7 @@ test('compare polyline values', function() { poly.closePath(); } - compareItems(importedPolyline, poly); + equals(importedPolyline, poly); }); test('compare negative polyline values', function() { @@ -393,5 +393,5 @@ test('compare negative polyline values', function() { poly.closePath(); } - compareItems(importedPolyline, poly); + equals(importedPolyline, poly); });