Merge branch 'master' into stylesource
@@ -33,33 +33,45 @@ function processFiles() {
|
||||
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 keys = Object.keys(info);
|
||||
|
||||
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);
|
||||
processFileTest();
|
||||
|
||||
}
|
||||
return processFiles();
|
||||
});
|
||||
compare.stdin.end();
|
||||
function processFileTest() {
|
||||
if (!keys.length) return processFiles();
|
||||
|
||||
var key = keys.shift();
|
||||
|
||||
var base = path.basename(name, '.info.json');
|
||||
|
||||
var actual = path.join(base_dir, base + '/' + key + '.actual.png');
|
||||
var expected = path.join(base_dir, base + '/' + key + '.expected.png');
|
||||
var diff = path.join(base_dir, base + '/' + key + '.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, key, info[key], error.trim(), Infinity);
|
||||
exitCode = 2;
|
||||
} else {
|
||||
var match = error.match(/^\d+(?:\.\d+)?\s+\(([^\)]+)\)\s*$/);
|
||||
var difference = match ? parseFloat(match[1]) : Infinity;
|
||||
writeResult(base, key, info[key], match ? '' : error, difference);
|
||||
|
||||
}
|
||||
processFileTest();
|
||||
});
|
||||
compare.stdin.end();
|
||||
}
|
||||
}
|
||||
|
||||
function writeResult(base, info, error, difference) {
|
||||
function writeResult(base, key, info, error, difference) {
|
||||
var color = 'green';
|
||||
var allowedDifference = ('diff' in info) ? info.diff : 0.01;
|
||||
if (difference > allowedDifference) {
|
||||
@@ -72,19 +84,18 @@ function writeResult(base, info, error, difference) {
|
||||
|
||||
html +=
|
||||
'<tr>\n' +
|
||||
' <td><img src="' + base + '.actual.png" onmouseover="this.src=\'' + base + '.expected.png\'" onmouseout="this.src=\'' + base + '.actual.png\'"></td>\n' +
|
||||
' <td><img src="' + base + '.expected.png" onmouseover="this.src=\'' + base + '.diff.png\'" onmouseout="this.src=\'' + base + '.expected.png\'"></td>\n' +
|
||||
' <td><img src="' + base + '/' + key + '.actual.png" onmouseover="this.src=\'' + base + '/' + key + '.expected.png\'" onmouseout="this.src=\'' + base + '/' + key + '.actual.png\'"></td>\n' +
|
||||
' <td><img src="' + base + '/' + key + '.expected.png" onmouseover="this.src=\'' + base + '/' + key + '.diff.png\'" onmouseout="this.src=\'' + base + '/' + key + '.expected.png\'"></td>\n' +
|
||||
' <td>\n' +
|
||||
' <h2 style="text-align:center; background:' + color + '"><a href="' + base + '.style.json">' + base + '</a></h2>\n' +
|
||||
' <h2 style="text-align:center; background:' + color + '"><a href="' + base + '.style.json">' + base + '/' + key + '</a></h2>\n' +
|
||||
(error ? ' <p>' + error + '</p>\n' : '') +
|
||||
' <ul>\n' +
|
||||
' <li>diff: <strong>' + difference + '</strong></li>\n' +
|
||||
' <li>zoom: <strong>' + (info.zoom || 0) + '</strong></li>\n' +
|
||||
' <li>latitude: <strong>' + (info.latitude || 0) + '</strong></li>\n' +
|
||||
' <li>longitude: <strong>' + (info.longitude || 0) + '</strong></li>\n' +
|
||||
' <li>angle: <strong>' + (info.angle || 0) + '</strong></li>\n' +
|
||||
' <li>width: <strong>' + (info.width || 0) + '</strong></li>\n' +
|
||||
' <li>height: <strong>' + (info.height || 0) + '</strong></li>\n' +
|
||||
' <li>center: <strong>' + (info.center || [0, 0]) + '</strong></li>\n' +
|
||||
' <li>bearing: <strong>' + (info.bearing || 0) + '</strong></li>\n' +
|
||||
' <li>width: <strong>' + (info.width || 512) + '</strong></li>\n' +
|
||||
' <li>height: <strong>' + (info.height || 512) + '</strong></li>\n' +
|
||||
' </ul>\n' +
|
||||
' </td>\n' +
|
||||
'</tr>\n'
|
||||
|
||||
8
test/fixtures/styles/0.info.json
vendored
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"zoom": 0,
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"angle": 0,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
}
|
||||
8
test/fixtures/styles/1.info.json
vendored
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"zoom": 0,
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"angle": 0,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
}
|
||||
BIN
test/fixtures/styles/road-width.expected.png
vendored
|
Before Width: | Height: | Size: 107 KiB |
26
test/fixtures/styles/road-width.info.json
vendored
@@ -1,8 +1,22 @@
|
||||
{
|
||||
"zoom": 14,
|
||||
"latitude": 52.499167,
|
||||
"longitude": 13.418056,
|
||||
"angle": 0,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
"z13.9": {
|
||||
"zoom": 13.9,
|
||||
"center": [52.499167, 13.418056],
|
||||
"height": 256
|
||||
},
|
||||
"z14.0": {
|
||||
"zoom": 14,
|
||||
"center": [52.499167, 13.418056],
|
||||
"height": 256
|
||||
},
|
||||
"z14.1": {
|
||||
"zoom": 14.1,
|
||||
"center": [52.499167, 13.418056],
|
||||
"height": 256
|
||||
},
|
||||
"z14.2": {
|
||||
"zoom": 14.2,
|
||||
"center": [52.499167, 13.418056],
|
||||
"height": 256
|
||||
}
|
||||
}
|
||||
|
||||
2
test/fixtures/styles/road-width.style.json
vendored
@@ -24,7 +24,7 @@
|
||||
"style": {
|
||||
"line-width": {
|
||||
"fn": "stops",
|
||||
"stops": [[13, 0], [13.999, 0], [14, 4], [14.1, 100]]
|
||||
"stops": [[13, 0], [13.999, 0], [14, 4], [14.1, 10], [14.2, 20]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
test/fixtures/styles/road-width/z13.9.expected.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
test/fixtures/styles/road-width/z14.0.expected.png
vendored
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
test/fixtures/styles/road-width/z14.1.expected.png
vendored
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
test/fixtures/styles/road-width/z14.2.expected.png
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
6
test/fixtures/styles/world-aa.info.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plain": {
|
||||
"center": [0, 0],
|
||||
"zoom": 0
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
6
test/fixtures/styles/world-no-aa.info.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plain": {
|
||||
"center": [0, 0],
|
||||
"zoom": 0
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -24,41 +24,49 @@ TEST_P(HeadlessTest, render) {
|
||||
|
||||
const std::string style = llmr::util::read_file(base_directory + "/" + base + ".style.json");
|
||||
const std::string info = llmr::util::read_file(base_directory + "/" + base + ".info.json");
|
||||
const std::string actual_image = base_directory + "/" + base + ".actual.png";
|
||||
|
||||
// Parse settings.
|
||||
rapidjson::Document doc;
|
||||
doc.Parse<0>((const char *const)info.c_str());
|
||||
ASSERT_EQ(false, doc.HasParseError());
|
||||
|
||||
const double zoom = doc.HasMember("zoom") ? doc["zoom"].GetDouble() : 0;
|
||||
const double angle = doc.HasMember("angle") ? doc["angle"].GetDouble() : 0;
|
||||
const double longitude = doc.HasMember("longitude") ? doc["longitude"].GetDouble() : 0;
|
||||
const double latitude = doc.HasMember("latitude") ? doc["latitude"].GetDouble() : 0;
|
||||
const unsigned int width = doc.HasMember("width") ? doc["width"].GetUint() : 0;
|
||||
const unsigned int height = doc.HasMember("height") ? doc["height"].GetUint() : 0;
|
||||
ASSERT_EQ(true, doc.IsObject());
|
||||
|
||||
// Setup OpenGL
|
||||
llmr::HeadlessView view;
|
||||
llmr::Map map(view);
|
||||
|
||||
view.resize(width, height);
|
||||
map.resize(width, height);
|
||||
for (auto it = doc.MemberBegin(), end = doc.MemberEnd(); it != end; it++) {
|
||||
const std::string name { it->name.GetString(), it->name.GetStringLength() };
|
||||
const rapidjson::Value &value = it->value;
|
||||
ASSERT_EQ(true, value.IsObject());
|
||||
if (value.HasMember("center")) ASSERT_EQ(true, value["center"].IsArray());
|
||||
|
||||
map.setStyleJSON(style);
|
||||
const std::string actual_image = base_directory + "/" + base + "/" + name + ".actual.png";
|
||||
|
||||
map.setLonLatZoom(longitude, latitude, zoom);
|
||||
map.setAngle(angle);
|
||||
map.setDebug(false);
|
||||
const double zoom = value.HasMember("zoom") ? value["zoom"].GetDouble() : 0;
|
||||
const double bearing = value.HasMember("bearing") ? value["bearing"].GetDouble() : 0;
|
||||
const double latitude = value.HasMember("center") ? value["center"][rapidjson::SizeType(0)].GetDouble() : 0;
|
||||
const double longitude = value.HasMember("center") ? value["center"][rapidjson::SizeType(1)].GetDouble() : 0;
|
||||
const unsigned int width = value.HasMember("width") ? value["width"].GetUint() : 512;
|
||||
const unsigned int height = value.HasMember("height") ? value["height"].GetUint() : 512;
|
||||
|
||||
// Run the loop. It will terminate when we don't have any further listeners.
|
||||
map.run();
|
||||
map.setStyleJSON(style);
|
||||
|
||||
const std::unique_ptr<uint32_t[]> pixels(new uint32_t[width * height]);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
|
||||
view.resize(width, height);
|
||||
map.resize(width, height);
|
||||
map.setLonLatZoom(longitude, latitude, zoom);
|
||||
map.setAngle(bearing);
|
||||
|
||||
// Run the loop. It will terminate when we don't have any further listeners.
|
||||
map.run();
|
||||
|
||||
const std::unique_ptr<uint32_t[]> pixels(new uint32_t[width * height]);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
|
||||
|
||||
const std::string image = llmr::util::compress_png(width, height, pixels.get(), true);
|
||||
llmr::util::write_file(actual_image, image);
|
||||
}
|
||||
|
||||
const std::string image = llmr::util::compress_png(width, height, pixels.get(), true);
|
||||
llmr::util::write_file(actual_image, image);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Headless, HeadlessTest, ::testing::ValuesIn([] {
|
||||
|
||||