ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ # This file was originally based on the meld3 package version 2.0.0 # (https://pypi.org/project/meld3/2.0.0/). The meld3 package is not # called out separately in Supervisor's license or copyright files # because meld3 had the same authors, copyright, and license as # Supervisor at the time this file was bundled with Supervisor. import unittest import re import sys _SIMPLE_XML = r""" Name Description """ _SIMPLE_XHTML = r""" Hello! """ _EMPTYTAGS_HTML = """

""" _BOOLEANATTRS_XHTML= """ """ _ENTITIES_XHTML= r"""

 

""" _COMPLEX_XHTML = r""" This will be escaped in html output: &
Name Description
""" _NVU_HTML = """ test doc Oh yeah...

Yup More Stuff Oh Yeah
1 2 3 4

And an image...

dumb """ _FILLMELDFORM_HTML = """\ Emergency Contacts
Emergency Contacts
Title
First Name
Middle Name
Last Name
Suffix
Address 1
Address 2
City
State
ZIP
Home Phone
Cell/Mobile Phone
Email Address
Over 18? (Checkbox Boolean)
Mail OK? (Checkbox Ternary)
Favorite Color (Radio) Red Green Blue

Return to list

""" class MeldAPITests(unittest.TestCase): def _makeElement(self, string): from supervisor.templating import parse_xmlstring return parse_xmlstring(string) def _makeElementFromHTML(self, string): from supervisor.templating import parse_htmlstring return parse_htmlstring(string) def test_findmeld(self): root = self._makeElement(_SIMPLE_XML) item = root.findmeld('item') self.assertEqual(item.tag, 'item') name = root.findmeld('name') self.assertEqual(name.text, 'Name') def test_findmeld_default(self): root = self._makeElement(_SIMPLE_XML) item = root.findmeld('item') self.assertEqual(item.tag, 'item') unknown = root.findmeld('unknown', 'foo') self.assertEqual(unknown, 'foo') self.assertEqual(root.findmeld('unknown'), None) def test_repeat_nochild(self): root = self._makeElement(_SIMPLE_XML) item = root.findmeld('item') self.assertEqual(item.tag, 'item') data = [{'name':'Jeff Buckley', 'description':'ethereal'}, {'name':'Slipknot', 'description':'heavy'}] for element, d in item.repeat(data): element.findmeld('name').text = d['name'] element.findmeld('description').text = d['description'] self.assertEqual(item[0].text, 'Jeff Buckley') self.assertEqual(item[1].text, 'ethereal') def test_repeat_child(self): root = self._makeElement(_SIMPLE_XML) list = root.findmeld('list') self.assertEqual(list.tag, 'list') data = [{'name':'Jeff Buckley', 'description':'ethereal'}, {'name':'Slipknot', 'description':'heavy'}] for element, d in list.repeat(data, 'item'): element.findmeld('name').text = d['name'] element.findmeld('description').text = d['description'] self.assertEqual(list[0][0].text, 'Jeff Buckley') self.assertEqual(list[0][1].text, 'ethereal') self.assertEqual(list[1][0].text, 'Slipknot') self.assertEqual(list[1][1].text, 'heavy') def test_mod(self): root = self._makeElement(_SIMPLE_XML) root % {'description':'foo', 'name':'bar'} name = root.findmeld('name') self.assertEqual(name.text, 'bar') desc = root.findmeld('description') self.assertEqual(desc.text, 'foo') def test_fillmelds(self): root = self._makeElement(_SIMPLE_XML) unfilled = root.fillmelds(**{'description':'foo', 'jammyjam':'a'}) desc = root.findmeld('description') self.assertEqual(desc.text, 'foo') self.assertEqual(unfilled, ['jammyjam']) def test_fillmeldhtmlform(self): data = [ {'honorific':'Mr.', 'firstname':'Chris', 'middlename':'Phillips', 'lastname':'McDonough', 'address1':'802 Caroline St.', 'address2':'Apt. 2B', 'city':'Fredericksburg', 'state': 'VA', 'zip':'22401', 'homephone':'555-1212', 'cellphone':'555-1313', 'email':'user@example.com', 'suffix':'Sr.', 'over18':True, 'mailok:inputgroup':'true', 'favorite_color:inputgroup':'Green'}, {'honorific':'Mr.', 'firstname':'Fred', 'middlename':'', 'lastname':'Rogers', 'address1':'1 Imaginary Lane', 'address2':'Apt. 3A', 'city':'Never Never Land', 'state': 'LA', 'zip':'00001', 'homephone':'555-1111', 'cellphone':'555-4444', 'email':'fred@neighborhood.com', 'suffix':'Jr.', 'over18':False, 'mailok:inputgroup':'false','favorite_color:inputgroup':'Yellow',}, {'firstname':'Fred', 'middlename':'', 'lastname':'Rogers', 'address1':'1 Imaginary Lane', 'address2':'Apt. 3A', 'city':'Never Never Land', 'state': 'LA', 'zip':'00001', 'homephone':'555-1111', 'cellphone':'555-4444', 'email':'fred@neighborhood.com', 'suffix':'IV', 'over18':False, 'mailok:inputgroup':'false', 'favorite_color:inputgroup':'Blue', 'notthere':1,}, ] root = self._makeElementFromHTML(_FILLMELDFORM_HTML) clone = root.clone() unfilled = clone.fillmeldhtmlform(**data[0]) self.assertEqual(unfilled, []) self.assertEqual(clone.findmeld('honorific').attrib['value'], 'Mr.') self.assertEqual(clone.findmeld('firstname').attrib['value'], 'Chris') middlename = clone.findmeld('middlename') self.assertEqual(middlename.attrib['value'], 'Phillips') suffix = clone.findmeld('suffix') self.assertEqual(suffix[1].attrib['selected'], 'selected') self.assertEqual(clone.findmeld('over18').attrib['checked'], 'checked') mailok = clone.findmeld('mailok:inputgroup') self.assertEqual(mailok[1].attrib['checked'], 'checked') favoritecolor = clone.findmeld('favorite_color:inputgroup') self.assertEqual(favoritecolor[1].attrib['checked'], 'checked') clone = root.clone() unfilled = clone.fillmeldhtmlform(**data[1]) self.assertEqual(unfilled, ['favorite_color:inputgroup']) self.assertEqual(clone.findmeld('over18').attrib.get('checked'), None) mailok = clone.findmeld('mailok:inputgroup') self.assertEqual(mailok[2].attrib['checked'], 'checked') self.assertEqual(mailok[1].attrib.get('checked'), None) clone = root.clone() unfilled = clone.fillmeldhtmlform(**data[2]) self.assertEqual(sorted(unfilled), ['notthere', 'suffix']) self.assertEqual(clone.findmeld('honorific').text, None) favoritecolor = clone.findmeld('favorite_color:inputgroup') self.assertEqual(favoritecolor[2].attrib['checked'], 'checked') self.assertEqual(favoritecolor[1].attrib.get('checked'), None) def test_replace_removes_all_elements(self): from supervisor.templating import Replace root = self._makeElement(_SIMPLE_XML) L = root.findmeld('list') L.replace('this is a textual replacement') R = root[0] self.assertEqual(R.tag, Replace) self.assertEqual(len(root.getchildren()), 1) def test_replace_replaces_the_right_element(self): from supervisor.templating import Replace root = self._makeElement(_SIMPLE_XML) D = root.findmeld('description') D.replace('this is a textual replacement') self.assertEqual(len(root.getchildren()), 1) L = root[0] self.assertEqual(L.tag, 'list') self.assertEqual(len(L.getchildren()), 1) I = L[0] self.assertEqual(I.tag, 'item') self.assertEqual(len(I.getchildren()), 2) N = I[0] self.assertEqual(N.tag, 'name') self.assertEqual(len(N.getchildren()), 0) D = I[1] self.assertEqual(D.tag, Replace) self.assertEqual(D.text, 'this is a textual replacement') self.assertEqual(len(D.getchildren()), 0) self.assertEqual(D.structure, False) def test_content(self): from supervisor.templating import Replace root = self._makeElement(_SIMPLE_XML) D = root.findmeld('description') D.content('this is a textual replacement') self.assertEqual(len(root.getchildren()), 1) L = root[0] self.assertEqual(L.tag, 'list') self.assertEqual(len(L.getchildren()), 1) I = L[0] self.assertEqual(I.tag, 'item') self.assertEqual(len(I.getchildren()), 2) N = I[0] self.assertEqual(N.tag, 'name') self.assertEqual(len(N.getchildren()), 0) D = I[1] self.assertEqual(D.tag, 'description') self.assertEqual(D.text, None) self.assertEqual(len(D.getchildren()), 1) T = D[0] self.assertEqual(T.tag, Replace) self.assertEqual(T.text, 'this is a textual replacement') self.assertEqual(T.structure, False) def test_attributes(self): from supervisor.templating import _MELD_ID root = self._makeElement(_COMPLEX_XHTML) D = root.findmeld('form1') D.attributes(foo='bar', baz='1', g='2', action='#') self.assertEqual(D.attrib, { 'foo':'bar', 'baz':'1', 'g':'2', 'method':'POST', 'action':'#', _MELD_ID: 'form1'}) def test_attributes_unicode(self): from supervisor.templating import _MELD_ID from supervisor.compat import as_string root = self._makeElement(_COMPLEX_XHTML) D = root.findmeld('form1') D.attributes(foo=as_string('bar', encoding='latin1'), action=as_string('#', encoding='latin1')) self.assertEqual(D.attrib, { 'foo':as_string('bar', encoding='latin1'), 'method':'POST', 'action': as_string('#', encoding='latin1'), _MELD_ID: 'form1'}) def test_attributes_nonstringtype_raises(self): root = self._makeElement('') self.assertRaises(ValueError, root.attributes, foo=1) class MeldElementInterfaceTests(unittest.TestCase): def _getTargetClass(self): from supervisor.templating import _MeldElementInterface return _MeldElementInterface def _makeOne(self, *arg, **kw): klass = self._getTargetClass() return klass(*arg, **kw) def test_repeat(self): root = self._makeOne('root', {}) from supervisor.templating import _MELD_ID item = self._makeOne('item', {_MELD_ID:'item'}) record = self._makeOne('record', {_MELD_ID:'record'}) name = self._makeOne('name', {_MELD_ID:'name'}) description = self._makeOne('description', {_MELD_ID:'description'}) record.append(name) record.append(description) item.append(record) root.append(item) data = [{'name':'Jeff Buckley', 'description':'ethereal'}, {'name':'Slipknot', 'description':'heavy'}] for element, d in item.repeat(data): element.findmeld('name').text = d['name'] element.findmeld('description').text = d['description'] self.assertEqual(len(root), 2) item1 = root[0] self.assertEqual(len(item1), 1) record1 = item1[0] self.assertEqual(len(record1), 2) name1 = record1[0] desc1 = record1[1] self.assertEqual(name1.text, 'Jeff Buckley') self.assertEqual(desc1.text, 'ethereal') item2 = root[1] self.assertEqual(len(item2), 1) record2 = item2[0] self.assertEqual(len(record2), 2) name2 = record2[0] desc2 = record2[1] self.assertEqual(name2.text, 'Slipknot') self.assertEqual(desc2.text, 'heavy') def test_content_simple_nostructure(self): el = self._makeOne('div', {'id':'thediv'}) el.content('hello') self.assertEqual(len(el._children), 1) replacenode = el._children[0] self.assertEqual(replacenode.parent, el) self.assertEqual(replacenode.text, 'hello') self.assertEqual(replacenode.structure, False) from supervisor.templating import Replace self.assertEqual(replacenode.tag, Replace) def test_content_simple_structure(self): el = self._makeOne('div', {'id':'thediv'}) el.content('hello', structure=True) self.assertEqual(len(el._children), 1) replacenode = el._children[0] self.assertEqual(replacenode.parent, el) self.assertEqual(replacenode.text, 'hello') self.assertEqual(replacenode.structure, True) from supervisor.templating import Replace self.assertEqual(replacenode.tag, Replace) def test_findmeld_simple(self): from supervisor.templating import _MELD_ID el = self._makeOne('div', {_MELD_ID:'thediv'}) self.assertEqual(el.findmeld('thediv'), el) def test_findmeld_simple_oneleveldown(self): from supervisor.templating import _MELD_ID el = self._makeOne('div', {_MELD_ID:'thediv'}) span = self._makeOne('span', {_MELD_ID:'thespan'}) el.append(span) self.assertEqual(el.findmeld('thespan'), span) def test_findmeld_simple_twolevelsdown(self): from supervisor.templating import _MELD_ID el = self._makeOne('div', {_MELD_ID:'thediv'}) span = self._makeOne('span', {_MELD_ID:'thespan'}) a = self._makeOne('a', {_MELD_ID:'thea'}) span.append(a) el.append(span) self.assertEqual(el.findmeld('thea'), a) def test_ctor(self): iface = self._makeOne('div', {'id':'thediv'}) self.assertEqual(iface.parent, None) self.assertEqual(iface.tag, 'div') self.assertEqual(iface.attrib, {'id':'thediv'}) def test_getiterator_simple(self): div = self._makeOne('div', {'id':'thediv'}) iterator = div.getiterator() self.assertEqual(len(iterator), 1) self.assertEqual(iterator[0], div) def test_getiterator(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) span3 = self._makeOne('span3', {'id':'3'}) span3.text = 'abc' span3.tail = ' ' div.append(span) span.append(span2) span2.append(span3) it = div.getiterator() self.assertEqual(len(it), 4) self.assertEqual(it[0], div) self.assertEqual(it[1], span) self.assertEqual(it[2], span2) self.assertEqual(it[3], span3) def test_getiterator_tag_ignored(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) span3 = self._makeOne('span3', {'id':'3'}) span3.text = 'abc' span3.tail = ' ' div.append(span) span.append(span2) span2.append(span3) it = div.getiterator(tag='div') self.assertEqual(len(it), 4) self.assertEqual(it[0], div) self.assertEqual(it[1], span) self.assertEqual(it[2], span2) self.assertEqual(it[3], span3) def test_append(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) div.append(span) self.assertEqual(div[0].tag, 'span') self.assertEqual(span.parent, div) def test__setitem__(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) div.append(span) div[0] = span2 self.assertEqual(div[0].tag, 'span') self.assertEqual(div[0].attrib, {'id':'2'}) self.assertEqual(div[0].parent, div) def test_insert(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) div.append(span) div.insert(0, span2) self.assertEqual(div[0].tag, 'span') self.assertEqual(div[0].attrib, {'id':'2'}) self.assertEqual(div[0].parent, div) self.assertEqual(div[1].tag, 'span') self.assertEqual(div[1].attrib, {}) self.assertEqual(div[1].parent, div) def test_clone_simple(self): div = self._makeOne('div', {'id':'thediv'}) div.text = 'abc' div.tail = ' ' span = self._makeOne('span', {}) div.append(span) div.clone() def test_clone(self): div = self._makeOne('div', {'id':'thediv'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) span3 = self._makeOne('span3', {'id':'3'}) span3.text = 'abc' span3.tail = ' ' div.append(span) span.append(span2) span2.append(span3) div2 = div.clone() self.assertEqual(div.tag, div2.tag) self.assertEqual(div.attrib, div2.attrib) self.assertEqual(div[0].tag, div2[0].tag) self.assertEqual(div[0].attrib, div2[0].attrib) self.assertEqual(div[0][0].tag, div2[0][0].tag) self.assertEqual(div[0][0].attrib, div2[0][0].attrib) self.assertEqual(div[0][0][0].tag, div2[0][0][0].tag) self.assertEqual(div[0][0][0].attrib, div2[0][0][0].attrib) self.assertEqual(div[0][0][0].text, div2[0][0][0].text) self.assertEqual(div[0][0][0].tail, div2[0][0][0].tail) self.assertNotEqual(id(div), id(div2)) self.assertNotEqual(id(div[0]), id(div2[0])) self.assertNotEqual(id(div[0][0]), id(div2[0][0])) self.assertNotEqual(id(div[0][0][0]), id(div2[0][0][0])) def test_deparent_noparent(self): div = self._makeOne('div', {}) self.assertEqual(div.parent, None) div.deparent() self.assertEqual(div.parent, None) def test_deparent_withparent(self): parent = self._makeOne('parent', {}) self.assertEqual(parent.parent, None) child = self._makeOne('child', {}) parent.append(child) self.assertEqual(parent.parent, None) self.assertEqual(child.parent, parent) self.assertEqual(parent[0], child) child.deparent() self.assertEqual(child.parent, None) self.assertRaises(IndexError, parent.__getitem__, 0) def test_setslice(self): parent = self._makeOne('parent', {}) child1 = self._makeOne('child1', {}) child2 = self._makeOne('child2', {}) child3 = self._makeOne('child3', {}) children = (child1, child2, child3) parent[0:2] = children self.assertEqual(child1.parent, parent) self.assertEqual(child2.parent, parent) self.assertEqual(child3.parent, parent) self.assertEqual(parent._children, list(children)) def test_delslice(self): parent = self._makeOne('parent', {}) child1 = self._makeOne('child1', {}) child2 = self._makeOne('child2', {}) child3 = self._makeOne('child3', {}) children = (child1, child2, child3) parent[0:2] = children del parent[0:2] self.assertEqual(child1.parent, None) self.assertEqual(child2.parent, None) self.assertEqual(child3.parent, parent) self.assertEqual(len(parent._children), 1) def test_remove(self): parent = self._makeOne('parent', {}) child1 = self._makeOne('child1', {}) parent.append(child1) parent.remove(child1) self.assertEqual(child1.parent, None) self.assertEqual(len(parent._children), 0) def test_lineage(self): from supervisor.templating import _MELD_ID div1 = self._makeOne('div', {_MELD_ID:'div1'}) span1 = self._makeOne('span', {_MELD_ID:'span1'}) span2 = self._makeOne('span', {_MELD_ID:'span2'}) span3 = self._makeOne('span', {_MELD_ID:'span3'}) span4 = self._makeOne('span', {_MELD_ID:'span4'}) span5 = self._makeOne('span', {_MELD_ID:'span5'}) span6 = self._makeOne('span', {_MELD_ID:'span6'}) unknown = self._makeOne('span', {}) div2 = self._makeOne('div2', {_MELD_ID:'div2'}) div1.append(span1) span1.append(span2) span2.append(span3) span3.append(unknown) unknown.append(span4) span4.append(span5) span5.append(span6) div1.append(div2) def ids(L): return [ x.meldid() for x in L ] self.assertEqual(ids(div1.lineage()), ['div1']) self.assertEqual(ids(span1.lineage()), ['span1', 'div1']) self.assertEqual(ids(span2.lineage()), ['span2', 'span1', 'div1']) self.assertEqual(ids(span3.lineage()), ['span3', 'span2', 'span1', 'div1']) self.assertEqual(ids(unknown.lineage()), [None, 'span3', 'span2', 'span1', 'div1']) self.assertEqual(ids(span4.lineage()), ['span4', None, 'span3', 'span2', 'span1','div1']) self.assertEqual(ids(span5.lineage()), ['span5', 'span4', None, 'span3', 'span2', 'span1','div1']) self.assertEqual(ids(span6.lineage()), ['span6', 'span5', 'span4', None,'span3', 'span2', 'span1','div1']) self.assertEqual(ids(div2.lineage()), ['div2', 'div1']) def test_shortrepr(self): from supervisor.compat import as_bytes div = self._makeOne('div', {'id':'div1'}) span = self._makeOne('span', {}) span2 = self._makeOne('span', {'id':'2'}) div2 = self._makeOne('div2', {'id':'div2'}) div.append(span) span.append(span2) div.append(div2) r = div.shortrepr() self.assertEqual(r, as_bytes('
' '
', encoding='latin1')) def test_shortrepr2(self): from supervisor.templating import parse_xmlstring from supervisor.compat import as_bytes root = parse_xmlstring(_COMPLEX_XHTML) r = root.shortrepr() self.assertEqual(r, as_bytes('\n' ' \n' ' \n' ' [...]\n\n' ' \n' ' [...]\n' '', encoding='latin1')) def test_diffmeld1(self): from supervisor.templating import parse_xmlstring from supervisor.templating import _MELD_ID root = parse_xmlstring(_COMPLEX_XHTML) clone = root.clone() div = self._makeOne('div', {_MELD_ID:'newdiv'}) clone.append(div) tr = clone.findmeld('tr') tr.deparent() title = clone.findmeld('title') title.deparent() clone.append(title) # unreduced diff = root.diffmeld(clone) changes = diff['unreduced'] addedtags = [ x.attrib[_MELD_ID] for x in changes['added'] ] removedtags = [x.attrib[_MELD_ID] for x in changes['removed'] ] movedtags = [ x.attrib[_MELD_ID] for x in changes['moved'] ] addedtags.sort() removedtags.sort() movedtags.sort() self.assertEqual(addedtags,['newdiv']) self.assertEqual(removedtags,['td1', 'td2', 'tr']) self.assertEqual(movedtags, ['title']) # reduced changes = diff['reduced'] addedtags = [ x.attrib[_MELD_ID] for x in changes['added'] ] removedtags = [x.attrib[_MELD_ID] for x in changes['removed'] ] movedtags = [ x.attrib[_MELD_ID] for x in changes['moved'] ] addedtags.sort() removedtags.sort() movedtags.sort() self.assertEqual(addedtags,['newdiv']) self.assertEqual(removedtags,['tr']) self.assertEqual(movedtags, ['title']) def test_diffmeld2(self): source = """ """ target = """ """ from supervisor.templating import parse_htmlstring source_root = parse_htmlstring(source) target_root = parse_htmlstring(target) changes = source_root.diffmeld(target_root) # unreduced actual = [x.meldid() for x in changes['unreduced']['moved']] expected = ['b'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['added']] expected = [] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['removed']] expected = [] self.assertEqual(expected, actual) # reduced actual = [x.meldid() for x in changes['reduced']['moved']] expected = ['b'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['added']] expected = [] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['removed']] expected = [] self.assertEqual(expected, actual) def test_diffmeld3(self): source = """ """ target = """ """ from supervisor.templating import parse_htmlstring source_root = parse_htmlstring(source) target_root = parse_htmlstring(target) changes = source_root.diffmeld(target_root) # unreduced actual = [x.meldid() for x in changes['unreduced']['moved']] expected = ['b', 'c'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['added']] expected = ['d', 'e'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['removed']] expected = ['z', 'y'] self.assertEqual(expected, actual) # reduced actual = [x.meldid() for x in changes['reduced']['moved']] expected = ['b'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['added']] expected = ['d'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['removed']] expected = ['z'] self.assertEqual(expected, actual) def test_diffmeld4(self): source = """ """ target = """

