diff --git a/bower.json b/bower.json
index a923f893..89baf391 100644
--- a/bower.json
+++ b/bower.json
@@ -27,6 +27,7 @@
"straps": "~1.7.2",
"acorn": "~0.5.0",
"qunit": "~1.20.0",
+ "resemblejs": "~2.0.1",
"stats.js": "r14"
},
"keywords": [
diff --git a/src/item/Item.js b/src/item/Item.js
index b27de970..9c1b83c7 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -1564,6 +1564,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
* raster.scale(5);
*/
rasterize: function(resolution, insert) {
+ // TODO: Switch to options object for more descriptive call signature.
var bounds = this.getStrokeBounds(),
scale = (resolution || this.getView().getResolution()) / 72,
// Floor top-left corner and ceil bottom-right corner, to never
diff --git a/test/index.html b/test/index.html
index 44e9102e..6c60d018 100644
--- a/test/index.html
+++ b/test/index.html
@@ -4,6 +4,7 @@
Paper.js Tests
+
diff --git a/test/js/helpers.js b/test/js/helpers.js
index 87d14a5c..9981f272 100644
--- a/test/js/helpers.js
+++ b/test/js/helpers.js
@@ -21,6 +21,15 @@ QUnit.begin(function() {
QUnit.config.hidepassed = true;
document.getElementById('qunit-tests').className += ' hidepass';
}
+ resemble.outputSettings({
+ errorColor: {
+ red: 255,
+ green: 51,
+ blue: 0
+ },
+ errorType: 'flat',
+ transparency: 1
+ });
});
// Register a jsDump parser for Base.
@@ -48,26 +57,71 @@ function compareProperties(actual, expected, properties, message, 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');
- equals(actual.name,
- // When item was cloned and had a name, the name will be versioned
- options && options.cloned && expected.name
- ? expected.name + ' 1' : 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);
+
+ function getImageTag(raster) {
+ return ''
+ }
+
+ if (options && options.rasterize) {
+ var resolution = options.rasterize == true ? 72 : options.rasterize;
+ var raster1 = actual && actual.rasterize(resolution, false),
+ raster2 = expected && expected.rasterize(resolution, false);
+ if (!raster1 || !raster2) {
+ QUnit.pushFailure('Unable to compare rasterized items: ' +
+ (!raster1 ? 'actual' : 'expected') + ' item is null',
+ QUnit.stack(2));
+ } else {
+ // Use resemble.js to compare the two rasterized items.
+ var id = QUnit.config.current.testId,
+ result;
+ resemble(raster1.getImageData())
+ .compareTo(raster2.getImageData())
+ // When working with imageData, this call is synchronous:
+ .onComplete(function(data) { result = data; });
+ var identical = result ? 100 - result.misMatchPercentage : 0,
+ ok = identical == 100.0;
+ QUnit.push(ok, identical.toFixed(1) + '% identical',
+ '100.0% identical', message);
+ if (!ok && result) {
+ var output = document.getElementById('qunit-test-output-' + id),
+ bounds = result.diffBounds;
+ output.querySelector('.test-expected td').innerHTML =
+ getImageTag(raster1);
+ var el = output.querySelector('.test-actual td');
+ el.innerHTML = getImageTag(raster2) + '
' +
+ el.innerHTML.replace(/<\/?pre>|"/g, '');
+ output.querySelector('.test-diff td').innerHTML =
+ getImageTag({
+ source: result.getImageDataUrl(),
+ width: bounds.right - bounds.left,
+ height: bounds.bottom - bounds.top
+ });
+ }
+ }
+ } else {
+ if (options && options.cloned)
+ QUnit.notStrictEqual(actual.id, expected.id,
+ 'not ' + message + '.id');
+ QUnit.strictEqual(actual.constructor, expected.constructor,
+ message + '.constructor');
+ // When item is cloned and has a name, the name will be versioned:
+ equals(actual.name,
+ options && options.cloned && expected.name
+ ? expected.name + ' 1' : 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);
+ }
}
// A list of comparator functions, based on `expected` type. See equals() for
diff --git a/test/tests/Path_Boolean.js b/test/tests/Path_Boolean.js
index 1e70b865..dcaf5127 100644
--- a/test/tests/Path_Boolean.js
+++ b/test/tests/Path_Boolean.js
@@ -27,7 +27,14 @@ test('path.unite(); #609', function() {
path2.closePath();
var result = path1.unite(path2);
- equals(result.pathData, 'M150,150c0,27.61424 -22.38576,50 -50,50c-27.61424,0 -50,-22.38576 -50,-50c0,-27.61424 22.38576,-50 50,-50c27.61424,0 50,22.38576 50,50z', 'result.pathData');
+ result.fillColor = 'blue';
+
+ var expected = new Path({
+ pathData: 'M150,150c0,27.61424 -22.38576,50 -50,50c-27.61424,0 -50,-22.38576 -50,-50c0,-27.61424 22.38576,-50 50,-50c27.61424,0 50,22.38576 50,50z',
+ fillColor: 'blue'
+ });
+
+ equals(result, expected, 'path1.unite(path2);', { rasterize: true });
});
test('ring.subtract(square); #610', function() {
@@ -50,6 +57,12 @@ test('ring.subtract(square); #610', function() {
var ring = outer.subtract(inner);
var result = ring.subtract(square);
+ result.fillColor = 'blue';
- equals(result.pathData, 'M-132,0c0,-69.53737 53.7698,-126.51614 122,-131.62689l0,32.12064c-50.53323,5.01724 -90,47.65277 -90,99.50625c0,51.85348 39.46677,94.489 90,99.50625l0,32.12064c-68.2302,-5.11075 -122,-62.08951 -122,-131.62689z');
+ var expected = new Path({
+ pathData: 'M-132,0c0,-69.53737 53.7698,-126.51614 122,-131.62689l0,32.12064c-50.53323,5.01724 -90,47.65277 -90,99.50625c0,51.85348 39.46677,94.489 90,99.50625l0,32.12064c-68.2302,-5.11075 -122,-62.08951 -122,-131.62689z',
+ fillColor: 'blue'
+ });
+
+ equals(result, expected, 'ring.subtract(square);', { rasterize: true });
});