From 09ded95f18b0b8ce24fdf65a7c930f3aa0aebc76 Mon Sep 17 00:00:00 2001 From: Miguel Sousa Date: Fri, 30 Aug 2019 13:08:22 -0700 Subject: [PATCH 1/2] [fdkutils] Various improvements * adds the ability to toggle the shell in runShellCmd and runShellCmdLogging * adds a timeout option to runShellCmd * checks the return code in run_shell_command_logging, runShellCmd and runShellCmdLogging (because they use Popen) --- python/afdko/fdkutils.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/python/afdko/fdkutils.py b/python/afdko/fdkutils.py index 40b7e397d..567178c18 100644 --- a/python/afdko/fdkutils.py +++ b/python/afdko/fdkutils.py @@ -9,7 +9,7 @@ import subprocess import tempfile -__version__ = '1.3.5' +__version__ = '1.3.6' def validate_path(path_str): @@ -98,6 +98,10 @@ def run_shell_command_logging(args): if out: print(out.decode()) if proc.poll() is not None: + if proc.returncode != 0: # must be called *after* poll() + msg = " ".join(args) + print(f"Error executing command '{msg}'") + return False out = proc.stdout.readline().rstrip() if out: print(out.decode()) @@ -133,24 +137,32 @@ def get_shell_command_output(args, std_error=False): return success, str_output -def runShellCmd(cmd): +def runShellCmd(cmd, shell=True, timeout=None): try: - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + p = subprocess.Popen(cmd, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdoutdata, _ = p.communicate() + stdoutdata, _ = p.communicate(timeout=timeout) str_output = stdoutdata.decode('utf-8', 'backslashreplace') + if p.returncode != 0: # must be called *after* communicate() + print(f"Error executing command '{cmd}'\n{str_output}") + str_output = "" + + except subprocess.TimeoutExpired as err: + p.kill() + print(f"{err}") # the 'err' will contain the command + str_output = "" + except (subprocess.CalledProcessError, OSError) as err: - msg = f"Error executing command '{cmd}'\n{err}" - print(msg) + print(f"Error executing command '{cmd}'\n{err}") str_output = "" return str_output -def runShellCmdLogging(cmd): +def runShellCmdLogging(cmd, shell=True): try: - proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + proc = subprocess.Popen(cmd, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while 1: output = proc.stdout.readline().rstrip() @@ -158,14 +170,17 @@ def runShellCmdLogging(cmd): print(output.decode('utf-8', 'backslashreplace')) if proc.poll() is not None: + if proc.returncode != 0: # must be called *after* poll() + print(f"Error executing command '{cmd}'") + return 1 + output = proc.stdout.readline().rstrip() if output: print(output.decode('utf-8', 'backslashreplace')) break except (subprocess.CalledProcessError, OSError) as err: - msg = f"Error executing command '{cmd}'\n{err}" - print(msg) + print(f"Error executing command '{cmd}'\n{err}") return 1 return 0 From b956fedb0da9a946dd9f6bcadd249063e954cb62 Mon Sep 17 00:00:00 2001 From: Miguel Sousa Date: Fri, 30 Aug 2019 13:10:17 -0700 Subject: [PATCH 2/2] [tests] Increase coverage in fdkutils --- tests/fdkutils_data/input/file.txt | 0 tests/fdkutils_data/input/font.cff | Bin 0 -> 518 bytes tests/fdkutils_data/input/font.otf | Bin 0 -> 1560 bytes tests/fdkutils_data/input/font.pfa | 68 +++++++ tests/fdkutils_data/input/font.pfb | Bin 0 -> 2510 bytes tests/fdkutils_data/input/font.ps | Bin 0 -> 7865 bytes tests/fdkutils_data/input/font.ttf | Bin 0 -> 1276 bytes .../input/font.ufo/fontinfo.plist | 166 ++++++++++++++++++ .../input/font.ufo/glyphs/_notdef.glif | 54 ++++++ .../input/font.ufo/glyphs/a.glif | 53 ++++++ .../input/font.ufo/glyphs/contents.plist | 10 ++ .../input/font.ufo/layercontents.plist | 10 ++ tests/fdkutils_data/input/font.ufo/lib.plist | 14 ++ .../input/font.ufo/metainfo.plist | 10 ++ tests/fdkutils_data/input/font2.pfa | 67 +++++++ tests/fdkutils_data/input/type1.txt | 75 ++++++++ tests/fdkutils_test.py | 135 +++++++++++++- 17 files changed, 660 insertions(+), 2 deletions(-) create mode 100644 tests/fdkutils_data/input/file.txt create mode 100644 tests/fdkutils_data/input/font.cff create mode 100644 tests/fdkutils_data/input/font.otf create mode 100644 tests/fdkutils_data/input/font.pfa create mode 100644 tests/fdkutils_data/input/font.pfb create mode 100644 tests/fdkutils_data/input/font.ps create mode 100644 tests/fdkutils_data/input/font.ttf create mode 100644 tests/fdkutils_data/input/font.ufo/fontinfo.plist create mode 100644 tests/fdkutils_data/input/font.ufo/glyphs/_notdef.glif create mode 100644 tests/fdkutils_data/input/font.ufo/glyphs/a.glif create mode 100644 tests/fdkutils_data/input/font.ufo/glyphs/contents.plist create mode 100644 tests/fdkutils_data/input/font.ufo/layercontents.plist create mode 100644 tests/fdkutils_data/input/font.ufo/lib.plist create mode 100644 tests/fdkutils_data/input/font.ufo/metainfo.plist create mode 100644 tests/fdkutils_data/input/font2.pfa create mode 100644 tests/fdkutils_data/input/type1.txt diff --git a/tests/fdkutils_data/input/file.txt b/tests/fdkutils_data/input/file.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fdkutils_data/input/font.cff b/tests/fdkutils_data/input/font.cff new file mode 100644 index 0000000000000000000000000000000000000000..5c7a410185f834a7b5d0de9d069a42fa1f430468 GIT binary patch literal 518 zcmZQ%U}0ilWMmWz&Mz%WP7O}XD-I~i*9}TdFU?6T0?DZSkY@NH!}vp%hvA1DvjY$F z{`wy$e`>IPKhEDH@coqFmLG*e3@nU{tf^O@80i@qKnzmIELKQVC@D%zNzF|x%2vov zQ*cblPfAq?t}HG|%`H~&%uCKMD#$NNEJ;mK$jnnH$w*ZQ&C3Mwf=hscK<#-c`uRl) z`9PT>h2;Fwypp2K)M7p7{DR7&%=C;B1tSAP104`)1SU=J*`Se8Qc_^0uU}qXu9paM zh+cAjuD+&@LV0FMhC)zkacWT+&}z5*yb=Y!#N1Q`b%;OI^`QO%g^U6)Xc&ONiGhic z(SOlT#V2Av3Vv$*DPa4~@aLWA)$bAqKe6_+?N_<-TY~ks==Zy#kuN>JbF+T0XY>5c z9i_|q+xhoO(H}|d--UnIuzt_|T_yTk=zG<7q3<=Ud_Q`=ht-RoIJkP_PWe8zNr9~A zzwcxF&Kr5_H@B^OW?r1!>LAvo8}}_eEPZ>vzpwo71VsEs2rltDpX(YWn=?+o$iJJ`qT={mz}vF1H{lo`GZ6~`oyGuGV z%j|5DhCl=nLEHL6$i7rkD}9g_O7TH_X{l9=h!G)uP$PNigCZzM>`a~DdS-VBv4(2g>9i~rpoz(% z{T%Ag=ctrvdjHn~$`_G3atQEWGOwY$jI=K&>r<}R;XHt_6ZLJfG*tk05JfPN1Vxf* z_ZRm&F#c)G_jExm>Xq*xjPdRDq?#5}&)&}-KDFc7KY`F@NgLGulWez z1r2*-T=j@F!yAswLIZr@$Q;&l-H~0Je0Z3F-yK|lrIuUs|u<4o0c$O>-u=6E^8bgaO(Ol;Uh^s&Df$XLNRuD89$aGpXUcsWFfB6T2-!XY?_ zSPxc}LOKQs?4lo~0T})tRpQ;?9P&G-?z2w~F+T{^+a;mKfD4lWa#z(RRVt_Iii)`x-?zu5w&k1?O{fZ56&@o+wf_$q5YHtJ*Nc;o9G#?r3O z%~B({7>1{J?}f#1uojHui$o&2CS|BBY2!p4Bb^y_l#=AxqE6)^=~L3GR!}ubrx}u0 zh@PY5B_(fbNgY94u4DqLMpU$DB(0VdUCYy=*sT`MYWZwVC*fcyc);f2DvvxWgFmP1 zg=YeR$;nAkvI`N@svLOo0GZ6|IWk0xRGYxmy{e*<0sJ44{k1;!i%viGBO&-o>}~7< zmSGZ?AMCxi+blfruNMRZ)_?QfHTK;8gMVANwQt$l!&_eCC-2BFeTJJiW`#b>{c<~R zbz2{K&CxpJachP*WNX@MH5$`KqcOubnCFbttatJD)f=C-T@c=Tk^k1XDHz*Fez4rn z9nC8zTdxlBS8m+Aa;N3Tg+zawmDYo)z0Hxu<14Kne&cJ0BYz3vE_Qopgfg zCt4b2%jR@>q5MhtR{34zf+d&h9>TV@UK%~+sejAkUV3cRy)^Iftj>Gz?}UHM5yphb EKZHYmzW@LL literal 0 HcmV?d00001 diff --git a/tests/fdkutils_data/input/font.pfa b/tests/fdkutils_data/input/font.pfa new file mode 100644 index 000000000..bf8fd7a03 --- /dev/null +++ b/tests/fdkutils_data/input/font.pfa @@ -0,0 +1,68 @@ +%!FontType1-1.1: SourceSansPro-Regular 2.20 +%ADOt1write: (1.0.35) +%%BeginResource: font SourceSansPro-Regular +12 dict dup begin +/FontType 1 def +/FontName /SourceSansPro-Regular def +/FontInfo 8 dict dup begin +/version (2.20) def +/Notice (Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.) def +/Copyright (Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'.) def +/FamilyName (Source Sans Pro) def +/UnderlinePosition -75 def +end def +/PaintType 0 def +/FontMatrix [0.001 0 0 0.001 0 0] def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +def +/FontBBox {52 -12 565 660} def +end +currentfile eexec BAB431EA06BB0A1031E1AA11919E714AC69FC716582140 +9A1388564981D942EE500B49D61B3CC97910D0CB9D859AC10E858AA99F37BFB7 +2DEC66AE63CC76B1AB7644B7BC12305229E38277565394BB6DA5F493CE706107 +205F453E09875F8FF73B622941D8AC93489CC6D0EC27CEE2D44FA72A3F08B67F +9DBFB2FDD4BFF31EDFE97BB0436DE92007E57FC5074AC64781FF43813AF5862C +6B62EF6E4670B6AC176837B456D927F440E3C6B86FC112485E370DDBB5DCDB62 +06B30D09F7F8F034DFEA33480DA86AE4A3C4DD5464F0D581E7C7F5AC84035C46 +74D6E1E9356D3CF8D4698BAED8F82C6B352E19D20F5F748816027D51AC11B251 +60B30397ABB4E3F43EA74323BDDE93300B2CB5EAA48C22C9AA025D721566CD0D +6FAFEEC84DE1547D6BDB7133C5EDEAFD4F621D321A9A8A1F633DED07E7B9C439 +737C35913DC45E44650ED27C1CA88A79C70ABCA3EEC9A6A7B1CE16535F497EA6 +9A331BDE88D35437E91C9C9B94631E6845D663E58230B45D52B42CD922939931 +B0FF6BB7D941471A1C46D90C8498F89F316DA57BF005A8BDB2110A9DF1AA1198 +21C28F9303DCF87A761BB41ABC336C6FF9FF125F7308C5424286DEF0971CBF4E +45A4C85F5DA06BCC70DA662DBFB04DD34B70532E4937B46ACCC8BF97B91E24AF +AE7C274EC6C9924BF6A23BD6B0A8E55BC1A5749F99D796612F3217FE9727AA84 +825F43627A45FAD58546ADC858AE74AD9CF5BDF15B7DFDF1E2BDB1C4F9C6B740 +F3DEA0BD315581004E851EFFCF086466C3C87A58EAB96D3EF4622FF404AAB193 +2891C6917CC22172B06B084903060263E175E1806144957CCA82E46B93C9F9AD +558629928A3E7ED449CFDC2FB10545FF08CA13FCDF9B2E61121DCCCEE75A9CFF +A6449FB61C61FC4E6E0B8F80E56BF1B8C3327A4F67DB6ACBC38FE4049ACF2693 +33DB03E4B9E294CC5051D84B5952ABE63EA04D391493975ECB1DC14E1BE4F13A +61A8ABFC03AB9C321936E9C303485D5B3D98F1A4DBD8E6BB644878399520AB9F +1A57A9133BF3C350FA123C4813ED026C4CE18ED994D7FF785688CF1FFCB3E05F +133710232F68D38D5138C2DF1001891FAA33376F249BCAAC5D7D0F5988F687BA +23F3EEEC995121AD06BAEF932CE04F300AA0683937EF60CD19BA8FC491FB0A06 +4BFA77D5EC2FB757911F96B268D98A17678385BAF2C35F8019622261789E838C +0E626AE55975586038321E9B88021A5AE29EF4564FD047ED6F9E6EF0D60D966B +3EB95D701792F39BD094238FAFCC8A080C13687EA25F8B7AB87A4345D77B860C +BC1279BF0E599CE8D5B6BAAF6417A58E1287C1B966B98307B3C2A0105D6E382D +ECE957CB963C41EEE4EEBA58938508F8C758E7D464201C505EC85441BCEF9988 +9CC05E8740A74E03AA339D209A2CB56580DE0FFF045C9DF7CD827AED90CEC420 +CE3A92A7BE47E652A81203ECE15E068361F93EEA815EEFCAE487EBED5A60A7D8 +3014636438535D747EE5768E9BB8E5855FD8B9A238D8AB4335514C2B866EB980 +71AA79D1867DB9433343EC2FAB34A26F66DF83E46C57DAC3BD7CA643E0A88634 +403AA76313C655DFF4FC538A7B4746F798CF03196628EA2559090A11F5FBDA98 +511337D637B066CA1F5A8DAD +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%EOF diff --git a/tests/fdkutils_data/input/font.pfb b/tests/fdkutils_data/input/font.pfb new file mode 100644 index 0000000000000000000000000000000000000000..954219686e237901fc0adf5d7b5464c36ac30c92 GIT binary patch literal 2510 zcmeHJX;c(f7G@{3bR#-qU^ICy9YE}zZWbj*WK$FgL}dv}(Oonx-BoRMHH!#x61Ito zxS)v82&ge2TVM=`;hA_aUvzcTPb-UeO zoE3_RaM&7{u;@%WhigixskX3Cgt)=71z&3rNQC_3Kx7h&4Fn=S4g_*32$**xlNd`7 z01F7_dp;1;8CAl!QAXV4xU4 z2@3}Js2ssD5iFxG-M0gkhGQaO5DrY!i>Vp^4#5GEh{WLwwxzV^YYT|tE}`6q2w+Ss zLSR=^Cc@`Qqgikl8G{kQJL+5^(PEnb=D*cw4@4v!2E3VcCX+>2h-Yc%^X`~EL83r} z2mzbR0}zHm;ban%C^VbP1raQQRskFa;4pp=V9*g1Cn^i1ay*jgA&g9VUuRoeGz>&= z*?>kg5SPaVJRURhcaUTfUyflgf(MGkFo5AOm=B`WzSB@qDJx+OYn79hv;LK%e@by^ zSIu>ggO!w*fyuJI^uK6~Pe)0cpCzllozAYJ#2>J-Z#_Xddrznqx2ik!BpNZclG=ax z6Fs3H`vBRqUbWXZU9ZL=V@)Qbby6{85$9mt_HeWFgmJmvXn`Wr*ZFR(){8<)#Q5X0 zZfSk#KOEiRJ3}>ZVIAL@qnS{LT^XUUrnEf0rqXk#d2KJPcRAOep{^V;xI`SNw8jUg(I-kX$`!CCsYRtJ`BVG%y*;n;*E{w-Gn`J30K04tk zz2Oht3u`K=_bPpOThaI2Ph4!xyD(lcu5cOIpl|3gtCG_!X`Z>6@H%w2>Q^y8rcHo& zzjj}vs^uhy^KT4PB1307=vz|twLRQxwws;Pp-m0FQO*w+@sZE47Jq})&k zb!e8+@UsUXYP!_SeRr0<`3L#S_tP?*X3ObNV1B1>^NV(U4qsk-G{S;v`!+@JA*gmQuU>L3rRGpZRU56MH_3S+GII3##+b;Q`?LYQlgYt@)4^p)v$N@sybaiuE6NXq z998cPYpf(!kN$M$;OAbwW?Z^HH(AniJ3BL+!z(Nuj@$6oX3f_AX6TaJYTKd47yABh zOf7m2X8TaGr!9-lY#9BDVT5-)W4T<-sJorQMt zSL+LQQQ-bsje$%Vh1ue=@fx$a;0^qmTNcz;SWTCPbw0gcq&s)?%?1$@VjG;Z7E zqpVBwOsU9SUHpA)JQC$Q78;NBXdlj_OUeRMz5kvZcRVcGOYM>vRG3s5vF{r^T3+NQ zx;ru%P~Y@A>3gW|hvl@&7;??7Z!B+3VX!H!H?& z)n~g~>ez7Fm-U{ID28-79QxJn`pe3(hShhH)@$Qyy9_^0&}C#|8s^C<=WdkbUi>;v zXC<%naeI>68sQqB;=L6CAwA@${uCR>;A70Bv$0REUtjwTG%_C0p#Bp-B6j-`9k-g6 z_>F^;V*fiYKkY8N(hsoiqMJ`%jb?Z%w)rre4E~7@r3`kKW+`@GfBJ0+=WCM}E7l%Y zxU%OU4k^d@&4RI66O{%+Fc&h+t{TT6o>-Ks1iJ3L(D%-J-Hn literal 0 HcmV?d00001 diff --git a/tests/fdkutils_data/input/font.ps b/tests/fdkutils_data/input/font.ps new file mode 100644 index 0000000000000000000000000000000000000000..1540309fd15ed7c77315494cab6a531ba458cf79 GIT binary patch literal 7865 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 Gk^CLrghYS< literal 0 HcmV?d00001 diff --git a/tests/fdkutils_data/input/font.ttf b/tests/fdkutils_data/input/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3b63081b3fa7eb01b7d96de1f501d73ff0789a95 GIT binary patch literal 1276 zcmb7E-D^{482`QJoSanYRw8KxQ9LF#X{*L2%{f^cCu^24zuHEt#UeNl>1iTOa!Q(N z3u6wp;n?W(qU>VAn0HbH@m~;RUU{=JCiG$#V-$8Fh+l{%{!UIdS`oqb@I3GH`#m4$ zd7twE0bnz}f(&hRY=3;@W$pzay2+l)m(3aYMS=J#@u5O#Ve0q9wa3JN5#K9X=A{3Z z;b*jOQj8)A&u`*u+J94a7t6JICzIh z49Q`+m?JIKZ{nV`hy*^9^kya3=W40RNa%v6NjP`fxMV5KDR`hr-%F?II_mD?Ec;t^ zLfyoTNe&vyq_g-0CQP>nc@^!X*WW>7e~Xw9&)J>Rw=3PPnC)bo=x(UZOp{1J0kf!; zrq66Nh^QOCHZcL`JW1`r1gkp}k+BIK*n&==-?z)xwJQ<{d6WIgWN53Lj0m51Laf%W z3UN507={u{|C?U8bV;24Qd)Xd8vLeExO?{E#ronuYxTIezsA{e(&Dywgl*UjYz>C> zgpo{y!=a$+jTlCMJkaS2MMA0?i5p2>RXhEGJ0Bmva?Q7=yZ6WrEtnsi$Ys28@OU6} zFtlLC+Yb-rPWg6z6w>?yfu8c2`X7Vad(*+4mpcyZ@9E-6+VNBCYyuw;yAzb)C30=P z!|=CkWnGL12RT_cM&WVYdQ%a-sVuD5KN&+AspR@TLM@C6>Wcon^3dd!}y z=B+WaGMlT~C#=F;$*jhreSLi?=c%VQxc9aE<5qR{yj{`UxT0Ol+m#CripFBGRN0)i z?AnwyZ)x$U9yN4*AgN`tHBLE(QJ!L$)(B3%N0(^b literal 0 HcmV?d00001 diff --git a/tests/fdkutils_data/input/font.ufo/fontinfo.plist b/tests/fdkutils_data/input/font.ufo/fontinfo.plist new file mode 100644 index 000000000..894448e00 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/fontinfo.plist @@ -0,0 +1,166 @@ + + + + + ascender + 712 + capHeight + 656 + copyright + Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. + descender + -205 + familyName + Source Sans Pro + guidelines + + + italicAngle + 0 + openTypeHheaAscender + 984 + openTypeHheaDescender + -273 + openTypeHheaLineGap + 0 + openTypeNameDesigner + Paul D. Hunt + openTypeNameLicense + This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFL. This Font Software is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software. + openTypeNameLicenseURL + http://scripts.sil.org/OFL + openTypeNameManufacturer + Adobe Systems Incorporated + openTypeNameManufacturerURL + http://www.adobe.com/type + openTypeOS2CodePageRanges + + 0 + 1 + 2 + 3 + 4 + 7 + 8 + 29 + + openTypeOS2Panose + + 2 + 11 + 5 + 3 + 3 + 4 + 3 + 2 + 2 + 4 + + openTypeOS2Type + + + openTypeOS2TypoAscender + 750 + openTypeOS2TypoDescender + -250 + openTypeOS2TypoLineGap + 0 + openTypeOS2UnicodeRanges + + 0 + 1 + 2 + 4 + 5 + 6 + 7 + 9 + 29 + 30 + 32 + 57 + + openTypeOS2VendorID + ADBO + openTypeOS2WinAscent + 984 + openTypeOS2WinDescent + 273 + postscriptBlueFuzz + 0 + postscriptBlueScale + 0.0625 + postscriptBlueValues + + -12 + 0 + 486 + 498 + 518 + 530 + 574 + 586 + 638 + 650 + 656 + 668 + 712 + 724 + + postscriptFamilyBlues + + -12 + 0 + 486 + 498 + 518 + 530 + 574 + 586 + 638 + 650 + 656 + 668 + 712 + 724 + + postscriptFamilyOtherBlues + + postscriptFontName + SourceSansPro-Regular + postscriptForceBold + + postscriptOtherBlues + + -217 + -205 + + postscriptStemSnapH + + 67 + 78 + + postscriptStemSnapV + + 84 + 95 + + postscriptUnderlinePosition + -75 + postscriptUnderlineThickness + 50 + styleName + Regular + trademark + Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + unitsPerEm + 1000 + versionMajor + 2 + versionMinor + 20 + xHeight + 486 + + diff --git a/tests/fdkutils_data/input/font.ufo/glyphs/_notdef.glif b/tests/fdkutils_data/input/font.ufo/glyphs/_notdef.glif new file mode 100644 index 000000000..241ba42b4 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/glyphs/_notdef.glif @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.adobe.type.autohint.v2 + + hintSetList + + + public.postscript.hints + + formatVersion + 1 + hintSetList + + + + + diff --git a/tests/fdkutils_data/input/font.ufo/glyphs/a.glif b/tests/fdkutils_data/input/font.ufo/glyphs/a.glif new file mode 100644 index 000000000..dbd373702 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/glyphs/a.glif @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A note comment on a glif file + + diff --git a/tests/fdkutils_data/input/font.ufo/glyphs/contents.plist b/tests/fdkutils_data/input/font.ufo/glyphs/contents.plist new file mode 100644 index 000000000..f7fa5dd46 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/glyphs/contents.plist @@ -0,0 +1,10 @@ + + + + + .notdef + _notdef.glif + a + a.glif + + diff --git a/tests/fdkutils_data/input/font.ufo/layercontents.plist b/tests/fdkutils_data/input/font.ufo/layercontents.plist new file mode 100644 index 000000000..03e5dde58 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/layercontents.plist @@ -0,0 +1,10 @@ + + + + + + public.default + glyphs + + + diff --git a/tests/fdkutils_data/input/font.ufo/lib.plist b/tests/fdkutils_data/input/font.ufo/lib.plist new file mode 100644 index 000000000..3d0849dab --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/lib.plist @@ -0,0 +1,14 @@ + + + + + public.glyphOrder + + .notdef + a + space + zerowidth + negative + + + diff --git a/tests/fdkutils_data/input/font.ufo/metainfo.plist b/tests/fdkutils_data/input/font.ufo/metainfo.plist new file mode 100644 index 000000000..edfd63767 --- /dev/null +++ b/tests/fdkutils_data/input/font.ufo/metainfo.plist @@ -0,0 +1,10 @@ + + + + + creator + org.robofab.ufoLib + formatVersion + 3 + + diff --git a/tests/fdkutils_data/input/font2.pfa b/tests/fdkutils_data/input/font2.pfa new file mode 100644 index 000000000..20e538318 --- /dev/null +++ b/tests/fdkutils_data/input/font2.pfa @@ -0,0 +1,67 @@ +%!PS-AdobeFont-1.0: SourceSansPro-Regular 2.20 +%%BeginResource: font SourceSansPro-Regular +12 dict dup begin +/FontType 1 def +/FontName /SourceSansPro-Regular def +/FontInfo 8 dict dup begin +/version (2.20) def +/Notice (Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.) def +/Copyright (Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'.) def +/FamilyName (Source Sans Pro) def +/UnderlinePosition -75 def +end def +/PaintType 0 def +/FontMatrix [0.001 0 0 0.001 0 0] def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +def +/FontBBox {52 -12 565 660} def +end +currentfile eexec BAB431EA06BB0A1031E1AA11919E714AC69FC716582140 +9A1388564981D942EE500B49D61B3CC97910D0CB9D859AC10E858AA99F37BFB7 +2DEC66AE63CC76B1AB7644B7BC12305229E38277565394BB6DA5F493CE706107 +205F453E09875F8FF73B622941D8AC93489CC6D0EC27CEE2D44FA72A3F08B67F +9DBFB2FDD4BFF31EDFE97BB0436DE92007E57FC5074AC64781FF43813AF5862C +6B62EF6E4670B6AC176837B456D927F440E3C6B86FC112485E370DDBB5DCDB62 +06B30D09F7F8F034DFEA33480DA86AE4A3C4DD5464F0D581E7C7F5AC84035C46 +74D6E1E9356D3CF8D4698BAED8F82C6B352E19D20F5F748816027D51AC11B251 +60B30397ABB4E3F43EA74323BDDE93300B2CB5EAA48C22C9AA025D721566CD0D +6FAFEEC84DE1547D6BDB7133C5EDEAFD4F621D321A9A8A1F633DED07E7B9C439 +737C35913DC45E44650ED27C1CA88A79C70ABCA3EEC9A6A7B1CE16535F497EA6 +9A331BDE88D35437E91C9C9B94631E6845D663E58230B45D52B42CD922939931 +B0FF6BB7D941471A1C46D90C8498F89F316DA57BF005A8BDB2110A9DF1AA1198 +21C28F9303DCF87A761BB41ABC336C6FF9FF125F7308C5424286DEF0971CBF4E +45A4C85F5DA06BCC70DA662DBFB04DD34B70532E4937B46ACCC8BF97B91E24AF +AE7C274EC6C9924BF6A23BD6B0A8E55BC1A5749F99D796612F3217FE9727AA84 +825F43627A45FAD58546ADC858AE74AD9CF5BDF15B7DFDF1E2BDB1C4F9C6B740 +F3DEA0BD315581004E851EFFCF086466C3C87A58EAB96D3EF4622FF404AAB193 +2891C6917CC22172B06B084903060263E175E1806144957CCA82E46B93C9F9AD +558629928A3E7ED449CFDC2FB10545FF08CA13FCDF9B2E61121DCCCEE75A9CFF +A6449FB61C61FC4E6E0B8F80E56BF1B8C3327A4F67DB6ACBC38FE4049ACF2693 +33DB03E4B9E294CC5051D84B5952ABE63EA04D391493975ECB1DC14E1BE4F13A +61A8ABFC03AB9C321936E9C303485D5B3D98F1A4DBD8E6BB644878399520AB9F +1A57A9133BF3C350FA123C4813ED026C4CE18ED994D7FF785688CF1FFCB3E05F +133710232F68D38D5138C2DF1001891FAA33376F249BCAAC5D7D0F5988F687BA +23F3EEEC995121AD06BAEF932CE04F300AA0683937EF60CD19BA8FC491FB0A06 +4BFA77D5EC2FB757911F96B268D98A17678385BAF2C35F8019622261789E838C +0E626AE55975586038321E9B88021A5AE29EF4564FD047ED6F9E6EF0D60D966B +3EB95D701792F39BD094238FAFCC8A080C13687EA25F8B7AB87A4345D77B860C +BC1279BF0E599CE8D5B6BAAF6417A58E1287C1B966B98307B3C2A0105D6E382D +ECE957CB963C41EEE4EEBA58938508F8C758E7D464201C505EC85441BCEF9988 +9CC05E8740A74E03AA339D209A2CB56580DE0FFF045C9DF7CD827AED90CEC420 +CE3A92A7BE47E652A81203ECE15E068361F93EEA815EEFCAE487EBED5A60A7D8 +3014636438535D747EE5768E9BB8E5855FD8B9A238D8AB4335514C2B866EB980 +71AA79D1867DB9433343EC2FAB34A26F66DF83E46C57DAC3BD7CA643E0A88634 +403AA76313C655DFF4FC538A7B4746F798CF03196628EA2559090A11F5FBDA98 +511337D637B066CA1F5A8DAD +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%EOF diff --git a/tests/fdkutils_data/input/type1.txt b/tests/fdkutils_data/input/type1.txt new file mode 100644 index 000000000..3c933314a --- /dev/null +++ b/tests/fdkutils_data/input/type1.txt @@ -0,0 +1,75 @@ +%!FontType1-1.1: SourceSansPro-Regular 2.20 +%ADOt1write: (1.0.34) +%%BeginResource: font SourceSansPro-Regular +12 dict dup begin +/FontType 1 def +/FontName /SourceSansPro-Regular def +/FontInfo 8 dict dup begin +/version (2.20) def +/Notice (Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.) def +/Copyright (Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'.) def +/FamilyName (Source Sans Pro) def +/UnderlinePosition -75 def +end def +/PaintType 0 def +/FontMatrix [0.001 0 0 0.001 0 0] def +/Encoding StandardEncoding def +/FontBBox {52 -12 565 660} def +end +%currentfile eexec dup /Private +15 dict dup begin +/-| {string currentfile exch readstring pop} def +/|- {def} def +/| {put} def +/BlueValues [-12 0 486 498 518 530 574 586 638 650 656 668 712 724] def +/OtherBlues [-217 -205] def +/BlueScale 0.0625 def +/BlueFuzz 0 def +/StdHW [67] def +/StdVW [84] def +/StemSnapH [67 78] def +/StemSnapV [84 95] def +/password 5839 def +/MinFeature {16 16} def +/OtherSubrs[{}{}{}{systemdict/internaldict known not{pop 3}{1183615869 +systemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup +/strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]def +/Subrs 5 array +dup 0 ## -| { 3 0 callother pop pop setcurrentpoint return } | +dup 1 ## -| { 0 1 callother return } | +dup 2 ## -| { 0 2 callother return } | +dup 3 ## -| { return } | +dup 4 ## -| { 3 1 3 callother pop callsubr return } | +def +put +dup /CharStrings +2 dict dup begin +/.notdef ## -| { 0 653 hsbw 0 58 hstem 600 60 hstem 89 65 vstem 498 67 vstem + 89 hmoveto 476 hlineto 660 vlineto -476 hlineto closepath 108 -602 rmoveto + 74 132 rlineto 54 103 rlineto 4 hlineto 52 -103 rlineto 73 -132 rlineto + closepath -129 329 rmoveto -50 94 rlineto -66 119 rlineto 235 hlineto -66 -119 rlineto + -49 -94 rlineto closepath -175 -277 rmoveto 462 vlineto 127 -232 rlineto + closepath 217 -230 rmoveto -126 230 rlineto 126 232 rlineto closepath endchar + } |- +/a ## -| { 0 504 hsbw 194 -12 rmoveto 61 0 54 32 46 38 rrcurveto 3 hlineto + 7 -58 rlineto 68 hlineto 298 vlineto 121 -50 79 -119 vhcurveto -78 0 -68 -34 -45 -29 rrcurveto + 32 -57 rlineto 38 26 51 26 56 0 rrcurveto 80 20 -60 -62 hvcurveto -207 -23 -91 -53 0 -106 rrcurveto + -87 61 -51 81 vhcurveto closepath 24 66 rmoveto -48 -38 23 55 hvcurveto + 0 62 56 40 162 20 rrcurveto -135 vlineto -47 -42 -38 -23 -47 0 rrcurveto + closepath endchar } |- +end put +end +dup /FontName get exch definefont pop +mark +%currentfile closefile +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%EOF diff --git a/tests/fdkutils_test.py b/tests/fdkutils_test.py index 90c89d474..954b1bc8d 100644 --- a/tests/fdkutils_test.py +++ b/tests/fdkutils_test.py @@ -1,9 +1,140 @@ import argparse import pytest +from os import linesep, path +import sys -from afdko.fdkutils import validate_path +from afdko.fdkutils import ( + get_temp_file_path, + get_temp_dir_path, + get_resources_dir, + get_font_format, + validate_path, + run_shell_command, + run_shell_command_logging, + get_shell_command_output, + runShellCmd, + runShellCmdLogging, +) +from test_utils import get_input_path +mac_linux_only = pytest.mark.skipif( + sys.platform == 'win32', reason="Mac/Linux subprocess results") -def test_validate_path(): +win_only = pytest.mark.skipif( + sys.platform != 'win32', reason="Windows subprocess results") + + +def test_validate_path_valid(): + assert path.exists(validate_path(get_temp_file_path())) is True + + +def test_validate_path_invalid(): with pytest.raises(argparse.ArgumentTypeError): validate_path('not_a_file_or_folder') + + +@pytest.mark.parametrize('path_comp', [None, 'path_component']) +def test_get_temp_dir_path(path_comp): + pth = get_temp_dir_path(path_comp) + if path_comp: + assert path.basename(pth) == path_comp + assert path.isdir(path.dirname(pth)) + else: + assert path.isdir(pth) + + +def test_get_resources_dir(): + assert path.isdir(get_resources_dir()) + + +@pytest.mark.parametrize('filename, fontformat', [ + ('file.txt', None), + ('font.ufo', 'UFO'), + ('font.otf', 'OTF'), + ('font.ttf', 'TTF'), + ('font.cff', 'CFF'), + ('font.pfa', 'PFA'), + ('font2.pfa', 'PFA'), + ('font.pfb', 'PFB'), + ('font.ps', 'PFC'), +]) +def test_get_font_format(filename, fontformat): + assert get_font_format(get_input_path(filename)) == fontformat + + +@pytest.mark.parametrize('cmd, rslt', [ + (['type1', '-h'], True), + (['type1', 'foo'], False), +]) +def test_run_shell_command(cmd, rslt): + assert run_shell_command(cmd) is rslt + + +@pytest.mark.parametrize('cmd, rslt', [ + (['type1', get_input_path('type1.txt')], True), + (['type1', get_input_path('type1.txt'), get_temp_file_path()], True), + (['type1', 'foo'], False), + ('type1 foo', False), +]) +def test_run_shell_command_logging(cmd, rslt): + assert run_shell_command_logging(cmd) is rslt + + +@pytest.mark.parametrize('cmd, rslt', [ + (['type1', '-h'], (True, f'usage: type1 [text [font]]{linesep}')), + (['type1', 'foo'], (False, None)), # goes thru the exception +]) +def test_get_shell_command_output(cmd, rslt): + assert get_shell_command_output(cmd) == rslt + + +def test_runShellCmd_timeout(): + assert runShellCmd('type1 -h', timeout=0) == '' + + +@mac_linux_only +@pytest.mark.parametrize('cmd, shell, str_out', [ + ('type1 -h', True, f'usage: type1 [text [font]]{linesep}'), + ('type1 -h', False, ''), # fails on Windows + (['type1', '-h'], True, ''), # fails on Windows + (['type1', '-h'], False, f'usage: type1 [text [font]]{linesep}'), +]) +def test_runShellCmd_mac_linux(cmd, shell, str_out): + assert runShellCmd(cmd, shell=shell) == str_out + + +@win_only +@pytest.mark.parametrize('cmd, shell', [ + ('type1 -h', True), + ('type1 -h', False), + (['type1', '-h'], True), + (['type1', '-h'], False), +]) +def test_runShellCmd_windows(cmd, shell): + # The shell command call always produces output on Windows, + # regardless of the value of the shell (True/False) and + # no matter if the command/args are a list or a string + assert runShellCmd(cmd, shell=shell) == ( + f'usage: type1 [text [font]]{linesep}') + + +@pytest.mark.parametrize('cmd, shell, str_out', [ + ('type1 foo', True, ''), + ('type1 foo', False, ''), + (['type1', 'foo'], True, ''), + (['type1', 'foo'], False, ''), +]) +def test_runShellCmd_error(cmd, shell, str_out): + assert runShellCmd(cmd, shell=shell) == str_out + + +@pytest.mark.parametrize('cmd, rtrn', [ + ('', 1), + ('type1 foo', 1), + ([''], 1), + (['tx', '-h'], 0), + (['tx', '-z'], 1), + (['type1', get_input_path('type1.txt'), get_temp_file_path()], 0), +]) +def test_runShellCmdLogging_shell_false(cmd, rtrn): + assert runShellCmdLogging(cmd, False) == rtrn