""" from supervisor.templating import parse_htmlstring source_root = parse_htmlstring(source) target_root = parse_htmlstring(target) changes = source_root.diffmeld(target_root) # unreduced actual = [x.meldid() for x in changes['unreduced']['moved']] expected = ['a', 'b'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['added']] expected = ['m', 'n'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['removed']] expected = ['c', 'd', 'z', 'y'] self.assertEqual(expected, actual) # reduced actual = [x.meldid() for x in changes['reduced']['moved']] expected = ['a'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['added']] expected = ['m'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['removed']] expected = ['c', 'z'] self.assertEqual(expected, actual) def test_diffmeld5(self): source = """ """ target = """

""" from supervisor.templating import parse_htmlstring source_root = parse_htmlstring(source) target_root = parse_htmlstring(target) changes = source_root.diffmeld(target_root) # unreduced actual = [x.meldid() for x in changes['unreduced']['moved']] expected = ['a', 'b', 'c', 'd'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['added']] expected = [] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['unreduced']['removed']] expected = [] self.assertEqual(expected, actual) # reduced actual = [x.meldid() for x in changes['reduced']['moved']] expected = ['a', 'c'] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['added']] expected = [] self.assertEqual(expected, actual) actual = [x.meldid() for x in changes['reduced']['removed']] expected = [] self.assertEqual(expected, actual) class ParserTests(unittest.TestCase): def _parse(self, *args): from supervisor.templating import parse_xmlstring root = parse_xmlstring(*args) return root def _parse_html(self, *args): from supervisor.templating import parse_htmlstring root = parse_htmlstring(*args) return root def test_parse_simple_xml(self): from supervisor.templating import _MELD_ID root = self._parse(_SIMPLE_XML) self.assertEqual(root.tag, 'root') self.assertEqual(root.parent, None) l1st = root[0] self.assertEqual(l1st.tag, 'list') self.assertEqual(l1st.parent, root) self.assertEqual(l1st.attrib[_MELD_ID], 'list') item = l1st[0] self.assertEqual(item.tag, 'item') self.assertEqual(item.parent, l1st) self.assertEqual(item.attrib[_MELD_ID], 'item') name = item[0] description = item[1] self.assertEqual(name.tag, 'name') self.assertEqual(name.parent, item) self.assertEqual(name.attrib[_MELD_ID], 'name') self.assertEqual(description.tag, 'description') self.assertEqual(description.parent, item) self.assertEqual(description.attrib[_MELD_ID], 'description') def test_parse_simple_xhtml(self): xhtml_ns = '{http://www.w3.org/1999/xhtml}%s' from supervisor.templating import _MELD_ID root = self._parse(_SIMPLE_XHTML) self.assertEqual(root.tag, xhtml_ns % 'html') self.assertEqual(root.attrib, {}) self.assertEqual(root.parent, None) body = root[0] self.assertEqual(body.tag, xhtml_ns % 'body') self.assertEqual(body.attrib[_MELD_ID], 'body') self.assertEqual(body.parent, root) def test_parse_complex_xhtml(self): xhtml_ns = '{http://www.w3.org/1999/xhtml}%s' from supervisor.templating import _MELD_ID root = self._parse(_COMPLEX_XHTML) self.assertEqual(root.tag, xhtml_ns % 'html') self.assertEqual(root.attrib, {}) self.assertEqual(root.parent, None) head = root[0] self.assertEqual(head.tag, xhtml_ns % 'head') self.assertEqual(head.attrib, {}) self.assertEqual(head.parent, root) meta = head[0] self.assertEqual(meta.tag, xhtml_ns % 'meta') self.assertEqual(meta.attrib['content'], 'text/html; charset=ISO-8859-1') self.assertEqual(meta.parent, head) title = head[1] self.assertEqual(title.tag, xhtml_ns % 'title') self.assertEqual(title.attrib[_MELD_ID], 'title') self.assertEqual(title.parent, head) body = root[2] self.assertEqual(body.tag, xhtml_ns % 'body') self.assertEqual(body.attrib, {}) self.assertEqual(body.parent, root) div1 = body[0] self.assertEqual(div1.tag, xhtml_ns % 'div') self.assertEqual(div1.attrib, {'{http://foo/bar}baz': 'slab'}) self.assertEqual(div1.parent, body) div2 = body[1] self.assertEqual(div2.tag, xhtml_ns % 'div') self.assertEqual(div2.attrib[_MELD_ID], 'content_well') self.assertEqual(div2.parent, body) form = div2[0] self.assertEqual(form.tag, xhtml_ns % 'form') self.assertEqual(form.attrib[_MELD_ID], 'form1') self.assertEqual(form.attrib['action'], '.') self.assertEqual(form.attrib['method'], 'POST') self.assertEqual(form.parent, div2) img = form[0] self.assertEqual(img.tag, xhtml_ns % 'img') self.assertEqual(img.parent, form) table = form[1] self.assertEqual(table.tag, xhtml_ns % 'table') self.assertEqual(table.attrib[_MELD_ID], 'table1') self.assertEqual(table.attrib['border'], '0') self.assertEqual(table.parent, form) tbody = table[0] self.assertEqual(tbody.tag, xhtml_ns % 'tbody') self.assertEqual(tbody.attrib[_MELD_ID], 'tbody') self.assertEqual(tbody.parent, table) tr = tbody[0] self.assertEqual(tr.tag, xhtml_ns % 'tr') self.assertEqual(tr.attrib[_MELD_ID], 'tr') self.assertEqual(tr.attrib['class'], 'foo') self.assertEqual(tr.parent, tbody) td1 = tr[0] self.assertEqual(td1.tag, xhtml_ns % 'td') self.assertEqual(td1.attrib[_MELD_ID], 'td1') self.assertEqual(td1.parent, tr) td2 = tr[1] self.assertEqual(td2.tag, xhtml_ns % 'td') self.assertEqual(td2.attrib[_MELD_ID], 'td2') self.assertEqual(td2.parent, tr) def test_nvu_html(self): from supervisor.templating import _MELD_ID from supervisor.templating import Comment root = self._parse_html(_NVU_HTML) self.assertEqual(root.tag, 'html') self.assertEqual(root.attrib, {}) self.assertEqual(root.parent, None) head = root[0] self.assertEqual(head.tag, 'head') self.assertEqual(head.attrib, {}) self.assertEqual(head.parent, root) meta = head[0] self.assertEqual(meta.tag, 'meta') self.assertEqual(meta.attrib['content'], 'text/html; charset=ISO-8859-1') title = head[1] self.assertEqual(title.tag, 'title') self.assertEqual(title.attrib[_MELD_ID], 'title') self.assertEqual(title.parent, head) body = root[1] self.assertEqual(body.tag, 'body') self.assertEqual(body.attrib, {}) self.assertEqual(body.parent, root) comment = body[0] self.assertEqual(comment.tag, Comment) table = body[3] self.assertEqual(table.tag, 'table') self.assertEqual(table.attrib, {'style': 'text-align: left; width: 100px;', 'border':'1', 'cellpadding':'2', 'cellspacing':'2'}) self.assertEqual(table.parent, body) href = body[5] self.assertEqual(href.tag, 'a') img = body[8] self.assertEqual(img.tag, 'img') def test_dupe_meldids_fails_parse_xml(self): meld_ns = "https://github.com/Supervisor/supervisor" repeated = ('' '' % meld_ns) self.assertRaises(ValueError, self._parse, repeated) def test_dupe_meldids_fails_parse_html(self): meld_ns = "https://github.com/Supervisor/supervisor" repeated = ('' '' % meld_ns) self.assertRaises(ValueError, self._parse_html, repeated) class UtilTests(unittest.TestCase): def test_insert_xhtml_doctype(self): from supervisor.templating import insert_doctype orig = '' actual = insert_doctype(orig) expected = '' self.assertEqual(actual, expected) def test_insert_doctype_after_xmldecl(self): from supervisor.templating import insert_doctype orig = '' actual = insert_doctype(orig) expected = '' self.assertEqual(actual, expected) def test_insert_meld_ns_decl(self): from supervisor.templating import insert_meld_ns_decl orig = '' actual = insert_meld_ns_decl(orig) expected = '' self.assertEqual(actual, expected) def test_prefeed_preserves_existing_meld_ns(self): from supervisor.templating import prefeed orig = '' actual = prefeed(orig) expected = '' self.assertEqual(actual, expected) def test_prefeed_preserves_existing_doctype(self): from supervisor.templating import prefeed orig = '' actual = prefeed(orig) self.assertEqual(actual, orig) class WriterTests(unittest.TestCase): def _parse(self, xml): from supervisor.templating import parse_xmlstring root = parse_xmlstring(xml) return root def _parse_html(self, xml): from supervisor.templating import parse_htmlstring root = parse_htmlstring(xml) return root def _write(self, fn, **kw): try: from io import BytesIO except: # python 2.5 from StringIO import StringIO as BytesIO out = BytesIO() fn(out, **kw) out.seek(0) actual = out.read() return actual def _write_xml(self, node, **kw): return self._write(node.write_xml, **kw) def _write_html(self, node, **kw): return self._write(node.write_html, **kw) def _write_xhtml(self, node, **kw): return self._write(node.write_xhtml, **kw) def assertNormalizedXMLEqual(self, a, b): from supervisor.compat import as_string a = normalize_xml(as_string(a, encoding='latin1')) b = normalize_xml(as_string(b, encoding='latin1')) self.assertEqual(a, b) def assertNormalizedHTMLEqual(self, a, b): from supervisor.compat import as_string a = normalize_xml(as_string(a, encoding='latin1')) b = normalize_xml(as_string(b, encoding='latin1')) self.assertEqual(a, b) def test_write_simple_xml(self): root = self._parse(_SIMPLE_XML) actual = self._write_xml(root) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) for el, data in root.findmeld('item').repeat(((1,2),)): el.findmeld('name').text = str(data[0]) el.findmeld('description').text = str(data[1]) actual = self._write_xml(root) expected = """ 1 2 """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_xhtml(root) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_as_html(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_html(root) expected = """ Hello! """ self.assertNormalizedHTMLEqual(actual, expected) def test_write_complex_xhtml_as_html(self): root = self._parse(_COMPLEX_XHTML) actual = self._write_html(root) expected = """ This will be escaped in html output: &
Name Description
""" self.assertNormalizedHTMLEqual(actual, expected) def test_write_complex_xhtml_as_xhtml(self): # I'm not entirely sure if the cdata "script" quoting in this # test is entirely correct for XHTML. Ryan Tomayko suggests # that escaped entities are handled properly in script tags by # XML-aware browsers at # http://sourceforge.net/mailarchive/message.php?msg_id=10835582 # but I haven't tested it at all. ZPT does not seem to do # this; it outputs unescaped data. root = self._parse(_COMPLEX_XHTML) actual = self._write_xhtml(root) expected = """ This will be escaped in html output: &
Name Description
""" self.assertNormalizedXMLEqual(actual, expected) def test_write_emptytags_html(self): from supervisor.compat import as_string root = self._parse(_EMPTYTAGS_HTML) actual = self._write_html(root) expected = """

