Merge pull request #7138 from ahocevar/pixelmatch-pixelratio

Improvements to the new test setup
This commit is contained in:
Andreas Hocevar
2017-08-17 08:56:07 -04:00
committed by GitHub
17 changed files with 99 additions and 48 deletions
+1 -1
View File
@@ -75,8 +75,8 @@
"mocha-phantomjs-core": "^2.1.0", "mocha-phantomjs-core": "^2.1.0",
"mustache": "2.3.0", "mustache": "2.3.0",
"phantomjs-prebuilt": "2.1.15", "phantomjs-prebuilt": "2.1.15",
"pixelmatch": "^4.0.2",
"proj4": "2.4.4", "proj4": "2.4.4",
"resemblejs": "2.2.4",
"serve-files": "1.0.1", "serve-files": "1.0.1",
"sinon": "3.2.0", "sinon": "3.2.0",
"slimerjs": "0.10.3" "slimerjs": "0.10.3"
+1 -1
View File
@@ -14,7 +14,7 @@
"expect": false, "expect": false,
"expectResemble": false, "expectResemble": false,
"proj4": false, "proj4": false,
"resemble": false, "pixelmatch": false,
"resembleCanvas": false, "resembleCanvas": false,
"sinon": false, "sinon": false,
"where": false "where": false
+1 -1
View File
@@ -29,7 +29,7 @@ in Chrome by default).
# Rendering tests # Rendering tests
The `test/rendering` directory contains rendering tests which compare a rendered map with a The `test/rendering` directory contains rendering tests which compare a rendered map with a
reference image using [resemble.js](http://huddle.github.io/Resemble.js/). reference image using [pixelmatch](https://github.com/mapbox/pixelmatch).
To run the tests in the browser, make sure the development server is running To run the tests in the browser, make sure the development server is running
(`make serve`) and open the URL (`make serve`) and open the URL
+4 -1
View File
@@ -19,6 +19,9 @@ module.exports = function(karma) {
}, },
files: [ files: [
{ {
pattern: 'module-global.js',
watched: false
}, {
pattern: path.resolve(__dirname, require.resolve('jquery/dist/jquery.js')), pattern: path.resolve(__dirname, require.resolve('jquery/dist/jquery.js')),
watched: false watched: false
}, { }, {
@@ -31,7 +34,7 @@ module.exports = function(karma) {
pattern: path.resolve(__dirname, require.resolve('proj4/dist/proj4.js')), pattern: path.resolve(__dirname, require.resolve('proj4/dist/proj4.js')),
watched: false watched: false
}, { }, {
pattern: path.resolve(__dirname, require.resolve('resemblejs/resemble.js')), pattern: path.resolve(__dirname, require.resolve('pixelmatch/index.js')),
watched: false watched: false
}, { }, {
pattern: path.resolve(__dirname, './test-extensions.js') pattern: path.resolve(__dirname, './test-extensions.js')
+1
View File
@@ -0,0 +1 @@
window.module = {};
+1
View File
@@ -41,6 +41,7 @@ describe('layer clipping', function() {
var map = null; var map = null;
beforeEach(function() { beforeEach(function() {
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(256, 256), target: createMapDiv(256, 256),
view: new ol.View({ view: new ol.View({
center: [0, 0], center: [0, 0],
+1
View File
@@ -15,6 +15,7 @@ describe('ol.rendering.layer.Image', function() {
function createMap(renderer) { function createMap(renderer) {
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(50, 50), target: createMapDiv(50, 50),
renderer: renderer, renderer: renderer,
view: new ol.View({ view: new ol.View({
+9 -6
View File
@@ -21,6 +21,7 @@ describe('ol.rendering.layer.Vector', function() {
var map; var map;
function createMap(renderer) { function createMap(renderer) {
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(80, 80), target: createMapDiv(80, 80),
renderer: renderer, renderer: renderer,
view: new ol.View({ view: new ol.View({
@@ -249,12 +250,12 @@ describe('ol.rendering.layer.Vector', function() {
map.once('postrender', function() { map.once('postrender', function() {
var canvas = map.getRenderer().canvas_; var canvas = map.getRenderer().canvas_;
// take a snapshot of this `overlaps: true` image // take a snapshot of this `overlaps: true` image
var referenceImage = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height); var referenceImage = canvas.toDataURL('image/png');
// now render the same with `overlaps: false` // now render the same with `overlaps: false`
layer.setSource(createSource(false)); layer.setSource(createSource(false));
// result should be similar to `overlaps: true` // result should be the same as with `overlaps: true`
map.once('postrender', function() { map.once('postrender', function(e) {
expectResemble(map, referenceImage, 2, done); expectResemble(map, referenceImage, 1e-9, done);
}); });
}); });
}); });
@@ -300,12 +301,12 @@ describe('ol.rendering.layer.Vector', function() {
map.once('postrender', function() { map.once('postrender', function() {
var canvas = map.getRenderer().canvas_; var canvas = map.getRenderer().canvas_;
// take a snapshot of this `overlaps: true` image // take a snapshot of this `overlaps: true` image
var referenceImage = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height); var referenceImage = canvas.toDataURL('image/png');
// now render the same with `overlaps: false` // now render the same with `overlaps: false`
layer.setSource(createSource(false)); layer.setSource(createSource(false));
// result should be exactly the same as with `overlaps: true` // result should be exactly the same as with `overlaps: true`
map.once('postrender', function() { map.once('postrender', function() {
expectResemble(map, referenceImage, 0, done); expectResemble(map, referenceImage, 1e-9, done);
}); });
}); });
}); });
@@ -316,6 +317,7 @@ describe('ol.rendering.layer.Vector', function() {
var map2; var map2;
beforeEach(function() { beforeEach(function() {
map2 = new ol.Map({ map2 = new ol.Map({
pixelRatio: 1,
target: createMapDiv(128, 128), target: createMapDiv(128, 128),
view: new ol.View({ view: new ol.View({
center: [0, 0], center: [0, 0],
@@ -404,6 +406,7 @@ describe('ol.rendering.layer.Vector', function() {
}); });
map3 = new ol.Map({ map3 = new ol.Map({
pixelRatio: 1,
layers: [layer], layers: [layer],
target: createMapDiv(100, 100), target: createMapDiv(100, 100),
view: view view: view
+1 -1
View File
@@ -15,7 +15,7 @@ describe('ol.rendering.layer.VectorTile', function() {
function createMap(renderer, opt_pixelRatio) { function createMap(renderer, opt_pixelRatio) {
map = new ol.Map({ map = new ol.Map({
pixelRatio: opt_pixelRatio, pixelRatio: opt_pixelRatio || 1,
target: createMapDiv(50, 50), target: createMapDiv(50, 50),
renderer: renderer, renderer: renderer,
view: new ol.View({ view: new ol.View({
+1
View File
@@ -21,6 +21,7 @@ describe('ol.rendering.Map', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(50, 50), target: createMapDiv(50, 50),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
+32 -8
View File
@@ -20,14 +20,20 @@ describe('ol.render', function() {
describe('ol.render.toContext()', function() { describe('ol.render.toContext()', function() {
it('creates a vector context from a Canvas 2d context', function() { it('creates a vector context from a Canvas 2d context', function() {
var vectorContext = ol.render.toContext(getContext(), {size: [100, 100]}); var vectorContext = ol.render.toContext(getContext(), {
pixelRatio: 1,
size: [100, 100]
});
expect(vectorContext).to.be.a(ol.render.VectorContext); expect(vectorContext).to.be.a(ol.render.VectorContext);
expect(vectorContext).to.be.a(ol.render.canvas.Immediate); expect(vectorContext).to.be.a(ol.render.canvas.Immediate);
}); });
it('can be used to render a point geometry', function(done) { it('can be used to render a point geometry', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
image: new ol.style.Circle({ image: new ol.style.Circle({
@@ -48,7 +54,10 @@ describe('ol.render', function() {
it('can be used to render a linestring geometry', function(done) { it('can be used to render a linestring geometry', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
@@ -69,7 +78,10 @@ describe('ol.render', function() {
it('respects lineCap for linestring', function(done) { it('respects lineCap for linestring', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
@@ -91,7 +103,10 @@ describe('ol.render', function() {
it('respects lineJoin for linestring', function(done) { it('respects lineJoin for linestring', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
@@ -113,7 +128,10 @@ describe('ol.render', function() {
it('can be used to render a polygon geometry', function(done) { it('can be used to render a polygon geometry', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
@@ -139,7 +157,10 @@ describe('ol.render', function() {
it('supports lineDash styles', function(done) { it('supports lineDash styles', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
@@ -161,7 +182,10 @@ describe('ol.render', function() {
it('supports lineDashOffset', function(done) { it('supports lineDashOffset', function(done) {
var context = getContext(); var context = getContext();
var vectorContext = ol.render.toContext(context, {size: [100, 100]}); var vectorContext = ol.render.toContext(context, {
pixelRatio: 1,
size: [100, 100]
});
var style = new ol.style.Style({ var style = new ol.style.Style({
stroke: new ol.style.Stroke({ stroke: new ol.style.Stroke({
+1
View File
@@ -23,6 +23,7 @@ describe('ol.rendering.style.Circle', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(50, 50), target: createMapDiv(50, 50),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
+1
View File
@@ -30,6 +30,7 @@ describe('ol.rendering.style.Icon', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(width ? width : 50, height ? height : 50), target: createMapDiv(width ? width : 50, height ? height : 50),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
+1
View File
@@ -24,6 +24,7 @@ describe('ol.rendering.style.Polygon', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(size, size), target: createMapDiv(size, size),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
@@ -23,6 +23,7 @@ describe('ol.rendering.style.RegularShape', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(50, 50), target: createMapDiv(50, 50),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
+1
View File
@@ -22,6 +22,7 @@ describe('ol.rendering.style.Text', function() {
}); });
map = new ol.Map({ map = new ol.Map({
pixelRatio: 1,
target: createMapDiv(200, 200), target: createMapDiv(200, 200),
renderer: renderer, renderer: renderer,
layers: [vectorLayer], layers: [vectorLayer],
+41 -29
View File
@@ -386,35 +386,47 @@ goog.require('ol.renderer.webgl.Map');
}; };
function resembleCanvas(canvas, referenceImage, tolerance, done) { function resembleCanvas(canvas, referenceImage, tolerance, done) {
if (showMap) { var width = canvas.width;
var wrapper = document.createElement('div'); var height = canvas.height;
wrapper.style.width = canvas.width + 'px'; var image = new Image();
wrapper.style.height = canvas.height + 'px'; image.addEventListener('load', function() {
wrapper.appendChild(canvas); expect(image.width).to.be(width);
document.body.appendChild(wrapper); expect(image.height).to.be(height);
document.body.appendChild(document.createTextNode(referenceImage)); var referenceCanvas = document.createElement('CANVAS');
} referenceCanvas.width = image.width;
referenceCanvas.height = image.height;
resemble(referenceImage) var referenceContext = referenceCanvas.getContext('2d');
.compareTo(canvas.getContext('2d').getImageData( referenceContext.drawImage(image, 0, 0, image.width, image.height);
0, 0, canvas.width, canvas.height)) if (showMap) {
.onComplete(function(data) { var wrapper = document.createElement('div');
if (!data.isSameDimensions) { wrapper.style.width = canvas.width + 'px';
expect().fail( wrapper.style.height = canvas.height + 'px';
'The dimensions of the reference image and ' + wrapper.appendChild(canvas);
'the test canvas are not the same.'); document.body.appendChild(wrapper);
} document.body.appendChild(document.createTextNode(referenceImage));
}
if (data.misMatchPercentage > tolerance) { var context = canvas.getContext('2d');
if (showDiff) { var output = context.createImageData(canvas.width, canvas.height);
var diffImage = new Image(); var mismatchPx = pixelmatch(
diffImage.src = data.getImageDataUrl(); context.getImageData(0, 0, width, height).data,
document.body.appendChild(diffImage); referenceContext.getImageData(0, 0, width, height).data,
} output.data, width, height);
expect(data.misMatchPercentage).to.be.below(tolerance); var mismatchPct = mismatchPx / (width * height) * 100;
} if (showDiff && mismatchPct > tolerance) {
done(); var diffCanvas = document.createElement('canvas');
}); diffCanvas.width = width;
diffCanvas.height = height;
diffCanvas.getContext('2d').putImageData(output, 0, 0);
document.body.appendChild(diffCanvas);
}
expect(mismatchPct).to.be.below(tolerance);
done();
});
image.addEventListener('error', function() {
expect().fail('Reference image could not be loaded');
done();
});
image.src = referenceImage;
} }
global.resembleCanvas = resembleCanvas; global.resembleCanvas = resembleCanvas;