PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/opt/cpanel/ea-ruby27/src/passenger-release-6.0.23/test/cxx/
Upload File :
Current File : //opt/cpanel/ea-ruby27/src/passenger-release-6.0.23/test/cxx/UtilsTest.cpp
#include <TestSupport.h>
#include <Utils.h>
#include <StrIntTools/StrIntUtils.h>
#include <SecurityKit/MemZeroGuard.h>
#include <FileTools/PathManip.h>
#include <FileTools/FileManip.h>
#include <ProcessManagement/Spawn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>

using namespace Passenger;
using namespace std;

namespace tut {
	struct UtilsTest: public TestBase {
		vector<string> output;
		string cwd;
		string oldPath;
		TempDir tempDir;

		UtilsTest(): tempDir("tmp.dir") {
			char buffer[PATH_MAX];
			cwd = getcwd(buffer, sizeof(buffer));
			oldPath = getenv("PATH");
			unsetenv("TMPDIR");
		}

		~UtilsTest() {
			setenv("PATH", oldPath.c_str(), 1);
			unsetenv("TMPDIR");
			chdir(cwd.c_str());
		}

		void testMakeDirTreeMode(const char *name, const char *mode, mode_t expected) {
			TempDir td("tmp.dir2");
			struct stat buf;
			mode_t allModes = S_IRWXU | S_ISUID | S_IRWXG | S_ISGID | S_IRWXO;

			makeDirTree("tmp.dir2/foo", mode);
			stat("tmp.dir2/foo", &buf);
			ensure_equals(name, buf.st_mode & allModes, expected);
		}
	};

	DEFINE_TEST_GROUP_WITH_LIMIT(UtilsTest, 100);

	/***** Test split() *****/

	TEST_METHOD(1) {
		split("", ':', output);
		ensure_equals(output.size(), 0u);

		splitIncludeSep("", ':', output);
		ensure_equals(output.size(), 0u);
	}

	TEST_METHOD(2) {
		split("hello world", ':', output);
		ensure_equals(output.size(), 1u);
		ensure_equals(output[0], "hello world");

		splitIncludeSep("hello world", ':', output);
		ensure_equals(output.size(), 1u);
		ensure_equals(output[0], "hello world");
	}

	TEST_METHOD(3) {
		split("hello world:foo bar", ':', output);
		ensure_equals(output.size(), 2u);
		ensure_equals(output[0], "hello world");
		ensure_equals(output[1], "foo bar");

		splitIncludeSep("hello world:foo bar", ':', output);
		ensure_equals(output.size(), 2u);
		ensure_equals(output[0], "hello world:");
		ensure_equals(output[1], "foo bar");
	}

	TEST_METHOD(4) {
		split("hello world:", ':', output);
		ensure_equals("(1)", output.size(), 2u);
		ensure_equals("(2)", output[0], "hello world");
		ensure_equals("(3)", output[1], "");

		splitIncludeSep("hello world:", ':', output);
		ensure_equals("(4)", output.size(), 1u);
		ensure_equals("(5)", output[0], "hello world:");
	}

	TEST_METHOD(5) {
		split(":hello world", ':', output);
		ensure_equals(output.size(), 2u);
		ensure_equals(output[0], "");
		ensure_equals(output[1], "hello world");

		splitIncludeSep(":hello world", ':', output);
		ensure_equals(output.size(), 2u);
		ensure_equals(output[0], ":");
		ensure_equals(output[1], "hello world");
	}

	TEST_METHOD(6) {
		split("abc:def::ghi", ':', output);
		ensure_equals(output.size(), 4u);
		ensure_equals(output[0], "abc");
		ensure_equals(output[1], "def");
		ensure_equals(output[2], "");
		ensure_equals(output[3], "ghi");

		splitIncludeSep("abc:def::ghi", ':', output);
		ensure_equals(output.size(), 4u);
		ensure_equals(output[0], "abc:");
		ensure_equals(output[1], "def:");
		ensure_equals(output[2], ":");
		ensure_equals(output[3], "ghi");
	}

