From ed5eb9edc1458692bf6ff71d5ec95a7d3400318f Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 20 Nov 2015 14:55:49 -0800 Subject: [PATCH] [test] Add pixelmatch; use in annotation tests --- .gitignore | 2 + configure | 1 + scripts/linux/after_script.sh | 15 +++++ scripts/linux/configure.sh | 1 + scripts/osx/configure.sh | 1 + test/api/annotations.cpp | 47 ++++++++------ .../annotations/add_multiple/expected.png | Bin 0 -> 4589 bytes .../annotations/custom_icon/expected.png | Bin 0 -> 1300 bytes .../annotations/fill_annotation/expected.png | Bin 0 -> 1543 bytes .../annotations/line_annotation/expected.png | Bin 0 -> 2412 bytes .../non_immediate_add/expected.png | Bin 0 -> 1543 bytes .../annotations/point_annotation/expected.png | Bin 0 -> 4273 bytes .../annotations/remove_point/expected.png | Bin 0 -> 1238 bytes .../annotations/remove_shape/expected.png | Bin 0 -> 1238 bytes .../expected.png | Bin 0 -> 1538 bytes .../annotations/switch_style/expected.png | Bin 0 -> 4273 bytes test/fixtures/util.cpp | 60 ++++++++++++++++++ test/fixtures/util.hpp | 9 +++ test/output/.gitkeep | 0 test/test.gypi | 1 + 20 files changed, 116 insertions(+), 21 deletions(-) create mode 100755 scripts/linux/after_script.sh create mode 100644 test/fixtures/annotations/add_multiple/expected.png create mode 100644 test/fixtures/annotations/custom_icon/expected.png create mode 100644 test/fixtures/annotations/fill_annotation/expected.png create mode 100644 test/fixtures/annotations/line_annotation/expected.png create mode 100644 test/fixtures/annotations/non_immediate_add/expected.png create mode 100644 test/fixtures/annotations/point_annotation/expected.png create mode 100644 test/fixtures/annotations/remove_point/expected.png create mode 100644 test/fixtures/annotations/remove_shape/expected.png create mode 100644 test/fixtures/annotations/style_sourced_shape_annotation/expected.png create mode 100644 test/fixtures/annotations/switch_style/expected.png delete mode 100644 test/output/.gitkeep diff --git a/.gitignore b/.gitignore index 21a7079fa..d5fb118e9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,8 @@ /test/fixtures/api/1.png /test/fixtures/api/2.png /test/fixtures/database/*.db +/test/fixtures/*/*/actual.png +/test/fixtures/*/*/diff.png /test/output /include/mbgl/shader/shaders.hpp /src/shader/shaders_gl.cpp diff --git a/configure b/configure index da993492a..8c74b1db8 100755 --- a/configure +++ b/configure @@ -104,6 +104,7 @@ print_flags geojsonvt static_libs cflags ldflags print_flags variant static_libs cflags ldflags print_flags rapidjson static_libs cflags ldflags print_flags gtest static_libs cflags ldflags +print_flags pixelmatch static_libs cflags ldflags CONFIG+=" } } diff --git a/scripts/linux/after_script.sh b/scripts/linux/after_script.sh new file mode 100755 index 000000000..f8e4bc348 --- /dev/null +++ b/scripts/linux/after_script.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e +set -o pipefail + +if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then + # Install and add awscli to PATH for uploading the results + pip install --user awscli + export PATH="`python -m site --user-base`/bin:${PATH}" + + REPO_NAME=$(basename $TRAVIS_REPO_SLUG) + + aws s3 cp --recursive --acl public-read test/fixtures/annotations \ + s3://mapbox/$REPO_NAME/render-tests/$TRAVIS_JOB_NUMBER/annotations +fi diff --git a/scripts/linux/configure.sh b/scripts/linux/configure.sh index f270c903e..6a88c13c0 100644 --- a/scripts/linux/configure.sh +++ b/scripts/linux/configure.sh @@ -15,6 +15,7 @@ GEOJSONVT_VERSION=2.1.6.3 VARIANT_VERSION=1.0 RAPIDJSON_VERSION=1.0.2 GTEST_VERSION=1.7.0 +PIXELMATCH_VERSION=0.9.0 function print_opengl_flags { CONFIG+=" 'opengl_cflags%': $(quote_flags $(pkg-config gl x11 --cflags)),"$LN diff --git a/scripts/osx/configure.sh b/scripts/osx/configure.sh index 34024a40f..823e3b626 100644 --- a/scripts/osx/configure.sh +++ b/scripts/osx/configure.sh @@ -15,3 +15,4 @@ GEOJSONVT_VERSION=2.1.6.3 VARIANT_VERSION=1.0 RAPIDJSON_VERSION=1.0.2 GTEST_VERSION=1.7.0 +PIXELMATCH_VERSION=0.9.0 diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp index b16ec71ef..c4fea0207 100644 --- a/test/api/annotations.cpp +++ b/test/api/annotations.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -15,12 +14,18 @@ using namespace mbgl; -std::string renderPNG(Map& map) { +UnassociatedImage render(Map& map) { std::promise promise; map.renderStill([&](std::exception_ptr, UnassociatedImage&& image) { promise.set_value(std::move(image)); }); - return encodePNG(promise.get_future().get()); + return std::move(promise.get_future().get()); +} + +void checkRendering(Map& map, const char * name) { + UnassociatedImage actual = render(map); + test::checkImage(std::string("test/fixtures/annotations/") + name + "/", + actual, 0.0002, 0.1); } TEST(Annotations, PointAnnotation) { @@ -30,9 +35,9 @@ TEST(Annotations, PointAnnotation) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + map.addPointAnnotation(PointAnnotation({ 0, -20 }, "default_marker")); - util::write_file("test/output/point_annotation.png", renderPNG(map)); + checkRendering(map, "point_annotation"); } TEST(Annotations, LineAnnotation) { @@ -51,7 +56,7 @@ TEST(Annotations, LineAnnotation) { map.addShapeAnnotation(ShapeAnnotation(segments, properties)); - util::write_file("test/output/line_annotation.png", renderPNG(map)); + checkRendering(map, "line_annotation"); } TEST(Annotations, FillAnnotation) { @@ -69,7 +74,7 @@ TEST(Annotations, FillAnnotation) { map.addShapeAnnotation(ShapeAnnotation(segments, properties)); - util::write_file("test/output/fill_annotation.png", renderPNG(map)); + checkRendering(map, "fill_annotation"); } TEST(Annotations, StyleSourcedShapeAnnotation) { @@ -84,7 +89,7 @@ TEST(Annotations, StyleSourcedShapeAnnotation) { map.addShapeAnnotation(ShapeAnnotation(segments, "annotation")); - util::write_file("test/output/style_sourced_shape_annotation.png", renderPNG(map)); + checkRendering(map, "style_sourced_shape_annotation"); } TEST(Annotations, AddMultiple) { @@ -96,11 +101,11 @@ TEST(Annotations, AddMultiple) { map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addPointAnnotation(PointAnnotation({ 0, -20 }, "default_marker")); - renderPNG(map); + render(map); map.addPointAnnotation(PointAnnotation({ 0, 20 }, "default_marker")); - util::write_file("test/output/add_multiple.png", renderPNG(map)); + checkRendering(map, "add_multiple"); } TEST(Annotations, NonImmediateAdd) { @@ -111,7 +116,7 @@ TEST(Annotations, NonImmediateAdd) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - renderPNG(map); + render(map); AnnotationSegments segments = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }}; @@ -120,7 +125,7 @@ TEST(Annotations, NonImmediateAdd) { map.addShapeAnnotation(ShapeAnnotation(segments, properties)); - util::write_file("test/output/non_immediate_add.png", renderPNG(map)); + checkRendering(map, "non_immediate_add"); } TEST(Annotations, RemovePoint) { @@ -132,11 +137,11 @@ TEST(Annotations, RemovePoint) { map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); uint32_t point = map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); - renderPNG(map); + render(map); map.removeAnnotation(point); - util::write_file("test/output/remove_point.png", renderPNG(map)); + checkRendering(map, "remove_point"); } TEST(Annotations, RemoveShape) { @@ -154,11 +159,11 @@ TEST(Annotations, RemoveShape) { map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); uint32_t shape = map.addShapeAnnotation(ShapeAnnotation(segments, properties)); - renderPNG(map); + render(map); map.removeAnnotation(shape); - util::write_file("test/output/remove_shape.png", renderPNG(map)); + checkRendering(map, "remove_shape"); } TEST(Annotations, ImmediateRemoveShape) { @@ -170,7 +175,7 @@ TEST(Annotations, ImmediateRemoveShape) { map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation({}, {}))); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - renderPNG(map); + render(map); } TEST(Annotations, SwitchStyle) { @@ -180,13 +185,13 @@ TEST(Annotations, SwitchStyle) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + map.addPointAnnotation(PointAnnotation({ 0, -20 }, "default_marker")); - renderPNG(map); + render(map); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - util::write_file("test/output/switch_style.png", renderPNG(map)); + checkRendering(map, "switch_style"); } TEST(Annotations, CustomIcon) { @@ -199,5 +204,5 @@ TEST(Annotations, CustomIcon) { map.setSprite("cafe", std::make_shared(12, 12, 1, std::string(12 * 12 * 4, '\xFF'))); map.addPointAnnotation(PointAnnotation({ 0, 0 }, "cafe")); - util::write_file("test/output/custom_icon.png", renderPNG(map)); + checkRendering(map, "custom_icon"); } diff --git a/test/fixtures/annotations/add_multiple/expected.png b/test/fixtures/annotations/add_multiple/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..deedf84330c5902065b36179477349d670d12a6a GIT binary patch literal 4589 zcmeHL`8(9z|9)#h3+gFKmeEtnE{QZ#MpD@x`;x68NsKYV7z{JCNka8lo-mYUCW9IK zSQ?XrkS#ldB-@N7%NS-D-|6$y_Ye5|@cH5SseeU}{*L7m8EN+VJKd~PG z05KC|BO3q^5)6d^QDH&n8uQJoK;haBCh$`H8cwDjmv4K?*p!Egh zdNA6q+D??ZOVZQD-|c=h!iPHQH9~7|=TO&tI{m0{DqdR~GQ&I56NDM(Tw0o$=VfXK z5xg@_os0r@i7Nct{4aB04vrqo9hp2aGy#IHJGf!41zMkSnf0qnd-=DmDS))Gk9w6$Q>cKY9<)z2RL*%Q2T3&zMW0o39C`)(9va6e@cU@eU+umgP^M_y2 za@y4X}}WIh8-O~PJk)01k_o>yc^e>J~yyiHXK8|0vAir z7zS%}yCyd);9E4fgx0N|KENd8{^5Tv9Y?5zqCN5`d$PNl_JImb?4pDeav$Ycew09( zj7~vz(7bI7k2gLzJ+>gj_Q2}TtX$hoE-q`HirKErz`?VOt3zu#8q=KJK9K8iHZPTi z8^YRAi`kxp+8aAg(V#txqrK_Xg*NDY0{lO>PPiKPyQh<~O|*$;G>godG}ozXjB87N z9r!hhN}K26#ZOr+aZYo$1EuxXQWVNX6V4y+I|gcBkUOJ&oxj>*Xeo zo-ujT)(aMFo?a(69zEY;)$~Si|1UBm_cclyh|W7g*ZW^c7tP^#mOMyiD5ZJ3pa6+X ziWu{vMt+yND9Pw+vk39l0DtNuuFJ)UXghH%p`whnL9@jQyjE(4{s>I$GpBcTD&Zcw zgW)ihY!dUYh(a?@VpA3F-uQMU1bziM-YKvm++rp@kv((>V| zmFU03#PWYCl0v4MZl~^JOt!K8gNWsd47qX0$X`hR%WuE561P-{D=EJbY%VueAUrH{ zx|)i`3i7bRQGbA9gLz$da0O(9QYu>JM&xYjNZpVdYO#f!_s-wYIvF+<2&p`pY`gtD zC-k{Xxz^_=O66KcbtF=n(A&>3IW&E~n0<8!FKTt1HExR;!+paIXE>l2_pNdY)4#lE z#p~8K=F6LrU=Nbi$cO_$z9qiZ@g7`z+tGu7qW%eftv)fom0b%V*i#ZP%gS+n%WnxP zAX&gJwy~s2#D00t0VlOML?b*uzMtTnbsk9C5N)0;xkR#oEsGJh$cdxhJQGF9X}>PcO!QZEdP^D0rdP_O77wqx1;KH|h(wSKY+=7t#XWWJbn9|6w2uR;lb*z)5R z<9lWCw0cTorCvqv4Y+NQr8Hm~@p!wI|ADl&(@y=Yljw#Q6yiCfvfwO0HFM$BRXEAU z)gs0FWeb7bAM0Beh#5QX{yDnse&&)>&lG#e1;h=A&~<5X_p4L(mgfYEWf)TZ9~w&s zrHCoR_Yowv@@|9J#DI5JwV z8P2{r75V+d-vob37ZH~4!u0J`7xO3W;I>kFFJ)rr%~$wY7A`vP@>{QPt|GgEw_M4a z%SX|MlJbVrO6ALkLeJP+|K^Q6j<1+)ulMt)$eb+;4PPFJw3S;Oo#K##(`(|8Q`>Ym zD{Qh^dzxdCJzF*5hq8Zn)1hMm-yYf|k$i=t4v9AhoLoI?&)aNB+Zv6c3Eg4aGS-!~ zM~A5Tv;DY18oEI*=>LhcG_mf%2Y2< zYmG25bhcx}&H5c|6mRH<_`pw)SU)6bbFP92+T@weUVj H8!PE*$l;oc(M*Cx(b7 z99bSp04@U^v;Dk_g9*mG0_<;kns78Hr%g!;Uin7 zSI%7Ck2qK}@Z&O4$Pi3oCh;%rTzt>X3nJ9y^ZjV_T;5D< zvOO$`3Y-LG!?PlIK@0Ku$F@_w|G+s>`)GZT^%$&3smuWv=BQ%ay$z74^3NKcHjxq9 zWKEGZt}b3RdKd2@<3Pfa0mBr>vvObV?z}xW!}I16QImXy*RA;yHfuyC2#0=JXqBpf&id{}%Jp4BD%dZc}yOn7Jw! zw`+3YVcimC%T(a%rZ!j$!ur0aVr0X!cHq!cCYH(2>BZIJGSEb9zZqvm;d{k+_3=q)|IQjG)Z{-IY%$f`1``_* z=-W3yqfh@FkYpOT6~5L@FJxiEnzFq^#Kp%5l-1kcH5b@D)lTWsd5FClLSF?`G{5oELWOJ8xN zJFp$m<&T!4RY^;09KwhYBnmPU-0fLu=E#@n|O#LR7AdwjEij7;kbq^v#?j2Tfntq zdnyY7aO_h@ zhpDJIjfK7zRHfrLJC+{_6|za`+&V;$7Qn z7>+jw!0m9idz=gN1yM@n-L^MQ4S^glILlyF`%bD4efMQu=mYd&cB%IZ2+bo;>gsR~(FqAHMA zOaTO1w>*97*U}ddY|pS0`OL5)T^~p)a$AR!w6kfwv1{J|zefSTZVmE6Q4zG>YPQWx zW$L1gFVJPTDY9i27KgjiOHq38+)&2M+=13N1cI>_Cw>lVql{63C?iyWI?E60Fw?I~ zd*~g;`sEC*nS=vfU>V>75i;k1}Qb zIuV@QIVL>VOHnaR87I^WeFW1heGH1L(w^eg9Mq|Tcp>FOL+_E&@T6$Dk~R#=-;F<# zSNB(6*j=QfyR$sLwArW<38o>6?%rFL{n)^#10V2nMP+bbq)6+7Y3lYqiz4+3Mw2@R?w={7uyu`;P$Xnv zE4Is2SB~{{$0UKaGn^cSpU~-3cqe4g<7+I4Cmp@i2+(oB)B^1Pq&^}0h3>g|%1cx* zg1YHDx5gWpQ7V6cLu3WBqyZJom!Hrvt**StJdGtY#Up|QX?-4k$N&)9^KbJn2mciv dh+BNeDH~>rZMi-xLGXX zUOvDsJFhywGa#YY-z_6%Y zc=iD&2Sy!{w+aHH0Sp%pclstME?^MrDii47(r9?`@QB(5fdB?>S8EOzRuP9U1xdoA mfsYyZqauhxsqw$a4n`qP775MHWgNg_j=|H_&t;ucLK6T_=e_~} literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/fill_annotation/expected.png b/test/fixtures/annotations/fill_annotation/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..30f6f1eb59203bf17630a0c0b7bd6ae69a045348 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=FIXJzX3_ zDj45hxtQq`DB^N4+e1BUO5d9kU6(o+ENQIS#U8_d@B5ip_GdEkj7%&X0tyZd3?qlp z81rC~d4PiGj(MLai*+2XKfm+1=n>%z7P;ql<~_Hu|M}lI3R3QmL z0|w>xfaX!{BPHk#EajNGQ~86%^KF-({q@~v|L5;}@#!8TDO-)40))ms{Sp3v_0iRK V&gZF|zkww?gQu&X%Q~loCIAi5HA(;g literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/line_annotation/expected.png b/test/fixtures/annotations/line_annotation/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..067027f1d17c167c7d2a9ad0f5b87461a405198b GIT binary patch literal 2412 zcmeHJ{X3Iu9Dl5-g}nAgl%tu1NH4Au=B2#9Tok>~R>#W`rHjiY$A*RDbjeE=Ng+ik z*_OiLu#HaXN!dAv?0AWlXGvyTW7cf8^KASH=eN#J&wXFl=l*^_-_PfB-Oqg`B*=T6 zmWdVs0PB2xyg~s$172zXsMYW%GPxmEwMz;0_5djTrqckh7US#Xe)N*Y?0aHE%rUdo z9QJ(=f3GLcP?m2WTJL%0kix{|R?rOGAEW(@ui5f)u#VRE&)(f^v?pM#?KM~Cpx^!6 zijq5++}$)=)Buf1|D3X;ZgX>H2EO~_#ZRn@$7fEwp$)Z5iZdqGjHj@M;{+{6Ie-QN ziPAU6W`8#ePQ2ki6{d50mp(t|_qtBfWQB4Mq=JQ@2GbQ2bqZr7D!@|M4)ysVnet==?>Y1C9PH47T-KwdQH`)_VDbej`!Z)?A)v*^gMo;>JMoq#cLPBz{ z5I`7K9OJOTC%4G?i+{I?kAcLe9j^lMTBN>G7ZoV8SuhWMw${%@JKV#XeN~>sEw;Ma zr4!PUUth&I8dZ4Ulaj-12ySjx(y1J9ILsX7i$6k|EG?d|7qGYa?5g<7D;5!k;`xlf z+eF7rkRx3+FP9)=*EfU_?D^UgRF)s*<}#$y;y{vT@*SA1TP3d&;qHUjqt)p$JbxET zgNevrKnuo!(HMt3EU`a}P&KI>pwFKtriy0O+!~qn;1Ue$+?UQ7gBngmK^TWlWL5*0O&2aLW`NFd z%j&k&_FAg+E{AefFe6QE2df{bR7)ZUzx`t2MEanqD7l?^R@58*EmLtWd30IcJNsvx zYjvlUo$zSv1VzS5L25wJZ)j;ItQ~t_m)p+?q4}CR2;?v8za3AGfJLTgXJtzHbwNre zl>X*Wjx%VdvLjK{=42J8YkYDC0(ovu0U4<>;Y4O(#2NyY-R}} z%Wr%LmYwa+80lx3WAQ#D@6tJ0k7R~{t}%6d7J@_#ep&*JS^kQ#8}z1x?W~S?s`_9X z+WyipQ2{&$C1H`VJNlzg~&F(=4XO~S@GQ9QGxHqQcU{!p?Yz}XQqI&ZIG{tA%X zHOu!%PYy>+adnvPKNcL$W+v+@&rOd`a>uef;66KPkzEmOJVgR5m>}qa+1}RUNR%ym zmi=-ooVBEx;;n}^WE*H8Jhg0{7ZUv!T6-jO%>yihmPuAgH{6fIaeXgYfPpc^j4kJ= zZb#HLc|)UG6RbWyy>AyI=jFx%fD}`sfHM>282rva>7=ig)lU4Hu^}^65iBZSW~N6@ zdt6R;p?C17z17rRYZA}L;HqXS$IX_jOj%J~F~f|La_-k^C|1osggsx=X`P-JB~8Pm z>6)CfMIieFi$*FB(J1m87>N~FS%V7`II8>V}GG4UtEPVbCgpJi9E}cBhVu? zYwY_9!DV>=xo+3&a;CZ=-cG68kc$Q{@Pdgt4d|9UNkOpxR$PQ)MsIwm*ifbCV2g~^ z6u2m9vdJR$z5oCK literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/non_immediate_add/expected.png b/test/fixtures/annotations/non_immediate_add/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..30f6f1eb59203bf17630a0c0b7bd6ae69a045348 GIT binary patch literal 1543 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=FIXJzX3_ zDj45hxtQq`DB^N4+e1BUO5d9kU6(o+ENQIS#U8_d@B5ip_GdEkj7%&X0tyZd3?qlp z81rC~d4PiGj(MLai*+2XKfm+1=n>%z7P;ql<~_Hu|M}lI3R3QmL z0|w>xfaX!{BPHk#EajNGQ~86%^KF-({q@~v|L5;}@#!8TDO-)40))ms{Sp3v_0iRK V&gZF|zkww?gQu&X%Q~loCIAi5HA(;g literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/point_annotation/expected.png b/test/fixtures/annotations/point_annotation/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..33299a2d6a40691a58defbf7013ef9a16647ec0f GIT binary patch literal 4273 zcmeHLS6CCs7EVG$KtUAHD=Y}8p)Cl~L>2>xMubQw(phN=QUoayNI*eB1r;{*y3$Jm z(n~^I6$Qj71cQVm6hR1tP!mcBH|~ACkN4p|?8}*%?>lGC`Oo?1%zTq-dkrQoCMyO2 z0K_e?Sl9yqK*1CU5D^v(?%`GbKUWdh2`pyQ0hP zqQ)~=LoLaK&!7V!=b*#2Blb!5w=JLMiCoq`qO1eC;b<-dtb3t&*-~3cQu?&%!PWg| zDiR&3m8TL+qp(R=pE6V zbe&URNmBsuAMyX3gT!ZrrgJ{rr%)xE&G%IL6+NfR)IaT-z7j+#dry{beF>|A6b_0* zbURKO`EbgH{b8h=vFu+R+7SQSjXqe3G!T+tPrh0e@$OS$qts#X zYk!R!U1Gv1SB8H1mvtUtrTO@^fWhvYqk5ZIRRk>K4H8j5s?C3> zVtmx`oq4p%jmb6LZ|+xw_Bt+J^d~Ou?pB;fN{4aoGgDI)k4Vh)I(&N%v+rOt8baok zdV(b%nJNjOnydTu4;S@RtFMM#(&J$!9eZyhyBLd0$G<4WPm~>FKCMu1x?_pYJ@zE0 z@h)e+=*7oNzlee>%I?DwM2QdVJ~{P2>ZB)0VK~-ir`WeNt1WY$*n}83aoiIN!Amsg^Ui`=@I8y$ zV96BWl+$_%rdGl0uPpT9Qt@R03bD1(y%Qt}PVU?eJD1ezn7>ByynQVs_$+)xrXt|x z$L_BqJ_-!#t*A(Oz4@`DQrKHLi!PZdV>`2}ke8fbC~5RBV~EgoGsOe|3;=B4J@jm1 zrERS(Oz*V@?6{pkS2B3DL18t420=r#{e%6?f)4-bz$O9<>~J{W=+LwBq1oc7Bki}S zPi99-pQjp}X@&_+_C*oKU41@zxrZ)}Bw|nQ_UVR>wNHKURnidIl+KBTZPl4xzmu59 zTs|t!$4-{r<1gEKCX0XyTa$?Fa|sS&go9h*l3V$F{DfI|}B;Q&EStDqZlRc7}O zH~byC9B*m7mGXY5qpbmvz4|pc($cut#(h?+<|Bk{J2cY} z_gowt_p=_RVzL<@%lT#Ji=o&tPw|`@`I?-7*dHx9Ya#KUn|r9bPTKGDrUceC?2Iv| zovT}Hti@gR4_Alk>{maQbB4Z}(7~S!fHRh_ zzs|zo!r!TRZgg9+YT`Fu^1B5UnLrSm(5r6A=b#|B=lgqK^Vhuqk%QW zR+ZKjl>4GI>)XmHNWbkv!L~wj#~> zF;rRUJBvjRbaMf!p5bQ0sxmpy$C zt#~SX{nVo9bK~R%u7+5>sI(Jq73d~_1TGeqtkpJn`}`IHBoKVt>dBYS?{etXjPir`#4znZ(YG~OKO ztC+i;Er)7^4lc^l>~lf zzTaymYeAzniKQNuSeNK1xN_^=1q?GVgO>wyppe6=pUg9fgHW~A?bybPD*GvUjUS}@jZL9pp$%iwQ`1Y`GtAm^& zPp1#`As@z$15}|M&~~ZGU0AAE!vTKesno_z75q1C3ke;2l3)O zht`F~|ERHwqKf0Mg*0@f5`$}@n1ICxNv4W|I8EIN_ak#~X4Ox2S4Sp$DO%e!y{-q+VBA4T58nPKtxjI90$tC@~B=)yyvJE_jcMH7t#SJ>=#QTHm+wrs zJS8D(tkv(T*5wuYwt57s6V-jsRYl3xk+?IfCTneK2aNAU3=N5onm-twQS-l{$fol@ zOg7%0ONNDhJG=5mIq)rnHPb?&c+xd7mH6&f{Jrxa+bNL=q5b>~r3sGm1#{6Ar3s0x zNRVyoQiGQj>mBV);XyKZ5%N1bX!64QpoxXj*Y%Ht+mLger4WFo3^ee> zBmVT**Y9e^kH8CWFOpL6uQG=J1riZF(f$$twhr|O7jLd925(WvQjL|?CO$np9fG)Y<12Z$D4FjXpE{9-X PX~f{^>gTe~DWM4f@<$XU literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/remove_shape/expected.png b/test/fixtures/annotations/remove_shape/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..04f8682f8806e2d9a513e366fb46fb1b2336a583 GIT binary patch literal 1238 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=Aw2JY5_^ zDj45hFa#+)wBW1%+iZ>whr|O7jLd925(WvQjL|?CO$np9fG)Y<12Z$D4FjXpE{9-X PX~f{^>gTe~DWM4f@<$XU literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/style_sourced_shape_annotation/expected.png b/test/fixtures/annotations/style_sourced_shape_annotation/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..09f48081a8088406f3a482b6fea2238fcdda653b GIT binary patch literal 1538 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=FJ$JY5_^ zDj45hIhcFcLB#oBsg;lWD-G3Cs}$VrndF$QCeQ1CYFWp^A)w&Uz`)2ff*3`O;rARG zLmt>YH`f(tx95MLzfNJEgYpNPf3JVO)BnHDtzP+S`rPSsbKr#H6@>r}i3X=wwMIckW`iOQ(^2gs zCg}Eb1zopr08#EN#{d8T literal 0 HcmV?d00001 diff --git a/test/fixtures/annotations/switch_style/expected.png b/test/fixtures/annotations/switch_style/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..33299a2d6a40691a58defbf7013ef9a16647ec0f GIT binary patch literal 4273 zcmeHLS6CCs7EVG$KtUAHD=Y}8p)Cl~L>2>xMubQw(phN=QUoayNI*eB1r;{*y3$Jm z(n~^I6$Qj71cQVm6hR1tP!mcBH|~ACkN4p|?8}*%?>lGC`Oo?1%zTq-dkrQoCMyO2 z0K_e?Sl9yqK*1CU5D^v(?%`GbKUWdh2`pyQ0hP zqQ)~=LoLaK&!7V!=b*#2Blb!5w=JLMiCoq`qO1eC;b<-dtb3t&*-~3cQu?&%!PWg| zDiR&3m8TL+qp(R=pE6V zbe&URNmBsuAMyX3gT!ZrrgJ{rr%)xE&G%IL6+NfR)IaT-z7j+#dry{beF>|A6b_0* zbURKO`EbgH{b8h=vFu+R+7SQSjXqe3G!T+tPrh0e@$OS$qts#X zYk!R!U1Gv1SB8H1mvtUtrTO@^fWhvYqk5ZIRRk>K4H8j5s?C3> zVtmx`oq4p%jmb6LZ|+xw_Bt+J^d~Ou?pB;fN{4aoGgDI)k4Vh)I(&N%v+rOt8baok zdV(b%nJNjOnydTu4;S@RtFMM#(&J$!9eZyhyBLd0$G<4WPm~>FKCMu1x?_pYJ@zE0 z@h)e+=*7oNzlee>%I?DwM2QdVJ~{P2>ZB)0VK~-ir`WeNt1WY$*n}83aoiIN!Amsg^Ui`=@I8y$ zV96BWl+$_%rdGl0uPpT9Qt@R03bD1(y%Qt}PVU?eJD1ezn7>ByynQVs_$+)xrXt|x z$L_BqJ_-!#t*A(Oz4@`DQrKHLi!PZdV>`2}ke8fbC~5RBV~EgoGsOe|3;=B4J@jm1 zrERS(Oz*V@?6{pkS2B3DL18t420=r#{e%6?f)4-bz$O9<>~J{W=+LwBq1oc7Bki}S zPi99-pQjp}X@&_+_C*oKU41@zxrZ)}Bw|nQ_UVR>wNHKURnidIl+KBTZPl4xzmu59 zTs|t!$4-{r<1gEKCX0XyTa$?Fa|sS&go9h*l3V$F{DfI|}B;Q&EStDqZlRc7}O zH~byC9B*m7mGXY5qpbmvz4|pc($cut#(h?+<|Bk{J2cY} z_gowt_p=_RVzL<@%lT#Ji=o&tPw|`@`I?-7*dHx9Ya#KUn|r9bPTKGDrUceC?2Iv| zovT}Hti@gR4_Alk>{maQbB4Z}(7~S!fHRh_ zzs|zo!r!TRZgg9+YT`Fu^1B5UnLrSm(5r6A=b#|B=lgqK^Vhuqk%QW zR+ZKjl>4GI>)XmHNWbkv!L~wj#~> zF;rRUJBvjRbaMf!p5bQ0sxmpy$C zt#~SX{nVo9bK~R%u7+5>sI(Jq73d~_1TGeqtkpJn`}`IHBoKVt>dBYS?{etXjPir`#4znZ(YG~OKO ztC+i;Er)7^4lc^l>~lf zzTaymYeAzniKQNuSeNK1xN_^=1q?GVgO>wyppe6=pUg9fgHW~A?bybPD*GvUjUS}@jZL9pp$%iwQ`1Y`GtAm^& zPp1#`As@z$15}|M&~~ZGU0AAE!vTKesno_z75q1C3ke;2l3)O zht`F~|ERHwqKf0Mg*0@f5`$}@n1ICxNv4W|I8EIN_ak#~X4Ox2S4Sp$DO%e!y{-q+VBA4T58nPKtxjI90$tC@~B=)yyvJE_jcMH7t#SJ>=#QTHm+wrs zJS8D(tkv(T*5wuYwt57s6V-jsRYl3xk+?IfCTneK2aNAU3=N5onm-twQS-l{$fol@ zOg7%0ONNDhJG=5mIq)rnHPb?&c+xd7mH6&f{Jrxa+bNL=q5b>~r3sGm1#{6Ar3s0x zNRVyoQiGQj>mBV);XyKZ5%N1bX!64QpoxXj*Y%Ht+mLger4WFo3^ee> zBmVT**Y9e^kH8CWFOpL6uQG=J1riZF(f$$t +#include +#include + +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" @@ -81,5 +85,61 @@ uint64_t crc64(const std::string& str) { return crc64(str.data(), str.size()); } +UnassociatedImage unpremultiply(const PremultipliedImage& src) { + UnassociatedImage dst { src.width, src.height }; + std::copy(src.data.get(), src.data.get() + src.size(), dst.data.get()); + + uint8_t* data = dst.data.get(); + for (size_t i = 0; i < dst.size(); i += 4) { + uint8_t& r = data[i + 0]; + uint8_t& g = data[i + 1]; + uint8_t& b = data[i + 2]; + uint8_t& a = data[i + 3]; + if (a) { + r = (255 * r + (a / 2)) / a; + g = (255 * g + (a / 2)) / a; + b = (255 * b + (a / 2)) / a; + } + } + + return std::move(dst); +} + +void checkImage(const std::string& base, + const UnassociatedImage& actual, + double imageThreshold, + double pixelThreshold) { + // TODO: the pixels produced by Map::renderStill are probably actually premultiplied, + // but Map::renderStill produces an UnassociatedImage. This probably should be fixed; + // here we just hack around it by copying the pixels to a PremultipliedImage (and + // un-premultiplying them when updating expected.png, since encodePNG wants + // un-premultiplied pixels). + PremultipliedImage actualActual { actual.width, actual.height }; + std::copy(actual.data.get(), actual.data.get() + actual.size(), actualActual.data.get()); + + if (getenv("UPDATE")) { + util::write_file(base + "/expected.png", encodePNG(unpremultiply(actualActual))); + return; + } + + PremultipliedImage expected = decodeImage(util::read_file(base + "/expected.png")); + UnassociatedImage diff { expected.width, expected.height }; + + ASSERT_EQ(expected.width, actual.width); + ASSERT_EQ(expected.height, actual.height); + + double pixels = mapbox::pixelmatch(actual.data.get(), + expected.data.get(), + expected.width, + expected.height, + diff.data.get(), + pixelThreshold); + + EXPECT_LE(pixels / (expected.width * expected.height), imageThreshold); + + util::write_file(base + "/actual.png", encodePNG(actual)); + util::write_file(base + "/diff.png", encodePNG(diff)); +} + } } diff --git a/test/fixtures/util.hpp b/test/fixtures/util.hpp index fbee03c2d..b369979e9 100644 --- a/test/fixtures/util.hpp +++ b/test/fixtures/util.hpp @@ -1,6 +1,10 @@ #ifndef MBGL_TEST_UTIL #define MBGL_TEST_UTIL +#include + +#include + #include #define SCOPED_TEST(name) \ @@ -20,6 +24,11 @@ void stopServer(pid_t pid); uint64_t crc64(const char*, size_t); uint64_t crc64(const std::string&); +void checkImage(const std::string& base, + const UnassociatedImage& actual, + double imageThreshold = 0, + double pixelThreshold = 0); + } } diff --git a/test/output/.gitkeep b/test/output/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/test.gypi b/test/test.gypi index 9530d5d49..c96b4f686 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -110,6 +110,7 @@ '<@(geojsonvt_cflags)', '<@(variant_cflags)', '<@(rapidjson_cflags)', + '<@(pixelmatch_cflags)', ], 'ldflags': [ '<@(gtest_ldflags)',