Merge pull request #146 from CartoDB/acceptance-tests
Acceptance tests validating final image output
This commit is contained in:
commit
7359471605
@ -1,3 +1,6 @@
|
|||||||
|
before_install:
|
||||||
|
- sudo apt-get install -y pkg-config libcairo2-dev libjpeg8-dev libgif-dev
|
||||||
|
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
|
13
Makefile
13
Makefile
@ -28,9 +28,22 @@ dist_folder:
|
|||||||
|
|
||||||
dist: dist_folder dist/torque.js
|
dist: dist_folder dist/torque.js
|
||||||
|
|
||||||
|
clean-results:
|
||||||
|
-@rm test/results/*.png
|
||||||
|
|
||||||
prepare-test-suite:
|
prepare-test-suite:
|
||||||
browserify test/suite.js > test/suite-bundle.js
|
browserify test/suite.js > test/suite-bundle.js
|
||||||
|
|
||||||
|
test: prepare-test-suite
|
||||||
|
@echo "***tests***"
|
||||||
|
./node_modules/node-qunit-phantomjs/bin/node-qunit-phantomjs test/suite.html
|
||||||
|
|
||||||
|
test-acceptance: clean-results
|
||||||
|
@echo "***acceptance***"
|
||||||
|
./node_modules/.bin/qunit -c lib/torque/ -t `find test/acceptance/ -name *.js`
|
||||||
|
|
||||||
|
test-all: test test-acceptance
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
|
|
||||||
|
@ -29,13 +29,18 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"leaflet": "0.7.3",
|
"leaflet": "0.7.3",
|
||||||
|
"underscore": "^1.6.0",
|
||||||
"node-qunit-phantomjs": "^1.0.0",
|
"node-qunit-phantomjs": "^1.0.0",
|
||||||
"browserify": "^7.0.0",
|
"browserify": "^7.0.0",
|
||||||
|
"mapnik": "https://github.com/CartoDB/node-mapnik/tarball/1.4.15-cdb1",
|
||||||
|
"canvas": "~1.2.1",
|
||||||
|
"request": "^2.53.0",
|
||||||
|
"qunit": "~0.7.5",
|
||||||
"qunitjs": "1.x",
|
"qunitjs": "1.x",
|
||||||
"uglify-js": "1.3.3"
|
"uglify-js": "1.3.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "make prepare-test-suite && ./node_modules/node-qunit-phantomjs/bin/node-qunit-phantomjs test/suite.html"
|
"test": "make test-all"
|
||||||
},
|
},
|
||||||
"main": "./lib/torque/index.js"
|
"main": "./lib/torque/index.js"
|
||||||
}
|
}
|
||||||
|
22
test/acceptance/example.js
Normal file
22
test/acceptance/example.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
var Canvas = require('canvas');
|
||||||
|
var image = require('../support/image');
|
||||||
|
|
||||||
|
QUnit.module('example');
|
||||||
|
|
||||||
|
test('reference test with canvas', function() {
|
||||||
|
var circleRadius = 20;
|
||||||
|
var canvasSize = circleRadius * 2 + 2;
|
||||||
|
var canvas = new Canvas(canvasSize, canvasSize);
|
||||||
|
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(circleRadius + 1, circleRadius + 1, circleRadius, 0, Math.PI * 2, true);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
var imageDiff = image.compare(canvas.toBuffer(), 'canvas_basic_reference.png');
|
||||||
|
|
||||||
|
equal(imageDiff, 0);
|
||||||
|
});
|
||||||
|
|
66
test/acceptance/renderer/point.js
Normal file
66
test/acceptance/renderer/point.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
var pointRenderer = require('../../support/point_renderer');
|
||||||
|
var image = require('../../support/image');
|
||||||
|
|
||||||
|
QUnit.module('renderer/point');
|
||||||
|
|
||||||
|
var IMAGE_DIFF_TOLERANCE = 4 / 100;
|
||||||
|
|
||||||
|
asyncTest('navy example', function(assert) {
|
||||||
|
var cartocss = [
|
||||||
|
'Map {',
|
||||||
|
' -torque-time-attribute: "date";',
|
||||||
|
' -torque-aggregation-function: "count(cartodb_id)";',
|
||||||
|
' -torque-frame-count: 760;',
|
||||||
|
' -torque-animation-duration: 15;',
|
||||||
|
' -torque-resolution: 2',
|
||||||
|
'}',
|
||||||
|
'#layer {',
|
||||||
|
' marker-width: 3;',
|
||||||
|
' marker-fill-opacity: 0.8;',
|
||||||
|
' marker-fill: #FEE391; ',
|
||||||
|
' comp-op: "lighten";',
|
||||||
|
' [value > 2] { marker-fill: #FEC44F; }',
|
||||||
|
' [value > 3] { marker-fill: #FE9929; }',
|
||||||
|
' [value > 4] { marker-fill: #EC7014; }',
|
||||||
|
' [value > 5] { marker-fill: #CC4C02; }',
|
||||||
|
' [value > 6] { marker-fill: #993404; }',
|
||||||
|
' [value > 7] { marker-fill: #662506; }',
|
||||||
|
' [frame-offset = 1] { marker-width: 10; marker-fill-opacity: 0.05;}',
|
||||||
|
' [frame-offset = 2] { marker-width: 15; marker-fill-opacity: 0.02;}',
|
||||||
|
'}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
var step = 300;
|
||||||
|
|
||||||
|
pointRenderer.getTile('default_navy_3-3-2.torque.json', cartocss, 3, 3, 2, step, function(err, canvas) {
|
||||||
|
assert.ok(!err, 'no error while getting tile');
|
||||||
|
var imageDiff = image.compare(canvas.toBuffer(), 'default_navy_3-3-2.png');
|
||||||
|
assert.ok(imageDiff < IMAGE_DIFF_TOLERANCE, 'navy tile is ok');
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('basic heatmap', function(assert) {
|
||||||
|
var cartocss = [
|
||||||
|
'Map {',
|
||||||
|
' -torque-time-attribute: "date";',
|
||||||
|
' -torque-aggregation-function: "count(cartodb_id)";',
|
||||||
|
' -torque-frame-count: 1;',
|
||||||
|
' -torque-resolution: 1',
|
||||||
|
'}',
|
||||||
|
'#layer {',
|
||||||
|
' marker-width: 4;',
|
||||||
|
' image-filters: colorize-alpha(blue, cyan, lightgreen, yellow , orange, red);',
|
||||||
|
' marker-file: url(http://s3.amazonaws.com/com.cartodb.assets.static/alphamarker.png);',
|
||||||
|
'}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
var step = 0;
|
||||||
|
|
||||||
|
pointRenderer.getTile('heatmap_navy_3-2-3.torque.json', cartocss, 3, 2, 3, step, function(err, canvas) {
|
||||||
|
assert.ok(!err, 'no error while getting tile');
|
||||||
|
var imageDiff = image.compare(canvas.toBuffer(), 'heatmap_navy_3-2-3.png');
|
||||||
|
assert.ok(imageDiff < IMAGE_DIFF_TOLERANCE, 'heatmap tile is ok');
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
});
|
BIN
test/fixtures/image/canvas_basic_reference.png
vendored
Normal file
BIN
test/fixtures/image/canvas_basic_reference.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 507 B |
BIN
test/fixtures/image/default_navy_3-3-2.png
vendored
Normal file
BIN
test/fixtures/image/default_navy_3-3-2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
BIN
test/fixtures/image/heatmap_navy_3-2-3.png
vendored
Normal file
BIN
test/fixtures/image/heatmap_navy_3-2-3.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
1
test/fixtures/json/default_navy_3-3-2.torque.json
vendored
Normal file
1
test/fixtures/json/default_navy_3-3-2.torque.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
test/fixtures/json/heatmap_navy_3-2-3.torque.json
vendored
Normal file
1
test/fixtures/json/heatmap_navy_3-2-3.torque.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
test/results/.gitignore
vendored
Normal file
1
test/results/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.png
|
19
test/support/image.js
Normal file
19
test/support/image.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
var mapnik = require('mapnik');
|
||||||
|
|
||||||
|
function compare(buffer, fixtureRelPath) {
|
||||||
|
save(__dirname + '/../results/' + fixtureRelPath, buffer);
|
||||||
|
|
||||||
|
var img = new mapnik.Image.fromBytesSync(buffer);
|
||||||
|
var reference = new mapnik.Image.openSync(__dirname + '/../fixtures/image/' + fixtureRelPath);
|
||||||
|
return img.compare(reference) / (reference.width() * reference.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(path, buffer) {
|
||||||
|
var img = new mapnik.Image.fromBytesSync(buffer);
|
||||||
|
img.save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
compare: compare,
|
||||||
|
save: save
|
||||||
|
};
|
59
test/support/point_renderer.js
Normal file
59
test/support/point_renderer.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
var Canvas = require('canvas');
|
||||||
|
var request = require('request');
|
||||||
|
var _ = require('underscore');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var torque = require('../../lib/torque/index');
|
||||||
|
|
||||||
|
|
||||||
|
function getTile(jsonRelPath, cartocss, z, x, y, step, callback) {
|
||||||
|
step = step || 0;
|
||||||
|
|
||||||
|
var cartoCssOptions = torque.common.TorqueLayer.optionsFromCartoCSS(cartocss);
|
||||||
|
|
||||||
|
var provider = new torque.providers.windshaft(_.extend({ no_fetch_map: true }, cartoCssOptions));
|
||||||
|
var rendererOptions = _.extend({cartocss: cartocss}, cartoCssOptions, {
|
||||||
|
canvasClass: Canvas,
|
||||||
|
imageClass: Canvas.Image,
|
||||||
|
setImageSrc: function(img, url, callback) {
|
||||||
|
var requestOpts = {
|
||||||
|
url: url,
|
||||||
|
method: 'GET',
|
||||||
|
encoding: null
|
||||||
|
};
|
||||||
|
request(requestOpts, function (err, response, body) {
|
||||||
|
if (!err && response.statusCode === 200) {
|
||||||
|
img.onload = function() {
|
||||||
|
callback(null);
|
||||||
|
};
|
||||||
|
img.onerror = function() {
|
||||||
|
callback(new Error('Could not load marker-file image: ' + url));
|
||||||
|
};
|
||||||
|
img.src = body;
|
||||||
|
} else {
|
||||||
|
callback(new Error('Could not load marker-file image: ' + url));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
qualifyURL: function(url) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var rows = JSON.parse(fs.readFileSync(__dirname + '/../fixtures/json/' + jsonRelPath));
|
||||||
|
|
||||||
|
var canvas = new Canvas(256, 256);
|
||||||
|
var pointRenderer = new torque.renderer.Point(canvas, rendererOptions);
|
||||||
|
|
||||||
|
pointRenderer.renderTile(provider.proccessTile(rows, {x: x, y: y}, z), step, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err, null);
|
||||||
|
}
|
||||||
|
pointRenderer.applyFilters();
|
||||||
|
return callback(null, canvas);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getTile: getTile
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user