	TEST_METHOD(7) {
		split("abc:::def", ':', output);
		ensure_equals(output.size(), 4u);
		ensure_equals(output[0], "abc");
		ensure_equals(output[1], "");
		ensure_equals(output[2], "");
		ensure_equals(output[3], "def");

		splitIncludeSep("abc:::def", ':', output);
		ensure_equals(output.size(), 4u);
		ensure_equals(output[0], "abc:");
		ensure_equals(output[1], ":");
		ensure_equals(output[2], ":");
		ensure_equals(output[3], "def");
	}


	/***** Test getSystemTempDir() *****/

	TEST_METHOD(11) {
		// It returns "/tmp" if the TMPDIR environment is NULL.
		ensure_equals(string(getSystemTempDir()), "/tmp");
	}

	TEST_METHOD(12) {
		// It returns "/tmp" if the TMPDIR environment is an empty string.
		setenv("TMPDIR", "", 1);
		ensure_equals(string(getSystemTempDir()), "/tmp");
	}

	TEST_METHOD(13) {
		// It returns the value of the TMPDIR environment if it is not NULL and not empty.
		setenv("TMPDIR", "/foo", 1);
		ensure_equals(string(getSystemTempDir()), "/foo");
	}


	/***** Test escapeForXml() *****/

	TEST_METHOD(25) {
		ensure_equals(escapeForXml(""), "");
		ensure_equals(escapeForXml("hello world"), "hello world");
		ensure_equals(escapeForXml("./hello_world/foo.txt"), "./hello_world/foo.txt");
		ensure_equals(escapeForXml("hello<world"), "hello&#60;world");
		ensure_equals(escapeForXml("hello\xFFworld"), "hello&#255;world");
		ensure_equals(escapeForXml("hello\xFF\xCCworld"), "hello&#255;&#204;world");
		ensure_equals(escapeForXml("hello\xFFworld\xCC"), "hello&#255;world&#204;");
		ensure_equals(escapeForXml("hello\nworld"), "hello&#10;world");
	}

	/***** Test extractDirName() *****/

	TEST_METHOD(26) {
		ensure_equals("Test 1", extractDirName("/usr/lib"), "/usr");
		ensure_equals("Test 2", extractDirName("/usr/lib/"), "/usr");
		ensure_equals("Test 3", extractDirName("/usr/"), "/");
		ensure_equals("Test 4", extractDirName("usr"), ".");
		ensure_equals("Test 5", extractDirName("/"), "/");
		ensure_equals("Test 6", extractDirName("///"), "/");
		ensure_equals("Test 7", extractDirName("."), ".");
		ensure_equals("Test 8", extractDirName(".."), ".");
		ensure_equals("Test 9", extractDirName("./foo"), ".");
		ensure_equals("Test 10", extractDirName("../foo"), "..");
		ensure_equals("Test 11", extractDirName(""), ".");
		ensure_equals("Test 12", extractDirName(".///"), ".");
		ensure_equals("Test 13", extractDirName("foo//bar"), "foo");
	}

	TEST_METHOD(27) {
		ensure_equals("Test 1", extractDirNameStatic("/usr/lib"), "/usr");
		ensure_equals("Test 2", extractDirNameStatic("/usr/lib/"), "/usr");
		ensure_equals("Test 3", extractDirNameStatic("/usr/"), "/");
		ensure_equals("Test 4", extractDirNameStatic("usr"), ".");
		ensure_equals("Test 5", extractDirNameStatic("/"), "/");
		ensure_equals("Test 6", extractDirNameStatic("///"), "/");
		ensure_equals("Test 7", extractDirNameStatic("."), ".");
		ensure_equals("Test 8", extractDirNameStatic(".."), ".");
		ensure_equals("Test 9", extractDirNameStatic("./foo"), ".");
		ensure_equals("Test 10", extractDirNameStatic("../foo"), "..");
		ensure_equals("Test 11", extractDirNameStatic(""), ".");
		ensure_equals("Test 12", extractDirNameStatic(".///"), ".");
		ensure_equals("Test 13", extractDirNameStatic("foo//bar"), "foo");
	}

