diff --git a/package.json b/package.json index 7aa7a73..ac5c57a 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,11 @@ "url": "https://github.com/dmester/canvas-renderer" }, "devDependencies": { - "tap": "^10.7.0" + "tap": "^12.1.1", + "pngjs": "^3.3.3" }, "scripts": { - "test": "tap tests/*.js" + "test": "tap tests/*Tests.js" }, "bugs": { "url": "https://github.com/dmester/canvas-renderer/issues" diff --git a/tests/colorUtils.js b/tests/colorUtilsTests.js similarity index 100% rename from tests/colorUtils.js rename to tests/colorUtilsTests.js diff --git a/tests/pngAssert.js b/tests/pngAssert.js new file mode 100644 index 0000000..9edc3d1 --- /dev/null +++ b/tests/pngAssert.js @@ -0,0 +1,82 @@ +/** + * canvas-renderer + * https://github.com/dmester/canvas-renderer + * + * Copyright (c) 2017-2018 Daniel Mester Pirttijärvi + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +"use strict"; + +/** + * This module will extend tap with the assert + * tap.equalPng(found : Buffer, wanted : Buffer, msg, extra) + */ + +const pngjs = require("pngjs"); + +function createDataUri(buffer) { + return "data:image/png;base64," + buffer.toString("base64"); +} + +function formatPixel(data, i) { + i -= i % 4; + return `rgba(${data[i]}, ${data[i + 1]}, ${data[i + 2]}, ${data[i + 3]})`; +} + +function register(tap) { + tap.Test.prototype.addAssert("equalPng", 2, function (found, wanted, message, extra) { + message = message || "PNG should be equal"; + + var foundPng = pngjs.PNG.sync.read(found); + var wantedPng = pngjs.PNG.sync.read(wanted); + + if (foundPng.width != wantedPng.width || + foundPng.height != wantedPng.height || + foundPng.data.length != wantedPng.data.length + ) { + extra.found = createDataUri(found); + extra.wanted = createDataUri(wanted); + return this.fail(message, extra); + } + + for (var i = 0; i < foundPng.data.length; i++) { + // Allow some difference due to rounding errors + if (Math.abs(foundPng.data[i] - wantedPng.data[i]) > 2) { + extra.found = createDataUri(found); + extra.wanted = createDataUri(wanted); + + var x = i % foundPng.width; + var y = (i / foundPng.width) | 0; + + extra.foundPixel = formatPixel(foundPng.data, i); + extra.wantedPixel = formatPixel(wantedPng.data, i); + extra.note = `Difference at pixel { x: ${x}, y: ${y} }.`; + + return this.fail(message, extra); + } + } + + return this.pass(message, extra); + }) +} + +module.exports = register; diff --git a/tests/trueColorTest.js b/tests/trueColorTests.js similarity index 92% rename from tests/trueColorTest.js rename to tests/trueColorTests.js index 270fdab..8547289 100644 --- a/tests/trueColorTest.js +++ b/tests/trueColorTests.js @@ -40,6 +40,7 @@ const fs = require("fs"); const tap = require("tap"); const canvasRenderer = require("../index"); +require("./pngAssert")(tap); var canvas = canvasRenderer.createCanvas(1000, 1000); canvas.backColor = "#abcdefff"; @@ -62,6 +63,5 @@ ctx.arc(400 + radius, 250 + radius, radius, 0, Math.PI * 2, false); // last argu ctx.closePath(); ctx.fill(); -var expected = fs.readFileSync(__dirname + "/expected-truecolor.png"); -var expectedB64 = Buffer.from(expected).toString("base64"); -tap.equal("data:image/png;base64," + expectedB64, canvas.toDataURL()); +var wanted = fs.readFileSync(__dirname + "/expected-truecolor.png"); +tap.equalPng(canvas.toPng(), wanted); diff --git a/tests/visualTest.js b/tests/visualTests.js similarity index 95% rename from tests/visualTest.js rename to tests/visualTests.js index 55742e4..3adad4d 100644 --- a/tests/visualTest.js +++ b/tests/visualTests.js @@ -35,6 +35,7 @@ const fs = require("fs"); const tap = require("tap"); const canvasRenderer = require("../index"); +require("./pngAssert")(tap); var canvas; @@ -172,7 +173,5 @@ ctx.lineTo(5, 95); ctx.closePath(); ctx.fill(); -var expected = fs.readFileSync(__dirname + "/expected.png"); -var expectedB64 = Buffer.from(expected).toString("base64"); -tap.equal("data:image/png;base64," + expectedB64, canvas.toDataURL()); - +var wanted = fs.readFileSync(__dirname + "/expected.png"); +tap.equalPng(canvas.toPng(), wanted);