Skip to content

Commit a5ca2a6

Browse files
committed
Use pngjs in tests to compare pixel data instead of raw data to avoid rounding errors and difference in zlib encoding.
1 parent 930bf3c commit a5ca2a6

File tree

5 files changed

+91
-9
lines changed

5 files changed

+91
-9
lines changed

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
"url": "https://github.com/dmester/canvas-renderer"
99
},
1010
"devDependencies": {
11-
"tap": "^10.7.0"
11+
"tap": "^12.1.1",
12+
"pngjs": "^3.3.3"
1213
},
1314
"scripts": {
14-
"test": "tap tests/*.js"
15+
"test": "tap tests/*Tests.js"
1516
},
1617
"bugs": {
1718
"url": "https://github.com/dmester/canvas-renderer/issues"
File renamed without changes.

tests/pngAssert.js

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* canvas-renderer
3+
* https://github.com/dmester/canvas-renderer
4+
*
5+
* Copyright (c) 2017-2018 Daniel Mester Pirttijärvi
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining
8+
* a copy of this software and associated documentation files (the
9+
* "Software"), to deal in the Software without restriction, including
10+
* without limitation the rights to use, copy, modify, merge, publish,
11+
* distribute, sublicense, and/or sell copies of the Software, and to
12+
* permit persons to whom the Software is furnished to do so, subject to
13+
* the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be
16+
* included in all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
*/
26+
27+
"use strict";
28+
29+
/**
30+
* This module will extend tap with the assert
31+
* tap.equalPng(found : Buffer, wanted : Buffer, msg, extra)
32+
*/
33+
34+
const pngjs = require("pngjs");
35+
36+
function createDataUri(buffer) {
37+
return "data:image/png;base64," + buffer.toString("base64");
38+
}
39+
40+
function formatPixel(data, i) {
41+
i -= i % 4;
42+
return `rgba(${data[i]}, ${data[i + 1]}, ${data[i + 2]}, ${data[i + 3]})`;
43+
}
44+
45+
function register(tap) {
46+
tap.Test.prototype.addAssert("equalPng", 2, function (found, wanted, message, extra) {
47+
message = message || "PNG should be equal";
48+
49+
var foundPng = pngjs.PNG.sync.read(found);
50+
var wantedPng = pngjs.PNG.sync.read(wanted);
51+
52+
if (foundPng.width != wantedPng.width ||
53+
foundPng.height != wantedPng.height ||
54+
foundPng.data.length != wantedPng.data.length
55+
) {
56+
extra.found = createDataUri(found);
57+
extra.wanted = createDataUri(wanted);
58+
return this.fail(message, extra);
59+
}
60+
61+
for (var i = 0; i < foundPng.data.length; i++) {
62+
// Allow some difference due to rounding errors
63+
if (Math.abs(foundPng.data[i] - wantedPng.data[i]) > 2) {
64+
extra.found = createDataUri(found);
65+
extra.wanted = createDataUri(wanted);
66+
67+
var x = i % foundPng.width;
68+
var y = (i / foundPng.width) | 0;
69+
70+
extra.foundPixel = formatPixel(foundPng.data, i);
71+
extra.wantedPixel = formatPixel(wantedPng.data, i);
72+
extra.note = `Difference at pixel { x: ${x}, y: ${y} }.`;
73+
74+
return this.fail(message, extra);
75+
}
76+
}
77+
78+
return this.pass(message, extra);
79+
})
80+
}
81+
82+
module.exports = register;

tests/trueColorTest.js renamed to tests/trueColorTests.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
const fs = require("fs");
4141
const tap = require("tap");
4242
const canvasRenderer = require("../index");
43+
require("./pngAssert")(tap);
4344

4445
var canvas = canvasRenderer.createCanvas(1000, 1000);
4546
canvas.backColor = "#abcdefff";
@@ -62,6 +63,5 @@ ctx.arc(400 + radius, 250 + radius, radius, 0, Math.PI * 2, false); // last argu
6263
ctx.closePath();
6364
ctx.fill();
6465

65-
var expected = fs.readFileSync(__dirname + "/expected-truecolor.png");
66-
var expectedB64 = Buffer.from(expected).toString("base64");
67-
tap.equal("data:image/png;base64," + expectedB64, canvas.toDataURL());
66+
var wanted = fs.readFileSync(__dirname + "/expected-truecolor.png");
67+
tap.equalPng(canvas.toPng(), wanted);

tests/visualTest.js renamed to tests/visualTests.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
const fs = require("fs");
3636
const tap = require("tap");
3737
const canvasRenderer = require("../index");
38+
require("./pngAssert")(tap);
3839

3940

4041
var canvas;
@@ -172,7 +173,5 @@ ctx.lineTo(5, 95);
172173
ctx.closePath();
173174
ctx.fill();
174175

175-
var expected = fs.readFileSync(__dirname + "/expected.png");
176-
var expectedB64 = Buffer.from(expected).toString("base64");
177-
tap.equal("data:image/png;base64," + expectedB64, canvas.toDataURL());
178-
176+
var wanted = fs.readFileSync(__dirname + "/expected.png");
177+
tap.equalPng(canvas.toPng(), wanted);

0 commit comments

Comments
 (0)