	/***** Test resolveSymlink() *****/

	TEST_METHOD(28) {
		TempDir d("tmp.symlinks");
		runShellCommand("touch tmp.symlinks/foo.txt");
		runShellCommand("ln -s /usr/bin tmp.symlinks/absolute_symlink");
		runShellCommand("ln -s foo.txt tmp.symlinks/file");
		runShellCommand("ln -s file tmp.symlinks/file2");
		runShellCommand("ln -s file2 tmp.symlinks/file3");
		ensure_equals(resolveSymlink("tmp.symlinks/file"), "tmp.symlinks/foo.txt");
		ensure_equals(resolveSymlink("tmp.symlinks/file2"), "tmp.symlinks/file");
		ensure_equals(resolveSymlink("tmp.symlinks/file3"), "tmp.symlinks/file2");
		ensure_equals(resolveSymlink("tmp.symlinks/absolute_symlink"), "/usr/bin");
	}

	/***** Test fillInMiddle() *****/

	TEST_METHOD(30) {
		ensure_equals(fillInMiddle(20, "server.", "123456", ".socket"), "server.123456.socket");
		ensure_equals(fillInMiddle(25, "server.", "123456", ".socket"), "server.123456.socket");
		ensure_equals(fillInMiddle(19, "server.", "123456", ".socket"), "server.12345.socket");
		ensure_equals(fillInMiddle(16, "server.", "123456", ".socket"), "server.12.socket");

		ensure_equals(fillInMiddle(10, "", "1234", ""), "1234");
		ensure_equals(fillInMiddle(4, "", "1234", ""), "1234");
		ensure_equals(fillInMiddle(2, "", "1234", ""), "12");

		ensure_equals(fillInMiddle(20, "", "1234", ".socket"), "1234.socket");
		ensure_equals(fillInMiddle(11, "", "1234", ".socket"), "1234.socket");
		ensure_equals(fillInMiddle(9, "", "1234", ".socket"), "12.socket");

		try {
			fillInMiddle(14, "server.", "123456", ".socket");
			fail();
		} catch (const ArgumentException &) { }

		try {
			fillInMiddle(10, "server.", "123456", ".socket");
			fail();
		} catch (const ArgumentException &) { }

		try {
			fillInMiddle(10, "server.", "", ".socket");
			fail();
		} catch (const ArgumentException &) { }
	}

	/***** Test MemZeroGuard *****/

	TEST_METHOD(31) {
		char buf[12] = "hello world";
		{
			MemZeroGuard g(buf, 2);
		}
		ensure(memcmp(buf, "\0\0llo world", sizeof(buf)) == 0);
	}

	TEST_METHOD(32) {
		string str("hello ");
		{
			MemZeroGuard g(str);
			str.append("world");
		}
		ensure(memcmp(str.c_str(), "\0\0\0\0\0\0\0\0\0\0\0", 11) == 0);
	}

	TEST_METHOD(33) {
		string str("hello ");
		{
			MemZeroGuard g(str);
			g.zeroNow();
			ensure(memcmp(str.c_str(), "\0\0\0\0\0\0", 6) == 0);
			str.append("world");
			ensure(memcmp(str.c_str(), "\0\0\0\0\0\0world", 11) == 0);
		}
		ensure(memcmp(str.c_str(), "\0\0\0\0\0\0\0\0\0\0\0", 11) == 0);
	}

	/***** Test parseModeString() *****/

	static bool modeStringCannotBeParsed(const StaticString &modeString) {
		try {
			parseModeString(modeString);
			return false;
		} catch (const InvalidModeStringException &) {
			return true;
		}
	}

	TEST_METHOD(36) {
		ensure_equals(parseModeString(""), (mode_t) 0);
		ensure_equals(parseModeString("u="), (mode_t) 0);
		ensure_equals(parseModeString("u=,u="), (mode_t) 0);
		ensure_equals(parseModeString("u=,g="), (mode_t) 0);
		ensure_equals(parseModeString("u=,g=,o="), (mode_t) 0);
		ensure_equals(parseModeString("u=,g=,o=,u=,g="), (mode_t) 0);
		ensure_equals(parseModeString("o="), (mode_t) 0);
	}