""" self.assertEqual(as_string(actual, encoding='latin1'), expected) def test_write_booleanattrs_xhtml_as_html(self): root = self._parse(_BOOLEANATTRS_XHTML) actual = self._write_html(root) expected = """ """ self.assertNormalizedHTMLEqual(actual, expected) def test_write_simple_xhtml_pipeline(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_xhtml(root, pipeline=True) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_pipeline(self): root = self._parse(_SIMPLE_XML) actual = self._write_xml(root, pipeline=True) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_override_encoding(self): root = self._parse(_SIMPLE_XML) actual = self._write_xml(root, encoding="latin-1") expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_as_fragment(self): root = self._parse(_SIMPLE_XML) actual = self._write_xml(root, fragment=True) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_with_doctype(self): root = self._parse(_SIMPLE_XML) from supervisor.templating import doctype actual = self._write_xml(root, doctype=doctype.xhtml) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_doctype_nodeclaration(self): root = self._parse(_SIMPLE_XML) from supervisor.templating import doctype actual = self._write_xml(root, declaration=False, doctype=doctype.xhtml) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xml_fragment_kills_doctype_and_declaration(self): root = self._parse(_SIMPLE_XML) from supervisor.templating import doctype actual = self._write_xml(root, declaration=True, doctype=doctype.xhtml, fragment=True) expected = """ Name Description """ self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_override_encoding(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_xhtml(root, encoding="latin-1", declaration=True) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_as_fragment(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_xhtml(root, fragment=True) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_with_doctype(self): root = self._parse(_SIMPLE_XHTML) from supervisor.templating import doctype actual = self._write_xhtml(root, doctype=doctype.xhtml) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_doctype_nodeclaration(self): root = self._parse(_SIMPLE_XHTML) from supervisor.templating import doctype actual = self._write_xhtml(root, declaration=False, doctype=doctype.xhtml) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_fragment_kills_doctype_and_declaration(self): root = self._parse(_SIMPLE_XHTML) from supervisor.templating import doctype actual = self._write_xhtml(root, declaration=True, doctype=doctype.xhtml, fragment=True) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_as_html_fragment(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_html(root, fragment=True) expected = """Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_with_doctype_as_html(self): root = self._parse(_SIMPLE_XHTML) actual = self._write_html(root) expected = """ Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_write_simple_xhtml_as_html_new_doctype(self): root = self._parse(_SIMPLE_XHTML) from supervisor.templating import doctype actual = self._write_html(root, doctype=doctype.html_strict) expected = """ Hello!""" self.assertNormalizedXMLEqual(actual, expected) def test_unknown_entity(self): # exception thrown may vary by python or expat version from xml.parsers import expat self.assertRaises((expat.error, SyntaxError), self._parse, '&fleeb;') def test_content_nostructure(self): root = self._parse(_SIMPLE_XML) D = root.findmeld('description') D.content('description &&', structure=False) actual = self._write_xml(root) expected = """ Name description &<foo>&<bar> """ self.assertNormalizedXMLEqual(actual, expected) def test_content_structure(self): root = self._parse(_SIMPLE_XML) D = root.findmeld('description') D.content('description & ', structure=True) actual = self._write_xml(root) expected = """ Name description & """ self.assertNormalizedXMLEqual(actual, expected) def test_replace_nostructure(self): root = self._parse(_SIMPLE_XML) D = root.findmeld('description') D.replace('description &&', structure=False) actual = self._write_xml(root) expected = """ Name description &<foo>&<bar> """ self.assertNormalizedXMLEqual(actual, expected) def test_replace_structure(self): root = self._parse(_SIMPLE_XML) D = root.findmeld('description') D.replace('description & ', structure=True) actual = self._write_xml(root) expected = """ Name description & """ self.assertNormalizedXMLEqual(actual, expected) def test_escape_cdata(self): from supervisor.compat import as_bytes from supervisor.templating import _escape_cdata a = ('< > <& &' && &foo "" ' 'http://www.example.com?foo=bar&bang=baz {') self.assertEqual( as_bytes('< > <& &' && &foo "" ' 'http://www.example.com?foo=bar&bang=baz {', encoding='latin1'), _escape_cdata(a)) def test_escape_cdata_unicodeerror(self): from supervisor.templating import _escape_cdata from supervisor.compat import as_bytes from supervisor.compat import as_string a = as_string(as_bytes('\x80', encoding='latin1'), encoding='latin1') self.assertEqual(as_bytes('€', encoding='latin1'), _escape_cdata(a, 'ascii')) def test_escape_attrib(self): from supervisor.templating import _escape_attrib from supervisor.compat import as_bytes a = ('< > <& &' && &foo "" ' 'http://www.example.com?foo=bar&bang=baz {') self.assertEqual( as_bytes('< > <& &' ' '&& &foo "" ' 'http://www.example.com?foo=bar&bang=baz {', encoding='latin1'), _escape_attrib(a, None)) def test_escape_attrib_unicodeerror(self): from supervisor.templating import _escape_attrib from supervisor.compat import as_bytes from supervisor.compat import as_string a = as_string(as_bytes('\x80', encoding='latin1'), encoding='latin1') self.assertEqual(as_bytes('€', encoding='latin1'), _escape_attrib(a, 'ascii')) def normalize_html(s): s = re.sub(r"[ \t]+", " ", s) s = re.sub(r"/>", ">", s) return s def normalize_xml(s): s = re.sub(r"\s+", " ", s) s = re.sub(r"(?s)\s+<", "<", s) s = re.sub(r"(?s)>\s+", ">", s) return s def test_suite(): return unittest.findTestCases(sys.modules[__name__]) def main(): unittest.main(defaultTest='test_suite') if __name__ == '__main__': main()