From fffb0f7df5e1a5b1ce1f75ecc466820328f86f4c Mon Sep 17 00:00:00 2001 From: samanpwbb Date: Wed, 4 Mar 2015 15:15:33 -0500 Subject: [PATCH 01/12] fix example blah real test Still not writing tests correctly --- README.md | 3 +- package.json | 4 +- test/fixtures/style-gz.json | 26 +++++++ test/fixtures/tiles-gz.tilejson | 13 ++++ test/fixtures/tiles/0-0-0.vector.pbf.gz | Bin 0 -> 7638 bytes test/js/map.test.js | 1 + test/map-gz.test.js | 96 ++++++++++++++++++++++++ 7 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/style-gz.json create mode 100644 test/fixtures/tiles-gz.tilejson create mode 100644 test/fixtures/tiles/0-0-0.vector.pbf.gz create mode 100644 test/map-gz.test.js diff --git a/README.md b/README.md index 618f99f57..4aa9d42b9 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,8 @@ var fileSource = new mbgl.FileSource(); fileSource.request = function(req) { request({ url: req.url, - encoding: null + encoding: null, + gzip: true }, function (err, res, body) { if (req.canceled) { return; diff --git a/package.json b/package.json index 0998cc15f..1e99cdc64 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,10 @@ "aws-sdk": "^2.1.9", "mapbox-gl-test-suite": "git://github.com/mapbox/mapbox-gl-test-suite#master", "mkdirp": "^0.5.0", + "request": "^2.53.0", "tap-spec": "^2.2.1", - "tape": "^3.5.0" + "tape": "^3.5.0", + "st": "^0.5.3" }, "scripts": { "install": "node-pre-gyp install || make", diff --git a/test/fixtures/style-gz.json b/test/fixtures/style-gz.json new file mode 100644 index 000000000..c47715490 --- /dev/null +++ b/test/fixtures/style-gz.json @@ -0,0 +1,26 @@ +{ + "version": 7, + "name": "Empty", + "sources": { + "mapbox": { + "type": "vector", + "url": "./fixtures/tiles-gz.tilejson", + "maxzoom": 15 + } + }, + "layers": [{ + "id": "background", + "type": "background", + "paint": { + "background-color": "aqua" + } + }, { + "id": "water", + "type": "fill", + "source": "mapbox", + "source-layer": "water", + "paint": { + "fill-color": "red" + } + }] +} diff --git a/test/fixtures/tiles-gz.tilejson b/test/fixtures/tiles-gz.tilejson new file mode 100644 index 000000000..55dd96d6c --- /dev/null +++ b/test/fixtures/tiles-gz.tilejson @@ -0,0 +1,13 @@ +{ + "bounds": [ -180, -85.0511, 180, 85.0511 ], + "center": [ 0, 0, 0 ], + "format": "pbf", + "id": "mapbox.mapbox-streets-v6-dev", + "maskLevel": 8, + "maxzoom": 15, + "minzoom": 0, + "name": "Mapbox Streets V6", + "scheme": "xyz", + "tilejson": "2.0.0", + "tiles": [ "./fixtures/tiles/{z}-{x}-{y}.vector.pbf.gz" ] +} diff --git a/test/fixtures/tiles/0-0-0.vector.pbf.gz b/test/fixtures/tiles/0-0-0.vector.pbf.gz new file mode 100644 index 0000000000000000000000000000000000000000..711659c101a8a0aa1d5e1d20bb8fa6daf5ca369a GIT binary patch literal 7638 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 Date: Sat, 7 Mar 2015 18:04:09 -0500 Subject: [PATCH 02/12] add working tests for gzip handling --- Makefile | 2 +- README.md | 37 ++++++++++++------------ test/fixtures/style-gz.json | 26 ----------------- test/fixtures/tiles-gz.tilejson | 13 --------- test/fixtures/tiles/0-0-0.vector.pbf.gz | Bin 7638 -> 0 bytes test/{map-gz.test.js => gz.test.js} | 35 +++++++++------------- 6 files changed, 33 insertions(+), 80 deletions(-) delete mode 100644 test/fixtures/style-gz.json delete mode 100644 test/fixtures/tiles-gz.tilejson delete mode 100644 test/fixtures/tiles/0-0-0.vector.pbf.gz rename test/{map-gz.test.js => gz.test.js} (68%) diff --git a/Makefile b/Makefile index 52ce7db88..b2029c442 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ $(MBGL)/config/%.gypi: $(MBGL) $(MBGL)/configure .PHONY: test-suite test-suite: - -@(`npm bin`/tape test/render.test.js | `npm bin`/tap-spec) + -@(`npm bin`/tape test/*.test.js | `npm bin`/tap-spec) .PHONY: test-js test-js: diff --git a/README.md b/README.md index 4aa9d42b9..ede241bc3 100644 --- a/README.md +++ b/README.md @@ -41,27 +41,11 @@ The first argument passed to `map.render` is an options object, all keys are opt longitude: {longitude}, // number (coordinate), defaults to 0 bearing: {bearing}, // number (in degrees, counter-clockwise from north), defaults to 0 ratio: {ratio} // number (scale factor), defaults to 1.0, - classes: {classes} // array of strings, optional * + classes: {classes} // array of strings, optional } ``` -* More about classes: https://github.com/mapbox/mapbox-gl-js/blob/master/API.md#working-with-style-classes - -## Mapbox API Access tokens - -To use styles that rely on Mapbox vector tiles, you must register a [API access token](https://www.mapbox.com/developers/api/#access-tokens) on the map. Use the `setAccessToken` method before load: - -```js -var map = mbgl.Map(fileSource); -var style = mapboxStyle; // includes a datasource with a reference to something like `mapbox://mapbox.mapbox-streets-v6` -map.setAccessToken(process.env.MAPBOX_ACCESS_TOKEN); -map.load(style); -map.render({}, function(err, image) { - if (err) throw err; - fs.writeFileSync('image.png', image); -}); - -``` +_More about classes: https://github.com/mapbox/mapbox-gl-js/blob/master/API.md#working-with-style-classes_ ## Testing @@ -170,3 +154,20 @@ fileSource.cancel = function(req) { ``` Note that in reality, Mapbox GL uses two types of protocols: `asset://` for files that should be loaded from some local static system, and `http://` (and `https://`), which should be loaded from the internet. However, stylesheets are free to use other protocols too, if your implementation of FileSource supports these; e.g. you could use `s3://` to indicate that files are supposed to be loaded from S3. + +## Mapbox API Access tokens + +To use styles that rely on Mapbox vector tiles, you must register a [API access token](https://www.mapbox.com/developers/api/#access-tokens) on the map. Use the `setAccessToken` method before load: + +```js +var map = mbgl.Map(fileSource); +var style = mapboxStyle; // includes a datasource with a reference to something like `mapbox://mapbox.mapbox-streets-v6` +map.setAccessToken(process.env.MAPBOX_ACCESS_TOKEN); +map.load(style); +map.render({}, function(err, image) { + if (err) throw err; + fs.writeFileSync('image.png', image); +}); + +``` + diff --git a/test/fixtures/style-gz.json b/test/fixtures/style-gz.json deleted file mode 100644 index c47715490..000000000 --- a/test/fixtures/style-gz.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": 7, - "name": "Empty", - "sources": { - "mapbox": { - "type": "vector", - "url": "./fixtures/tiles-gz.tilejson", - "maxzoom": 15 - } - }, - "layers": [{ - "id": "background", - "type": "background", - "paint": { - "background-color": "aqua" - } - }, { - "id": "water", - "type": "fill", - "source": "mapbox", - "source-layer": "water", - "paint": { - "fill-color": "red" - } - }] -} diff --git a/test/fixtures/tiles-gz.tilejson b/test/fixtures/tiles-gz.tilejson deleted file mode 100644 index 55dd96d6c..000000000 --- a/test/fixtures/tiles-gz.tilejson +++ /dev/null @@ -1,13 +0,0 @@ -{ - "bounds": [ -180, -85.0511, 180, 85.0511 ], - "center": [ 0, 0, 0 ], - "format": "pbf", - "id": "mapbox.mapbox-streets-v6-dev", - "maskLevel": 8, - "maxzoom": 15, - "minzoom": 0, - "name": "Mapbox Streets V6", - "scheme": "xyz", - "tilejson": "2.0.0", - "tiles": [ "./fixtures/tiles/{z}-{x}-{y}.vector.pbf.gz" ] -} diff --git a/test/fixtures/tiles/0-0-0.vector.pbf.gz b/test/fixtures/tiles/0-0-0.vector.pbf.gz deleted file mode 100644 index 711659c101a8a0aa1d5e1d20bb8fa6daf5ca369a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7638 zcmV;{9Vy};iwFqYKJ8Qh128QxEif*2Wn*-2axQRUW&nkG39wy9dFJV}?|t^A&vMT> z_uPHIZ{PP#(({v^q$kO;Ey?n;k*&p+YzPM96$8d#Y%mPqkN{=^#AXSEt*8l!fl8SK zCJZ4A!=wT;$qW=*d8P2VcxLQRf!l&PH4uD~tm!^+ z(3f0?D;15fm=3T{f?0mX%?4sZX=M~N+r?Z|&mtd|09s#L5;#MNiezK%sGT;3oTG4J z?I&RFEE|nZwF+oXIE7ZCsB(7x(vaOEs=dIEeUr9&rl#n6?}l6Cm2}LJjS1sP@IFwW zw7{>}Y=hCqeg^chf?<}Tny^3QyG2uPwsgvS3@k^R!cfs8+=Y^zG`K>2e^oan?`-WB zUiUloTZHSKI~r8}EI=EhO8+gOKl2c%R2r(WH8+gf?+34}UH7VBA--qo+?&83fqTf% zRYt!7dfx!3DBmLtR8rL()S{p%$hC}<%qPK(bl6IWOlQcdt5Y$exbqE}ZXogNzlZs0qvYa4eID(X_h-uw`7iq$3BEN>_i^?)Jcp{9}7WU_vu zRw(-gY3st)2g%l+1D_;I#7{`?)Si0^MdD|L+*>`oS!t{0Z7qM;NPH;VH~Tn+g263+ z41Xb>0pBbh8=DbleDcVE&lMwQ!W{9K_Q2y{PT4ThN}w5TMG2KkVgI1mkz*&FAjhdU zfQsn!yo?AOEpG@QA1Jw~(WxBoOwk3(8R!hol>CzHr>@K`?uU^s`fE~4BVxFucrYlC zLKqUaR9nrz0)GLlMxls8F_<}a3vz1vVL$4WW@fqZ9_wJtm#VTq10*K~mvX-uaF(d& zzMWT#WL$k0K>XJDV1+)^Bg-AIJZtka1^$?6)BVP1I4a$6T%(q&S_cYi5o@aKN2l%Xpg1BtYH6xowS z+E4SwN+Ha-hd`?`G{}rj6&NpZBs5iG7h1j{q_ro&^mv0AxN`E4LfIbaD!Sw9P_@&X zwd_{GkNH+oso$17hASgHub2_xAZdS@>v9>!GO>B63J##;CoK2E6_q>gO{3! zOEsl!F_k3d=Em!~kPXmOo+?Of(2ghRMYXDx08t)irbMF~yR~{u_<0!TV069zB`_bL zZJn9#HEQ(HeN)}L#tk+*aU47V$|8jx0FAu-Zjd-zQ;Kk22WnKAlwpIr9vMz6Em>(T zAG3Yv`5bvo(sl(lHrG66t>(0I&C`F6?4Cr!Ue$X5qQ*5s^ znv#`ycCzslco>M&sKC|A;+w%eTJIg;wOqY9+on5g(v%w>T`X9fUP@HPO_;K%7_&jN zuyv*DxL%S>7knB9JaU6Oi>YNfEp+i3K3VtfNZ${pouWpqI<)J3#ah&ZzX~CWL)xYT%f(arP^qI;ypV@+ZK(>lwKjvPnrb;v1x! z>Q!`PG4oFzJE2{F=K(Ug@uW1hb~Nlwn_8KO9tFkK2~eColnOC4U4xuDc5tDg6rFVJ zh7mZwT12v5Z;If?X_p;p?C+=T{joKio_{xp9|WLQs*J>9WIJS9l%58k0#5)!bEiF9 zJFeJ;(fvnEW_Gnl)MC!udM|hcm~HI`puAD0K&9`3ftUg_1*v)hiCIL%{bD`-ZBp7t zqr(mW|F6PjHwIe5OQq|!4JiC(=JlXHuJ_zZPFtY@g}*WWsfai)CNVFCr@%ePnoGN? z0R`uWG|~yAaS#e4BI;UFR1~4`M({Zbg#rgn1cmp3Vx~Z-iH4;^!RsJSO&FJh!hhEP z$UsDFDJEY1D`gltL`On06n+T+QiUSnU{!w#Kz&$TbuUCllHzyYNm^Ny*Ev2g2`Kz! zS{P3(McWkK4pz=4%jPv16h4ZIC=P~b&x697(e;SXps!(7j}(t1E%XjmhN19x#*-A9 zQ>PQU1%>7z*FBe*|v5 z*%ouJbr6(aBaM~3=yYTVI_xfxy*3m+ucwID@~ELg;n%v8)k0P420I5`IhZ9CH%K)! z2!)@6zauvb2Ag{V^k<#%mJqq}P!H~d!bkEm8Dbg)Ff9z?KLU8S<}=Y^4x>oJes326$YRz-F;$8CSkd?8 z_kzsPDGNjpulR~!BTctC78{$|NY3;z7UTaVpGRGeEev7veki@e&15AI^d!UXA5u|P zNCAO8_K>i~+?k_pjtJdA-U4|IHvHsz24ze2 z3IPj+e^>c?vd&Mq#)z9-TXnIgn71=XFikbaZ_j>*nm5WpGx5mwfh%KR|A}lA3V-N6 zNbQr4EED7Z3=GQOC@inXLPDr5`Bu+QSRu)9g#1R;;rJcN6-saH|C0CeSbz% zqMIZwxS&M`q3~5Ohm25KV(M7;pOE`{wtBWgnbTIktpPnxD9o9EOC}9L6)`s7O*~}C zY|X_x#uDOvy)I$_JwmQPWF9_zRYIO4qzaCe|3*Dc&a-YnT)H&GJpuk2+%U<{P4sYl zlJ|pa5B0gY1;U$Ot2NKYOl6{787q~#P)Y$i%|kgdob?{Y0&s?-_X&vCSIV@N$7 zrZpTHKW9HoA*csd6LaAJhkER)V)IaVo`nc9xo2XienX0X28Qi@^Q+`aNv~PL{;?;) zz)anrm?FI_ry8o0I05P0P*%%s_z;jIe3TDU22xc$qA@2w&(g>aw^}ne)jYxcn0kZ~ z&JC>j1RNMk&67nbIM#X^Tp2)zN5oDbmm8cp9|@8pU=|n4vQ?mnTq)EJobgur>b1Jg zhftb)CxElL^E`QGIjk<%7wiLJfvCnJ8ec?7l$8&5uK6$cM9*>e)AddH@X!Uxv>pPO zqu;3fFE5Ld)C_H9Y>dsah5{lto?yfUHVk8qK|?l?J8=fnP|ezY zQ}&%Eb0YD&3E|6DSQSazuoT=dK4AR=_$XkSLdg_^8Z%mALfJG_Z&3;iRV(14vrnt~ z*~UW2O@sjkXP39J6!No>1V!9eLuB={!Vo^~MiU9C?u3~4j|1vfPhveof#$wWK~jU7 zr&>K^u|<`&pzw9_Ox97!;T(u_ILDLKam{xe$}MocJhluIr(33m1j8c~toR?vSL~aV zs1b)5Iy%-CHUo7q->GDead%~-O-)+pQJ9`z0^O|ZQ@xR48T&k)LaFA7A}*I_EfmrN z!A>!Hh^-)#R}B_Vznc~6ifpl&89`yElDa6NOKM3v6_Bi=c^9#J{-@l1P!*Ngl(ihna3WpumNg zrGJh?tDUAm!m<1@^{vkHK56)pHEtW&RtPPv>Inc}YKXAU*>PyGjY;S>j$EoubxUYM z;|ew?&JxtjMa3Fg92!5TG3nsGQ{=`cz~TBW^s6>E_!%kK9$FV72Q)_Xil-LFNK{GZ z{t)zTJBEZe0k%_Njhaf-iH)Q6Xm+5qCKm^^V-Etmdp}rX)5SS{RDsg*>!j*hiMeBnxo4vz zO6x^|ScsProwKVHVXvnLL$y?=(ZqVX9A_=lUbccxT+M8&R+xzyvd{_~ZcTAUr|z^b zxVAm(FL~UAqE!rj;oi;>&$C%Rn@yss0X1u&%y%P&(F|+{Zw^uUcv@qfquR-16ZKVl zXwW(`cc$j-=LkQR+^9obm>5Z@F?)RMkP*5hRaVSEH0wmMH+U%k|@>cp9QB% z;w`0`8bDs}(Mn*4vTK{KIZ!z`CM((MzAj57uAApmq7oe)tXgz=nc|JM$xTmqAT$Fy zF2+v1O1HE&?Tea`1@e*1O>j%gTA@%ne%ry@Td#bzErkQuj0l>ijnK?8Zd`G@z*HQY zvf6@fG)XzU6)@iFI9rO#%*gnb$&pUC3K6pDVXFnos_8bvvgWe$v8_+%Mk0{8BT&dA z<$aK4iw#a)MYK;bUj*@dOzB2_^P2kV-K6Cbue%c2s^$VKawPil!*z4E`<{Wsnn)N0YcSc~6tOn}DZ$+pA>#G_+WsuqTt7`#b3nRImY;C?S&ccggg3u)8mUr1skk`3liJQi zuT5+I3O>^xu*hoj0WKiI{iJ{r!Zal;{|md-rw;TLE-$a7r5eWMBkp1y7DIo-GRFJ3 zg1v+MIldQ@9Zlu7eVqvd7pi%Gq~%Np97NX&jYLj%+RZ1y;}{PVb0xgRH%T4ow2Ek) zJAY|>pZq8(m`Z58vT{k8Rf;~yibb0A6x+?zQOy*aE>qsBnrekea+^#xs$x8;Om*XG zLitu0_x~157AK0zl#=kR2!r%2{2BElu|UvOrPh7g)h*&r6O!H)75V)B9#B zwS>)bmGPz;hv(S@1%_-^NBvf8$pJ5hx7W<MJjdYG%#STJMrLcoNIK35$a8X}Vv8 z+GsL`^=o!TBXLuP4g9CtJ(-QRf%Q1-qBzsL(P$Vn1RNOZFLv`u} z;E-Zbqm^vlT<^EN&5>DBUh_?+O1ZWSw@ck@bBOY%iolFqCzgwp6gJ6`urEyHgV>O- z((Ath1=+I;<}f*6dO*@~_U^4v+3KK@Jq0Wi#ZH0D7a^-*HyB2-S{^P^y+&aSOw<*3 zga;)k{K$U_yZ|)W7oxb#N8zMM6dl?%k<3*LOE!hblDq4F434r(DcPGm%mSxpxZQ>Z z62wQWCY!h+dbaXBi&8eWXneF6)Y~#vFOWhx#}HkK zTi}iTH&Shr7{8aizQI%N{asUk$B87pcW9j^V#V*UY_pgK7Ta#hHLa{RfZRTIvLVN4Ovvl_V(;AQ zsC6=IEm6bL*iovzRaK`LaQcqNL8NBaRk&n&Zo^*`?hRDlQOt!{(e~XrajL~zuQSzJ zN1U|>qSa2GwQ<*K1%}bC&G%R?KAgaMy%`G72szVoWYy-4zCh%2U|KsW`8X^sn?Y^9 zguJ+GCqffRC0tC>8jPHnj+~rNs|PA8 z{W@3lGFqrRlG)B84yzTBue+!WQrv#v9Y~Y*XwK0jB}^=wnMs}ZNX{E~sdA#gtV{SV zu8qD&ih(_lP*lOg3E)EJdby2?v=@ z#nm#`q{Bd*B%x;T1N=0Kl54Hg15U9tqQMqt;)OqzJ_s_$j$GKpb_pLsg}UxFok4SI z4pwmjV!lYez*D7SKxj(ORaHB{oaP!?BI{h3xqjYk6C;+vMILLy+|*suBX!&nM@2`| zUB)A&0E)6%@aRC$2s`DFFy)rXpg1V*w-+V5(rCw}n%C{QO5hklX`CXe8Q7vR69hFOsV#UbAn&Q=4BV-sDV#~BpDOx|2HQEfIxlb5?Y#VXsg2 z8e9-N)e}G&JxGJVi*c4~C!)3b`exCdQ$w3`46-$(T&mxK& zBl?3NEv2IT%Feb)IORZfNvl}1OF2DrVqRE2POoKZc$^uJ-vl(HzE2~Xr{QRCwVmL) z_Y)W(k;j-4xITavtpCr?R7<}GyT3)9x}7*MJb?MI@D<$CFbn=(=KJ%`e`jz7?Tjyh zvx*?yQwA15Q81$?h3+-FltRabvJ$cv&Dq8%!4JH@er?Pfwr6{j5Ez>URL&^IfIrw-~)aLB^>`g7!??DJsgmaVl>g3jwsDKw%1 ziV7oobdVl2Qj|3SWhIs?Iw~rX?pfub!T$tX~f1tEG5bW+C?+qfiI{;wN6ooGa^4@of*d25l;jI~no$W|_ z^31N0=~WxuT@&XCz(Y&G`_hnvAaI~@@~X%oTqi$fzXzWJXaYtDN{|t-7-TRi0u54{h9gRq!t1nbH%+tpvc>0aepPTEoSZ=d_()nHZguprGw-Ozv4j@q5hdC?A^Hm z5dez#(Fm?8)P?6ue^aOv1SXBlLREss@YR=1;REI8v%9gG425mnp~TLo#uM0i47QKd zcohoL(C+ys=$?b#+jlcLU=|2sGhsqyFZpC_J z945jJV_3KoM4GCRkf$6>4R;UQJ)}GF92X5X zNm#bEr!3mr*4bURes$e~@QL!%#x6fN9>=nT(crM>FiA9xz>snVDPr&Qny4u_-N9W4 z2*QiR1ix=v`Gq~(Uheqsn7_>GIJ@C3G!^HO-+B4v(NCA^fPfUGYk>8j(Z2dJ7ao=G z^LFBlWT3O-|2>b;)XUH_Rin4- zx6d18{?|W#3{+KCv71`J?nj^PP`^+3i5Kk(iuVYxRy`oovxIFhG0EF!St z%jBM!{^~fEd)rHL(#z!Jm&=i#p1^X?{N(*F$tk2tL0VxHR@;@+cjew={EEeL@BQt* z25C|TZ7>#Vzf9j3{C^om!ud;Q&z!$}=HhLLzIf)sHsW?ZPu=v=!}i6O9`Ryy% fs.statSync('test/results/image-gz-fail.png')['size'], 'render is smaller than unpacked render'); server.close(t.end); }); }); From 7864dca80ad3e3522dfbd663b3d9a35cb431c244 Mon Sep 17 00:00:00 2001 From: samanpwbb Date: Sat, 7 Mar 2015 18:30:39 -0500 Subject: [PATCH 03/12] remove unused --- test/js/map.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/js/map.test.js b/test/js/map.test.js index 63a9d3919..50bab644d 100644 --- a/test/js/map.test.js +++ b/test/js/map.test.js @@ -7,7 +7,6 @@ var mbgl = require('../..'); var fs = require('fs'); var path = require('path'); var mkdirp = require('mkdirp'); -var suitePath = path.dirname(require.resolve('mapbox-gl-test-suite/package.json')); mkdirp.sync('test/results'); From 71c724eaf394213d146459234b00e447af18e52c Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Mon, 9 Mar 2015 22:08:13 -0400 Subject: [PATCH 04/12] only fail on pbf request, check exact error --- test/{ => js}/gz.test.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) rename test/{ => js}/gz.test.js (80%) diff --git a/test/gz.test.js b/test/js/gz.test.js similarity index 80% rename from test/gz.test.js rename to test/js/gz.test.js index 299b61dfe..a38f505af 100644 --- a/test/gz.test.js +++ b/test/js/gz.test.js @@ -3,18 +3,18 @@ /* jshint node: true */ var test = require('tape'); -var mbgl = require('../'); +var mbgl = require('../..'); var fs = require('fs'); var path = require('path'); var mkdirp = require('mkdirp'); var http = require('http'); var request = require('request'); var st = require('st'); -var style = require('../test/fixtures/style.json'); +var style = require('../../test/fixtures/style.json'); mkdirp.sync('test/results'); -var server = http.createServer(st({path: __dirname})); +var server = http.createServer(st({path: __dirname + '/..'})); server.listen(2900); function setup(fileSource, callback) { @@ -25,10 +25,13 @@ function getFileSource(gzip, t) { var fileSource = new mbgl.FileSource(); fileSource.request = function(req) { + var parts = req.url.split('.'); + var filetype = parts[parts.length - 1]; + request({ url: 'http://localhost:2900' + path.join('/', req.url), encoding: null, - gzip: gzip, + gzip: filetype === 'pbf' ? gzip : true, headers: { 'Accept-Encoding': 'gzip' } @@ -52,7 +55,7 @@ test('before tests', function(t) { test('unpacked gzip', function(t) { mbgl.on('message', function(msg) { - t.error(msg, 'doesn\'t emit warning'); + t.error(msg); }); setup(getFileSource(true, t), function(map) { @@ -70,7 +73,10 @@ test('unpacked gzip', function(t) { test('unhandled gzip', function(t) { mbgl.on('message', function(msg) { - t.ok(msg, 'emits warning'); + t.ok(msg, 'emits error'); + t.equal(msg.class, 'ParseTile'); + t.equal(msg.severity, 'ERROR'); + t.equal(msg.text, 'Parsing [0/0/0] failed: pbf unknown field type exception'); }); setup(getFileSource(false, t), function(map) { From 0cf80f34b255c4ab2dbd895184f29c2121019ecc Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Tue, 10 Mar 2015 00:45:43 -0400 Subject: [PATCH 05/12] EventEmitter.once in unhandled gzip --- test/js/gz.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/js/gz.test.js b/test/js/gz.test.js index a38f505af..e6ca13a9b 100644 --- a/test/js/gz.test.js +++ b/test/js/gz.test.js @@ -72,7 +72,7 @@ test('unpacked gzip', function(t) { test('unhandled gzip', function(t) { - mbgl.on('message', function(msg) { + mbgl.once('message', function(msg) { t.ok(msg, 'emits error'); t.equal(msg.class, 'ParseTile'); t.equal(msg.severity, 'ERROR'); From 39694e5bf041e725009516573570d8d8f95ddfb7 Mon Sep 17 00:00:00 2001 From: samanpwbb Date: Tue, 10 Mar 2015 17:46:00 -0400 Subject: [PATCH 06/12] cleanup and add image comparisons to gz tests --- .gitignore | 3 +- test/js/gz.test.js | 115 +++++++++++++++++++++++++++--- test/results/gz-fail-expected.png | Bin 0 -> 5636 bytes 3 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 test/results/gz-fail-expected.png diff --git a/.gitignore b/.gitignore index cf1aea98a..80e156730 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /build /lib /node_modules -/test/results +/test/results/* +!/test/results/*-expected.png image.png diff --git a/test/js/gz.test.js b/test/js/gz.test.js index e6ca13a9b..228897edc 100644 --- a/test/js/gz.test.js +++ b/test/js/gz.test.js @@ -10,9 +10,11 @@ var mkdirp = require('mkdirp'); var http = require('http'); var request = require('request'); var st = require('st'); +var spawn = require('child_process').spawn; var style = require('../../test/fixtures/style.json'); +var dir = 'test/results'; -mkdirp.sync('test/results'); +mkdirp.sync(dir); var server = http.createServer(st({path: __dirname + '/..'})); server.listen(2900); @@ -61,10 +63,54 @@ test('unpacked gzip', function(t) { setup(getFileSource(true, t), function(map) { map.load(style); map.render({}, function(err, image) { - mbgl.compressPNG(image, function(err, data) { - fs.writeFileSync('test/results/image-gz-success.png', data); - mbgl.removeAllListeners('message'); - t.end(); + mbgl.compressPNG(image, function(err, image) { + t.error(err); + + var expected = path.join(dir, 'gz-success-expected.png'); + var actual = path.join(dir, 'gz-success-actual.png'); + var diff = path.join(dir, 'gz-success-diff.png'); + + if (process.env.UPDATE) { + fs.writeFile(expected, image, function(err) { + t.error(err); + mbgl.removeAllListeners('message'); + t.end(); + }); + } else { + fs.writeFile(actual, image, function(err) { + + var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff]); + var error = ''; + + compare.stderr.on('data', function(data) { + error += data.toString(); + }); + + compare.on('error', function(err) { + t.error(err); + }); + + compare.on('exit', function (code) { + // The compare program returns 2 on error otherwise 0 if the images are similar or 1 if they are dissimilar. + if (code === 2) { + writeResult(error.trim(), Infinity); + } else { + var match = error.match(/^\d+(?:\.\d+)?\s+\(([^\)]+)\)\s*$/); + var difference = match ? parseFloat(match[1]) : Infinity; + writeResult(match ? '' : error, difference); + } + }); + + compare.stdin.end(); + + function writeResult(error, difference) { + t.ok(difference <= 0.001, 'actual matches expected'); + mbgl.removeAllListeners('message'); + t.end(); + } + + }); + } }); }); }); @@ -72,22 +118,69 @@ test('unpacked gzip', function(t) { test('unhandled gzip', function(t) { - mbgl.once('message', function(msg) { + mbgl.on('message', function(msg) { t.ok(msg, 'emits error'); t.equal(msg.class, 'ParseTile'); t.equal(msg.severity, 'ERROR'); - t.equal(msg.text, 'Parsing [0/0/0] failed: pbf unknown field type exception'); + t.equal(msg.text.indexOf('failed: pbf unknown field type exception') !== -1, true); }); setup(getFileSource(false, t), function(map) { map.load(style); map.render({}, function(err, image) { - mbgl.compressPNG(image, function(err, data) { - fs.writeFileSync('test/results/image-gz-fail.png', data); - t.ok(fs.statSync('test/results/image-gz-success.png')['size'] > fs.statSync('test/results/image-gz-fail.png')['size'], 'render is smaller than unpacked render'); - server.close(t.end); + mbgl.compressPNG(image, function(err, image) { + t.error(err); + + var expected = path.join(dir, 'gz-fail-expected.png'); + var actual = path.join(dir, 'gz-fail-actual.png'); + var diff = path.join(dir, 'gz-fail-diff.png'); + + if (process.env.UPDATE) { + fs.writeFile(expected, image, function(err) { + t.error(err); + server.close(t.end); + }); + } else { + fs.writeFile(actual, image, function(err) { + + var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff]); + var error = ''; + + compare.stderr.on('data', function(data) { + error += data.toString(); + }); + + compare.on('error', function(err) { + t.error(err); + }); + + compare.on('exit', function (code) { + // The compare program returns 2 on error otherwise 0 if the images are similar or 1 if they are dissimilar. + if (code === 2) { + writeResult(error.trim(), Infinity); + } else { + var match = error.match(/^\d+(?:\.\d+)?\s+\(([^\)]+)\)\s*$/); + var difference = match ? parseFloat(match[1]) : Infinity; + writeResult(match ? '' : error, difference); + } + }); + + compare.stdin.end(); + + function writeResult(error, difference) { + t.ok(difference <= 0.001, 'actual matches expected'); + mbgl.removeAllListeners('message'); + server.close(t.end); + } + + }); + } }); }); }); }); + + + + diff --git a/test/results/gz-fail-expected.png b/test/results/gz-fail-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..ddb90d8b8fd296d0f46fff1bf364d55cec915dac GIT binary patch literal 5636 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn2Dage(c!@6@aFBup__j$TF zhEy=Vz2+#$puofIcwqnYLkW+!@ojpkTzya1y@7#|iG^bci=Woo4J;f23Jwhi#0?m1 zm_VWe99$9%2QRs*Ie=8LHOK>Hfec4RW`&4dC%~!?FnnMJGZZuu7+Ac;XM&BBV5ozb z%fiajknmDT7_5=`06)llhQ5bDIgmZ5*U7ftx^yWF<@v~+U*0@$irX{wu+^R ziOpd{$wW?&#s|hr<1RP-Cn5Jh0)@Z=+2W;o4V@E@FG|i4?u+h?Bw44FVdQ&MBb@0Qlf}hyVZp literal 0 HcmV?d00001 From b5f894298342003075d8c1f7e1406cab23d806c2 Mon Sep 17 00:00:00 2001 From: samanpwbb Date: Tue, 10 Mar 2015 19:51:59 -0400 Subject: [PATCH 07/12] cleanup tests --- .gitignore | 4 +- test/compare.js | 31 +++++++ test/expected/expected.png | Bin 0 -> 2381 bytes .../gz-fail-expected.png | Bin test/expected/gz-success.png | Bin 0 -> 41488 bytes test/js/gz.test.js | 86 ++++-------------- test/js/map.test.js | 4 +- test/render.test.js | 44 ++------- 8 files changed, 64 insertions(+), 105 deletions(-) create mode 100644 test/compare.js create mode 100644 test/expected/expected.png rename test/{results => expected}/gz-fail-expected.png (100%) create mode 100644 test/expected/gz-success.png diff --git a/.gitignore b/.gitignore index 80e156730..247901be6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /build /lib /node_modules -/test/results/* -!/test/results/*-expected.png +/test/actual/ +/test/results image.png diff --git a/test/compare.js b/test/compare.js new file mode 100644 index 000000000..1f9dc234e --- /dev/null +++ b/test/compare.js @@ -0,0 +1,31 @@ +var spawn = require('child_process').spawn; +var fs = require('fs'); + +function compare(actual, expected, diff, t, callback) { + var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff]); + var error = ''; + + compare.stderr.on('data', function(data) { + error += data.toString(); + }); + + compare.on('error', function(err) { + t.error(err); + }); + + compare.on('exit', function (code) { + // The compare program returns 2 on error otherwise 0 if the images are similar or 1 if they are dissimilar. + if (code === 2) { + callback(error.trim(), Infinity); + } else { + var match = error.match(/^\d+(?:\.\d+)?\s+\(([^\)]+)\)\s*$/); + var difference = match ? parseFloat(match[1]) : Infinity; + callback(match ? '' : error, difference); + } + }); + + compare.stdin.end(); + +} + +module.exports = compare; diff --git a/test/expected/expected.png b/test/expected/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..a18f56aff39b8b6a0ed02d4ff51c59b60984caf9 GIT binary patch literal 2381 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 z zpOHRz*j}#SwEj*^u;BzBF&+VUScTDSO^}w$S$&^pxaSIGZQLs;fSN9TjJ8joB1NKo z6wUsDsu3c4LiQEcz4#1sFEAc*@ojR$=_UyF` zz5Cnn(*BU$+FVlZmf_`iZ4>Np^5DRVNlE&dMfHE$dr~L?U9*|`_3PT;`RCs!Fhv`To46p}%!j?_u4~1b4FpMjW^hM~& zi!TO`H+Lu?|Ui z?2C>nbC)3lYltE|{&Ovcqi+aC+5N`4PsiHp@!XoK9H^64&$g?Qiaz(>HSGS;4m2}qfDAXUOXsiNY|~z4 zomaDT(jPBuU4&N+2KiG6l8#9uNr?SmXD?E-WVURr;$DjV+uu7K94lyR2i%Vku#yA= zF{r3#z=b{X?Ijj4J3ZR#37^?K7mbg@5Zl#glV#vPBap!8*ePdEh#=CYR^HC*J(vBP z2W?^-lL>ZHwoC9iZ-~X*uc7uI>N=xI*ojys4hUV>mhT^xNb_)r6%#Eaz%%}^> zSu5wtr}~ZQZrAO@y$pQyvMV`JFTVa2hXT$%r@O^Xdpnl_cfj!Bw((%($M@54j9;>T zMcF7pSAr5APiiEITKvDZp@UOr63PnD@r6I?$s(IXm#VtcGX2q{zFsCk4^L`GBgC>! z0Q++J9%;p~T1?**rCe_y8MK^s({z3+@ZfzY_V+I5I!3g~QR3UdlAUl^i6+3J)U{w( zmTo2P6aQQJdw5#bj);hS6O=ZP=x3Z`FZVOK#Q!v`qpl3*P3Y*Hx%<`g!ZZ|j=2BYR}|al6lPn*XOUAih7v>2vXPa(07Wno z$iFlF6{~EZF8sp#g6l+gYo_DR_ad15rsv$P#|?Kbb1n1k^DSzZ2-xMYTbjW?8of#xk`N(;^fhW`h4N^s6Ls> z7cArly3AW)gdO^vfiO+!a~|z=W*VHj$HJVEF+sNUIS9JG2=S5wxx~wv0;V#p`7+ML zl;&S-64jh7Bp~DQ+$<=EZNxS6Nu1NP+c<$cg}X$>YHK_S21|6idp1+$ZA#}&j^qGa zI#JitZb{3i#5)a{AOR;YwfCmydmr`{1PoF5vtu{Hju_V_F&ri`$ zhW?9l+Um;;U{%CuQnG7GKA63%girb43cWEUR(zxj5|EwJUY1=PE#pc3p8$Jusk1#nWgtXG@ozYbLP~n(JdMT1Te zz=`2Tcfxm*zY#TNqnWtgEut~TRe!t6jZ~?XgG_zkbW423mV2|Qi_7>6*d02D*;>p! zdJ!~?@oHifoG1B!;uy;pSAy6tRs7ZTC=xR=)-9u!r*)(CtM%@`eylaTtA?K_ENI#b z^L+vBU@G!V9)=L;Y1FGVSXb2lctRhVZqDs<0jv&IL@k$6HP|%71w|dj6!v74fkt6~ zV%p@bv|gx>cQ4A6-AK9Jmo&&XX(|~tbDmmHIoEzDt1l@r8{U^GZXHa+WQClKgeZok zm3t~B_Uz(wonoDU>LqRiv&0+j_>tW>G%3 zsShs)N?&PcGT(C*+RMG2wNyCBTN+W$p%_J=JJXivJIRBcD zgdU(*#|@~E3{t?L?|37-z zBh}&R@dC-Jp`Plr!)HQg_iM%B)Q9!@0y&4{;WFV?hG_F44U3WY#_{vaV{LEoR7~GHl^t+Yh`I^v8e=MSNG7b=1 zSfuQ2qR%z};Z~`un8nuLVlgBBy%T&gT)XjQ0(U`C0yz(fp)Zs40#nwF&f;5j~NRM$oC~NB_FOEF( zvOUoi?XP*zX{MAw0?=15-AWu_adGK?k=pt$$_pY4iZ3zaD4MMa-2;}OD!lL}caFFd-9P)XlR%B z2uE3*vdny|j9&e9?kMMIfD3NKRr7H&PNHzjW80G;vBc922Z_+a`i!lYcYDE?4T28# zmS^i4pn;|&<8l!kwI`6~<9+QBCm5H+Lgt%)@aGde%8t6SCiCmgVESs9OJ~HRRyA;4a z=)ZqjpR(@-b(=pPZLfo@hp{=2yUi#`x`{y7@v`Y7vdB)!_j1o|nv3>FQ#D`Vo_5)E zDO4+r?x$PbgcQ6p5}5C{CbG(&E2J^UTW*xcpZ7&uEJVRl$DZCv(X8H)aRi}*u`PFo z(Kadt?rRsD5l*^hSwINPMSuIo?brbpMs?5afmaRo$zd?XEJgFx@#or7bYMG)mC@Zn z&exfp4va^d)_c9#{8m@D_$7z5HI`uK;o3;{OWZmip zo37CY_aADcI*XY#AwA$zxO~p=7n9_82=ha9OtZ@Fc$Q_gJAN6hueb29)oVbW7wG*7 z+POR&FB)@0Ep%8i=SN7ZTmlM}ZG+^BRea1_;@21RO{6tNUu~ei18|( zSAG#Ng<5r->0t1!J71A0L&p=x={>hkv@`o_2fz z5WM$`G75qM}5X-SkrF z&k{P8HjkDse*SaI2MG#myAdXc{_%287x1-Q*ZZO=UiU3ylWd+}2lsvyZlJQt)Q`zS zz=)YD{yUfw2Dh_t9~C}Ut?@-~zyr7|%bCKBM}g5SjdStcREOsMM3JZp-Ejjlspu?7if65?6AI zmNgqrJWI5$({f$IRMK4VwcK)9p8XMF`K?^vG#y4?f{^<_GTUDn?9$*6jVdmmCMW;C zU2K}Tqe^t+Ox!#!+k}i$(C**269^^zY@SCwe!G?U^IZP=A`n7#p3UOyu$Q=N97c&K zwwBSDdI%H=Eh=doJE1_U*1b)%?xnM-u;v)pEKdUv5yk;6c=cN7PU9Y;^EKEvgT^g( zGWS~RCMA0y5k)4>Y0xiJQ~H;;IPw65$BKx5N^W-0T$)Na#_ZjJ73NS7Kv+5_o?K=vq|;~VUlXBHus__+6F7_4J>KCSE{utNE^YW*pBiE&#rYH>ID4? zVans7jNT(!daA4Odu641w09CHHaaTUOVckf?|p!tqC zN?zhkHm#b!LlmptxnC1(e=->hudw_kpWaEAk=XWRadk_pn)5TvNR|D+*Ezxr(ZSaZMBvT$#&MI`1?7nh=V}dh8Ty;`NcwwaLm_im<@hnM>O7(C3zk zlk5k6h+Wd$c{+svA;_CPhW0%yAQ^n+Xh(J1C#zX?=JYsbS=W>yu{+9by z$p*r=0RmA~f0Ypb5hum3Ns}qgC-)9VaVV<2VeN=cRluANgOBViuT*vVLY6g2XZqSz z#Kqq6Psw4V;0Q3W)jT=M2Vg)xhsueyNLRn~kp@FQqb4z2{J;mkd6@6Mi92ci{Jle* zFDmeX1RjGglT&y{wsT{hsHb%&vWG}kD;s0hwZN554hp6Q%Yl zY3`KG44I3+q=>kwMEswz4(8b;@_jYAPF;G?VK`%iuwlK?eBG``9RFehaN2jR$RkWe2(8 ztvgmNpHCsI|1RvdBSvxkFb2u}x&lVY-3yBo^4;{k7f;qaMsF++_!d6I|0*WFUh(ai=^9!@wr+uK056gvJ`jN$9 ztVb`HFU(Z6)8B^GmBwgmOW01l{x_}er}*Y~%ky=)Ty?%n(47m1`N+=mNel$*1aAay zwro(44d6o5732$or~Xj6@Y6&fi@ns0XES9T zEk$tA^8{8V-sR9@*2Ac42NYBq&pXV32=xG86=E+aBg^UiHR6%IdTdhTe-oL{?6HeaS_D#Vq6lo+>-W zDgzEI)_@315DsSZu^2{pg3h0^`qQ?CWu8SDrY#Uxc6Xf&GIN{bhu*}yknv>W{D9Bt zZha?D$2q{Sp#**n7ft4R+HO4OG_#47Z&kb3YW%F0skoK?iZMYA0H0UWa-a8sI_xv$ z(HA|PH*SxJysaDtz(nhH;I{9HcnLtVh0NEzcpLH7G|P5^LGY9t$OpY&_K^=dD4-K3 zgLI>7-pi}8IT zR0vH#1QMwUf};2eh)C}xQ4tUcHB>7tbcmr^KtOsgA#fIazl(E!uFmh{E@!~$seLRCvRBH*44QqWA5g~aKL!+NGLl0DI zUzIT?i4+#DHz8CaGdW~T6rL@eIa%^9yN1CA-(?|OI@o zj9q%j?`hap&)P~g)*#41pC4{;xG#wy<+h=9%c9#-J4zrFuo>eA6ZLfIBbU>LusX&o z1D53Bbiy_ABOyhe6O~dcVOj$iXW=P`PlD=4$p+)c)6Z8#sPG?>fkjm4t-0 z@|yhvInU9fm@wdxz*V|BM4gUQPCa_uTntxTYPU67_WR=y8(Yt8mWNd;j6U(>{BGAq zL%~&sq?JETpkf=X1M|Z8P1ufzGf8|aPvZoHHbFk?&Nq52lk4Q&Ko1VC@GoZ|uuA!N zZQ5vX`G!_DkUZpft%`ExZg%5(4~j z!ICRE7as^j^erM@am|*D#vc8dkx_LWHn0CgJ&S!kX}d@;WV!RD=@ti&m;@c(CAM|m z02-nsWeyCW5uWlwO=(1)d|2vY}`d};!BI-TLlPpax)Jz{Q z(dXeJfSvF$yIk%w$c3#0`&z#*LRNQeuAzuOkM0fd<9e;}M8>pp)MsFLfzPeSx`7DA zKj@J1aDeqkb^%NGZ3L7IxS=kxE2FsB`Uci(tT^a_<1&X>IPrG}8^>PMgLE_|3i1cx zK(Qe3Exz^Da*7-7n#K$wxT>yt<@I&gEBOy=QS8f8<5Cc%&8zuK#YNSzH9Lnt5+Go6 z8V9#RHQjlt()uNuX9R3;=cgNK5AfVeNxJ0o4~o3F4!aSUl))}`m$!Jx0OZA(ZF2uA z?W?_o_f+s>B$IIvS^3Iblu09fN#nAHPq{VlqJ5mAzYlVD@sz?<& zQkJ-*N!OWGke5br?LILEPjU_G>iuxPMA1IuWnSMiwjIls+Ge_+!}j>emaXSRl1?km zxWgiiZAG)+iyUCtK|5C1$-(;jWTQRdFhhO^774?C*?jl4AxdE-!9RzU^BBk#{ClmE zDfB(Bnat&xs zw>DbOZP=`U9({OVOAos@Z6rcqN1(tu#%YkWnPcYb@`7Ys)PX9gf$lrL)sM`M!ax)n zO{J~x|G03?#(rvH<h0i^Ab#t3T?V4O$ z9BnuhxS3<>*0n2QJW>aC3R))piO~U9@`l8tnuXN7(rMxB=$s3c4O{s|Tl;l=2u2`Q zV0$Tse@{Zm0`;t!TB5VQ2FM1yAP@3AvtB)W?kfytY_=B*PqfV+_feYHn;{x3i5U)WTgaw&h@tSk5o4aP>0I)l(q}?$DS}b!3!X$BJ z@G8sS){QKH*qvo2)ZVB;;QX?HEd@`du)nPx!vL|9n^2WK^?|^i@Yh2O1T|j*v$ZSe z_h$exQ3hUkPwJ4+bLdKf#R*0kSYmb zv|8C!o|p36V-2qgbYuO)xomZIklc=z6P*lF;?T06Y8x+$>@F^l(0MRsZ0%90YJ3x& zABC#HX`b)kDb01&@>JRf4jpNH143?I5E$OL$a*TGG|%nCGs-C_*ZjvvNydo|WnGuh z7KB7f@=Nc$D?C7y$Tqfj@R$;A<*=%qRWHvD>gD=se`iUOeb+gjj#je1g8`d8HQ2%ek!-9x&<~6T~i;O5pUAIFogw>MR+nqWIX8vMsFH|H?Zp`gB)m;ii{Y?WDhR`lP>mLGLMC$!4T? zT7x)~f^<8QA&wrSPt%;XKIT%a*F$UOKQvo>TOYX{P4PsmOi%hph|l_a)mZj|aCKd; zh0g<1K@H5kr*9(CFeq$}K1=tfC(n$ww$}!x^0o#%#{Glo0mBbCth&YTJy!M^ZTzF5 zicK)*KK`XS{)f#3Rs&(SqZ0qo$zaHjK(c#NyL5L)?N7YWiwiQ&fmRg#$RV{+Fw3x)SqfMh1MR%jV!6N zT~HiP8~1;D+^}Dssab+29lpTR%<8#b-8YPzs5(`>5A1bY0j!i0qI~%6s zhJnM>+NMQ3U=ybXdB5!Y(jcMN>O|m*w;`X=|1(v`HyYxt7c5EJ@JRs4NwFZtlCxVgC=gZ<6XKK?vuwW&4_N)YFsBD5deQ2(g`}DhHoyZ3JJQWg1MMuTuzcp8>qYFp|6m3Ha6DW&A2a61vSZ({b=-VTMebw1?iDhE~}4pSp`U$g4D zn;%=FbPC;XkIAgO$ndSPqI+~3yVosLw!*i^ajm}Qqld8-;$1W4SoJoYcCL8$x1DKG zWou*BqfXm1URaNYn-NKA{%ERuPzw)qhP$(@)B9Iz*>L}~=!k(OcE4H^!*D@_yHk(p zW#aeSU#kw>0BW-+lyXBd#HOjB{6aoQaEg6;ibvlcL+>>cthQ za9^HF)tZGDU0AE=(+U-5G)_Mf)m9~z!96YpE_crIEt9N@T%sZ&BEB|6baZ-1RayM+ z3?b9A-9_3P#vnfP%o54JGRKLtKvuavI$k&C7Qfl)eV@Y&%#T50b8R0~E#J-)2gM(Y zPFjVUEQj6T3$}MtbcT?8ewyovzzj(69#i{}$>umUOtT`o0Aq9H{o|)WgaV&~j-`6G z17DTA79C4gs8}brDFRC%*CvPRpygUL;-t=u`U&G9+`@TkVCe`+!=&mVyR))1@{ITB z^=t6wMf$p5rASXtUS(H^c@Ynf739RrxF(Q}`q%v#oIjRbF6K{_N)w1F&I`TLW&lp} zYffurG?fJPDD1CC=NEu-w-n&$r#AHIMx1~-a+02obtn`Sx_&`&dmPsj48N$|_? zJm%=X#C5_Xyl9xL2Riv#2P#Wb&f3ViC!iubkE5WW_xOQ(f$hV`lDiFe&WB3-`lI<*hgKe`JH*7I0R@IXD-hs#*BMvKI zYb?&QkQ7GVesHh48>JV9yRCQQA@T})qe!{l^xed=<4nAd4*Cc2btL-~5G#r@Z#h)ld*NQb$Ra#it@PN9gIm=Rkw$P$P+wHlJQ5ozsE(UM6hMTqWhr6yat_akoaP z>GblEqZe#kfcM)W0!@38wWRieZO-!MtGv{UO!Ug}hbrA_J()&LPU9z0=Ef0NCPWwxv&n2M5hDln;N#R;H}c}ds|Tt&4uRl%Osg6? zdDTmnJ~ua4y=>(~B4f7}X3Q(B@vE;qX^V~u>q=+UE}mDI@Q zpx+`TetoZN4o;Wc`jT*_&u*ajh`x=h^sXdBO&HmU(20L=N|kf9Cr0^N`X@Yl0=<=Km%^I zg5;$PCdbEWlij8%E0Y4I%qd>8scqbd>cEXUMuF&--*~s_5RSrv%X=sdTAHt>vYISoYhV0kzgE_KDAWbJcFh3p+30L2aEZfHkY+LWrFqCQO} zD`o$>rz4amP}6Oa7T=|}lkA>sobvktSJR~GWP`o1XD7>!UCm&tfeNGLXg=f1-sZ#- z*3a@br!z+w4GH4!&BV27=?S!(%CTzsQ{8DuuXi~Yv{dgKr%c@#AFdfvC-3l!5_ZtQ!he<3w!QOh_;B0PBcgX4R!3iacFig?;y#S>h{ibHzy-e> z+TS}E^Z*b-BFFPTE!adu=U2LOT>Z6r6|c8}1L}ghTG9CxTWU^Xnb%4tsGius$vK%* zZpgf(`2G_`*A=sPSc^WL>z=0vfRiG)Ap6yUSE^MCo5FGZkZ*xrB^D;$p?A7Y>lSqt zv>dq&oYa?IZ4(_;fy%DfI?Lg=BOGpmPBpq+b0a%L(=_L$Ohs)l@U8*}5W|;$UABKtN?c?>$o z-sBGoCT5FyzBj}?(?l@dEq5JN%FZC=f^B89(RV`1Ak@=aK;a)~rtU&CVtD96kQ+ zq4ni%B3aXs`Ep0kli~QKlk52@B3mhl>15{TI~USN-+er=wbWxju`iUwuJ9rMi|YA= zXYTXYM14FUZ>!!st;K%gvn3l1FOTem0B=Z{JJd*3gS`1?i*&KYY)^i5@KH#5_-Gd- zMt@M$D-mQFvL2~5bjXf+%h$mk{_=68b$5ZCxQE6bEV?e+F(G4B=O32ak_XK!@QVB= zJT9dk4?XJn0iEKM@zIm)WPedTd>2wc7Vo@>85Dt>A6`p87qP!M3e;R12%%4x-Dy#w z6q1jUH?sh65~BjPr+$nq20fC!Xc7m9t?Zp^P;IA*2s@0QPbnaIO|WhUz$qGeLUTFs z8{}V0l8B8bw9GRb9YQMIl9}bxFRx*uvL;>33j96`*`AKrX5>@X;Q%(M-+N;aKxN*% z4>F=8jBD9GdEc@!gVCpNueRwNeQ>j*Iu}eO0B@MBaULl?H^f|fHj^FtIov>B(AC^8 zS~TIpOb#NookT!Gk8?X0LhaxWW`>QIx zT}UF0*PxlI(kqMKS&vqdV%F=Bz%f?PAkwU+@YVemm1~SPdA4=Q%!!zTaW7&7Ouj!J zkvV0-3U5B^FjYXo461GSwPlbl&zalw= zTM|!1Qz8pbUjkEK!psO+r&i)jweu#zqr^N`7hBM#2oHh})Ap)n$u&E*?uGd?GQA%7 zPX;_)mbqN|4)YG0UrX12qBBAc62gD`x9O2LbZ2)lr-^WUe51y?yU300^QBTBkvpJ- z$c*KhKR8QzZ83DDLBOdkj}P5ZbTcHKD_K9j*kWFukY)Qg9#{`|0KQEj z;8q?;<3Iyd$duCDcY&;I>ATa#p6&~+NuC{cIL1Wtb^^4cktR{)_C~fTvQsex048#G zDH?56g>Q>z$}?!z&PghDL6#@9GEGt^Zf$^MLIbgH$di?AR(`((cA+H`wyhS3ndAv{ zVpIMGFc<1)7*+c6LW*;<&<8756bEp1)5lMIUb^@%Hpgp_fiz;uObS5NQMb2<>Bj>{ z`LGjDQU#SPUYBl+1~b0hZen(NU69iL7p(*5P;$J@5SJTqWF={&*du@x4c!eB-LlCW z7yAoaLSRh-j|U+Jwd_4?K&y5ULZlgNNpn>4KNRAg0Vj$Ukh;2i+5<%QTc95DUF~0B zGA;%@WY0yWo5ub`(Q$B`j-$VB>g`hU}p!8^t*1? Date: Tue, 10 Mar 2015 20:24:56 -0400 Subject: [PATCH 08/12] more cleanup --- .gitignore | 2 +- test/compare.js | 1 - test/expected/expected.png | Bin 2381 -> 0 bytes test/render.test.js | 12 +++++------- 4 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 test/expected/expected.png diff --git a/.gitignore b/.gitignore index 247901be6..8334ef326 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /build /lib /node_modules -/test/actual/ +/test/actual /test/results image.png diff --git a/test/compare.js b/test/compare.js index 1f9dc234e..12a46f5cd 100644 --- a/test/compare.js +++ b/test/compare.js @@ -1,5 +1,4 @@ var spawn = require('child_process').spawn; -var fs = require('fs'); function compare(actual, expected, diff, t, callback) { var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff]); diff --git a/test/expected/expected.png b/test/expected/expected.png deleted file mode 100644 index a18f56aff39b8b6a0ed02d4ff51c59b60984caf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2381 zcmeAS@N?(olHy`uVBq!ia0y~yU;;83893O0)X@p&(m}l9Aa^H*b?0PWGB9wmd%8G= zR4~51& Date: Tue, 10 Mar 2015 20:38:19 -0400 Subject: [PATCH 09/12] fix names --- test/expected/{gz-fail-expected.png => gz-fail.png} | Bin test/js/gz.test.js | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename test/expected/{gz-fail-expected.png => gz-fail.png} (100%) diff --git a/test/expected/gz-fail-expected.png b/test/expected/gz-fail.png similarity index 100% rename from test/expected/gz-fail-expected.png rename to test/expected/gz-fail.png diff --git a/test/js/gz.test.js b/test/js/gz.test.js index 8c39a93ef..4c198061d 100644 --- a/test/js/gz.test.js +++ b/test/js/gz.test.js @@ -108,8 +108,8 @@ test('unhandled gzip', function(t) { mbgl.compressPNG(image, function(err, image) { t.error(err); - var expected = path.join(expectedDir, 'gz-fail-expected.png'); - var actual = path.join(actualDir, 'gz-fail-actual.png'); + var expected = path.join(expectedDir, 'gz-fail.png'); + var actual = path.join(actualDir, 'gz-fail.png'); var diff = path.join(actualDir, 'gz-fail-diff.png'); if (process.env.UPDATE) { From 204517a6027c88ef7c5d85dfe12a0a8d648df311 Mon Sep 17 00:00:00 2001 From: samanpwbb Date: Tue, 10 Mar 2015 20:46:49 -0400 Subject: [PATCH 10/12] try less strict difference? --- test/js/gz.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/js/gz.test.js b/test/js/gz.test.js index 4c198061d..75b569ab6 100644 --- a/test/js/gz.test.js +++ b/test/js/gz.test.js @@ -82,7 +82,7 @@ test('unpacked gzip', function(t) { fs.writeFile(actual, image, function(err) { t.error(err); compare(actual, expected, diff, t, function(error, difference) { - t.ok(difference <= 0.001, 'actual matches expected'); + t.ok(difference <= 0.1, 'actual matches expected'); mbgl.removeAllListeners('message'); t.end(); }); @@ -121,7 +121,7 @@ test('unhandled gzip', function(t) { fs.writeFile(actual, image, function(err) { t.error(err); compare(actual, expected, diff, t, function(error, difference) { - t.ok(difference <= 0.001, 'actual matches expected'); + t.ok(difference <= 0.1, 'actual matches expected'); mbgl.removeAllListeners('message'); server.close(t.end); }); From 7ef8550feafc31c48362c6e84f72457954fc48e1 Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Wed, 11 Mar 2015 16:47:40 -0400 Subject: [PATCH 11/12] minor organizational changes, compare Map test image --- .gitignore | 11 +- Makefile | 2 +- test/compare.js | 7 +- .../{gz-success.png => gzip/success.png} | Bin .../{gz-fail.png => gzip/unhandled.png} | Bin test/expected/map/image.png | Bin 0 -> 41488 bytes test/js/gz.test.js | 138 ------------------ test/js/gzip.test.js | 130 +++++++++++++++++ test/js/map.test.js | 34 ++++- 9 files changed, 166 insertions(+), 156 deletions(-) rename test/expected/{gz-success.png => gzip/success.png} (100%) rename test/expected/{gz-fail.png => gzip/unhandled.png} (100%) create mode 100644 test/expected/map/image.png delete mode 100644 test/js/gz.test.js create mode 100644 test/js/gzip.test.js diff --git a/.gitignore b/.gitignore index 8334ef326..2f53e5d17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -/build -/lib -/node_modules -/test/actual -/test/results -image.png +build +lib +node_modules +test/actual +test/diff diff --git a/Makefile b/Makefile index b2029c442..52ce7db88 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ $(MBGL)/config/%.gypi: $(MBGL) $(MBGL)/configure .PHONY: test-suite test-suite: - -@(`npm bin`/tape test/*.test.js | `npm bin`/tap-spec) + -@(`npm bin`/tape test/render.test.js | `npm bin`/tap-spec) .PHONY: test-js test-js: diff --git a/test/compare.js b/test/compare.js index 12a46f5cd..aaac14f36 100644 --- a/test/compare.js +++ b/test/compare.js @@ -1,6 +1,6 @@ var spawn = require('child_process').spawn; -function compare(actual, expected, diff, t, callback) { +module.exports = function compare(actual, expected, diff, t, callback) { var compare = spawn('compare', ['-metric', 'MAE', actual, expected, diff]); var error = ''; @@ -24,7 +24,4 @@ function compare(actual, expected, diff, t, callback) { }); compare.stdin.end(); - -} - -module.exports = compare; +}; diff --git a/test/expected/gz-success.png b/test/expected/gzip/success.png similarity index 100% rename from test/expected/gz-success.png rename to test/expected/gzip/success.png diff --git a/test/expected/gz-fail.png b/test/expected/gzip/unhandled.png similarity index 100% rename from test/expected/gz-fail.png rename to test/expected/gzip/unhandled.png diff --git a/test/expected/map/image.png b/test/expected/map/image.png new file mode 100644 index 0000000000000000000000000000000000000000..b39617e1f6a3d54d2d8b527c2fac500170703392 GIT binary patch literal 41488 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 z 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 Date: Thu, 12 Mar 2015 09:24:36 -0700 Subject: [PATCH 12/12] reduce diff sensitivity so tests pass on linux, mkdirp.sync --- test/js/gzip.test.js | 4 ++-- test/js/map.test.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/js/gzip.test.js b/test/js/gzip.test.js index f401f4059..6866db059 100644 --- a/test/js/gzip.test.js +++ b/test/js/gzip.test.js @@ -20,7 +20,7 @@ server.listen(0); function filePath(name) { return ['expected', 'actual', 'diff'].reduce(function(prev, key) { var dir = path.join('test', key, 'gzip'); - mkdirp(dir); + mkdirp.sync(dir); prev[key] = path.join(dir, name); return prev; }, {}); @@ -81,7 +81,7 @@ test('gzip', function(t) { fs.writeFile(filename.actual, image, function(err) { t.error(err); compare(filename.actual, filename.expected, filename.diff, t, function(error, difference) { - t.ok(difference <= 0.001, 'actual matches expected'); + t.ok(difference <= 0.01, 'actual matches expected'); t.end(); }); }); diff --git a/test/js/map.test.js b/test/js/map.test.js index 38729413e..5b9a751a5 100644 --- a/test/js/map.test.js +++ b/test/js/map.test.js @@ -13,7 +13,7 @@ var compare = require('../compare.js'); function filePath(name) { return ['expected', 'actual', 'diff'].reduce(function(prev, key) { var dir = path.join('test', key, 'map'); - mkdirp(dir); + mkdirp.sync(dir); prev[key] = path.join(dir, name); return prev; }, {}); @@ -196,7 +196,7 @@ test('Map', function(t) { fs.writeFile(filename.actual, image, function(err) { t.error(err); compare(filename.actual, filename.expected, filename.diff, t, function(error, difference) { - t.ok(difference <= 0.001, 'actual matches expected'); + t.ok(difference <= 0.01, 'actual matches expected'); t.end(); }); });