	TEST_METHOD(37) {
		ensure_equals("(1)", parseModeString("u=rwx"), (mode_t) S_IRWXU);
		ensure_equals("(2)", parseModeString("g=rwx"), (mode_t) S_IRWXG);
		ensure_equals("(3)", parseModeString("o=rwx"), (mode_t) S_IRWXO);
		ensure_equals("(4)", parseModeString("u=r,g=,o=rx"),
			(mode_t) (S_IRUSR | S_IROTH | S_IXOTH));
		ensure_equals("(5)", parseModeString("o=r,g=wx"),
			(mode_t) (S_IROTH | S_IWGRP | S_IXGRP));
		ensure_equals("(6)", parseModeString("u=r,g=w,o=x,u=x"),
			(mode_t) (S_IRUSR | S_IXUSR | S_IWGRP | S_IXOTH));
		ensure_equals("(7)", parseModeString("u=rs,g=ws"),
			(mode_t) (S_IRUSR | S_ISUID | S_IWGRP | S_ISGID));
		ensure_equals("(7)", parseModeString("u=rwx,g=rwx,+t"),
			(mode_t) (S_IRWXU | S_IRWXG | S_ISVTX));
	}

	TEST_METHOD(38) {
		ensure(modeStringCannotBeParsed("0"));
		ensure(modeStringCannotBeParsed("0600"));
		ensure(modeStringCannotBeParsed("600"));
		ensure(modeStringCannotBeParsed("x=rs"));
		ensure(modeStringCannotBeParsed("u=rs,g=rs,x=rs"));
		ensure(modeStringCannotBeParsed("x=rs"));
		ensure(modeStringCannotBeParsed("rwxrwxrwx"));
	}

	/***** Test makeDirTree() *****/

	TEST_METHOD(40) {
		// Creating a single subdirectory works.
		makeDirTree("tmp.dir/foo");
		ensure_equals(getFileType("tmp.dir/foo"), FT_DIRECTORY);
	}

	TEST_METHOD(41) {
		// Creating multiple subdirectories works.
		makeDirTree("tmp.dir/foo/bar");
		ensure_equals(getFileType("tmp.dir/foo"), FT_DIRECTORY);
		ensure_equals(getFileType("tmp.dir/foo/bar"), FT_DIRECTORY);
	}

	TEST_METHOD(42) {
		// It applies the permissions to all created directories.
		struct stat buf, buf2;

		stat("tmp.dir", &buf);
		makeDirTree("tmp.dir/foo/bar", "u=rwxs,g=,o=rx");
		stat("tmp.dir", &buf2);
		ensure_equals(buf.st_mode, buf2.st_mode);

		stat("tmp.dir/foo", &buf);
		stat("tmp.dir/foo/bar", &buf2);
		ensure_equals(buf.st_mode, buf2.st_mode);
		ensure_equals((mode_t) (buf.st_mode & 0xFFF),
			(mode_t) (S_IRUSR | S_IWUSR | S_IXUSR | S_ISUID |
			S_IROTH | S_IXOTH));
	}

	TEST_METHOD(43) {
		// It correctly parses the permission string.
		testMakeDirTreeMode("empty 1", "", (mode_t) 0);
		testMakeDirTreeMode("empty 2", "u=", (mode_t) 0);
		testMakeDirTreeMode("empty 3", "g=", (mode_t) 0);
		testMakeDirTreeMode("empty 4", "o=", (mode_t) 0);
		testMakeDirTreeMode("empty 5", "u=,g=", (mode_t) 0);
		testMakeDirTreeMode("empty 6", "g=,o=", (mode_t) 0);

		testMakeDirTreeMode("(1)", "u=rwxs,g=rwxs,o=rwx",
			S_IRWXU | S_ISUID | S_IRWXG | S_ISGID | S_IRWXO);
		testMakeDirTreeMode("(2)", "u=s,g=rx,o=w",
			S_ISUID | S_IRGRP | S_IXGRP | S_IWOTH);
		testMakeDirTreeMode("(3)", "u=rwxs,g=,o=rwx",
			S_IRWXU | S_ISUID | S_IRWXO);
	}

