diff --git a/.gitignore b/.gitignore
index 8e63281ca..5cf9666f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
*.xcodeproj
*.o
*.actual.png
+*.diff.png
/node_modules
/mapnik-packaging
/macosx/build
diff --git a/.travis.yml b/.travis.yml
index dddd096c8..46f8aabe0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,6 +29,7 @@ script:
- make linux -j4 BUILDTYPE=${BUILDTYPE}
- make test -j4 BUILDTYPE=${BUILDTYPE}
- ./scripts/run_tests.sh
+- ./scripts/compare_images.js
after_script:
- ./scripts/deploy_results.sh
diff --git a/scripts/compare_images.js b/scripts/compare_images.js
new file mode 100755
index 000000000..f243753c3
--- /dev/null
+++ b/scripts/compare_images.js
@@ -0,0 +1,95 @@
+#!/usr/bin/env node
+
+var fs = require('fs');
+var path = require('path');
+var spawn = require('child_process').spawn;
+
+var base_dir = path.join(path.resolve('.'), 'test/fixtures/styles');
+
+var files = fs.readdirSync(base_dir).filter(function(name) {
+ return name.match(/\.info\.json$/);
+});
+
+var html =
+ '\n' +
+ '
\n' +
+ '\n' +
+ ' | Actual | \n' +
+ ' Expected | \n' +
+ ' Info | \n' +
+ '
\n';
+
+var exitCode = 0;
+
+processFiles();
+
+function processFiles() {
+ if (!files.length) return done();
+
+ var name = files.shift();
+
+ var info = require(path.join(base_dir, name));
+ var base = path.basename(name, '.info.json');
+
+ var actual = path.join(base_dir, base + '.actual.png');
+ var expected = path.join(base_dir, base + '.expected.png');
+ var diff = path.join(base_dir, base + '.diff.png');
+
+ var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff ]);
+ var error = '';
+ compare.stderr.on('data', function(data) {
+ error += data.toString();
+ });
+ compare.on('exit', function(code, signal) {
+ // The compare program returns 2 on error otherwise 0 if the images are similar or 1 if they are dissimilar.
+ if (code == 2) {
+ writeResult(base, info, error.trim(), Infinity);
+ exitCode = 2;
+ } else {
+ var difference = parseFloat(error.match(/^\d+(?:\.\d+)?\s+\(([^\)]+)\)\s*$/)[1]);
+ writeResult(base, info, '', difference);
+
+ }
+ return processFiles();
+ });
+ compare.stdin.end();
+}
+
+function writeResult(base, info, error, difference) {
+ var color = 'green';
+ if (difference > 0.01 && exitCode < 1) {
+ exitCode = 1;
+ color = 'red';
+ }
+
+ html +=
+ '\n' +
+ '  | \n' +
+ '  | \n' +
+ ' \n' +
+ ' \n' +
+ (error ? ' ' + error + ' \n' : '') +
+ ' \n' +
+ ' - diff: ' + difference + '
\n' +
+ ' - zoom: ' + (info.zoom || 0) + '
\n' +
+ ' - latitude: ' + (info.latitude || 0) + '
\n' +
+ ' - longitude: ' + (info.longitude || 0) + '
\n' +
+ ' - angle: ' + (info.angle || 0) + '
\n' +
+ ' - width: ' + (info.width || 0) + '
\n' +
+ ' - height: ' + (info.height || 0) + '
\n' +
+ ' \n' +
+ ' | \n' +
+ '
\n'
+ ;
+}
+
+function done() {
+ html += "
\n";
+
+ fs.writeFileSync(path.join(base_dir, 'index.html'), html);
+
+ process.exit(exitCode);
+}
\ No newline at end of file
diff --git a/scripts/create_result_table.js b/scripts/create_result_table.js
deleted file mode 100644
index ad604890f..000000000
--- a/scripts/create_result_table.js
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env node
-
-var fs = require('fs');
-var path = require('path');
-
-var html =
- '\n' +
- '\n' +
- '\n' +
- ' | Actual | \n' +
- ' Expected | \n' +
- ' Info | \n' +
- '
\n';
-
-var dir = fs.readdirSync('./test/fixtures/styles').filter(function(name) {
- return name.match(/\.info\.json$/);
-}).forEach(function(name) {
- var info = require(path.join(path.resolve('.'), './test/fixtures/styles', name));
- var base = path.basename(name, '.info.json');
-
- html +=
- '\n' +
- '  | \n' +
- '  | \n' +
- ' \n' +
- ' \n' +
- ' \n' +
- ' - zoom: ' + (info.zoom || 0) + '
\n' +
- ' - latitude: ' + (info.latitude || 0) + '
\n' +
- ' - longitude: ' + (info.longitude || 0) + '
\n' +
- ' - angle: ' + (info.angle || 0) + '
\n' +
- ' - width: ' + (info.width || 0) + '
\n' +
- ' - height: ' + (info.height || 0) + '
\n' +
- ' \n' +
- ' | \n' +
- '
\n'
- ;
-});
-
-html += "