	TEST_METHOD(44) {
		// It doesn't do anything if the directory already exists.
		struct stat buf, buf2;
		stat("tmp.dir", &buf);
		makeDirTree("tmp.dir");
		stat("tmp.dir", &buf2);
		ensure_equals(buf.st_mode, buf2.st_mode);
	}

	/***** Test stringToULL(), stringToUint *****/

	TEST_METHOD(47) {
		ensure_equals(stringToULL(""), 0ull);
		ensure_equals(stringToULL("bla"), 0ull);
		ensure_equals(stringToULL("0"), 0ull);
		ensure_equals(stringToULL("000"), 0ull);
		ensure_equals(stringToULL("1"), 1ull);
		ensure_equals(stringToULL("9"), 9ull);
		ensure_equals(stringToULL("010"), 10ull);
		ensure_equals(stringToULL("928"), 928ull);
		ensure_equals(stringToULL("2937104"), 2937104ull);
		ensure_equals(stringToULL("18446744073709551615"), 18446744073709551615ull);
		ensure_equals(stringToULL("    5abcdef1234"), 5ull);

		ensure_equals(stringToUint(""), 0u);
		ensure_equals(stringToUint("bla"), 0u);
		ensure_equals(stringToUint("0"), 0u);
		ensure_equals(stringToUint("000"), 0u);
		ensure_equals(stringToUint("1"), 1u);
		ensure_equals(stringToUint("9"), 9u);
		ensure_equals(stringToUint("010"), 10u);
		ensure_equals(stringToUint("928"), 928u);
		ensure_equals(stringToUint("2937104"), 2937104u);
		ensure_equals(stringToUint("    5abcdef1234"), 5u);
	}

	/***** Test integerToHex() and integerToHexatri() *****/

	TEST_METHOD(48) {
		char buf[sizeof(int) * 2 + 1];

		ensure_equals("(1)", integerToHex<int>(0x0, buf), 1u);
		ensure("(1)", strcmp(buf, "0") == 0);

		ensure_equals("(2)", integerToHex<int>(0x1, buf), 1u);
		ensure("(2)", strcmp(buf, "1") == 0);

		ensure_equals("(3)", integerToHex<int>(0x9, buf), 1u);
		ensure("(3)", strcmp(buf, "9") == 0);

		ensure_equals("(4)", integerToHex<int>(0xe, buf), 1u);
		ensure("(4)", strcmp(buf, "e") == 0);

		ensure_equals("(5)", integerToHex<unsigned int>(0xdeadbeef, buf), 8u);
		ensure("(5)", strcmp(buf, "deadbeef") == 0);

		ensure_equals("(6)", integerToHex<int>(0x1234f, buf), 5u);
		ensure("(6)", strcmp(buf, "1234f") == 0);


		ensure_equals("(7)", integerToHexatri<int>(0x0, buf), 1u);
		ensure("(7)", strcmp(buf, "0") == 0);

		ensure_equals("(8)", integerToHexatri<int>(0x1, buf), 1u);
		ensure("(8)", strcmp(buf, "1") == 0);

		ensure_equals("(9)", integerToHexatri<int>(0x9, buf), 1u);
		ensure("(9)", strcmp(buf, "9") == 0);

		ensure_equals("(10)", integerToHexatri<int>(0xe, buf), 1u);
		ensure("(10)", strcmp(buf, "e") == 0);

		ensure_equals("(11)", integerToHexatri<int>(35, buf), 1u);
		ensure("(11)", strcmp(buf, "z") == 0);

		ensure_equals(integerToHexatri<unsigned int>(0xdeadbeef, buf), 7u);
		ensure(strcmp(buf, "1ps9wxb") == 0);

		ensure_equals(integerToHexatri<int>(0x1234f, buf), 4u);
		ensure(strcmp(buf, "1ljj") == 0);
	}

	/***** Test hexToULL(), hexToUint() and hexatriToULL() *****/

	TEST_METHOD(49) {
		ensure_equals(hexToULL(""), 0ull);
		ensure_equals(hexToULL("   "), 0ull);
		ensure_equals(hexToULL("1"), 1ull);
		ensure_equals(hexToULL("9"), 9ull);
		ensure_equals(hexToULL("a"), 10ull);
		ensure_equals(hexToULL("B"), 11ull);
		ensure_equals(hexToULL("1234"), 4660ull);
		ensure_equals(hexToULL("1a6b"), 6763ull);
		ensure_equals(hexToULL("1A6B"), 6763ull);
		ensure_equals(hexToULL("1a6B"), 6763ull);
		ensure_equals(hexToULL("deadbeef"), 3735928559ull);
		ensure_equals(hexToULL("dEaDbEeF"), 3735928559ull);
		ensure_equals(hexToULL("09a2s89"), 2466ull);
		ensure_equals(hexToULL(" 9a2s89"), 0ull);

		ensure_equals(hexToUint(""), 0u);
		ensure_equals(hexToUint("   "), 0u);
		ensure_equals(hexToUint("1"), 1u);
		ensure_equals(hexToUint("9"), 9u);
		ensure_equals(hexToUint("a"), 10u);
		ensure_equals(hexToUint("B"), 11u);
		ensure_equals(hexToUint("1234"), 4660u);
		ensure_equals(hexToUint("1a6b"), 6763u);
		ensure_equals(hexToUint("1A6B"), 6763u);
		ensure_equals(hexToUint("1a6B"), 6763u);
		ensure_equals(hexToUint("deadbeef"), 3735928559u);
		ensure_equals(hexToUint("dEaDbEeF"), 3735928559u);
		ensure_equals(hexToUint("09a2s89"), 2466u);
		ensure_equals(hexToUint(" 9a2s89"), 0u);

		ensure_equals(hexatriToULL(""), 0ull);
		ensure_equals(hexatriToULL("   "), 0ull);
		ensure_equals(hexatriToULL("1"), 1ull);
		ensure_equals(hexatriToULL("9"), 9ull);
		ensure_equals(hexatriToULL("a"), 10ull);
		ensure_equals(hexatriToULL("B"), 11ull);
		ensure_equals(hexatriToULL("1234"), 49360ull);
		ensure_equals(hexatriToULL("1a6z"), 59867ull);
		ensure_equals(hexatriToULL("1A6Z"), 59867ull);
		ensure_equals(hexatriToULL("1a6Z"), 59867ull);
		ensure_equals(hexatriToULL("deadroof"), 1049836874415ull);
		ensure_equals(hexatriToULL("dEaDrOoF"), 1049836874415ull);
		ensure_equals(hexatriToULL("09a2s89"), 561121641ull);
		ensure_equals(hexatriToULL(" 9a2s89"), 0ull);
	}

	/***** Test stringToLL(), stringToInt() *****/

	TEST_METHOD(50) {
		ensure_equals(stringToLL(""), 0ll);
		ensure_equals(stringToLL("bla"), 0ll);
		ensure_equals(stringToLL("0"), 0ll);
		ensure_equals(stringToLL("000"), 0ll);
		ensure_equals(stringToLL("1"), 1ll);
		ensure_equals(stringToLL("9"), 9ll);
		ensure_equals(stringToLL("010"), 10ll);
		ensure_equals(stringToLL("928"), 928ll);
		ensure_equals(stringToLL("2937104"), 2937104ll);
		ensure_equals(stringToLL("9223372036854775807"), 9223372036854775807ll);
		ensure_equals(stringToLL("    5abcdef1234"), 5ll);

		ensure_equals(stringToLL("-0"), 0ll);
		ensure_equals(stringToLL("-1"), -1ll);
		ensure_equals(stringToLL("-010"), -10ll);
		ensure_equals(stringToLL("-9876"), -9876ll);
		ensure_equals(stringToLL("-9223372036854775807"), -9223372036854775807ll);
		ensure_equals(stringToLL("    -5abcdef1234"), -5ll);

		ensure_equals(stringToInt(""), 0);
		ensure_equals(stringToInt("bla"), 0);
		ensure_equals(stringToInt("0"), 0);
		ensure_equals(stringToInt("000"), 0);
		ensure_equals(stringToInt("1"), 1);
		ensure_equals(stringToInt("9"), 9);
		ensure_equals(stringToInt("010"), 10);
		ensure_equals(stringToInt("928"), 928);
		ensure_equals(stringToInt("2937104"), 2937104);
		ensure_equals(stringToInt("    5abcdef1234"), 5);

		ensure_equals(stringToInt("-0"), 0ll);
		ensure_equals(stringToInt("-1"), -1ll);
		ensure_equals(stringToInt("-010"), -10ll);
		ensure_equals(stringToInt("-9876"), -9876);
		ensure_equals(stringToInt("    -5abcdef1234"), -5);
	}

	/***** Test cEscapeString() *****/

	TEST_METHOD(51) {
		ensure_equals(cEscapeString(""), "");
		ensure_equals(cEscapeString("abcdXYZ123!?"), "abcdXYZ123!?");
		ensure_equals(cEscapeString("foo\n"), "foo\\n");
		ensure_equals(cEscapeString("foo\r\nbar\e"), "foo\\r\\nbar\\e");
		ensure_equals(cEscapeString(StaticString("\0\x1\x2\x3\x4\x5\x6\x7\x8\x9", 10)),
			"\\000\\001\\002\\003\\004\\005\\006\\007\\010\\t");
		ensure_equals(cEscapeString("\xFF\xFE\t\xD0"), "\\377\\376\\t\\320");
	}

	/***** Test escapeHTML() *****/

	TEST_METHOD(52) {
		const char weird[] = "Weird \x01\x00 characters?";
		ensure_equals(escapeHTML(""), "");
		ensure_equals(escapeHTML("hello\n\r\t WORLD!"), "hello\n\r\t WORLD!");
		ensure_equals(escapeHTML("<b>bold</b>"), "&lt;b&gt;bold&lt;/b&gt;");
		ensure_equals(escapeHTML(StaticString(weird, sizeof(weird) - 1)),
			"Weird &#1;&#0; characters?");
		ensure_equals(escapeHTML("UTF-8: ☃ ☀; ☁ ☂\x01"), "UTF-8: ☃ ☀; ☁ ☂&#1;");
	}

	/***** Test absolutizePath() *****/

	TEST_METHOD(53) {
		ensure_equals(absolutizePath(""), cwd);
		ensure_equals(absolutizePath("."), cwd);
		ensure_equals(absolutizePath("foo"), cwd + "/foo");
		ensure_equals(absolutizePath("foo/bar"), cwd + "/foo/bar");
		ensure_equals(absolutizePath("foo//bar"), cwd + "/foo/bar");
		ensure_equals(absolutizePath("foo/bar///baz"), cwd + "/foo/bar/baz");
		ensure_equals(absolutizePath("foo/./bar"), cwd + "/foo/bar");
		ensure_equals(absolutizePath("foo/bar/../baz"), cwd + "/foo/baz");
		ensure_equals(absolutizePath("foo/bar/../.."), cwd);
		ensure_equals(absolutizePath("foo/.././bar"), cwd + "/bar");
		ensure_equals(absolutizePath("foo/../bar/./baz"), cwd + "/bar/baz");
		ensure_equals(absolutizePath("foo/"), cwd + "/foo");
		ensure_equals(absolutizePath("foo//"), cwd + "/foo");

		ensure_equals(absolutizePath("/"), "/");
		ensure_equals(absolutizePath("////"), "/");
		ensure_equals(absolutizePath("/."), "/");
		ensure_equals(absolutizePath("/foo"), "/foo");
		ensure_equals(absolutizePath("/foo/bar"), "/foo/bar");
		ensure_equals(absolutizePath("/foo//bar"), "/foo/bar");
		ensure_equals(absolutizePath("/foo/bar///baz"), "/foo/bar/baz");
		ensure_equals(absolutizePath("/foo/./bar"), "/foo/bar");
		ensure_equals(absolutizePath("/foo/bar/../baz"), "/foo/baz");
		ensure_equals(absolutizePath("/foo/bar/../.."), "/");
		ensure_equals(absolutizePath("/foo/.././bar"), "/bar");
		ensure_equals(absolutizePath("/foo/../bar/./baz"), "/bar/baz");
		ensure_equals(absolutizePath("/foo/"), "/foo");
		ensure_equals(absolutizePath("/foo//"), "/foo");
		ensure_equals(absolutizePath("//foo/bar"), "/foo/bar");
		ensure_equals(absolutizePath("///foo//bar"), "/foo/bar");
		ensure_equals(absolutizePath("/../.."), "/");
		ensure_equals(absolutizePath("/../.././foo"), "/foo");

		chdir("/usr/lib");
		ensure_equals(absolutizePath(".."), "/usr");
		ensure_equals(absolutizePath("."), "/usr/lib");
		ensure_equals(absolutizePath("../.."), "/");
		ensure_equals(absolutizePath("../../foo"), "/foo");
		ensure_equals(absolutizePath("../.././foo/bar"), "/foo/bar");

		ensure_equals(absolutizePath("..", "/usr/local/bin"), "/usr/local");
		ensure_equals(absolutizePath(".", "/usr/local/bin"), "/usr/local/bin");
		ensure_equals(absolutizePath("../..", "/usr/local/bin"), "/usr");
		ensure_equals(absolutizePath("../../foo", "/usr/local/bin"), "/usr/foo");
		ensure_equals(absolutizePath("../.././foo/bar", "/usr/local/bin"), "/usr/foo/bar");
	}

	/***** Test constantTimeCompare() *****/

	TEST_METHOD(54) {
		ensure("(1)", constantTimeCompare("", ""));
		ensure("(2)", constantTimeCompare("a", "a"));
		ensure("(3)", constantTimeCompare("aa", "aa"));
		ensure("(4)", constantTimeCompare("abc", "abc"));

		ensure("(5)", !constantTimeCompare("", "a"));
		ensure("(6)", !constantTimeCompare("", "abcd"));
		ensure("(7)", !constantTimeCompare("ab", "cd"));
		ensure("(8)", !constantTimeCompare("ab", "abc"));
		ensure("(9)", !constantTimeCompare("ab", "abcd"));

		ensure("(10)", !constantTimeCompare("a", ""));
		ensure("(11)", !constantTimeCompare("abcd", ""));
		ensure("(12)", !constantTimeCompare("cd", "ab"));
		ensure("(13)", !constantTimeCompare("abc", "ab"));
		ensure("(14)", !constantTimeCompare("abcd", "ab"));
	}

	/***** Test integerToOtherBase() *****/

	TEST_METHOD(56) {
		char buf[20], smallbuf[4];

		ensure_equals("(1)", integerToOtherBase<int, 10>(0, buf, sizeof(buf)), 1u);
		ensure_equals("(1.1)", buf[0], '0');
		ensure_equals("(1.2)", buf[1], '\0');

		ensure_equals("(2)", integerToOtherBase<int, 10>(1234, buf, sizeof(buf)), 4u);
		ensure_equals("(2.1)", buf[0], '1');
		ensure_equals("(2.2)", buf[1], '2');
		ensure_equals("(2.3)", buf[2], '3');
		ensure_equals("(2.4)", buf[3], '4');
		ensure_equals("(2.5)", buf[4], '\0');

		ensure_equals("(3)", integerToOtherBase<int, 10>(123, smallbuf, sizeof(smallbuf)), 3u);
		ensure_equals("(3.1)", smallbuf[0], '1');
		ensure_equals("(3.2)", smallbuf[1], '2');
		ensure_equals("(3.3)", smallbuf[2], '3');
		ensure_equals("(3.4)", smallbuf[3], '\0');

		try {
			integerToOtherBase<int, 10>(1234, smallbuf, sizeof(smallbuf));
			fail("Exception expected");
		} catch (const std::length_error &) {
			// Pass.
		}
	}
}