diff options
Diffstat (limited to 'src/zope/tal/tests')
164 files changed, 5371 insertions, 0 deletions
diff --git a/src/zope/tal/tests/__init__.py b/src/zope/tal/tests/__init__.py new file mode 100644 index 0000000..b711d36 --- /dev/null +++ b/src/zope/tal/tests/__init__.py @@ -0,0 +1,2 @@ +# +# This file is necessary to make this directory a package. diff --git a/src/zope/tal/tests/input/__init__.py b/src/zope/tal/tests/input/__init__.py new file mode 100644 index 0000000..b711d36 --- /dev/null +++ b/src/zope/tal/tests/input/__init__.py @@ -0,0 +1,2 @@ +# +# This file is necessary to make this directory a package. diff --git a/src/zope/tal/tests/input/acme_template.pt b/src/zope/tal/tests/input/acme_template.pt new file mode 100644 index 0000000..0af01ba --- /dev/null +++ b/src/zope/tal/tests/input/acme_template.pt @@ -0,0 +1,15 @@ +<!-- This is ACME's generic look and feel, which is based on +PNOME's look and feel. --> +<html metal:extend-macro="pnome_macros_page" metal:define-macro="page"> +<head> +<title metal:fill-slot="title">ACME Look and Feel</title> +</head> +<body> +<div metal:fill-slot="page-footer"> +Copyright 2004 Acme Inc. +<div metal:define-slot="disclaimer"> +Standard disclaimers apply. +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/input/document_list.pt b/src/zope/tal/tests/input/document_list.pt new file mode 100644 index 0000000..8226be1 --- /dev/null +++ b/src/zope/tal/tests/input/document_list.pt @@ -0,0 +1,21 @@ +<!-- ACME's document_list uses the ACME look and feel --> +<html metal:use-macro="acme_macros_page"> +<head> +<title metal:fill-slot="title">Acme Document List</title> +<style metal:fill-slot="local-styles" type="text/css"> + body { background-color: white; } +</style> +</head> +<body> +<div metal:fill-slot="content"> +<h1>Documents</h1> +<ul> +<li>Rocket Science for Dummies</li> +<li>Birds for the Gourmet Chef</li> +</ul> +</div> +<div metal:fill-slot="disclaimer"> +This document list is classified. +</div> +</body> +</html> diff --git a/src/zope/tal/tests/input/pnome_template.pt b/src/zope/tal/tests/input/pnome_template.pt new file mode 100644 index 0000000..f4d1c66 --- /dev/null +++ b/src/zope/tal/tests/input/pnome_template.pt @@ -0,0 +1,23 @@ +<!-- fakeplone is a fictional user interface created by a large, +well-focused team of graphics designers --> +<html metal:define-macro="page"> +<head> +<title metal:define-slot="title">Title here</title> +<metal:block define-slot="local-styles"> +</metal:block> +</head> +<body> +<div> + <div metal:define-slot="annoying-quote"> + "The early bird gets the worm, but the second mouse gets the cheese." + </div> + <a href="#">Preferences...</a> +</div> +<div metal:define-slot="content"> + Content here +</div> +<div metal:define-slot="page-footer"> + page footer +</div> +</body> +</html> diff --git a/src/zope/tal/tests/input/test01.html b/src/zope/tal/tests/input/test01.html new file mode 100644 index 0000000..e2ae0c4 --- /dev/null +++ b/src/zope/tal/tests/input/test01.html @@ -0,0 +1,56 @@ +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> + + <head>dadada</head> + + <body xmlns:z="http://xml.zope.org/namespaces/tal" z:define="foo python:1"> +<h1 z:condition="python:0">This title is not displayed</h1> + <h1 z:condition="python:1" z:content="str:This +Is +The +Replaced +Title">Title</h1> + + <!-- test entity references --> + &HarryPotter; + + <!-- examples adapted from TemplateAttributeLanguageSyntax --> + + <span z:content="str:here/id"/> + + <p z:define="x str:template/title; global five python:2+3;" z:content="text var:five"/> + + <p z:repeat="car python:['honda', 'subaru', 'acura']"> + <span z:replace="var:car"/> + </p> + + <p xml:foo="bar">foo bar</p> + + <!-- more examples --> + + <ul> + <span z:repeat="car python:['honda', 'subaru', 'acura']"> + <li z:content="var:car">Car Name</li> + </span> + </ul> + + <!-- test attribute expansion --> + + <a href="foo" z:attributes="href python:'http://python.org' ">python</a> + <a z:attributes="href python:'http://python.org' ">python</a> + + <!-- test insert/replace structure --> + <span z:content="structure python:None" /> + <span z:replace="structure python:None" /> + + <span z:define="global x str:<h3>Header Level 3</h3>" /> + <span z:define="global x python:'&' + 'nbsp;;' + x" /> + + <span z:replace="structure x" /> + <span z:content="structure x" /> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test01.xml b/src/zope/tal/tests/input/test01.xml new file mode 100644 index 0000000..82038e9 --- /dev/null +++ b/src/zope/tal/tests/input/test01.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" ?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> + + <head>dadada</head> + + <body xmlns:z="http://xml.zope.org/namespaces/tal" z:define="foo python:1"> +<h1 z:condition="python:0">This title is not displayed</h1> + <h1 z:condition="python:1" z:content="str:This +Is +The +Replaced +Title">Title</h1> + + <!-- test entity references --> + &HarryPotter; + + <!-- examples adapted from TemplateAttributeLanguageSyntax --> + + <span z:content="str:here/id"/> + + <p z:define="x str:template/title; global five python:2+3;" z:content="text var:five"/> + + <p z:repeat="car python:['honda', 'subaru', 'acura']"> + <span z:replace="var:car"/> + </p> + + <p xml:foo="bar">foo bar</p> + + <!-- more examples --> + + <ul> + <span z:repeat="car python:['honda', 'subaru', 'acura']"> + <li z:content="var:car">Car Name</li> + </span> + </ul> + + <!-- test attribute expansion --> + + <a href="foo" z:attributes="href python:'http://python.org' ">python</a> + <a z:attributes="href python:'http://python.org' ">python</a> + + <!-- test insert/replace structure --> + <span z:content="structure python:None" /> + <span z:replace="structure python:None" /> + + <span z:define="global x str:<h3>Header Level 3</h3>" /> + <span z:define="global x python:'&' + 'nbsp;;' + x" /> + + <span z:replace="structure x" /> + <span z:content="structure x" /> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test02.html b/src/zope/tal/tests/input/test02.html new file mode 100644 index 0000000..df2fb18 --- /dev/null +++ b/src/zope/tal/tests/input/test02.html @@ -0,0 +1,118 @@ +<biztalk_1 xmlns="urn:schemas-biztalk-org:biztalk:biztalk_1"> + +<foo:header xmlns:foo="whomping-willow" plain="guido" quote='"' apostrophe="'" both=""'" lt="<" gt=">" amp="&" foo=""> + <manifest> + <document> + <name>sample1</name> + <description>a simple invoice</description> + </document> + </manifest> +</foo:header> + +<body> + +<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order --> + +<Invoice xmlns="urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"> + <Header> + <InvoiceNumber>01786</InvoiceNumber> + <InvoiceDate>2000-03-17</InvoiceDate> <!-- March 17th, 2000 --> + <OrderNo>55377</OrderNo> + <OrderDate>2000-03-15</OrderDate> <!-- March 15th, 2000 --> + <CustomerPO>GJ03405</CustomerPO> + <ShipMethod>DAVE 1</ShipMethod> + <ShipDate>2000-03-17</ShipDate> <!-- March 17th, 2000 --> + <CustomerID>K5211(34)</CustomerID> + <SalesPersonCode>23</SalesPersonCode> + <TaxID>23</TaxID> + </Header> + <InvoiceTo> + <Name>SHIPWRIGHT RESTAURANTS LIMITED</Name> + <AddressLine>125 NORTH SERVICE ROAD W</AddressLine> + <AddressLine>WESTLAKE ACCESS</AddressLine> + <City>NORTH BAY</City> + <PostCode>L8B1O5</PostCode> + <State>ONTARIO</State> + <Country>CANADA</Country> + </InvoiceTo> + <ShipTo> + <Name/> + <AddressLine>ATTN: PAULINE DEGRASSI</AddressLine> + <City/> + <PostCode/> + <State/> + <Country/> + </ShipTo> + <DetailLines> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 5309</PartNumber> + <PartDescription>#1013 12 OZ.MUNICH STEIN</PartDescription> + <UnitPrice>37.72</UnitPrice> + <LineTotal>37.72</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6420</PartNumber> + <PartDescription>PROVINCIAL DINNER FORK</PartDescription> + <UnitPrice>17.98</UnitPrice> + <LineTotal>107.88</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>72</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>JR20643</PartNumber> + <PartDescription>PLASTIC HANDLED STEAK KNIFE</PartDescription> + <UnitPrice>.81</UnitPrice> + <LineTotal>58.32</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6410</PartNumber> + <PartDescription>PROVINCIAL TEASPOONS</PartDescription> + <UnitPrice>12.16</UnitPrice> + <LineTotal>72.96</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>0</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6411</PartNumber> + <PartDescription>PROVINCIAL RD BOWL SPOON</PartDescription> + <QuantityBackOrdered>6</QuantityBackOrdered> + <UnitPrice>17.98</UnitPrice> + <LineTotal>0.00</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>DO 3218</PartNumber> + <PartDescription>34 OZ DUAL DIAL SCALE AM3218</PartDescription> + <UnitPrice>70.00</UnitPrice> + <DiscountPercentage>5.0</DiscountPercentage> + <LineTotal>66.50</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 195</PartNumber> + <PartDescription>20 OZ.BEER PUB GLASS</PartDescription> + <UnitPrice>55.90</UnitPrice> + <LineTotal>55.90</LineTotal> + </DetailLine> + </DetailLines> + <Totals> + <SubTotal>399.28</SubTotal> + <DiscountTotal>3.50</DiscountTotal> + <FreightTotal>23.75</FreightTotal> + <GSTTotal>29.61</GSTTotal> + <ProvTaxTotal>33.84</ProvTaxTotal> + <OtherTotal>33.84</OtherTotal> + <InvoiceTotal>486.48</InvoiceTotal> + </Totals> +</Invoice> + +</body> +</biztalk_1> diff --git a/src/zope/tal/tests/input/test02.xml b/src/zope/tal/tests/input/test02.xml new file mode 100644 index 0000000..69567ea --- /dev/null +++ b/src/zope/tal/tests/input/test02.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" ?> +<biztalk_1 xmlns="urn:schemas-biztalk-org:biztalk:biztalk_1"> + +<foo:header xmlns:foo="whomping-willow" plain="guido" quote='"' apostrophe="'" both=""'" lt="<" gt=">" amp="&" foo=""> + <manifest> + <document> + <name>sample1</name> + <description>a simple invoice</description> + </document> + </manifest> +</foo:header> + +<body> + +<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order --> + +<Invoice xmlns="urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"> + <Header> + <InvoiceNumber>01786</InvoiceNumber> + <InvoiceDate>2000-03-17</InvoiceDate> <!-- March 17th, 2000 --> + <OrderNo>55377</OrderNo> + <OrderDate>2000-03-15</OrderDate> <!-- March 15th, 2000 --> + <CustomerPO>GJ03405</CustomerPO> + <ShipMethod>DAVE 1</ShipMethod> + <ShipDate>2000-03-17</ShipDate> <!-- March 17th, 2000 --> + <CustomerID>K5211(34)</CustomerID> + <SalesPersonCode>23</SalesPersonCode> + <TaxID>23</TaxID> + </Header> + <InvoiceTo> + <Name>SHIPWRIGHT RESTAURANTS LIMITED</Name> + <AddressLine>125 NORTH SERVICE ROAD W</AddressLine> + <AddressLine>WESTLAKE ACCESS</AddressLine> + <City>NORTH BAY</City> + <PostCode>L8B1O5</PostCode> + <State>ONTARIO</State> + <Country>CANADA</Country> + </InvoiceTo> + <ShipTo> + <Name/> + <AddressLine>ATTN: PAULINE DEGRASSI</AddressLine> + <City/> + <PostCode/> + <State/> + <Country/> + </ShipTo> + <DetailLines> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 5309</PartNumber> + <PartDescription>#1013 12 OZ.MUNICH STEIN</PartDescription> + <UnitPrice>37.72</UnitPrice> + <LineTotal>37.72</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6420</PartNumber> + <PartDescription>PROVINCIAL DINNER FORK</PartDescription> + <UnitPrice>17.98</UnitPrice> + <LineTotal>107.88</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>72</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>JR20643</PartNumber> + <PartDescription>PLASTIC HANDLED STEAK KNIFE</PartDescription> + <UnitPrice>.81</UnitPrice> + <LineTotal>58.32</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6410</PartNumber> + <PartDescription>PROVINCIAL TEASPOONS</PartDescription> + <UnitPrice>12.16</UnitPrice> + <LineTotal>72.96</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>0</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6411</PartNumber> + <PartDescription>PROVINCIAL RD BOWL SPOON</PartDescription> + <QuantityBackOrdered>6</QuantityBackOrdered> + <UnitPrice>17.98</UnitPrice> + <LineTotal>0.00</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>DO 3218</PartNumber> + <PartDescription>34 OZ DUAL DIAL SCALE AM3218</PartDescription> + <UnitPrice>70.00</UnitPrice> + <DiscountPercentage>5.0</DiscountPercentage> + <LineTotal>66.50</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 195</PartNumber> + <PartDescription>20 OZ.BEER PUB GLASS</PartDescription> + <UnitPrice>55.90</UnitPrice> + <LineTotal>55.90</LineTotal> + </DetailLine> + </DetailLines> + <Totals> + <SubTotal>399.28</SubTotal> + <DiscountTotal>3.50</DiscountTotal> + <FreightTotal>23.75</FreightTotal> + <GSTTotal>29.61</GSTTotal> + <ProvTaxTotal>33.84</ProvTaxTotal> + <OtherTotal>33.84</OtherTotal> + <InvoiceTotal>486.48</InvoiceTotal> + </Totals> +</Invoice> + +</body> +</biztalk_1> diff --git a/src/zope/tal/tests/input/test03.html b/src/zope/tal/tests/input/test03.html new file mode 100644 index 0000000..a0230e1 --- /dev/null +++ b/src/zope/tal/tests/input/test03.html @@ -0,0 +1,9 @@ +<p xmlns:z="http://xml.zope.org/namespaces/tal"> + <span z:define="local x str:hello brave new world"> + <span z:content="text local:x">outer variable x, first appearance</span> + <span z:define="local x str:goodbye cruel world"> + <span z:content="text local:x">inner variable x</span> + </span> + <span z:content="text local:x">outer variable x, second appearance</span> + </span> +</p> diff --git a/src/zope/tal/tests/input/test03.xml b/src/zope/tal/tests/input/test03.xml new file mode 100644 index 0000000..830149d --- /dev/null +++ b/src/zope/tal/tests/input/test03.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<p xmlns:z="http://xml.zope.org/namespaces/tal"> + <span z:define="local x str:hello brave new world"> + <span z:content="text local:x">outer variable x, first appearance</span> + <span z:define="local x str:goodbye cruel world"> + <span z:content="text local:x">inner variable x</span> + </span> + <span z:content="text local:x">outer variable x, second appearance</span> + </span> +</p> diff --git a/src/zope/tal/tests/input/test04.html b/src/zope/tal/tests/input/test04.html new file mode 100644 index 0000000..bdaad39 --- /dev/null +++ b/src/zope/tal/tests/input/test04.html @@ -0,0 +1,26 @@ +<html> + + <body xmlns:m="http://xml.zope.org/namespaces/metal" xmlns:z="http://xml.zope.org/namespaces/tal" m:define-macro="body" z:define="global count python:0"> + + <ul m:define-macro="whoops"> + <li z:repeat="item python:range(count)"> + <span z:replace="item">1</span> + <span z:replace="global:message"/> + </li> + </ul> + + <span z:define="global count python:2; global message str:hello world"/> + + <p m:use-macro="whoops">use-macro + <span m:fill-slot="whoops">fill-slot</span> + </p> + + <span z:define="global message str:goodbye cruel world"/> + + <p m:use-macro="whoops">use-macro</p> + + <p m:define-slot="whoops">define-slot</p> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test04.xml b/src/zope/tal/tests/input/test04.xml new file mode 100644 index 0000000..bde6cef --- /dev/null +++ b/src/zope/tal/tests/input/test04.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" ?> +<html> + + <body xmlns:m="http://xml.zope.org/namespaces/metal" xmlns:z="http://xml.zope.org/namespaces/tal" m:define-macro="body" z:define="global count python:0"> + + <ul m:define-macro="whoops"> + <li z:repeat="item python:range(count)"> + <span z:replace="item">1</span> + <span z:replace="global:message"/> + </li> + </ul> + + <span z:define="global count python:2; global message str:hello world"/> + + <p m:use-macro="whoops">use-macro + <span m:fill-slot="whoops">fill-slot</span> + </p> + + <span z:define="global message str:goodbye cruel world"/> + + <p m:use-macro="whoops">use-macro</p> + + <p m:define-slot="whoops">define-slot</p> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test05.html b/src/zope/tal/tests/input/test05.html new file mode 100644 index 0000000..21f6b68 --- /dev/null +++ b/src/zope/tal/tests/input/test05.html @@ -0,0 +1,9 @@ +<html> + + <body xmlns:m="http://xml.zope.org/namespaces/metal" m:define-macro="body"> + + <h1>This is the body of test5</h1> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test05.xml b/src/zope/tal/tests/input/test05.xml new file mode 100644 index 0000000..fcaaf6b --- /dev/null +++ b/src/zope/tal/tests/input/test05.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<html> + + <body xmlns:m="http://xml.zope.org/namespaces/metal" m:define-macro="body"> + + <h1>This is the body of test5</h1> + + </body> + +</html> diff --git a/src/zope/tal/tests/input/test06.html b/src/zope/tal/tests/input/test06.html new file mode 100644 index 0000000..ac1264d --- /dev/null +++ b/src/zope/tal/tests/input/test06.html @@ -0,0 +1,6 @@ +<html> + <body xmlns:m="http://xml.zope.org/namespaces/metal" + m:use-macro="tests/input/test05.html/body"> + dummy body in test6 + </body> +</html> diff --git a/src/zope/tal/tests/input/test06.xml b/src/zope/tal/tests/input/test06.xml new file mode 100644 index 0000000..b32bd0f --- /dev/null +++ b/src/zope/tal/tests/input/test06.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<html> + <body xmlns:m="http://xml.zope.org/namespaces/metal" + m:use-macro="tests/input/test05.xml/body"> + dummy body in test6 + </body> +</html> diff --git a/src/zope/tal/tests/input/test07.html b/src/zope/tal/tests/input/test07.html new file mode 100644 index 0000000..bff98f0 --- /dev/null +++ b/src/zope/tal/tests/input/test07.html @@ -0,0 +1,11 @@ +<table xmlns:m="http://xml.zope.org/namespaces/metal" m:define-macro="myTable"> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span m:define-slot="bottomRight">Bottom Right</span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/input/test07.xml b/src/zope/tal/tests/input/test07.xml new file mode 100644 index 0000000..e5c520a --- /dev/null +++ b/src/zope/tal/tests/input/test07.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" ?> +<table xmlns:m="http://xml.zope.org/namespaces/metal" m:define-macro="myTable"> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span m:define-slot="bottomRight">Bottom Right</span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/input/test08.html b/src/zope/tal/tests/input/test08.html new file mode 100644 index 0000000..1e4915b --- /dev/null +++ b/src/zope/tal/tests/input/test08.html @@ -0,0 +1,44 @@ +<table xmlns:m="http://xml.zope.org/namespaces/metal" m:use-macro="tests/input/test07.html/myTable"> +<!-- macro use with slots --> + <tr> + <td> + <span m:fill-slot="bottomRight"> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + </span> + </td> + </tr> +</table> diff --git a/src/zope/tal/tests/input/test08.xml b/src/zope/tal/tests/input/test08.xml new file mode 100644 index 0000000..b0360fa --- /dev/null +++ b/src/zope/tal/tests/input/test08.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" ?> +<table xmlns:m="http://xml.zope.org/namespaces/metal" m:use-macro="tests/input/test07.xml/myTable"> +<!-- macro use with slots --> + <tr> + <td> + <span m:fill-slot="bottomRight"> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + </span> + </td> + </tr> +</table> diff --git a/src/zope/tal/tests/input/test09.html b/src/zope/tal/tests/input/test09.html new file mode 100644 index 0000000..35f481a --- /dev/null +++ b/src/zope/tal/tests/input/test09.html @@ -0,0 +1,30 @@ +<html> +<body> +<p> + Just a bunch of text. +<p>more text... +<ul> + <li>first item + <li>second item + + <ol> + <li>second list, first item + <li>second list, second item + <dl compact> + <dt>term 1 + <dt>term 2 + <dd>definition + </dl> + </ol> + + <li>Now let's have a paragraph... + <p>My Paragraph + </li> + + <li>And a table in a list item: + <table> + </table> +</ul> + +</body> +</html> diff --git a/src/zope/tal/tests/input/test09.xml b/src/zope/tal/tests/input/test09.xml new file mode 100644 index 0000000..c3d10d7 --- /dev/null +++ b/src/zope/tal/tests/input/test09.xml @@ -0,0 +1,30 @@ +<html> +<body> +<p> + Just a bunch of text.</p> +<p>more text...</p> +<ul> + <li>first item</li> + <li>second item + + <ol> + <li>second list, first item</li> + <li>second list, second item + <dl compact=""> + <dt>term 1</dt> + <dt>term 2</dt> + <dd>definition</dd> + </dl></li> + </ol></li> + + <li>Now let's have a paragraph... + <p>My Paragraph</p> + </li> + + <li>And a table in a list item: + <table> + </table></li> +</ul> + +</body> +</html> diff --git a/src/zope/tal/tests/input/test10.html b/src/zope/tal/tests/input/test10.html new file mode 100644 index 0000000..6ecca4c --- /dev/null +++ b/src/zope/tal/tests/input/test10.html @@ -0,0 +1,48 @@ +<html><body> +<table xmlns:m="http://xml.zope.org/namespaces/metal" m:use-macro="tests/input/test07.html/myTable"> +<!-- macro use with slots --> + <tr> + <td> + <span m:fill-slot="bottomRight"> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <hr> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <br><br> + </span> + </td> + </tr> +</table> +</body></html> diff --git a/src/zope/tal/tests/input/test11.html b/src/zope/tal/tests/input/test11.html new file mode 100644 index 0000000..89f7563 --- /dev/null +++ b/src/zope/tal/tests/input/test11.html @@ -0,0 +1,19 @@ +<html xmlns:tal="http://xml.zope.org/namespaces/tal"> + <p tal:replace="structure string:<a>bar</a>" + tal:attributes="href string:http://www.python.org">dummy text</p> + <p tal:define="x python:1" tal:on-error="string:bad boy!"> + <span tal:define="x python:2"> + <span tal:define="x python:3"> + <span tal:content="python:1/0"/> + </span> + </span> + </p> + <p tal:on-error="string:x undefined"> + <span tal:content="x"/> + </p> + <tal:block on-error="string:x undefined" replace="x" /> + <tal:block on-error="string:x undefined"> + <p tal:content="x">p</p> + </tal:block> + <div tal:replace="structure string:<hr />">rule</div> +</html> diff --git a/src/zope/tal/tests/input/test11.xml b/src/zope/tal/tests/input/test11.xml new file mode 100644 index 0000000..435f95c --- /dev/null +++ b/src/zope/tal/tests/input/test11.xml @@ -0,0 +1,14 @@ +<html xmlns:tal="http://xml.zope.org/namespaces/tal"> + <p tal:replace="structure string:<a>bar</a>" + tal:attributes="href string:http://www.python.org">dummy text</p> + <p tal:define="x python:1" tal:on-error="string:bad boy!"> + <span tal:define="x python:2"> + <span tal:define="x python:3"> + <span tal:content="python:1/0"/> + </span> + </span> + </p> + <p tal:on-error="string:x undefined"> + <span tal:content="x"/> + </p> +</html> diff --git a/src/zope/tal/tests/input/test12.html b/src/zope/tal/tests/input/test12.html new file mode 100644 index 0000000..94d9a66 --- /dev/null +++ b/src/zope/tal/tests/input/test12.html @@ -0,0 +1,24 @@ +<span tal:define="global true python:1; global false python:0" /> + +<img ismap> +<img ismap=ismap> +<img ismap="ismap"> +<img ismap="foo"> + +<img ismap tal:attributes="ismap true"> +<img ismap tal:attributes="ismap false"> +<img ismap tal:attributes="ismap nothing"> + +<img ismap="foo" tal:attributes="ismap true"> +<img ismap="foo" tal:attributes="ismap false"> +<img ismap="foo" tal:attributes="ismap nothing"> + +<img tal:attributes="ismap true"> +<img tal:attributes="ismap false"> +<img tal:attributes="ismap nothing"> + +<span tal:define="global x string:x.gif" /> + +<img src="foo"> +<img src="foo" tal:attributes="src x"> +<img src="foo" tal:attributes="src nothing"> diff --git a/src/zope/tal/tests/input/test13.html b/src/zope/tal/tests/input/test13.html new file mode 100644 index 0000000..d68e0ce --- /dev/null +++ b/src/zope/tal/tests/input/test13.html @@ -0,0 +1,7 @@ +Here's a stray greater than: > + +<script> + <!-- no comment --> + <notag> + &noentity; +</script> diff --git a/src/zope/tal/tests/input/test14.html b/src/zope/tal/tests/input/test14.html new file mode 100644 index 0000000..0aaa751 --- /dev/null +++ b/src/zope/tal/tests/input/test14.html @@ -0,0 +1,10 @@ +<table> + <tr> + <td tal:repeat="x python:['car', 'bike', 'broomstick']" tal:content="x"> + </td> + </tr> +</table> + +<p> + <span tal:repeat="x python:['Harry', 'Ron', 'Hermione']" tal:replace="x" /> +</p> diff --git a/src/zope/tal/tests/input/test14.xml b/src/zope/tal/tests/input/test14.xml new file mode 100644 index 0000000..c596135 --- /dev/null +++ b/src/zope/tal/tests/input/test14.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" ?> +<html xmlns:tal="http://xml.zope.org/namespaces/tal"> + +<table> + <tr> + <td tal:repeat="x python:['car', 'bike', 'broomstick']" tal:content="x"> + </td> + </tr> +</table> + +<p> + <span tal:repeat="x python:['Harry', 'Ron', 'Hermione']" tal:replace="x" /> +</p> + +</html> diff --git a/src/zope/tal/tests/input/test15.html b/src/zope/tal/tests/input/test15.html new file mode 100644 index 0000000..0cd456e --- /dev/null +++ b/src/zope/tal/tests/input/test15.html @@ -0,0 +1,26 @@ +<span metal:define-macro="INNER"> + <span metal:define-slot="INNERSLOT">INNERSLOT</span> +</span> + +<xxx metal:use-macro="INNER"> + <xxx metal:fill-slot="INNERSLOT">inner-argument</xxx> +</xxx> + +<div metal:define-macro="OUTER"> +<div metal:use-macro="INNER"> + <xxx metal:define-slot="OUTERSLOT" metal:fill-slot="INNERSLOT"> + OUTERSLOT + </xxx> +</div> +</div> + +<div metal:use-macro="OUTER"> +<span> + <xxx> + <div metal:fill-slot="OUTERSLOT">outer-argument</div> + </xxx> +</span> +</div> + +<div metal:use-macro="OUTER"> +</div> diff --git a/src/zope/tal/tests/input/test16.html b/src/zope/tal/tests/input/test16.html new file mode 100644 index 0000000..1414f45 --- /dev/null +++ b/src/zope/tal/tests/input/test16.html @@ -0,0 +1,2 @@ +<a href="valid/link.html" + tal:attributes="href python:'/base/' + attrs['href']">blah, blah</a> diff --git a/src/zope/tal/tests/input/test16.xml b/src/zope/tal/tests/input/test16.xml new file mode 100644 index 0000000..2efb2ab --- /dev/null +++ b/src/zope/tal/tests/input/test16.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<body xmlns:tal="http://xml.zope.org/namespaces/tal"> + +<ImG href="foo" Alt="bar" + tal:attributes="Href string:about:foo;alT string:baz" /> + +</body> diff --git a/src/zope/tal/tests/input/test17.html b/src/zope/tal/tests/input/test17.html new file mode 100644 index 0000000..5a5ebb3 --- /dev/null +++ b/src/zope/tal/tests/input/test17.html @@ -0,0 +1,6 @@ +<tal:block tal:content="string:Yes">No</tal:block> +<tal:block content="string:Yes">No</tal:block> +<tal:block>Yes</tal:block> + +<metal:block tal:content="string:Yes">No</metal:block> +<metal:block>Yes</metal:block> diff --git a/src/zope/tal/tests/input/test17.xml b/src/zope/tal/tests/input/test17.xml new file mode 100644 index 0000000..ecb617a --- /dev/null +++ b/src/zope/tal/tests/input/test17.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<body xmlns:z="http://xml.zope.org/namespaces/tal" + xmlns:z2="http://xml.zope.org/namespaces/metal"> +<z:block z:content="string:Yes">No</z:block> +<z:block content="string:Yes">No</z:block> +<z:block>Yes</z:block> + +<z2:block z:content="string:Yes">No</z2:block> +<z2:block>Yes</z2:block> +</body> diff --git a/src/zope/tal/tests/input/test18.html b/src/zope/tal/tests/input/test18.html new file mode 100644 index 0000000..c3a5c26 --- /dev/null +++ b/src/zope/tal/tests/input/test18.html @@ -0,0 +1,16 @@ +<p tal:omit-tag="">Content</p> +<p tal:omit-tag=""></p> +<img tal:omit-tag=""> + +<p tal:omit-tag="string:Yes">Content</p> +<p tal:omit-tag="string:Yes"></p> +<img tal:omit-tag="string:Yes"> + +<p tal:omit-tag="nothing">Content</p> +<p tal:omit-tag="nothing"></p> +<img tal:omit-tag="nothing"> + +<p tal:define="txt string:Yes" tal:omit-tag="" tal:content="txt">No</p> +<p tal:define="txt string:Yes" tal:omit-tag="" tal:replace="txt">No</p> +<p tal:omit-tag="" tal:content="default">Yes</p> +<p tal:omit-tag="" tal:replace="default">Yes</p> diff --git a/src/zope/tal/tests/input/test18.xml b/src/zope/tal/tests/input/test18.xml new file mode 100644 index 0000000..5a0cca4 --- /dev/null +++ b/src/zope/tal/tests/input/test18.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<body xmlns:tal="http://xml.zope.org/namespaces/tal" + xmlns:metal="http://xml.zope.org/namespaces/metal"> +<p tal:omit-tag="">Content</p> +<p tal:omit-tag=""></p> +<img tal:omit-tag=""/> + +<p tal:omit-tag="string:Yes">Content</p> +<p tal:omit-tag="string:Yes"></p> +<img tal:omit-tag="string:Yes"/> + +<p tal:omit-tag="nothing">Content</p> +<p tal:omit-tag="nothing"></p> +<img tal:omit-tag="nothing" /> + +<p tal:define="txt string:Yes" tal:omit-tag="" tal:content="txt">No</p> +<p tal:define="txt string:Yes" tal:omit-tag="" tal:replace="txt">No</p> +<p tal:omit-tag="" tal:content="default">Yes</p> +<p tal:omit-tag="" tal:replace="default">Yes</p> +</body> diff --git a/src/zope/tal/tests/input/test19.html b/src/zope/tal/tests/input/test19.html new file mode 100644 index 0000000..a56632a --- /dev/null +++ b/src/zope/tal/tests/input/test19.html @@ -0,0 +1,5 @@ +<span i18n:translate="">Replace this</span> +<span i18n:translate="msgid">This is a +translated string</span> +<span i18n:translate="">And another +translated string</span> diff --git a/src/zope/tal/tests/input/test19.xml b/src/zope/tal/tests/input/test19.xml new file mode 100644 index 0000000..fe4bf79 --- /dev/null +++ b/src/zope/tal/tests/input/test19.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<body xmlns:i18n="http://xml.zope.org/namespaces/i18n"> +<span i18n:translate="">Replace this</span> +<span i18n:translate="msgid">This is a +translated string</span> +<span i18n:translate="">And another +translated string</span> +</body> diff --git a/src/zope/tal/tests/input/test20.html b/src/zope/tal/tests/input/test20.html new file mode 100644 index 0000000..f302213 --- /dev/null +++ b/src/zope/tal/tests/input/test20.html @@ -0,0 +1 @@ +<span i18n:translate="">replaceable <p tal:replace="str:here">content</p></span> diff --git a/src/zope/tal/tests/input/test20.xml b/src/zope/tal/tests/input/test20.xml new file mode 100644 index 0000000..5050883 --- /dev/null +++ b/src/zope/tal/tests/input/test20.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<body xmlns:tal="http://xml.zope.org/namespaces/tal" + xmlns:metal="http://xml.zope.org/namespaces/metal" + xmlns:i18n="http://xml.zope.org/namespaces/i18n"> +<span i18n:translate="">replaceable <p tal:replace="str:here">content</p></span> +</body> diff --git a/src/zope/tal/tests/input/test21.html b/src/zope/tal/tests/input/test21.html new file mode 100644 index 0000000..95f925e --- /dev/null +++ b/src/zope/tal/tests/input/test21.html @@ -0,0 +1,4 @@ +<span i18n:translate=""> + <span tal:replace="str:Lomax" i18n:name="name" /> was born in + <span tal:replace="str:Antarctica" i18n:name="country" />. +</span> diff --git a/src/zope/tal/tests/input/test21.xml b/src/zope/tal/tests/input/test21.xml new file mode 100644 index 0000000..eea370b --- /dev/null +++ b/src/zope/tal/tests/input/test21.xml @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<body xmlns:tal="http://xml.zope.org/namespaces/tal" + xmlns:metal="http://xml.zope.org/namespaces/metal" + xmlns:i18n="http://xml.zope.org/namespaces/i18n"> +<span i18n:translate=""> + <span tal:replace="str:Lomax" i18n:name="name" /> was born in + <span tal:replace="str:Antarctica" i18n:name="country" />. +</span> +</body> diff --git a/src/zope/tal/tests/input/test22.html b/src/zope/tal/tests/input/test22.html new file mode 100644 index 0000000..a4a7e93 --- /dev/null +++ b/src/zope/tal/tests/input/test22.html @@ -0,0 +1,4 @@ +<span i18n:translate=""> + <span tal:omit-tag="" i18n:name="name"><b>Jim</b></span> was born in + <span tal:omit-tag="" i18n:name="country">the USA</span>. +</span> diff --git a/src/zope/tal/tests/input/test22.xml b/src/zope/tal/tests/input/test22.xml new file mode 100644 index 0000000..54b57d8 --- /dev/null +++ b/src/zope/tal/tests/input/test22.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<body xmlns:tal="http://xml.zope.org/namespaces/tal"> + <span tal:content="default">content</span> + <span tal:omit-tag="" tal:content="default">omit</span> + <span tal:replace="default">replace</span> +</body> diff --git a/src/zope/tal/tests/input/test23.html b/src/zope/tal/tests/input/test23.html new file mode 100644 index 0000000..bfe6665 --- /dev/null +++ b/src/zope/tal/tests/input/test23.html @@ -0,0 +1,2 @@ +<span i18n:data="here/currentTime" + i18n:translate="timefmt">2:32 pm</span> diff --git a/src/zope/tal/tests/input/test24.html b/src/zope/tal/tests/input/test24.html new file mode 100644 index 0000000..6d53984 --- /dev/null +++ b/src/zope/tal/tests/input/test24.html @@ -0,0 +1,12 @@ +<input name="Delete" + tal:attributes="name string:delete_button" + i18n:attributes="name"> + +<input name="Delete" + i18n:attributes="name message-id"> + +<input i18n:attributes=" name message-id; + attr input-attr "> + +<input i18n:attributes=" name message-id; + attr input-attr;"> diff --git a/src/zope/tal/tests/input/test25.html b/src/zope/tal/tests/input/test25.html new file mode 100644 index 0000000..25a99cf --- /dev/null +++ b/src/zope/tal/tests/input/test25.html @@ -0,0 +1 @@ +<input name="Delete" i18n:attributes="name"> diff --git a/src/zope/tal/tests/input/test26.html b/src/zope/tal/tests/input/test26.html new file mode 100644 index 0000000..fa5a99d --- /dev/null +++ b/src/zope/tal/tests/input/test26.html @@ -0,0 +1,3 @@ +<span i18n:translate="jobnum"> + Job #<span tal:replace="context/@@object_name" + i18n:name="jobnum">NN</span></span> diff --git a/src/zope/tal/tests/input/test27.html b/src/zope/tal/tests/input/test27.html new file mode 100644 index 0000000..b9c16cb --- /dev/null +++ b/src/zope/tal/tests/input/test27.html @@ -0,0 +1,5 @@ +<p i18n:translate="verify">Your contact email address is recorded as + <a href="mailto:user@example.com" + tal:content="request/submitter" + i18n:name="email">user@host.com</a> +</p> diff --git a/src/zope/tal/tests/input/test28.html b/src/zope/tal/tests/input/test28.html new file mode 100644 index 0000000..0364663 --- /dev/null +++ b/src/zope/tal/tests/input/test28.html @@ -0,0 +1,5 @@ +<p i18n:translate="verify">Your contact email address is recorded as + <span tal:omit-tag="" i18n:name="email"> + <a href="mailto:user@example.com" + tal:content="request/submitter">user@host.com</a></span> +</p> diff --git a/src/zope/tal/tests/input/test29.html b/src/zope/tal/tests/input/test29.html new file mode 100644 index 0000000..e2f1e82 --- /dev/null +++ b/src/zope/tal/tests/input/test29.html @@ -0,0 +1,4 @@ +<div i18n:translate="">At the tone the time will be +<span i18n:data="here/currentTime" + i18n:translate="timefmt" + i18n:name="time">2:32 pm</span>... beep!</div> diff --git a/src/zope/tal/tests/input/test30.html b/src/zope/tal/tests/input/test30.html new file mode 100644 index 0000000..6f8c6ef --- /dev/null +++ b/src/zope/tal/tests/input/test30.html @@ -0,0 +1,6 @@ +<p i18n:translate="verify">Your contact email address is recorded as +<a href="user@host.com" + tal:attributes="href string:mailto:${request/submitter}" + tal:content="request/submitter" + i18n:name="email">user@host.com</a> +</p> diff --git a/src/zope/tal/tests/input/test31.html b/src/zope/tal/tests/input/test31.html new file mode 100644 index 0000000..c927f42 --- /dev/null +++ b/src/zope/tal/tests/input/test31.html @@ -0,0 +1,7 @@ +<p i18n:translate="verify">Your contact email address is recorded as +<span tal:omit-tag="" i18n:name="email"> +<a href="user@host.com" + tal:attributes="href string:mailto:${request/submitter}" + tal:content="request/submitter"> + user@host.com</a></span> +</p> diff --git a/src/zope/tal/tests/input/test32.html b/src/zope/tal/tests/input/test32.html new file mode 100644 index 0000000..3b09bad --- /dev/null +++ b/src/zope/tal/tests/input/test32.html @@ -0,0 +1,4 @@ +<span i18n:translate="origin"> + <span tal:content="str:Lomax" i18n:name="name" /> was born in + <span tal:content="str:Antarctica" i18n:name="country" />. +</span> diff --git a/src/zope/tal/tests/input/test33.html b/src/zope/tal/tests/input/test33.html new file mode 100644 index 0000000..f5dcf58 --- /dev/null +++ b/src/zope/tal/tests/input/test33.html @@ -0,0 +1 @@ +<span i18n:translate="">don't translate me</span> diff --git a/src/zope/tal/tests/input/test34.html b/src/zope/tal/tests/input/test34.html new file mode 100644 index 0000000..4cd6ff0 --- /dev/null +++ b/src/zope/tal/tests/input/test34.html @@ -0,0 +1,11 @@ +<span i18n:translate="don't translate me"> + stuff + <span tal:replace="string:foobar" i18n:name="longname" /> + more stuff +</span> + +<span i18n:translate=""> + stuff + <span tal:replace="string:foobar" i18n:name="longname" /> + more stuff +</span> diff --git a/src/zope/tal/tests/input/test35.html b/src/zope/tal/tests/input/test35.html new file mode 100644 index 0000000..7964e9f --- /dev/null +++ b/src/zope/tal/tests/input/test35.html @@ -0,0 +1,7 @@ +<span metal:define-macro="page" tal:omit-tag=""> + <h1 metal:define-slot="name" tal:omit-tag="" /> +</span> + +<span metal:use-macro="page"> + <h1 metal:fill-slot="name" tal:content="macroname">name</h1> +</span>
\ No newline at end of file diff --git a/src/zope/tal/tests/input/test36.html b/src/zope/tal/tests/input/test36.html new file mode 100644 index 0000000..bf4932a --- /dev/null +++ b/src/zope/tal/tests/input/test36.html @@ -0,0 +1,6 @@ +<span tal:replace="string:<foo>" /> +<span i18n:translate=""> + <span tal:replace="string:<foo>" i18n:name="name1" /> + <span tal:replace="structure string:<bar />" i18n:name="name2" /> + <span tal:omit-tag="" i18n:name="name3"><b>some</b> <i>text</i></span> +</span> diff --git a/src/zope/tal/tests/input/test_domain.html b/src/zope/tal/tests/input/test_domain.html new file mode 100644 index 0000000..95d40a2 --- /dev/null +++ b/src/zope/tal/tests/input/test_domain.html @@ -0,0 +1,7 @@ +<div i18n:domain="lower"> +<span i18n:translate="">Replace this</span> +<span i18n:translate="msgid">This is a +translated string</span> +<span i18n:translate="">And another +translated string</span> +</div> diff --git a/src/zope/tal/tests/input/test_failed_attr_translation.html b/src/zope/tal/tests/input/test_failed_attr_translation.html new file mode 100644 index 0000000..1c395c7 --- /dev/null +++ b/src/zope/tal/tests/input/test_failed_attr_translation.html @@ -0,0 +1,2 @@ +<input value="don't translate me" + i18n:attributes="value"> diff --git a/src/zope/tal/tests/input/test_metal1.html b/src/zope/tal/tests/input/test_metal1.html new file mode 100644 index 0000000..a5371ce --- /dev/null +++ b/src/zope/tal/tests/input/test_metal1.html @@ -0,0 +1,61 @@ +<span metal:define-macro="OUTER"> + AAA + <span metal:define-macro="INNER">INNER</span> + BBB +</span> + +<xxx metal:use-macro="OUTER"> +</xxx> + +<xxx metal:use-macro="INNER"> +</xxx> + +<span metal:define-macro="OUTER2"> + AAA + <xxx metal:define-slot="OUTERSLOT"> + <span metal:define-macro="INNER2">INNER</span> + </xxx> + BBB +</span> + +<xxx metal:use-macro="OUTER2"> +</xxx> + +<xxx metal:use-macro="INNER2"> +</xxx> + +<xxx metal:use-macro="OUTER2"> + <yyy metal:fill-slot="OUTERSLOT">OUTERSLOT</yyy> +</xxx> + +<span metal:define-macro="OUTER3"> + AAA + <xxx metal:define-slot="OUTERSLOT"> + <span metal:define-macro="INNER3">INNER + <xxx metal:define-slot="INNERSLOT">INNERSLOT</xxx> + </span> + </xxx> + BBB +</span> + +<xxx metal:use-macro="OUTER3"> +</xxx> + +<xxx metal:use-macro="OUTER3"> + <yyy metal:fill-slot="OUTERSLOT">OUTERSLOT</yyy> +</xxx> + +<xxx metal:use-macro="INNER3"> +</xxx> + +<xxx metal:use-macro="INNER3"> + <yyy metal:fill-slot="INNERSLOT">INNERSLOT</yyy> +</xxx> + +<xxx metal:use-macro="INNER3"> + <yyy metal:fill-slot="INNERSLOT"> + <zzz metal:define-macro="INSLOT">INSLOT</zzz> + </yyy> +</xxx> + +<xxx metal:use-macro="INSLOT"></xxx> diff --git a/src/zope/tal/tests/input/test_metal2.html b/src/zope/tal/tests/input/test_metal2.html new file mode 100644 index 0000000..425508a --- /dev/null +++ b/src/zope/tal/tests/input/test_metal2.html @@ -0,0 +1,7 @@ +<div metal:define-macro="OUTER"> + OUTER + <span metal:define-macro="INNER">INNER</span> + OUTER +</div> + +<div metal:use-macro="OUTER"/> diff --git a/src/zope/tal/tests/input/test_metal3.html b/src/zope/tal/tests/input/test_metal3.html new file mode 100644 index 0000000..b0af907 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal3.html @@ -0,0 +1 @@ +<span tal:attributes="class string:foo">Should not get attr in metal</span> diff --git a/src/zope/tal/tests/input/test_metal4.html b/src/zope/tal/tests/input/test_metal4.html new file mode 100644 index 0000000..dc774d3 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal4.html @@ -0,0 +1,4 @@ +<!-- the outer element *must* be tal:something or metal:something --> +<metal:block define-macro="page" i18n:domain="zope"> + <title metal:define-slot="title">Z3 UI</title> +</metal:block> diff --git a/src/zope/tal/tests/input/test_metal5.html b/src/zope/tal/tests/input/test_metal5.html new file mode 100644 index 0000000..8bae3d8 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal5.html @@ -0,0 +1,4 @@ +<!-- the outer element *must* include tal:omit-tag='' --> +<x tal:omit-tag="" metal:define-macro="page" i18n:domain="zope"> + <title metal:define-slot="title">Z3 UI</title> +</x> diff --git a/src/zope/tal/tests/input/test_metal6.html b/src/zope/tal/tests/input/test_metal6.html new file mode 100644 index 0000000..ce243f2 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal6.html @@ -0,0 +1,5 @@ +<metal:block define-macro="page"> + <html i18:domain="zope"> + <metal:block define-slot="title">Z3 UI</metal:block> + </html> +</metal:block> diff --git a/src/zope/tal/tests/input/test_metal7.html b/src/zope/tal/tests/input/test_metal7.html new file mode 100644 index 0000000..75ec511 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal7.html @@ -0,0 +1,6 @@ +<html metal:define-macro="page" i18n:domain="zope"> + <x metal:define-slot="title" /> +</html> +<html metal:use-macro="page"> + <x metal:fill-slot="title" /> +</html> diff --git a/src/zope/tal/tests/input/test_metal8.html b/src/zope/tal/tests/input/test_metal8.html new file mode 100644 index 0000000..40d8a43 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal8.html @@ -0,0 +1,15 @@ +<html metal:define-macro="page" i18n:domain="zope"> +<body> +<div metal:define-macro="workspace"> +<div metal:define-slot="body"> +Default body +</div> +</div> +</body> +</html> + +<html metal:use-macro="page"> +<div metal:fill-slot="body"> +Filled-in body +</div> +</html> diff --git a/src/zope/tal/tests/input/test_metal9.html b/src/zope/tal/tests/input/test_metal9.html new file mode 100644 index 0000000..46b1b45 --- /dev/null +++ b/src/zope/tal/tests/input/test_metal9.html @@ -0,0 +1,23 @@ +<div metal:define-macro="macro1" i18n:domain="zope"> +<span metal:define-slot="slot1"> +Default for macro1 +</span> +</div> + +<div metal:define-macro="macro2" metal:extend-macro="macro1" i18n:domain="zope"> +<span metal:fill-slot="slot1"> +Macro 2's slot 1 decoration +<span metal:define-slot="slot1"> +Default for macro2 +</span> +</span> +</div> + +<div metal:use-macro="macro2"> +</div> + +<div metal:use-macro="macro2"> +<span metal:fill-slot="slot1"> +Custom slot1 +</span> +</div> diff --git a/src/zope/tal/tests/input/test_sa1.html b/src/zope/tal/tests/input/test_sa1.html new file mode 100644 index 0000000..8879865 --- /dev/null +++ b/src/zope/tal/tests/input/test_sa1.html @@ -0,0 +1,6 @@ +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa1.xml b/src/zope/tal/tests/input/test_sa1.xml new file mode 100644 index 0000000..d00a46d --- /dev/null +++ b/src/zope/tal/tests/input/test_sa1.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa2.html b/src/zope/tal/tests/input/test_sa2.html new file mode 100644 index 0000000..1c4e06b --- /dev/null +++ b/src/zope/tal/tests/input/test_sa2.html @@ -0,0 +1,9 @@ +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa2.xml b/src/zope/tal/tests/input/test_sa2.xml new file mode 100644 index 0000000..b54d6a1 --- /dev/null +++ b/src/zope/tal/tests/input/test_sa2.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa3.html b/src/zope/tal/tests/input/test_sa3.html new file mode 100644 index 0000000..675805d --- /dev/null +++ b/src/zope/tal/tests/input/test_sa3.html @@ -0,0 +1,15 @@ +<html> +<body> + <div metal:define-macro="macro1">This is macro1 on sa3 line 3. + <span metal:define-slot="slot1">This is slot1 on sa3 line 4.</span> + This is the end of macro1 on sa3 line 5. + </div> + <p>Some text on sa3 line 7.</p> + <p metal:use-macro="macro1"> + This text on sa3 line 9 will disappear. + <b metal:fill-slot="slot1">Text from sa3 line 10 is filled into slot1.</b> + This text on sa3 line 11 will disappear. + </p> + <p>This is some text on sa3 line 13.</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa3.xml b/src/zope/tal/tests/input/test_sa3.xml new file mode 100644 index 0000000..79e3251 --- /dev/null +++ b/src/zope/tal/tests/input/test_sa3.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<html> +<body xmlns:metal="http://xml.zope.org/namespaces/metal"> + <div metal:define-macro="macro1">This is macro1 on sa3 line 4. + <span metal:define-slot="slot1">This is slot1 on sa3 line 5.</span> + This is the end of macro1 on sa3 line 6. + </div> + <p>Some text on sa3 line 8.</p> + <p metal:use-macro="macro1"> + This text on sa3 line 10 will disappear. + <b metal:fill-slot="slot1">Text from sa3 line 11 is filled into slot1.</b> + This text on sa3 line 12 will disappear. + </p> + <p>This is some text on sa3 line 14.</p> +</body> +</html> diff --git a/src/zope/tal/tests/input/test_sa4.html b/src/zope/tal/tests/input/test_sa4.html new file mode 100644 index 0000000..97596f6 --- /dev/null +++ b/src/zope/tal/tests/input/test_sa4.html @@ -0,0 +1,11 @@ +<html> +<body> + <p>Some text on sa4 line 3.</p> + <p metal:use-macro="tests/input/test_sa3.html/macro1"> + This text on sa4 line 5 will disappear. + <b metal:fill-slot="slot1">Text from sa4 line 6 is filled into slot1.</b> + This text on sa4 line 7 will disappear. + </p> + <p>This is some text on sa4 line 9.</p> +</body> +</html> diff --git a/src/zope/tal/tests/markbench.py b/src/zope/tal/tests/markbench.py new file mode 100644 index 0000000..f08f9e2 --- /dev/null +++ b/src/zope/tal/tests/markbench.py @@ -0,0 +1,187 @@ +#! /usr/bin/env python +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Run benchmarks of TAL vs. DTML + +$Id$ +""" + +import warnings +warnings.filterwarnings("ignore", category=DeprecationWarning) + +import os +os.environ['NO_SECURITY'] = 'true' + +import getopt +import sys +import time + +from cStringIO import StringIO + +#from zope.documenttemplate.dt_html import HTMLFile + +from zope.tal.htmltalparser import HTMLTALParser +from zope.tal.talinterpreter import TALInterpreter +from zope.tal.dummyengine import DummyEngine + + +def time_apply(f, args, kwargs, count): + r = [None] * count + for i in range(4): + f(*args, **kwargs) + t0 = time.clock() + for i in r: + pass + t1 = time.clock() + for i in r: + f(*args, **kwargs) + t = time.clock() - t1 - (t1 - t0) + return t / count + +def time_zpt(fn, count): + from zope.pagetemplate.pagetemplate import PageTemplate + pt = PageTemplate() + pt.write(open(fn).read()) + return time_apply(pt.pt_render, (data,), {}, count) + +def time_tal(fn, count): + p = HTMLTALParser() + p.parseFile(fn) + program, macros = p.getCode() + engine = DummyEngine(macros) + engine.globals = data + tal = TALInterpreter(program, macros, engine, StringIO(), wrap=0, + tal=1, strictinsert=0) + return time_apply(tal, (), {}, count) + +def time_dtml(fn, count): + html = HTMLFile(fn) + return time_apply(html, (), data, count) + +def profile_zpt(fn, count, profiler): + from zope.pagetemplate.pagetemplate import PageTemplate + pt = PageTemplate() + pt.write(open(fn).read()) + for i in range(4): + pt.pt_render(extra_context=data) + r = [None] * count + for i in r: + profiler.runcall(pt.pt_render, 0, data) + +def profile_tal(fn, count, profiler): + p = HTMLTALParser() + p.parseFile(fn) + program, macros = p.getCode() + engine = DummyEngine(macros) + engine.globals = data + tal = TALInterpreter(program, macros, engine, StringIO(), wrap=0, + tal=1, strictinsert=0) + for i in range(4): + tal() + r = [None] * count + for i in r: + profiler.runcall(tal) + +# Figure out where the benchmark files are: +try: + fname = __file__ +except NameError: + fname = sys.argv[0] +taldir = os.path.dirname(os.path.dirname(os.path.abspath(fname))) +benchdir = os.path.join(taldir, 'benchmark') + +# Construct templates for the filenames: +tal_fn = os.path.join(benchdir, 'tal%.2d.html') +dtml_fn = os.path.join(benchdir, 'dtml%.2d.html') + +def compare(n, count, profiler=None, verbose=1): + if verbose: + t1 = int(time_zpt(tal_fn % n, count) * 1000 + 0.5) + t2 = int(time_tal(tal_fn % n, count) * 1000 + 0.5) + t3 = 'n/a' # int(time_dtml(dtml_fn % n, count) * 1000 + 0.5) + print '%.2d: %10s %10s %10s' % (n, t1, t2, t3) + if profiler: + profile_tal(tal_fn % n, count, profiler) + +def main(count, profiler=None, verbose=1): + n = 1 + if verbose: + print '##: %10s %10s %10s' % ('ZPT', 'TAL', 'DTML') + while os.path.isfile(tal_fn % n) and os.path.isfile(dtml_fn % n): + compare(n, count, profiler, verbose) + n = n + 1 + +def get_signal_name(sig): + import signal + for name in dir(signal): + if getattr(signal, name) == sig: + return name + return None + +data = {'x':'X', 'r2': range(2), 'r8': range(8), 'r64': range(64)} +for i in range(10): + data['x%s' % i] = 'X%s' % i + +if __name__ == "__main__": + filename = "markbench.prof" + profiler = None + runtests = False + verbose = True + + opts, args = getopt.getopt(sys.argv[1:], "pqt") + for opt, arg in opts: + if opt == "-p": + import profile + profiler = profile.Profile() + elif opt == "-q": + verbose = False + elif opt == "-t": + runtests = True + + if runtests: + srcdir = os.path.dirname(os.path.dirname(taldir)) + topdir = os.path.dirname(srcdir) + pwd = os.getcwd() + os.chdir(topdir) + rc = os.spawnl(os.P_WAIT, sys.executable, + sys.executable, "test.py", "zope.tal.tests") + if rc > 0: + # TODO: Failing tests don't cause test.py to report an + # error; not sure why. ;-( + sys.exit(rc) + elif rc < 0: + sig = -rc + print >>sys.stderr, ( + "Process exited, signal %d (%s)." + % (sig, get_signal_name(sig) or "<unknown signal>")) + sys.exit(1) + os.chdir(pwd) + + if len(args) >= 1: + for arg in args: + compare(int(arg), 25, profiler, verbose) + else: + main(25, profiler, verbose) + + if profiler is not None: + profiler.dump_stats(filename) + import pstats + p = pstats.Stats(filename) + p.strip_dirs() + p.sort_stats('time', 'calls') + try: + p.print_stats(20) + except IOError, e: + if e.errno != errno.EPIPE: + raise diff --git a/src/zope/tal/tests/output/__init__.py b/src/zope/tal/tests/output/__init__.py new file mode 100644 index 0000000..b711d36 --- /dev/null +++ b/src/zope/tal/tests/output/__init__.py @@ -0,0 +1,2 @@ +# +# This file is necessary to make this directory a package. diff --git a/src/zope/tal/tests/output/acme_template.html b/src/zope/tal/tests/output/acme_template.html new file mode 100644 index 0000000..3d37355 --- /dev/null +++ b/src/zope/tal/tests/output/acme_template.html @@ -0,0 +1,26 @@ +<!-- This is ACME's generic look and feel, which is based on +PNOME's look and feel. --> +<html> +<head> +<title>ACME Look and Feel</title> + + +</head> +<body> +<div> + <div> + "The early bird gets the worm, but the second mouse gets the cheese." + </div> + <a href="#">Preferences...</a> +</div> +<div> + Content here +</div> +<div> +Copyright 2004 Acme Inc. +<div> +Standard disclaimers apply. +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/output/acme_template_source.html b/src/zope/tal/tests/output/acme_template_source.html new file mode 100644 index 0000000..11f19d3 --- /dev/null +++ b/src/zope/tal/tests/output/acme_template_source.html @@ -0,0 +1,27 @@ +<!-- This is ACME's generic look and feel, which is based on +PNOME's look and feel. --> +<html metal:define-macro="page" + metal:use-macro="pnome_macros_page"> +<head> +<title metal:fill-slot="title">ACME Look and Feel</title> +<metal:block> +</metal:block> +</head> +<body> +<div> + <div> + "The early bird gets the worm, but the second mouse gets the cheese." + </div> + <a href="#">Preferences...</a> +</div> +<div> + Content here +</div> +<div metal:fill-slot="page-footer"> +Copyright 2004 Acme Inc. +<div metal:define-slot="disclaimer"> +Standard disclaimers apply. +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/output/document_list.html b/src/zope/tal/tests/output/document_list.html new file mode 100644 index 0000000..9e0ea10 --- /dev/null +++ b/src/zope/tal/tests/output/document_list.html @@ -0,0 +1,30 @@ +<!-- ACME's document_list uses the ACME look and feel --> +<html> +<head> +<title>Acme Document List</title> +<style type="text/css"> + body { background-color: white; } +</style> +</head> +<body> +<div> + <div> + "The early bird gets the worm, but the second mouse gets the cheese." + </div> + <a href="#">Preferences...</a> +</div> +<div> +<h1>Documents</h1> +<ul> +<li>Rocket Science for Dummies</li> +<li>Birds for the Gourmet Chef</li> +</ul> +</div> +<div> +Copyright 2004 Acme Inc. +<div> +This document list is classified. +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/output/document_list_source.html b/src/zope/tal/tests/output/document_list_source.html new file mode 100644 index 0000000..69600e0 --- /dev/null +++ b/src/zope/tal/tests/output/document_list_source.html @@ -0,0 +1,30 @@ +<!-- ACME's document_list uses the ACME look and feel --> +<html metal:use-macro="acme_macros_page"> +<head> +<title metal:fill-slot="title">Acme Document List</title> +<style metal:fill-slot="local-styles" type="text/css"> + body { background-color: white; } +</style> +</head> +<body> +<div> + <div> + "The early bird gets the worm, but the second mouse gets the cheese." + </div> + <a href="#">Preferences...</a> +</div> +<div metal:fill-slot="content"> +<h1>Documents</h1> +<ul> +<li>Rocket Science for Dummies</li> +<li>Birds for the Gourmet Chef</li> +</ul> +</div> +<div> +Copyright 2004 Acme Inc. +<div metal:fill-slot="disclaimer"> +This document list is classified. +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/output/test01.html b/src/zope/tal/tests/output/test01.html new file mode 100644 index 0000000..7064db0 --- /dev/null +++ b/src/zope/tal/tests/output/test01.html @@ -0,0 +1,68 @@ +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> + + <head>dadada</head> + + <body> + + <h1>This +Is +The +Replaced +Title</h1> + + <!-- test entity references --> + &HarryPotter; + + <!-- examples adapted from TemplateAttributeLanguageSyntax --> + + <span>here/id</span> + + <p>5</p> + + <p> + honda + </p> + <p> + subaru + </p> + <p> + acura + </p> + + <p xml:foo="bar">foo bar</p> + + <!-- more examples --> + + <ul> + <span> + <li>honda</li> + </span> + <span> + <li>subaru</li> + </span> + <span> + <li>acura</li> + </span> + </ul> + + <!-- test attribute expansion --> + + <a href="http://python.org">python</a> + <a href="http://python.org">python</a> + + <!-- test insert/replace structure --> + <span></span> + + + <span /> + <span /> + + <h3>Header Level 3</h3> + <span> <h3>Header Level 3</h3></span> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test01.xml b/src/zope/tal/tests/output/test01.xml new file mode 100644 index 0000000..91e9851 --- /dev/null +++ b/src/zope/tal/tests/output/test01.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" ?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> + + <head>dadada</head> + + <body> + + <h1>This Is The Replaced Title</h1> + + <!-- test entity references --> + &HarryPotter; + + <!-- examples adapted from TemplateAttributeLanguageSyntax --> + + <span>here/id</span> + + <p>5</p> + + <p> + honda + </p> + <p> + subaru + </p> + <p> + acura + </p> + + <p xml:foo="bar">foo bar</p> + + <!-- more examples --> + + <ul> + <span> + <li>honda</li> + </span> + <span> + <li>subaru</li> + </span> + <span> + <li>acura</li> + </span> + </ul> + + <!-- test attribute expansion --> + + <a href="http://python.org">python</a> + <a href="http://python.org">python</a> + + <!-- test insert/replace structure --> + <span></span> + + + <span/> + <span/> + + <h3>Header Level 3</h3> + <span> <h3>Header Level 3</h3></span> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test02.html b/src/zope/tal/tests/output/test02.html new file mode 100644 index 0000000..8d081fc --- /dev/null +++ b/src/zope/tal/tests/output/test02.html @@ -0,0 +1,118 @@ +<biztalk_1 xmlns="urn:schemas-biztalk-org:biztalk:biztalk_1"> + +<foo:header xmlns:foo="whomping-willow" plain="guido" quote=""" apostrophe="'" both=""'" lt="<" gt=">" amp="&" foo=""> + <manifest> + <document> + <name>sample1</name> + <description>a simple invoice</description> + </document> + </manifest> +</foo:header> + +<body> + +<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order --> + +<invoice xmlns="urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"> + <header> + <invoicenumber>01786</invoicenumber> + <invoicedate>2000-03-17</invoicedate> <!-- March 17th, 2000 --> + <orderno>55377</orderno> + <orderdate>2000-03-15</orderdate> <!-- March 15th, 2000 --> + <customerpo>GJ03405</customerpo> + <shipmethod>DAVE 1</shipmethod> + <shipdate>2000-03-17</shipdate> <!-- March 17th, 2000 --> + <customerid>K5211(34)</customerid> + <salespersoncode>23</salespersoncode> + <taxid>23</taxid> + </header> + <invoiceto> + <name>SHIPWRIGHT RESTAURANTS LIMITED</name> + <addressline>125 NORTH SERVICE ROAD W</addressline> + <addressline>WESTLAKE ACCESS</addressline> + <city>NORTH BAY</city> + <postcode>L8B1O5</postcode> + <state>ONTARIO</state> + <country>CANADA</country> + </invoiceto> + <shipto> + <name /> + <addressline>ATTN: PAULINE DEGRASSI</addressline> + <city /> + <postcode /> + <state /> + <country /> + </shipto> + <detaillines> + <detailline> + <quantityshipped>1</quantityshipped> + <unitofmeasure>CS</unitofmeasure> + <partnumber>DM 5309</partnumber> + <partdescription>#1013 12 OZ.MUNICH STEIN</partdescription> + <unitprice>37.72</unitprice> + <linetotal>37.72</linetotal> + </detailline> + <detailline> + <quantityshipped>6</quantityshipped> + <unitofmeasure>DZ</unitofmeasure> + <partnumber>ON 6420</partnumber> + <partdescription>PROVINCIAL DINNER FORK</partdescription> + <unitprice>17.98</unitprice> + <linetotal>107.88</linetotal> + </detailline> + <detailline> + <quantityshipped>72</quantityshipped> + <unitofmeasure>EA</unitofmeasure> + <partnumber>JR20643</partnumber> + <partdescription>PLASTIC HANDLED STEAK KNIFE</partdescription> + <unitprice>.81</unitprice> + <linetotal>58.32</linetotal> + </detailline> + <detailline> + <quantityshipped>6</quantityshipped> + <unitofmeasure>DZ</unitofmeasure> + <partnumber>ON 6410</partnumber> + <partdescription>PROVINCIAL TEASPOONS</partdescription> + <unitprice>12.16</unitprice> + <linetotal>72.96</linetotal> + </detailline> + <detailline> + <quantityshipped>0</quantityshipped> + <unitofmeasure>DZ</unitofmeasure> + <partnumber>ON 6411</partnumber> + <partdescription>PROVINCIAL RD BOWL SPOON</partdescription> + <quantitybackordered>6</quantitybackordered> + <unitprice>17.98</unitprice> + <linetotal>0.00</linetotal> + </detailline> + <detailline> + <quantityshipped>1</quantityshipped> + <unitofmeasure>EA</unitofmeasure> + <partnumber>DO 3218</partnumber> + <partdescription>34 OZ DUAL DIAL SCALE AM3218</partdescription> + <unitprice>70.00</unitprice> + <discountpercentage>5.0</discountpercentage> + <linetotal>66.50</linetotal> + </detailline> + <detailline> + <quantityshipped>1</quantityshipped> + <unitofmeasure>CS</unitofmeasure> + <partnumber>DM 195</partnumber> + <partdescription>20 OZ.BEER PUB GLASS</partdescription> + <unitprice>55.90</unitprice> + <linetotal>55.90</linetotal> + </detailline> + </detaillines> + <totals> + <subtotal>399.28</subtotal> + <discounttotal>3.50</discounttotal> + <freighttotal>23.75</freighttotal> + <gsttotal>29.61</gsttotal> + <provtaxtotal>33.84</provtaxtotal> + <othertotal>33.84</othertotal> + <invoicetotal>486.48</invoicetotal> + </totals> +</invoice> + +</body> +</biztalk_1> diff --git a/src/zope/tal/tests/output/test02.xml b/src/zope/tal/tests/output/test02.xml new file mode 100644 index 0000000..71ff075 --- /dev/null +++ b/src/zope/tal/tests/output/test02.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" ?> +<biztalk_1 xmlns="urn:schemas-biztalk-org:biztalk:biztalk_1"> + +<foo:header xmlns:foo="whomping-willow" plain="guido" quote=""" apostrophe="'" both=""'" lt="<" gt=">" amp="&" foo=""> + <manifest> + <document> + <name>sample1</name> + <description>a simple invoice</description> + </document> + </manifest> +</foo:header> + +<body> + +<!-- sample1.xml is an example of a simple invoice for a small restaurant supplies order --> + +<Invoice xmlns="urn:http://schemas.biztalk.org/united_rest_com/yw7sg15x.xml"> + <Header> + <InvoiceNumber>01786</InvoiceNumber> + <InvoiceDate>2000-03-17</InvoiceDate> <!-- March 17th, 2000 --> + <OrderNo>55377</OrderNo> + <OrderDate>2000-03-15</OrderDate> <!-- March 15th, 2000 --> + <CustomerPO>GJ03405</CustomerPO> + <ShipMethod>DAVE 1</ShipMethod> + <ShipDate>2000-03-17</ShipDate> <!-- March 17th, 2000 --> + <CustomerID>K5211(34)</CustomerID> + <SalesPersonCode>23</SalesPersonCode> + <TaxID>23</TaxID> + </Header> + <InvoiceTo> + <Name>SHIPWRIGHT RESTAURANTS LIMITED</Name> + <AddressLine>125 NORTH SERVICE ROAD W</AddressLine> + <AddressLine>WESTLAKE ACCESS</AddressLine> + <City>NORTH BAY</City> + <PostCode>L8B1O5</PostCode> + <State>ONTARIO</State> + <Country>CANADA</Country> + </InvoiceTo> + <ShipTo> + <Name/> + <AddressLine>ATTN: PAULINE DEGRASSI</AddressLine> + <City/> + <PostCode/> + <State/> + <Country/> + </ShipTo> + <DetailLines> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 5309</PartNumber> + <PartDescription>#1013 12 OZ.MUNICH STEIN</PartDescription> + <UnitPrice>37.72</UnitPrice> + <LineTotal>37.72</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6420</PartNumber> + <PartDescription>PROVINCIAL DINNER FORK</PartDescription> + <UnitPrice>17.98</UnitPrice> + <LineTotal>107.88</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>72</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>JR20643</PartNumber> + <PartDescription>PLASTIC HANDLED STEAK KNIFE</PartDescription> + <UnitPrice>.81</UnitPrice> + <LineTotal>58.32</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>6</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6410</PartNumber> + <PartDescription>PROVINCIAL TEASPOONS</PartDescription> + <UnitPrice>12.16</UnitPrice> + <LineTotal>72.96</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>0</QuantityShipped> + <UnitOfMeasure>DZ</UnitOfMeasure> + <PartNumber>ON 6411</PartNumber> + <PartDescription>PROVINCIAL RD BOWL SPOON</PartDescription> + <QuantityBackOrdered>6</QuantityBackOrdered> + <UnitPrice>17.98</UnitPrice> + <LineTotal>0.00</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>EA</UnitOfMeasure> + <PartNumber>DO 3218</PartNumber> + <PartDescription>34 OZ DUAL DIAL SCALE AM3218</PartDescription> + <UnitPrice>70.00</UnitPrice> + <DiscountPercentage>5.0</DiscountPercentage> + <LineTotal>66.50</LineTotal> + </DetailLine> + <DetailLine> + <QuantityShipped>1</QuantityShipped> + <UnitOfMeasure>CS</UnitOfMeasure> + <PartNumber>DM 195</PartNumber> + <PartDescription>20 OZ.BEER PUB GLASS</PartDescription> + <UnitPrice>55.90</UnitPrice> + <LineTotal>55.90</LineTotal> + </DetailLine> + </DetailLines> + <Totals> + <SubTotal>399.28</SubTotal> + <DiscountTotal>3.50</DiscountTotal> + <FreightTotal>23.75</FreightTotal> + <GSTTotal>29.61</GSTTotal> + <ProvTaxTotal>33.84</ProvTaxTotal> + <OtherTotal>33.84</OtherTotal> + <InvoiceTotal>486.48</InvoiceTotal> + </Totals> +</Invoice> + +</body> +</biztalk_1> diff --git a/src/zope/tal/tests/output/test03.html b/src/zope/tal/tests/output/test03.html new file mode 100644 index 0000000..7fb5156 --- /dev/null +++ b/src/zope/tal/tests/output/test03.html @@ -0,0 +1,9 @@ +<p> + <span> + <span>hello brave new world</span> + <span> + <span>goodbye cruel world</span> + </span> + <span>hello brave new world</span> + </span> +</p> diff --git a/src/zope/tal/tests/output/test03.xml b/src/zope/tal/tests/output/test03.xml new file mode 100644 index 0000000..24be638 --- /dev/null +++ b/src/zope/tal/tests/output/test03.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<p> + <span> + <span>hello brave new world</span> + <span> + <span>goodbye cruel world</span> + </span> + <span>hello brave new world</span> + </span> +</p> diff --git a/src/zope/tal/tests/output/test04.html b/src/zope/tal/tests/output/test04.html new file mode 100644 index 0000000..f0666da --- /dev/null +++ b/src/zope/tal/tests/output/test04.html @@ -0,0 +1,38 @@ +<html> + + <body> + + <ul> + </ul> + + <span /> + + <ul> + <li> + 0 + hello world + </li> + <li> + 1 + hello world + </li> + </ul> + + <span /> + + <ul> + <li> + 0 + goodbye cruel world + </li> + <li> + 1 + goodbye cruel world + </li> + </ul> + + <p>define-slot</p> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test04.xml b/src/zope/tal/tests/output/test04.xml new file mode 100644 index 0000000..8b73d02 --- /dev/null +++ b/src/zope/tal/tests/output/test04.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" ?> +<html> + + <body> + + <ul> + </ul> + + <span/> + + <ul> + <li> + 0 + hello world + </li> + <li> + 1 + hello world + </li> + </ul> + + <span/> + + <ul> + <li> + 0 + goodbye cruel world + </li> + <li> + 1 + goodbye cruel world + </li> + </ul> + + <p>define-slot</p> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test05.html b/src/zope/tal/tests/output/test05.html new file mode 100644 index 0000000..006851a --- /dev/null +++ b/src/zope/tal/tests/output/test05.html @@ -0,0 +1,9 @@ +<html> + + <body> + + <h1>This is the body of test5</h1> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test05.xml b/src/zope/tal/tests/output/test05.xml new file mode 100644 index 0000000..0bc2691 --- /dev/null +++ b/src/zope/tal/tests/output/test05.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<html> + + <body> + + <h1>This is the body of test5</h1> + + </body> + +</html> diff --git a/src/zope/tal/tests/output/test06.html b/src/zope/tal/tests/output/test06.html new file mode 100644 index 0000000..d3f58d9 --- /dev/null +++ b/src/zope/tal/tests/output/test06.html @@ -0,0 +1,7 @@ +<html> + <body> + + <h1>This is the body of test5</h1> + + </body> +</html> diff --git a/src/zope/tal/tests/output/test06.xml b/src/zope/tal/tests/output/test06.xml new file mode 100644 index 0000000..b9ad4ac --- /dev/null +++ b/src/zope/tal/tests/output/test06.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" ?> +<html> + <body> + + <h1>This is the body of test5</h1> + + </body> +</html> diff --git a/src/zope/tal/tests/output/test07.html b/src/zope/tal/tests/output/test07.html new file mode 100644 index 0000000..e0b3d88 --- /dev/null +++ b/src/zope/tal/tests/output/test07.html @@ -0,0 +1,11 @@ +<table> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span>Bottom Right</span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/output/test07.xml b/src/zope/tal/tests/output/test07.xml new file mode 100644 index 0000000..8884d97 --- /dev/null +++ b/src/zope/tal/tests/output/test07.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" ?> +<table> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span>Bottom Right</span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/output/test08.html b/src/zope/tal/tests/output/test08.html new file mode 100644 index 0000000..06e01b2 --- /dev/null +++ b/src/zope/tal/tests/output/test08.html @@ -0,0 +1,47 @@ +<table> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + </span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/output/test08.xml b/src/zope/tal/tests/output/test08.xml new file mode 100644 index 0000000..51a969c --- /dev/null +++ b/src/zope/tal/tests/output/test08.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" ?> +<table> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + </span></td> + </tr> +</table> diff --git a/src/zope/tal/tests/output/test09.html b/src/zope/tal/tests/output/test09.html new file mode 100644 index 0000000..844c1a9 --- /dev/null +++ b/src/zope/tal/tests/output/test09.html @@ -0,0 +1,30 @@ +<html> +<body> +<p> + Just a bunch of text.</p> +<p>more text...</p> +<ul> + <li>first item</li> + <li>second item + + <ol> + <li>second list, first item</li> + <li>second list, second item + <dl compact> + <dt>term 1</dt> + <dt>term 2</dt> + <dd>definition</dd> + </dl></li> + </ol></li> + + <li>Now let's have a paragraph... + <p>My Paragraph</p> + </li> + + <li>And a table in a list item: + <table> + </table></li> +</ul> + +</body> +</html> diff --git a/src/zope/tal/tests/output/test09.xml b/src/zope/tal/tests/output/test09.xml new file mode 100644 index 0000000..c3d10d7 --- /dev/null +++ b/src/zope/tal/tests/output/test09.xml @@ -0,0 +1,30 @@ +<html> +<body> +<p> + Just a bunch of text.</p> +<p>more text...</p> +<ul> + <li>first item</li> + <li>second item + + <ol> + <li>second list, first item</li> + <li>second list, second item + <dl compact=""> + <dt>term 1</dt> + <dt>term 2</dt> + <dd>definition</dd> + </dl></li> + </ol></li> + + <li>Now let's have a paragraph... + <p>My Paragraph</p> + </li> + + <li>And a table in a list item: + <table> + </table></li> +</ul> + +</body> +</html> diff --git a/src/zope/tal/tests/output/test10.html b/src/zope/tal/tests/output/test10.html new file mode 100644 index 0000000..d9cc7ed --- /dev/null +++ b/src/zope/tal/tests/output/test10.html @@ -0,0 +1,51 @@ +<html><body> +<table> +<!-- macro definition with slots --> + <tr> + <td>Top Left</td> + <td>Top Right</td> + </tr> + <tr> + <td>Bottom left</td> + <td><span> + <h1>Some headline</h1> + <p>This is the real contents of the bottom right slot.</p> + <hr> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <p>It is supposed to contain a lot of text. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb. Blah, blah, blab. + Blabber, blabber, blah. Baah, baah, barb.</p> + <br><br> + </span></td> + </tr> +</table> +</body></html> diff --git a/src/zope/tal/tests/output/test11.html b/src/zope/tal/tests/output/test11.html new file mode 100644 index 0000000..9e2223c --- /dev/null +++ b/src/zope/tal/tests/output/test11.html @@ -0,0 +1,8 @@ +<html> + <a href="http://www.python.org">bar</a> + <p>bad boy!</p> + <p>x undefined</p> + x undefined + x undefined + <hr /> +</html> diff --git a/src/zope/tal/tests/output/test11.xml b/src/zope/tal/tests/output/test11.xml new file mode 100644 index 0000000..caba039 --- /dev/null +++ b/src/zope/tal/tests/output/test11.xml @@ -0,0 +1,5 @@ +<html> + <a href="http://www.python.org">bar</a> + <p>bad boy!</p> + <p>x undefined</p> +</html> diff --git a/src/zope/tal/tests/output/test12.html b/src/zope/tal/tests/output/test12.html new file mode 100644 index 0000000..9533b42 --- /dev/null +++ b/src/zope/tal/tests/output/test12.html @@ -0,0 +1,24 @@ +<span /> + +<img ismap> +<img ismap="ismap"> +<img ismap="ismap"> +<img ismap="foo"> + +<img ismap="ismap"> +<img> +<img> + +<img ismap="ismap"> +<img> +<img> + +<img ismap="ismap"> +<img> +<img> + +<span /> + +<img src="foo"> +<img src="x.gif"> +<img> diff --git a/src/zope/tal/tests/output/test13.html b/src/zope/tal/tests/output/test13.html new file mode 100644 index 0000000..d68e0ce --- /dev/null +++ b/src/zope/tal/tests/output/test13.html @@ -0,0 +1,7 @@ +Here's a stray greater than: > + +<script> + <!-- no comment --> + <notag> + &noentity; +</script> diff --git a/src/zope/tal/tests/output/test14.html b/src/zope/tal/tests/output/test14.html new file mode 100644 index 0000000..b9bf468 --- /dev/null +++ b/src/zope/tal/tests/output/test14.html @@ -0,0 +1,13 @@ +<table> + <tr> + <td>car</td> + <td>bike</td> + <td>broomstick</td> + </tr> +</table> + +<p> + Harry + Ron + Hermione +</p> diff --git a/src/zope/tal/tests/output/test14.xml b/src/zope/tal/tests/output/test14.xml new file mode 100644 index 0000000..67c0c37 --- /dev/null +++ b/src/zope/tal/tests/output/test14.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" ?> +<html> + +<table> + <tr> + <td>car</td> + <td>bike</td> + <td>broomstick</td> + </tr> +</table> + +<p> + Harry + Ron + Hermione +</p> + +</html> diff --git a/src/zope/tal/tests/output/test15.html b/src/zope/tal/tests/output/test15.html new file mode 100644 index 0000000..314fd43 --- /dev/null +++ b/src/zope/tal/tests/output/test15.html @@ -0,0 +1,29 @@ +<span> + <span>INNERSLOT</span> +</span> + +<span> + <xxx>inner-argument</xxx> +</span> + +<div> +<span> + <xxx> + OUTERSLOT + </xxx> +</span> +</div> + +<div> +<span> + <div>outer-argument</div> +</span> +</div> + +<div> +<span> + <xxx> + OUTERSLOT + </xxx> +</span> +</div> diff --git a/src/zope/tal/tests/output/test16.html b/src/zope/tal/tests/output/test16.html new file mode 100644 index 0000000..d3ea228 --- /dev/null +++ b/src/zope/tal/tests/output/test16.html @@ -0,0 +1 @@ +<a href="/base/valid/link.html">blah, blah</a> diff --git a/src/zope/tal/tests/output/test16.xml b/src/zope/tal/tests/output/test16.xml new file mode 100644 index 0000000..77e9069 --- /dev/null +++ b/src/zope/tal/tests/output/test16.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<body> + +<ImG href="foo" Alt="bar" alT="baz" Href="about:foo"/> + +</body> diff --git a/src/zope/tal/tests/output/test17.html b/src/zope/tal/tests/output/test17.html new file mode 100644 index 0000000..e50997d --- /dev/null +++ b/src/zope/tal/tests/output/test17.html @@ -0,0 +1,6 @@ +Yes +Yes +Yes + +Yes +Yes diff --git a/src/zope/tal/tests/output/test17.xml b/src/zope/tal/tests/output/test17.xml new file mode 100644 index 0000000..7a54cdb --- /dev/null +++ b/src/zope/tal/tests/output/test17.xml @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<body> +Yes +Yes +Yes + +Yes +Yes +</body> diff --git a/src/zope/tal/tests/output/test18.html b/src/zope/tal/tests/output/test18.html new file mode 100644 index 0000000..f49e29e --- /dev/null +++ b/src/zope/tal/tests/output/test18.html @@ -0,0 +1,16 @@ +Content + + + +Content + + + +<p>Content</p> +<p></p> +<img> + +Yes +Yes +Yes +Yes diff --git a/src/zope/tal/tests/output/test18.xml b/src/zope/tal/tests/output/test18.xml new file mode 100644 index 0000000..77eba02 --- /dev/null +++ b/src/zope/tal/tests/output/test18.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<body> +Content + + + +Content + + + +<p>Content</p> +<p/> +<img/> + +Yes +Yes +Yes +Yes +</body> diff --git a/src/zope/tal/tests/output/test19.html b/src/zope/tal/tests/output/test19.html new file mode 100644 index 0000000..2341a4a --- /dev/null +++ b/src/zope/tal/tests/output/test19.html @@ -0,0 +1,3 @@ +<span>REPLACE THIS</span> +<span>MSGID</span> +<span>AND ANOTHER TRANSLATED STRING</span> diff --git a/src/zope/tal/tests/output/test19.xml b/src/zope/tal/tests/output/test19.xml new file mode 100644 index 0000000..4460acd --- /dev/null +++ b/src/zope/tal/tests/output/test19.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<body> +<span>REPLACE THIS</span> +<span>MSGID</span> +<span>AND ANOTHER TRANSLATED STRING</span> +</body> diff --git a/src/zope/tal/tests/output/test20.html b/src/zope/tal/tests/output/test20.html new file mode 100644 index 0000000..606b989 --- /dev/null +++ b/src/zope/tal/tests/output/test20.html @@ -0,0 +1 @@ +<span>REPLACEABLE HERE</span> diff --git a/src/zope/tal/tests/output/test20.xml b/src/zope/tal/tests/output/test20.xml new file mode 100644 index 0000000..ed1f9fe --- /dev/null +++ b/src/zope/tal/tests/output/test20.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<body> +<span>REPLACEABLE HERE</span> +</body> diff --git a/src/zope/tal/tests/output/test21.html b/src/zope/tal/tests/output/test21.html new file mode 100644 index 0000000..95b3b08 --- /dev/null +++ b/src/zope/tal/tests/output/test21.html @@ -0,0 +1 @@ +<span>Lomax WAS BORN IN Antarctica.</span> diff --git a/src/zope/tal/tests/output/test21.xml b/src/zope/tal/tests/output/test21.xml new file mode 100644 index 0000000..c373d52 --- /dev/null +++ b/src/zope/tal/tests/output/test21.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<body> +<span>Lomax WAS BORN IN Antarctica.</span> +</body> diff --git a/src/zope/tal/tests/output/test22.html b/src/zope/tal/tests/output/test22.html new file mode 100644 index 0000000..6c1b6de --- /dev/null +++ b/src/zope/tal/tests/output/test22.html @@ -0,0 +1 @@ +<span><b>Jim</b> WAS BORN IN the USA.</span> diff --git a/src/zope/tal/tests/output/test22.xml b/src/zope/tal/tests/output/test22.xml new file mode 100644 index 0000000..c2e79c5 --- /dev/null +++ b/src/zope/tal/tests/output/test22.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<body> + <span>content</span> + omit + replace +</body> diff --git a/src/zope/tal/tests/output/test23.html b/src/zope/tal/tests/output/test23.html new file mode 100644 index 0000000..0ea1654 --- /dev/null +++ b/src/zope/tal/tests/output/test23.html @@ -0,0 +1 @@ +<span>59 minutes after 6 PM</span> diff --git a/src/zope/tal/tests/output/test24.html b/src/zope/tal/tests/output/test24.html new file mode 100644 index 0000000..8dbfba3 --- /dev/null +++ b/src/zope/tal/tests/output/test24.html @@ -0,0 +1,7 @@ +<input name="DELETE_BUTTON"> + +<input name="MESSAGE-ID"> + +<input name="MESSAGE-ID" attr="INPUT-ATTR"> + +<input name="MESSAGE-ID" attr="INPUT-ATTR"> diff --git a/src/zope/tal/tests/output/test25.html b/src/zope/tal/tests/output/test25.html new file mode 100644 index 0000000..6b80bd3 --- /dev/null +++ b/src/zope/tal/tests/output/test25.html @@ -0,0 +1 @@ +<input name="DELETE"> diff --git a/src/zope/tal/tests/output/test26.html b/src/zope/tal/tests/output/test26.html new file mode 100644 index 0000000..9d179a6 --- /dev/null +++ b/src/zope/tal/tests/output/test26.html @@ -0,0 +1 @@ +<span>7 is the JOB NUMBER</span> diff --git a/src/zope/tal/tests/output/test27.html b/src/zope/tal/tests/output/test27.html new file mode 100644 index 0000000..96229e4 --- /dev/null +++ b/src/zope/tal/tests/output/test27.html @@ -0,0 +1 @@ +<p>Your contact email address is recorded as <a href="mailto:user@example.com">aperson@dom.ain</a></p> diff --git a/src/zope/tal/tests/output/test28.html b/src/zope/tal/tests/output/test28.html new file mode 100644 index 0000000..96229e4 --- /dev/null +++ b/src/zope/tal/tests/output/test28.html @@ -0,0 +1 @@ +<p>Your contact email address is recorded as <a href="mailto:user@example.com">aperson@dom.ain</a></p> diff --git a/src/zope/tal/tests/output/test29.html b/src/zope/tal/tests/output/test29.html new file mode 100644 index 0000000..886137e --- /dev/null +++ b/src/zope/tal/tests/output/test29.html @@ -0,0 +1 @@ +<div>AT THE TONE THE TIME WILL BE <span>59 minutes after 6 PM</span>... BEEP!</div> diff --git a/src/zope/tal/tests/output/test30.html b/src/zope/tal/tests/output/test30.html new file mode 100644 index 0000000..964b772 --- /dev/null +++ b/src/zope/tal/tests/output/test30.html @@ -0,0 +1 @@ +<p>Your contact email address is recorded as <a href="mailto:${request/submitter}">aperson@dom.ain</a></p> diff --git a/src/zope/tal/tests/output/test31.html b/src/zope/tal/tests/output/test31.html new file mode 100644 index 0000000..964b772 --- /dev/null +++ b/src/zope/tal/tests/output/test31.html @@ -0,0 +1 @@ +<p>Your contact email address is recorded as <a href="mailto:${request/submitter}">aperson@dom.ain</a></p> diff --git a/src/zope/tal/tests/output/test32.html b/src/zope/tal/tests/output/test32.html new file mode 100644 index 0000000..f39bd97 --- /dev/null +++ b/src/zope/tal/tests/output/test32.html @@ -0,0 +1 @@ +<span><span>Lomax</span> was born in <span>Antarctica</span></span> diff --git a/src/zope/tal/tests/output/test33.html b/src/zope/tal/tests/output/test33.html new file mode 100644 index 0000000..4472f21 --- /dev/null +++ b/src/zope/tal/tests/output/test33.html @@ -0,0 +1 @@ +<span>don't translate me</span> diff --git a/src/zope/tal/tests/output/test34.html b/src/zope/tal/tests/output/test34.html new file mode 100644 index 0000000..1d7b5f2 --- /dev/null +++ b/src/zope/tal/tests/output/test34.html @@ -0,0 +1,7 @@ +<span> + stuff + foobar + more stuff +</span> + +<span>STUFF foobar MORE STUFF</span> diff --git a/src/zope/tal/tests/output/test35.html b/src/zope/tal/tests/output/test35.html new file mode 100644 index 0000000..b1a9d2e --- /dev/null +++ b/src/zope/tal/tests/output/test35.html @@ -0,0 +1,6 @@ + + + + + + <h1>page</h1> diff --git a/src/zope/tal/tests/output/test36.html b/src/zope/tal/tests/output/test36.html new file mode 100644 index 0000000..2a563c1 --- /dev/null +++ b/src/zope/tal/tests/output/test36.html @@ -0,0 +1,2 @@ +<foo> +<span><foo> <bar /> <b>some</b> <i>text</i></span> diff --git a/src/zope/tal/tests/output/test_domain.html b/src/zope/tal/tests/output/test_domain.html new file mode 100644 index 0000000..6a282ac --- /dev/null +++ b/src/zope/tal/tests/output/test_domain.html @@ -0,0 +1,5 @@ +<div> +<span>replace this</span> +<span>msgid</span> +<span>and another translated string</span> +</div> diff --git a/src/zope/tal/tests/output/test_failed_attr_translation.html b/src/zope/tal/tests/output/test_failed_attr_translation.html new file mode 100644 index 0000000..cd34b1f --- /dev/null +++ b/src/zope/tal/tests/output/test_failed_attr_translation.html @@ -0,0 +1 @@ +<input value="don't translate me"> diff --git a/src/zope/tal/tests/output/test_metal1.html b/src/zope/tal/tests/output/test_metal1.html new file mode 100644 index 0000000..c8cc346 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal1.html @@ -0,0 +1,79 @@ +<span metal:define-macro="OUTER"> + AAA + <span metal:define-macro="INNER">INNER</span> + BBB +</span> + +<span metal:use-macro="OUTER"> + AAA + <span>INNER</span> + BBB +</span> + +<span metal:use-macro="INNER">INNER</span> + +<span metal:define-macro="OUTER2"> + AAA + <xxx metal:define-slot="OUTERSLOT"> + <span metal:define-macro="INNER2">INNER</span> + </xxx> + BBB +</span> + +<span metal:use-macro="OUTER2"> + AAA + <xxx> + <span>INNER</span> + </xxx> + BBB +</span> + +<span metal:use-macro="INNER2">INNER</span> + +<span metal:use-macro="OUTER2"> + AAA + <yyy metal:fill-slot="OUTERSLOT">OUTERSLOT</yyy> + BBB +</span> + +<span metal:define-macro="OUTER3"> + AAA + <xxx metal:define-slot="OUTERSLOT"> + <span metal:define-macro="INNER3">INNER + <xxx metal:define-slot="INNERSLOT">INNERSLOT</xxx> + </span> + </xxx> + BBB +</span> + +<span metal:use-macro="OUTER3"> + AAA + <xxx> + <span>INNER + <xxx>INNERSLOT</xxx> + </span> + </xxx> + BBB +</span> + +<span metal:use-macro="OUTER3"> + AAA + <yyy metal:fill-slot="OUTERSLOT">OUTERSLOT</yyy> + BBB +</span> + +<span metal:use-macro="INNER3">INNER + <xxx>INNERSLOT</xxx> + </span> + +<span metal:use-macro="INNER3">INNER + <yyy metal:fill-slot="INNERSLOT">INNERSLOT</yyy> + </span> + +<span metal:use-macro="INNER3">INNER + <yyy metal:fill-slot="INNERSLOT"> + <zzz metal:define-macro="INSLOT">INSLOT</zzz> + </yyy> + </span> + +<zzz metal:use-macro="INSLOT">INSLOT</zzz> diff --git a/src/zope/tal/tests/output/test_metal2.html b/src/zope/tal/tests/output/test_metal2.html new file mode 100644 index 0000000..7e56c0c --- /dev/null +++ b/src/zope/tal/tests/output/test_metal2.html @@ -0,0 +1,11 @@ +<div metal:define-macro="OUTER"> + OUTER + <span metal:define-macro="INNER">INNER</span> + OUTER +</div> + +<div metal:use-macro="OUTER"> + OUTER + <span>INNER</span> + OUTER +</div> diff --git a/src/zope/tal/tests/output/test_metal3.html b/src/zope/tal/tests/output/test_metal3.html new file mode 100644 index 0000000..b0af907 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal3.html @@ -0,0 +1 @@ +<span tal:attributes="class string:foo">Should not get attr in metal</span> diff --git a/src/zope/tal/tests/output/test_metal4.html b/src/zope/tal/tests/output/test_metal4.html new file mode 100644 index 0000000..dc774d3 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal4.html @@ -0,0 +1,4 @@ +<!-- the outer element *must* be tal:something or metal:something --> +<metal:block define-macro="page" i18n:domain="zope"> + <title metal:define-slot="title">Z3 UI</title> +</metal:block> diff --git a/src/zope/tal/tests/output/test_metal5.html b/src/zope/tal/tests/output/test_metal5.html new file mode 100644 index 0000000..8bae3d8 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal5.html @@ -0,0 +1,4 @@ +<!-- the outer element *must* include tal:omit-tag='' --> +<x tal:omit-tag="" metal:define-macro="page" i18n:domain="zope"> + <title metal:define-slot="title">Z3 UI</title> +</x> diff --git a/src/zope/tal/tests/output/test_metal6.html b/src/zope/tal/tests/output/test_metal6.html new file mode 100644 index 0000000..ce243f2 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal6.html @@ -0,0 +1,5 @@ +<metal:block define-macro="page"> + <html i18:domain="zope"> + <metal:block define-slot="title">Z3 UI</metal:block> + </html> +</metal:block> diff --git a/src/zope/tal/tests/output/test_metal7.html b/src/zope/tal/tests/output/test_metal7.html new file mode 100644 index 0000000..cc449ed --- /dev/null +++ b/src/zope/tal/tests/output/test_metal7.html @@ -0,0 +1,6 @@ +<html metal:define-macro="page" i18n:domain="zope"> + <x metal:define-slot="title" /> +</html> +<html metal:use-macro="page" i18n:domain="zope"> + <x metal:fill-slot="title" /> +</html> diff --git a/src/zope/tal/tests/output/test_metal8.html b/src/zope/tal/tests/output/test_metal8.html new file mode 100644 index 0000000..d56adab --- /dev/null +++ b/src/zope/tal/tests/output/test_metal8.html @@ -0,0 +1,19 @@ +<html metal:define-macro="page" i18n:domain="zope"> +<body> +<div metal:define-macro="workspace"> +<div metal:define-slot="body"> +Default body +</div> +</div> +</body> +</html> + +<html metal:use-macro="page" i18n:domain="zope"> +<body> +<div> +<div metal:fill-slot="body"> +Filled-in body +</div> +</div> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_metal9.html b/src/zope/tal/tests/output/test_metal9.html new file mode 100644 index 0000000..4cbc637 --- /dev/null +++ b/src/zope/tal/tests/output/test_metal9.html @@ -0,0 +1,32 @@ +<div metal:define-macro="macro1" i18n:domain="zope"> +<span metal:define-slot="slot1"> +Default for macro1 +</span> +</div> + +<div metal:define-macro="macro2" metal:use-macro="macro1" i18n:domain="zope"> +<span metal:fill-slot="slot1"> +Macro 2's slot 1 decoration +<span metal:define-slot="slot1"> +Default for macro2 +</span> +</span> +</div> + +<div metal:use-macro="macro2" i18n:domain="zope"> +<span metal:fill-slot="slot1"> +Macro 2's slot 1 decoration +<span> +Default for macro2 +</span> +</span> +</div> + +<div metal:use-macro="macro2" i18n:domain="zope"> +<span metal:fill-slot="slot1"> +Macro 2's slot 1 decoration +<span metal:fill-slot="slot1"> +Custom slot1 +</span> +</span> +</div> diff --git a/src/zope/tal/tests/output/test_sa1.html b/src/zope/tal/tests/output/test_sa1.html new file mode 100644 index 0000000..a37b9e9 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa1.html @@ -0,0 +1,10 @@ +<!-- +============================================================================== +tests/input/test_sa1.html +============================================================================== +--><html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa1.xml b/src/zope/tal/tests/output/test_sa1.xml new file mode 100644 index 0000000..8e1f4cc --- /dev/null +++ b/src/zope/tal/tests/output/test_sa1.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" ?><!-- +============================================================================== +tests/input/test_sa1.xml +============================================================================== +--> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa2.html b/src/zope/tal/tests/output/test_sa2.html new file mode 100644 index 0000000..4709b49 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa2.html @@ -0,0 +1,13 @@ +<!-- +============================================================================== +tests/input/test_sa2.html +============================================================================== +--><!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa2.xml b/src/zope/tal/tests/output/test_sa2.xml new file mode 100644 index 0000000..30b5699 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa2.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" ?><!-- +============================================================================== +tests/input/test_sa2.xml +============================================================================== +--> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "DTD/xhtml1-transitional.dtd"> +<html> +<title>Simple test of source annotations</title> +<body> +<p>Foo!</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa3.html b/src/zope/tal/tests/output/test_sa3.html new file mode 100644 index 0000000..8431438 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa3.html @@ -0,0 +1,42 @@ +<!-- +============================================================================== +tests/input/test_sa3.html +============================================================================== +--><html> +<body> + <!-- +============================================================================== +tests/input/test_sa3.html (line 3) +============================================================================== +--><div>This is macro1 on sa3 line 3. + <span>This is slot1 on sa3 line 4.</span><!-- +============================================================================== +tests/input/test_sa3.html (line 4) +============================================================================== +--> + This is the end of macro1 on sa3 line 5. + </div> + <p>Some text on sa3 line 7.</p> + <!-- +============================================================================== +tests/input/test_sa3.html (line 3) +============================================================================== +--><div>This is macro1 on sa3 line 3. + <!-- +============================================================================== +tests/input/test_sa3.html (line 10) +============================================================================== +--><b>Text from sa3 line 10 is filled into slot1.</b><!-- +============================================================================== +tests/input/test_sa3.html (line 4) +============================================================================== +--> + This is the end of macro1 on sa3 line 5. + </div><!-- +============================================================================== +tests/input/test_sa3.html (line 12) +============================================================================== +--> + <p>This is some text on sa3 line 13.</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa3.xml b/src/zope/tal/tests/output/test_sa3.xml new file mode 100644 index 0000000..bd20f83 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa3.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" ?><!-- +============================================================================== +tests/input/test_sa3.xml +============================================================================== +--> +<html> +<body> + <!-- +============================================================================== +tests/input/test_sa3.xml (line 4) +============================================================================== +--><div>This is macro1 on sa3 line 4. + <span>This is slot1 on sa3 line 5.</span><!-- +============================================================================== +tests/input/test_sa3.xml (line 5) +============================================================================== +--> + This is the end of macro1 on sa3 line 6. + </div> + <p>Some text on sa3 line 8.</p> + <!-- +============================================================================== +tests/input/test_sa3.xml (line 4) +============================================================================== +--><div>This is macro1 on sa3 line 4. + <!-- +============================================================================== +tests/input/test_sa3.xml (line 11) +============================================================================== +--><b>Text from sa3 line 11 is filled into slot1.</b><!-- +============================================================================== +tests/input/test_sa3.xml (line 5) +============================================================================== +--> + This is the end of macro1 on sa3 line 6. + </div><!-- +============================================================================== +tests/input/test_sa3.xml (line 13) +============================================================================== +--> + <p>This is some text on sa3 line 14.</p> +</body> +</html> diff --git a/src/zope/tal/tests/output/test_sa4.html b/src/zope/tal/tests/output/test_sa4.html new file mode 100644 index 0000000..4aca908 --- /dev/null +++ b/src/zope/tal/tests/output/test_sa4.html @@ -0,0 +1,30 @@ +<!-- +============================================================================== +tests/input/test_sa4.html +============================================================================== +--><html> +<body> + <p>Some text on sa4 line 3.</p> + <!-- +============================================================================== +tests/input/test_sa3.html (line 3) +============================================================================== +--><div>This is macro1 on sa3 line 3. + <!-- +============================================================================== +tests/input/test_sa4.html (line 6) +============================================================================== +--><b>Text from sa4 line 6 is filled into slot1.</b><!-- +============================================================================== +tests/input/test_sa3.html (line 4) +============================================================================== +--> + This is the end of macro1 on sa3 line 5. + </div><!-- +============================================================================== +tests/input/test_sa4.html (line 8) +============================================================================== +--> + <p>This is some text on sa4 line 9.</p> +</body> +</html> diff --git a/src/zope/tal/tests/run.py b/src/zope/tal/tests/run.py new file mode 100644 index 0000000..b4dab8c --- /dev/null +++ b/src/zope/tal/tests/run.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Run all tests. + +$Id$ +""" +import sys +import unittest + +from zope.tal.tests import utils +from zope.tal.tests import test_htmltalparser +from zope.tal.tests import test_talinterpreter +from zope.tal.tests import test_files +from zope.tal.tests import test_sourcepos + +# TODO this code isn't picked up by the Zope 3 test framework.. +def test_suite(): + suite = unittest.TestSuite() + suite.addTest(test_htmltalparser.test_suite()) + if not utils.skipxml: + import test_xmlparser + suite.addTest(test_xmlparser.test_suite()) + suite.addTest(test_talinterpreter.test_suite()) + suite.addTest(test_files.test_suite()) + suite.addTest(test_sourcepos.test_suite()) + return suite + +def main(): + return utils.run_suite(test_suite()) + +if __name__ == "__main__": + errs = main() + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/test_files.py b/src/zope/tal/tests/test_files.py new file mode 100644 index 0000000..e26f00a --- /dev/null +++ b/src/zope/tal/tests/test_files.py @@ -0,0 +1,90 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests that run driver.py over input files comparing to output files. + +$Id$ +""" + +import glob +import os +import sys +import unittest + +import zope.tal.runtest + +from zope.tal.tests import utils + + +class FileTestCase(unittest.TestCase): + + def __init__(self, file, dir): + self.__file = file + self.__dir = dir + unittest.TestCase.__init__(self) + + # For unittest. + def shortDescription(self): + path = os.path.basename(self.__file) + return '%s (%s)' % (path, self.__class__) + + def runTest(self): + basename = os.path.basename(self.__file) + #sys.stdout.write(basename + " ") + sys.stdout.flush() + if basename.startswith('test_sa'): + sys.argv = ["", "-Q", "-a", self.__file] + elif basename.startswith('test_metal'): + sys.argv = ["", "-Q", "-m", self.__file] + else: + sys.argv = ["", "-Q", self.__file] + pwd = os.getcwd() + try: + try: + os.chdir(self.__dir) + zope.tal.runtest.main() + finally: + os.chdir(pwd) + except SystemExit, what: + if what.code: + self.fail("output for %s didn't match" % self.__file) + +try: + script = __file__ +except NameError: + script = sys.argv[0] + +def test_suite(): + suite = unittest.TestSuite() + dir = os.path.dirname(script) + dir = os.path.abspath(dir) + parentdir = os.path.dirname(dir) + prefix = os.path.join(dir, "input", "test*.") + if utils.skipxml: + xmlargs = [] + else: + xmlargs = glob.glob(prefix + "xml") + xmlargs.sort() + htmlargs = glob.glob(prefix + "html") + htmlargs.sort() + args = xmlargs + htmlargs + if not args: + sys.stderr.write("Warning: no test input files found!!!\n") + for arg in args: + case = FileTestCase(arg, parentdir) + suite.addTest(case) + return suite + +if __name__ == "__main__": + errs = utils.run_suite(test_suite()) + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/test_htmltalparser.py b/src/zope/tal/tests/test_htmltalparser.py new file mode 100644 index 0000000..eb53f51 --- /dev/null +++ b/src/zope/tal/tests/test_htmltalparser.py @@ -0,0 +1,1021 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for the HTMLTALParser code generator. + +$Id$ +""" +import pprint +import sys +import unittest + +from zope.tal import htmltalparser, taldefs +from zope.tal.tests import utils + + +class TestCaseBase(unittest.TestCase): + + prologue = "" + epilogue = "" + initial_program = [('version', taldefs.TAL_VERSION), ('mode', 'html')] + final_program = [] + + def _merge(self, p1, p2): + if p1 and p2: + op1, args1 = p1[-1] + op2, args2 = p2[0] + if op1.startswith('rawtext') and op2.startswith('rawtext'): + return (p1[:-1] + + [rawtext(args1[0] + args2[0])] + + p2[1:]) + return p1+p2 + + def _run_check(self, source, program, macros={}): + parser = htmltalparser.HTMLTALParser() + parser.parseString(self.prologue + source + self.epilogue) + got_program, got_macros = parser.getCode() + program = self._merge(self.initial_program, program) + program = self._merge(program, self.final_program) + self.assert_(got_program == program, + "Program:\n" + pprint.pformat(got_program) + + "\nExpected:\n" + pprint.pformat(program)) + self.assert_(got_macros == macros, + "Macros:\n" + pprint.pformat(got_macros) + + "\nExpected:\n" + pprint.pformat(macros)) + + def _should_error(self, source, exc=taldefs.TALError): + def parse(self=self, source=source): + parser = htmltalparser.HTMLTALParser() + parser.parseString(self.prologue + source + self.epilogue) + self.assertRaises(exc, parse) + + +def rawtext(s): + """Compile raw text to the appropriate instruction.""" + if "\n" in s: + return ("rawtextColumn", (s, len(s) - (s.rfind("\n") + 1))) + else: + return ("rawtextOffset", (s, len(s))) + + +class HTMLTALParserTestCases(TestCaseBase): + + def test_code_simple_identity(self): + self._run_check("""<html a='b' b="c" c=d><title>My Title</html>""", [ + rawtext('<html a="b" b="c" c="d">' + '<title>My Title</title></html>'), + ]) + + def test_code_implied_list_closings(self): + self._run_check("""<ul><li><p><p><li></ul>""", [ + rawtext('<ul><li><p></p><p></p></li><li></li></ul>'), + ]) + self._run_check("""<dl><dt><dt><dd><dd><ol><li><li></ol></dl>""", [ + rawtext('<dl><dt></dt><dt></dt><dd></dd>' + '<dd><ol><li></li><li></li></ol></dd></dl>'), + ]) + + def test_code_implied_table_closings(self): + self._run_check("""<p>text <table><tr><th>head\t<tr><td>cell\t""" + """<table><tr><td>cell \n \t \n<tr>""", [ + rawtext('<p>text</p> <table><tr><th>head</th>' + '</tr>\t<tr><td>cell\t<table><tr><td>cell</td>' + '</tr> \n \t \n<tr></tr></table></td></tr></table>'), + ]) + self._run_check("""<table><tr><td>cell """ + """<table><tr><td>cell </table></table>""", [ + rawtext('<table><tr><td>cell <table><tr><td>cell</td></tr>' + ' </table></td></tr></table>'), + ]) + + def test_code_bad_nesting(self): + def check(self=self): + self._run_check("<a><b></a></b>", []) + self.assertRaises(htmltalparser.NestingError, check) + + def test_code_attr_syntax(self): + output = [ + rawtext('<a b="v" c="v" d="v" e></a>'), + ] + self._run_check("""<a b='v' c="v" d=v e>""", output) + self._run_check("""<a b = 'v' c = "v" d = v e>""", output) + self._run_check("""<a\nb\n=\n'v'\nc\n=\n"v"\nd\n=\nv\ne>""", output) + self._run_check("""<a\tb\t=\t'v'\tc\t=\t"v"\td\t=\tv\te>""", output) + + def test_code_attr_values(self): + self._run_check( + """<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'>""", [ + rawtext('<a b="xxx\n\txxx" c="yyy\t\nyyy" d="\txyz\n"></a>')]) + self._run_check("""<a b='' c="">""", [ + rawtext('<a b="" c=""></a>'), + ]) + + def test_code_attr_entity_replacement(self): + # we expect entities *not* to be replaced by HTLMParser! + self._run_check("""<a b='&><"''>""", [ + rawtext('<a b="&><"\'"></a>'), + ]) + self._run_check("""<a b='\"'>""", [ + rawtext('<a b="""></a>'), + ]) + self._run_check("""<a b='&'>""", [ + rawtext('<a b="&"></a>'), + ]) + self._run_check("""<a b='<'>""", [ + rawtext('<a b="<"></a>'), + ]) + + def test_code_attr_funky_names(self): + self._run_check("""<a a.b='v' c:d=v e-f=v>""", [ + rawtext('<a a.b="v" c:d="v" e-f="v"></a>'), + ]) + + def test_code_pcdata_entityref(self): + self._run_check(""" """, [ + rawtext(' '), + ]) + + def test_code_short_endtags(self): + self._run_check("""<html><img/></html>""", [ + rawtext('<html><img /></html>'), + ]) + + +class METALGeneratorTestCases(TestCaseBase): + + def test_null(self): + self._run_check("", []) + + def test_define_macro(self): + macro = self.initial_program + [ + ('startTag', ('p', [('metal:define-macro', 'M', 'metal')])), + rawtext('booh</p>'), + ] + program = [ + ('setPosition', (1, 0)), + ('defineMacro', ('M', macro)), + ] + macros = {'M': macro} + self._run_check('<p metal:define-macro="M">booh</p>', program, macros) + + def test_use_macro(self): + self._run_check('<p metal:use-macro="M">booh</p>', [ + ('setPosition', (1, 0)), + ('useMacro', + ('M', '$M$', {}, + [('startTag', ('p', [('metal:use-macro', 'M', 'metal')])), + rawtext('booh</p>')])), + ]) + + def test_define_slot(self): + macro = self.initial_program + [ + ('startTag', ('p', [('metal:define-macro', 'M', 'metal')])), + rawtext('foo'), + ('setPosition', (1, 29)), + ('defineSlot', ('S', + [('startTag', ('span', [('metal:define-slot', 'S', 'metal')])), + rawtext('spam</span>')])), + rawtext('bar</p>'), + ] + program = [('setPosition', (1, 0)), + ('defineMacro', ('M', macro))] + macros = {'M': macro} + self._run_check('<p metal:define-macro="M">foo' + '<span metal:define-slot="S">spam</span>bar</p>', + program, macros) + + def test_fill_slot(self): + self._run_check('<p metal:use-macro="M">foo' + '<span metal:fill-slot="S">spam</span>bar</p>', [ + ('setPosition', (1, 0)), + ('useMacro', + ('M', '$M$', + {'S': [('startTag', ('span', + [('metal:fill-slot', 'S', 'metal')])), + rawtext('spam</span>')]}, + [('startTag', ('p', [('metal:use-macro', 'M', 'metal')])), + rawtext('foo'), + ('setPosition', (1, 26)), + ('fillSlot', ('S', + [('startTag', ('span', [('metal:fill-slot', 'S', 'metal')])), + rawtext('spam</span>')])), + rawtext('bar</p>')])), + ]) + + +class TALGeneratorTestCases(TestCaseBase): + + def test_null(self): + self._run_check("", []) + + def test_define_1(self): + self._run_check("<p tal:define='xyzzy string:spam'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:define': 'xyzzy string:spam'}), + ('setLocal', ('xyzzy', '$string:spam$')), + ('startTag', ('p', [('tal:define', 'xyzzy string:spam', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_define_2(self): + self._run_check("<p tal:define='local xyzzy string:spam'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:define': 'local xyzzy string:spam'}), + ('setLocal', ('xyzzy', '$string:spam$')), + ('startTag', ('p', + [('tal:define', 'local xyzzy string:spam', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_define_3(self): + self._run_check("<p tal:define='global xyzzy string:spam'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:define': 'global xyzzy string:spam'}), + ('setGlobal', ('xyzzy', '$string:spam$')), + ('startTag', ('p', + [('tal:define', 'global xyzzy string:spam', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_define_4(self): + self._run_check("<p tal:define='x string:spam; y x'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:define': 'x string:spam; y x'}), + ('setLocal', ('x', '$string:spam$')), + ('setLocal', ('y', '$x$')), + ('startTag', ('p', [('tal:define', 'x string:spam; y x', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_define_5(self): + self._run_check("<p tal:define='x string:;;;;; y x'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:define': 'x string:;;;;; y x'}), + ('setLocal', ('x', '$string:;;$')), + ('setLocal', ('y', '$x$')), + ('startTag', ('p', [('tal:define', 'x string:;;;;; y x', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_define_6(self): + self._run_check( + "<p tal:define='x string:spam; global y x; local z y'></p>", [ + ('setPosition', (1, 0)), + ('beginScope', + {'tal:define': 'x string:spam; global y x; local z y'}), + ('setLocal', ('x', '$string:spam$')), + ('setGlobal', ('y', '$x$')), + ('setLocal', ('z', '$y$')), + ('startTag', ('p', + [('tal:define', 'x string:spam; global y x; local z y', 'tal')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_condition(self): + self._run_check( + "<p><span tal:condition='python:1'><b>foo</b></span></p>", [ + rawtext('<p>'), + ('setPosition', (1, 3)), + ('beginScope', {'tal:condition': 'python:1'}), + ('condition', ('$python:1$', + [('startTag', ('span', [('tal:condition', 'python:1', 'tal')])), + rawtext('<b>foo</b></span>')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_content_1(self): + self._run_check("<p tal:content='string:foo'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:content': 'string:foo'}), + ('startTag', ('p', [('tal:content', 'string:foo', 'tal')])), + ('insertText', ('$string:foo$', [rawtext('bar')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_content_2(self): + self._run_check("<p tal:content='text string:foo'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:content': 'text string:foo'}), + ('startTag', ('p', [('tal:content', 'text string:foo', 'tal')])), + ('insertText', ('$string:foo$', [rawtext('bar')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_content_3(self): + self._run_check("<p tal:content='structure string:<br>'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:content': 'structure string:<br>'}), + ('startTag', ('p', + [('tal:content', 'structure string:<br>', 'tal')])), + ('insertStructure', + ('$string:<br>$', {}, [rawtext('bar')])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_replace_1(self): + self._run_check("<p tal:replace='string:foo'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:replace': 'string:foo'}), + ('optTag', + ('p', + '', + None, + 0, + [('startTag', ('p', [('tal:replace', 'string:foo', 'tal')]))], + [('insertText', ('$string:foo$', [('rawtextOffset', ('bar', 3))]))])), + ('endScope', ()), + ]) + + def test_replace_2(self): + self._run_check("<p tal:replace='text string:foo'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:replace': 'text string:foo'}), + ('optTag', + ('p', + '', + None, + 0, + [('startTag', ('p', [('tal:replace', 'text string:foo', 'tal')]))], + [('insertText', ('$string:foo$', [('rawtextOffset', ('bar', 3))]))])), + ('endScope', ()), + ]) + + def test_replace_3(self): + self._run_check("<p tal:replace='structure string:<br>'>bar</p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:replace': 'structure string:<br>'}), + ('optTag', + ('p', + '', + None, + 0, + [('startTag', ('p', [('tal:replace', 'structure string:<br>', 'tal')]))], + [('insertStructure', + ('$string:<br>$', {}, [('rawtextOffset', ('bar', 3))]))])), + ('endScope', ()), + ]) + + def test_repeat(self): + self._run_check("<p tal:repeat='x python:(1,2,3)'>" + "<span tal:replace='x'>dummy</span></p>", [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:repeat': 'x python:(1,2,3)'}), + ('loop', ('x', '$python:(1,2,3)$', + [('startTag', ('p', + [('tal:repeat', 'x python:(1,2,3)', 'tal')])), + ('setPosition', (1, 33)), + ('beginScope', {'tal:replace': 'x'}), + ('optTag', + ('span', + '', + None, + 0, + [('startTag', ('span', [('tal:replace', 'x', 'tal')]))], + [('insertText', ('$x$', [('rawtextOffset', ('dummy', 5))]))])), + ('endScope', ()), + rawtext('</p>')])), + ('endScope', ()), + ]) + + def test_script_1(self): + self._run_check('<p tal:script="text/server-python">code</p>', [ + ('setPosition', (1, 0)), + ('beginScope', {'tal:script': 'text/server-python'}), + ('startTag', ('p', + [('tal:script', 'text/server-python', 'tal')])), + ('evaluateCode', ('text/server-python', + [('rawtextOffset', ('code', 4))])), + ('endScope', ()), + rawtext('</p>'), + ]) + + def test_script_2(self): + self._run_check('<tal:block script="text/server-python">' + 'code' + '</tal:block>', [ + ('setPosition', (1, 0)), + ('beginScope', {'script': 'text/server-python'}), + ('optTag', + ('tal:block', + None, + 'tal', + 0, + [('startTag', ('tal:block', + [('script', 'text/server-python', 'tal')]))], + [('evaluateCode', + ('text/server-python', + [('rawtextOffset', ('code', 4))]))])), + ('endScope', ()) + ]) + + def test_script_3(self): + self._run_check('<script type="text/server-python">code</script>', [ + ('setPosition', (1, 0)), + ('beginScope', {}), + ('optTag', + ('script', + '', + None, + 0, + [('rawtextOffset', ('<script>', 8))], + [('evaluateCode', + ('text/server-python', [('rawtextOffset', ('code', 4))]))])), + ('endScope', ()) + ]) + + def test_script_4(self): + self._run_check('<script type="text/javascript">code</script>', [ + ('rawtextOffset', + ('<script type="text/javascript">code</script>', 44)) + ]) + + def test_attributes_1(self): + self._run_check("<a href='foo' name='bar' tal:attributes=" + "'href string:http://www.zope.org; x string:y'>" + "link</a>", [ + ('setPosition', (1, 0)), + ('beginScope', + {'tal:attributes': 'href string:http://www.zope.org; x string:y', + 'name': 'bar', 'href': 'foo'}), + ('startTag', ('a', + [('href', 'foo', 'replace', '$string:http://www.zope.org$', 0, None), + ('name', 'name="bar"'), + ('tal:attributes', + 'href string:http://www.zope.org; x string:y', 'tal'), + ('x', None, 'insert', '$string:y$', 0, None)])), + ('endScope', ()), + rawtext('link</a>'), + ]) + + def test_attributes_2(self): + self._run_check("<p tal:replace='structure string:<img>' " + "tal:attributes='src string:foo.png'>duh</p>", [ + ('setPosition', (1, 0)), + ('beginScope', + {'tal:attributes': 'src string:foo.png', + 'tal:replace': 'structure string:<img>'}), + ('optTag', + ('p', + '', + None, + 0, + [('startTag', + ('p', + [('tal:replace', 'structure string:<img>', 'tal'), + ('tal:attributes', 'src string:foo.png', 'tal')]))], + [('insertStructure', + ('$string:<img>$', + {'src': ('$string:foo.png$', False, None)}, + [('rawtextOffset', ('duh', 3))]))])), + ('endScope', ())]) + + def test_on_error_1(self): + self._run_check("<p tal:on-error='string:error' " + "tal:content='notHere'>okay</p>", [ + ('setPosition', (1, 0)), + ('beginScope', + {'tal:content': 'notHere', 'tal:on-error': 'string:error'}), + ('onError', + ([('startTag', ('p', + [('tal:on-error', 'string:error', 'tal'), + ('tal:content', 'notHere', 'tal')])), + ('insertText', ('$notHere$', [rawtext('okay')])), + rawtext('</p>')], + [('startTag', ('p', + [('tal:on-error', 'string:error', 'tal'), + ('tal:content', 'notHere', 'tal')])), + ('insertText', ('$string:error$', [])), + rawtext('</p>')])), + ('endScope', ()), + ]) + + def test_on_error_2(self): + self._run_check("<p tal:on-error='string:error' " + "tal:replace='notHere'>okay</p>", [ + ('setPosition', (1, 0)), + ('beginScope', + {'tal:replace': 'notHere', 'tal:on-error': 'string:error'}), + ('onError', + ([('optTag', + ('p', + '', + None, + 0, + [('startTag', + ('p', + [('tal:on-error', 'string:error', 'tal'), + ('tal:replace', 'notHere', 'tal')]))], + [('insertText', ('$notHere$', [('rawtextOffset', ('okay', 4))]))]))], + [('startTag', + ('p', + [('tal:on-error', 'string:error', 'tal'), + ('tal:replace', 'notHere', 'tal')])), + ('insertText', ('$string:error$', [])), + ('rawtextOffset', ('</p>', 4))])), + ('endScope', ()), + ]) + + def test_dup_attr(self): + self._should_error("<img tal:condition='x' tal:condition='x'>") + self._should_error("<img metal:define-macro='x' " + "metal:define-macro='x'>", taldefs.METALError) + + def test_tal_errors(self): + self._should_error("<p tal:define='x' />") + self._should_error("<p tal:repeat='x' />") + self._should_error("<p tal:foobar='x' />") + self._should_error("<p tal:replace='x' tal:content='x' />") + self._should_error("<p tal:replace='x'>") + for tag in htmltalparser.EMPTY_HTML_TAGS: + self._should_error("<%s tal:content='string:foo'>" % tag) + + def test_metal_errors(self): + exc = taldefs.METALError + self._should_error(2*"<p metal:define-macro='x'>xxx</p>", exc) + self._should_error("<html metal:use-macro='x'>" + + 2*"<p metal:fill-slot='y' />" + "</html>", exc) + self._should_error("<p metal:foobar='x' />", exc) + self._should_error("<p metal:define-macro='x'>", exc) + + def test_extend_macro_errors(self): + exc = taldefs.METALError + # extend-macro requires define-macro: + self._should_error("<p metal:extend-macro='x'>xxx</p>", exc) + # extend-macro prevents use-macro: + self._should_error("<p metal:extend-macro='x'" + " metal:use-macro='x'" + " metal:define-macro='y'>xxx</p>", exc) + # use-macro doesn't co-exist with define-macro: + self._should_error("<p metal:use-macro='x'" + " metal:define-macro='y'>xxx</p>", exc) + + # + # I18N test cases + # + + def test_i18n_attributes(self): + self._run_check("<img alt='foo' i18n:attributes='alt'>", [ + ('setPosition', (1, 0)), + ('beginScope', {'alt': 'foo', 'i18n:attributes': 'alt'}), + ('startTag', ('img', + [('alt', 'foo', 'replace', None, 1, None), + ('i18n:attributes', 'alt', 'i18n')])), + ('endScope', ()), + ]) + self._run_check("<img alt='foo' i18n:attributes='alt foo ; bar'>", [ + ('setPosition', (1, 0)), + ('beginScope', {'alt': 'foo', 'i18n:attributes': 'alt foo ; bar'}), + ('startTag', ('img', + [('alt', 'foo', 'replace', None, 1, 'foo'), + ('i18n:attributes', 'alt foo ; bar', 'i18n'), + ('bar', None, 'insert', None, 1, None)])), + ('endScope', ()), + ]) + + def test_i18n_name_bad_name(self): + self._should_error("<span i18n:name='not a valid name' />") + self._should_error("<span i18n:name='-bad-name' />") + + def test_i18n_attributes_repeated_attr(self): + self._should_error("<a i18n:attributes='href; href' />") + self._should_error("<a i18n:attributes='href; HREF' />") + + def test_i18n_translate(self): + # input/test19.html + self._run_check('''\ +<span i18n:translate="">Replace this</span> +<span i18n:translate="msgid">This is a +translated string</span> +<span i18n:translate="">And another +translated string</span> +''', [ + ('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': ''}), + ('startTag', ('span', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', ('', [('rawtextOffset', ('Replace this', 12))])), + ('rawtextBeginScope', + ('</span>\n', 0, (2, 0), 1, {'i18n:translate': 'msgid'})), + ('startTag', ('span', [('i18n:translate', 'msgid', 'i18n')])), + ('insertTranslation', + ('msgid', [('rawtextColumn', ('This is a\ntranslated string', 17))])), + ('rawtextBeginScope', ('</span>\n', 0, (4, 0), 1, {'i18n:translate': ''})), + ('startTag', ('span', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', + ('', [('rawtextColumn', ('And another\ntranslated string', 17))])), + ('endScope', ()), + ('rawtextColumn', ('</span>\n', 0))]) + + def test_i18n_translate_with_nested_tal(self): + self._run_check('''\ +<span i18n:translate="">replaceable <p tal:replace="str:here">content</p></span> +''', [ + ('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': ''}), + ('startTag', ('span', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', + ('', + [('rawtextOffset', ('replaceable ', 12)), + ('setPosition', (1, 36)), + ('beginScope', {'tal:replace': 'str:here'}), + ('optTag', + ('p', + '', + None, + 0, + [('startTag', ('p', [('tal:replace', 'str:here', 'tal')]))], + [('insertText', + ('$str:here$', [('rawtextOffset', ('content', 7))]))])), + ('endScope', ())])), + ('endScope', ()), + ('rawtextColumn', ('</span>\n', 0)) + ]) + + def test_i18n_name(self): + # input/test21.html + self._run_check('''\ +<span i18n:translate=""> + <span tal:replace="str:Lomax" i18n:name="name" /> was born in + <span tal:replace="str:Antarctica" i18n:name="country" />. +</span> +''', [ + ('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': ''}), + ('startTag', ('span', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', + ('', + [('rawtextBeginScope', + ('\n ', + 2, + (2, 2), + 0, + {'i18n:name': 'name', 'tal:replace': 'str:Lomax'})), + ('i18nVariable', + ('name', + [('optTag', + ('span', + '', + None, + 1, + [('startEndTag', + ('span', + [('tal:replace', 'str:Lomax', 'tal'), + ('i18n:name', 'name', 'i18n')]))], + [('insertText', ('$str:Lomax$', []))]))], + None, + 0)), + ('rawtextBeginScope', + (' was born in\n ', + 2, + (3, 2), + 1, + {'i18n:name': 'country', 'tal:replace': 'str:Antarctica'})), + ('i18nVariable', + ('country', + [('optTag', + ('span', + '', + None, + 1, + [('startEndTag', + ('span', + [('tal:replace', 'str:Antarctica', 'tal'), + ('i18n:name', 'country', 'i18n')]))], + [('insertText', ('$str:Antarctica$', []))]))], + None, + 0)), + ('endScope', ()), + ('rawtextColumn', ('.\n', 0))])), + ('endScope', ()), + ('rawtextColumn', ('</span>\n', 0)) + ]) + + def test_i18n_name_with_content(self): + self._run_check('<div i18n:translate="">This is text for ' + '<span i18n:translate="" tal:content="bar" i18n:name="bar_name"/>.' + '</div>', [ +('setPosition', (1, 0)), +('beginScope', {'i18n:translate': ''}), +('startTag', ('div', [('i18n:translate', '', 'i18n')])), +('insertTranslation', + ('', + [('rawtextOffset', ('This is text for ', 17)), + ('setPosition', (1, 40)), + ('beginScope', + {'tal:content': 'bar', 'i18n:name': 'bar_name', 'i18n:translate': ''}), + ('i18nVariable', + ('bar_name', + [('startTag', + ('span', + [('i18n:translate', '', 'i18n'), + ('tal:content', 'bar', 'tal'), + ('i18n:name', 'bar_name', 'i18n')])), + ('insertI18nText', ('$bar$', [])), + ('rawtextOffset', ('</span>', 7))], + None, + 0)), + ('endScope', ()), + ('rawtextOffset', ('.', 1))])), +('endScope', ()), +('rawtextOffset', ('</div>', 6)) + ]) + + def test_i18n_name_implicit_value(self): + # input/test22.html + self._run_check('''\ +<span i18n:translate=""> + <span tal:omit-tag="" i18n:name="name"><b>Jim</b></span> was born in + <span tal:omit-tag="" i18n:name="country">the USA</span>. +</span> +''', [('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': ''}), + ('startTag', ('span', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', + ('', + [('rawtextBeginScope', + ('\n ', 2, (2, 2), 0, {'i18n:name': 'name', 'tal:omit-tag': ''})), + ('i18nVariable', + ('name', + [('optTag', + ('span', + '', + None, + 0, + [('startTag', + ('span', + [('tal:omit-tag', '', 'tal'), + ('i18n:name', 'name', 'i18n')]))], + [('rawtextOffset', ('<b>Jim</b>', 10))]))], + None, + 0)), + ('rawtextBeginScope', + (' was born in\n ', + 2, + (3, 2), + 1, + {'i18n:name': 'country', 'tal:omit-tag': ''})), + ('i18nVariable', + ('country', + [('optTag', + ('span', + '', + None, + 0, + [('startTag', + ('span', + [('tal:omit-tag', '', 'tal'), + ('i18n:name', 'country', 'i18n')]))], + [('rawtextOffset', ('the USA', 7))]))], + None, + 0)), + ('endScope', ()), + ('rawtextColumn', ('.\n', 0))])), + ('endScope', ()), + ('rawtextColumn', ('</span>\n', 0)) + ]) + + def test_i18n_context_domain(self): + self._run_check("<span i18n:domain='mydomain'/>", [ + ('setPosition', (1, 0)), + ('beginI18nContext', {'domain': 'mydomain', + 'source': None, 'target': None}), + ('beginScope', {'i18n:domain': 'mydomain'}), + ('startEndTag', ('span', [('i18n:domain', 'mydomain', 'i18n')])), + ('endScope', ()), + ('endI18nContext', ()), + ]) + + def test_i18n_context_source(self): + self._run_check("<span i18n:source='en'/>", [ + ('setPosition', (1, 0)), + ('beginI18nContext', {'source': 'en', + 'domain': 'default', 'target': None}), + ('beginScope', {'i18n:source': 'en'}), + ('startEndTag', ('span', [('i18n:source', 'en', 'i18n')])), + ('endScope', ()), + ('endI18nContext', ()), + ]) + + def test_i18n_context_source_target(self): + self._run_check("<span i18n:source='en' i18n:target='ru'/>", [ + ('setPosition', (1, 0)), + ('beginI18nContext', {'source': 'en', 'target': 'ru', + 'domain': 'default'}), + ('beginScope', {'i18n:source': 'en', 'i18n:target': 'ru'}), + ('startEndTag', ('span', [('i18n:source', 'en', 'i18n'), + ('i18n:target', 'ru', 'i18n')])), + ('endScope', ()), + ('endI18nContext', ()), + ]) + + def test_i18n_context_in_define_slot(self): + text = ("<div metal:use-macro='M' i18n:domain='mydomain'>" + "<div metal:fill-slot='S'>spam</div>" + "</div>") + self._run_check(text, [ + ('setPosition', (1, 0)), + ('useMacro', + ('M', '$M$', + {'S': [('startTag', ('div', + [('metal:fill-slot', 'S', 'metal')])), + rawtext('spam</div>')]}, + [('beginI18nContext', {'domain': 'mydomain', + 'source': None, 'target': None}), + ('beginScope', + {'i18n:domain': 'mydomain', 'metal:use-macro': 'M'}), + ('startTag', ('div', [('metal:use-macro', 'M', 'metal'), + ('i18n:domain', 'mydomain', 'i18n')])), + ('setPosition', (1, 48)), + ('fillSlot', ('S', + [('startTag', + ('div', [('metal:fill-slot', 'S', 'metal')])), + rawtext('spam</div>')])), + ('endScope', ()), + rawtext('</div>'), + ('endI18nContext', ())])), + ]) + + def test_i18n_data(self): + # input/test23.html + self._run_check('''\ +<span i18n:data="here/currentTime" + i18n:translate="timefmt">2:32 pm</span> +''', [ + ('setPosition', (1, 0)), + ('beginScope', + {'i18n:translate': 'timefmt', 'i18n:data': 'here/currentTime'}), + ('startTag', + ('span', + [('i18n:data', 'here/currentTime', 'i18n'), + ('i18n:translate', 'timefmt', 'i18n')])), + ('insertTranslation', + ('timefmt', [('rawtextOffset', ('2:32 pm', 7))], '$here/currentTime$')), + ('endScope', ()), + ('rawtextColumn', ('</span>\n', 0)) + ]) + + def test_i18n_data_with_name(self): + # input/test29.html + self._run_check('''\ +<div i18n:translate="">At the tone the time will be +<span i18n:data="here/currentTime" + i18n:translate="timefmt" + i18n:name="time">2:32 pm</span>... beep!</div> +''', [('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': ''}), + ('startTag', ('div', [('i18n:translate', '', 'i18n')])), + ('insertTranslation', + ('', + [('rawtextBeginScope', + ('At the tone the time will be\n', + 0, + (2, 0), + 0, + {'i18n:data': 'here/currentTime', + 'i18n:name': 'time', + 'i18n:translate': 'timefmt'})), + ('i18nVariable', + ('time', + [('startTag', + ('span', + [('i18n:data', 'here/currentTime', 'i18n'), + ('i18n:translate', 'timefmt', 'i18n'), + ('i18n:name', 'time', 'i18n')])), + ('insertTranslation', + ('timefmt', + [('rawtextOffset', ('2:32 pm', 7))], + '$here/currentTime$')), + ('rawtextOffset', ('</span>', 7))], + None, + 0)), + ('endScope', ()), + ('rawtextOffset', ('... beep!', 9))])), + ('endScope', ()), + ('rawtextColumn', ('</div>\n', 0)) + ]) + + def test_i18n_name_around_tal_content(self): + # input/test28.html + self._run_check('''\ +<p i18n:translate="verify">Your contact email address is recorded as + <span tal:omit-tag="" i18n:name="email"> + <a href="mailto:user@example.com" + tal:content="request/submitter">user@host.com</a></span> +</p> +''', [('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': 'verify'}), + ('startTag', ('p', [('i18n:translate', 'verify', 'i18n')])), + ('insertTranslation', + ('verify', + [('rawtextBeginScope', + ('Your contact email address is recorded as\n ', + 4, + (2, 4), + 0, + {'i18n:name': 'email', 'tal:omit-tag': ''})), + ('i18nVariable', + ('email', + [('optTag', + ('span', + '', + None, + 0, + [('startTag', + ('span', + [('tal:omit-tag', '', 'tal'), + ('i18n:name', 'email', 'i18n')]))], + [('rawtextBeginScope', + ('\n ', + 4, + (3, 4), + 0, + {'href': 'mailto:user@example.com', + 'tal:content': 'request/submitter'})), + ('startTag', + ('a', + [('href', 'href="mailto:user@example.com"'), + ('tal:content', 'request/submitter', 'tal')])), + ('insertText', + ('$request/submitter$', + [('rawtextOffset', ('user@host.com', 13))])), + ('endScope', ()), + ('rawtextOffset', ('</a>', 4))]))], + None, + 0)), + ('endScope', ()), + ('rawtextColumn', ('\n', 0))])), + ('endScope', ()), + ('rawtextColumn', ('</p>\n', 0)) + ]) + + def test_i18n_name_with_tal_content(self): + # input/test27.html + self._run_check('''\ +<p i18n:translate="verify">Your contact email address is recorded as + <a href="mailto:user@example.com" + tal:content="request/submitter" + i18n:name="email">user@host.com</a> +</p> +''', [ + ('setPosition', (1, 0)), + ('beginScope', {'i18n:translate': 'verify'}), + ('startTag', ('p', [('i18n:translate', 'verify', 'i18n')])), + ('insertTranslation', + ('verify', + [('rawtextBeginScope', + ('Your contact email address is recorded as\n ', + 4, + (2, 4), + 0, + {'href': 'mailto:user@example.com', + 'i18n:name': 'email', + 'tal:content': 'request/submitter'})), + ('i18nVariable', + ('email', + [('startTag', + ('a', + [('href', 'href="mailto:user@example.com"'), + ('tal:content', 'request/submitter', 'tal'), + ('i18n:name', 'email', 'i18n')])), + ('insertText', + ('$request/submitter$', + [('rawtextOffset', ('user@host.com', 13))])), + ('rawtextOffset', ('</a>', 4))], + None, + 0)), + ('endScope', ()), + ('rawtextColumn', ('\n', 0))])), + ('endScope', ()), + ('rawtextColumn', ('</p>\n', 0)) + ]) + + +def test_suite(): + suite = unittest.makeSuite(HTMLTALParserTestCases) + suite.addTest(unittest.makeSuite(METALGeneratorTestCases)) + suite.addTest(unittest.makeSuite(TALGeneratorTestCases)) + return suite + + +if __name__ == "__main__": + errs = utils.run_suite(test_suite()) + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/test_sourcepos.py b/src/zope/tal/tests/test_sourcepos.py new file mode 100644 index 0000000..4034b21 --- /dev/null +++ b/src/zope/tal/tests/test_sourcepos.py @@ -0,0 +1,93 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for TALInterpreter. + +$Id$ +""" +import unittest + +from StringIO import StringIO + +from zope.tal.htmltalparser import HTMLTALParser +from zope.tal.talinterpreter import TALInterpreter +from zope.tal.talgenerator import TALGenerator +from zope.tal.dummyengine import DummyEngine + + +page1 = '''<html metal:use-macro="main"><body> +<div metal:fill-slot="body"> +page1=<span tal:replace="position:" /> +</div> +</body></html>''' + +main_template = '''<html metal:define-macro="main"><body> +main_template=<span tal:replace="position:" /> +<div metal:define-slot="body" /> +main_template=<span tal:replace="position:" /> +<div metal:use-macro="foot" /> +main_template=<span tal:replace="position:" /> +</body></html>''' + +footer = '''<div metal:define-macro="foot"> +footer=<span tal:replace="position:" /> +</div>''' + +expected = '''<html><body> +main_template=main_template (2,14) +<div> +page1=page1 (3,6) +</div> +main_template=main_template (4,14) +<div> +footer=footer (2,7) +</div> +main_template=main_template (6,14) +</body></html>''' + + + +class SourcePosTestCase(unittest.TestCase): + + def parse(self, eng, s, fn): + gen = TALGenerator(expressionCompiler=eng, xml=0, source_file=fn) + parser = HTMLTALParser(gen) + parser.parseString(s) + program, macros = parser.getCode() + return program, macros + + def test_source_positions(self): + # Ensure source file and position are set correctly by TAL + macros = {} + eng = DummyEngine(macros) + page1_program, page1_macros = self.parse(eng, page1, 'page1') + main_template_program, main_template_macros = self.parse( + eng, main_template, 'main_template') + footer_program, footer_macros = self.parse(eng, footer, 'footer') + + macros['main'] = main_template_macros['main'] + macros['foot'] = footer_macros['foot'] + + stream = StringIO() + interp = TALInterpreter(page1_program, macros, eng, stream) + interp() + self.assertEqual(stream.getvalue().strip(), expected.strip(), + "Got result:\n%s\nExpected:\n%s" + % (stream.getvalue(), expected)) + + +def test_suite(): + return unittest.makeSuite(SourcePosTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest='test_suite') diff --git a/src/zope/tal/tests/test_talgettext.py b/src/zope/tal/tests/test_talgettext.py new file mode 100644 index 0000000..bdfbfd8 --- /dev/null +++ b/src/zope/tal/tests/test_talgettext.py @@ -0,0 +1,78 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for the talgettext utility. + +$Id$ +""" +import sys +import unittest +from StringIO import StringIO + +from zope.tal.htmltalparser import HTMLTALParser +from zope.tal.talgettext import POTALInterpreter +from zope.tal.talgettext import POEngine +from zope.tal.tests import utils + +class test_POEngine(unittest.TestCase): + """Test the PO engine functionality, which simply adds items to a catalog + as .translate is called + """ + + def test_translate(self): + test_keys = ['foo', 'bar', 'blarf', 'washington'] + + engine = POEngine() + engine.file = 'foo.pt' + for key in test_keys: + engine.translate(key, 'domain') + + for key in test_keys: + self.failIf(key not in engine.catalog['domain'], + "POEngine catalog does not properly store message ids" + ) + + def test_dynamic_msgids(self): + sample_source = """ + <p i18n:translate=""> + Some + <span tal:replace="string:strange">dynamic</span> + text. + </p> + <p i18n:translate=""> + A <a tal:attributes="href path:dynamic">link</a>. + </p> + """ + p = HTMLTALParser() + p.parseString(sample_source) + program, macros = p.getCode() + engine = POEngine() + engine.file = 'sample_source' + POTALInterpreter(program, macros, engine, stream=StringIO(), + metal=False)() + msgids = [] + for domain in engine.catalog.values(): + msgids += domain.keys() + msgids.sort() + self.assertEquals(msgids, + ['A <a href="${DYNAMIC_CONTENT}">link</a>.', + 'Some ${DYNAMIC_CONTENT} text.']) + + +def test_suite(): + suite = unittest.makeSuite(test_POEngine) + return suite + +if __name__ == "__main__": + errs = utils.run_suite(test_suite()) + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/test_talinterpreter.py b/src/zope/tal/tests/test_talinterpreter.py new file mode 100644 index 0000000..c9e8ed7 --- /dev/null +++ b/src/zope/tal/tests/test_talinterpreter.py @@ -0,0 +1,853 @@ +# -*- coding: ISO-8859-1 -*- +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for TALInterpreter. + +$Id$ +""" +import os +import sys +import unittest + +from StringIO import StringIO + +from zope.tal.taldefs import METALError, I18NError, TAL_VERSION +from zope.tal.taldefs import TALExpressionError +from zope.tal.htmltalparser import HTMLTALParser +from zope.tal.talparser import TALParser +from zope.tal.talinterpreter import TALInterpreter +from zope.tal.talgenerator import TALGenerator +from zope.tal.dummyengine import DummyEngine +from zope.tal.dummyengine import MultipleDomainsDummyEngine +from zope.tal.dummyengine import DummyTranslationDomain +from zope.tal.tests import utils +from zope.i18nmessageid import Message + + +class TestCaseBase(unittest.TestCase): + + def _compile(self, source, source_file=None): + generator = TALGenerator(xml=0, source_file=source_file) + parser = HTMLTALParser(generator) + parser.parseString(source) + program, macros = parser.getCode() + return program, macros + + +class MacroErrorsTestCase(TestCaseBase): + + def setUp(self): + dummy, macros = self._compile('<p metal:define-macro="M">Booh</p>') + self.macro = macros['M'] + self.engine = DummyEngine(macros) + program, dummy = self._compile('<p metal:use-macro="M">Bah</p>') + self.interpreter = TALInterpreter(program, {}, self.engine) + + def tearDown(self): + try: + self.interpreter() + except METALError: + pass + else: + self.fail("Expected METALError") + + def test_mode_error(self): + self.macro[1] = ("mode", "duh") + + def test_version_error(self): + self.macro[0] = ("version", "duh") + + +class MacroFunkyErrorTest(TestCaseBase): + + def test_div_in_p_using_macro(self): + dummy, macros = self._compile('<p metal:define-macro="M">Booh</p>') + engine = DummyEngine(macros) + program, dummy = self._compile( + '<p metal:use-macro="M"><div>foo</div></p>') + interpreter = TALInterpreter(program, {}, engine) + + output = interpreter() + self.assertEqual(output, '<p><div>foo</div></p>') + + +class MacroExtendTestCase(TestCaseBase): + + def setUp(self): + s = self._read(('input', 'pnome_template.pt')) + self.pnome_program, pnome_macros = self._compile(s) + s = self._read(('input', 'acme_template.pt')) + self.acme_program, acme_macros = self._compile(s) + s = self._read(('input', 'document_list.pt')) + self.doclist_program, doclist_macros = self._compile(s) + macros = { + 'pnome_macros_page': pnome_macros['page'], + 'acme_macros_page': acme_macros['page'], + } + self.engine = DummyEngine(macros) + + def _read(self, path): + dir = os.path.dirname(__file__) + fn = os.path.join(dir, *path) + f = open(fn) + data = f.read() + f.close() + return data + + def test_preview_acme_template(self): + # An ACME designer is previewing the ACME design. For the + # purposes of this use case, extending a macro should act the + # same as using a macro. + result = StringIO() + interpreter = TALInterpreter( + self.acme_program, {}, self.engine, stream=result) + interpreter() + actual = result.getvalue().strip() + expected = self._read(('output', 'acme_template.html')).strip() + self.assertEqual(actual, expected) + + def test_preview_acme_template_source(self): + # Render METAL attributes in acme_template + result = StringIO() + interpreter = TALInterpreter( + self.acme_program, {}, self.engine, stream=result, tal=False) + interpreter() + actual = result.getvalue().strip() + expected = self._read(('output', 'acme_template_source.html')).strip() + self.assertEqual(actual, expected) + + +class I18NCornerTestCaseBase(TestCaseBase): + + def factory(self, msgid, default, mapping={}): + raise NotImplementedError("abstract method") + + def setUp(self): + self.engine = DummyEngine() + # Make sure we'll translate the msgid not its unicode representation + self.engine.setLocal('foo', + self.factory('FoOvAlUe${empty}', 'default', {'empty': ''})) + self.engine.setLocal('bar', 'BaRvAlUe') + + def _check(self, program, expected): + result = StringIO() + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + self.assertEqual(expected, result.getvalue()) + + def test_simple_messageid_translate(self): + # This test is mainly here to make sure our DummyEngine works + # correctly. + program, macros = self._compile( + '<span i18n:translate="" tal:content="foo"/>') + self._check(program, '<span>FOOVALUE</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:replace="foo"/>') + self._check(program, 'FOOVALUE\n') + + # i18n messages defined in Python are translated automatically + # (no i18n:translate necessary) + program, macros = self._compile( + '<span tal:content="foo" />') + self._check(program, '<span>FOOVALUE</span>\n') + + program, macros = self._compile( + '<span tal:replace="foo" />') + self._check(program, 'FOOVALUE\n') + + def test_attributes_translation(self): + program, macros = self._compile( + '<span tal:attributes="test bar"/>') + self._check(program, '<span test="BaRvAlUe" />\n') + + program, macros = self._compile( + '<span test="bar" i18n:attributes="test"/>') + self._check(program, '<span test="BAR" />\n') + + program, macros = self._compile( + '<span tal:attributes="test bar" i18n:attributes="test"/>') + self._check(program, '<span test="BARVALUE" />\n') + + # i18n messages defined in Python are translated automatically + # (no i18n:attributes necessary) + program, macros = self._compile( + '<span tal:attributes="test foo"/>') + self._check(program, '<span test="FOOVALUE" />\n') + + def test_text_variable_translate(self): + program, macros = self._compile( + '<span tal:content="bar"/>') + self._check(program, '<span>BaRvAlUe</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:content="bar"/>') + self._check(program, '<span>BARVALUE</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:replace="bar"/>') + self._check(program, 'BARVALUE\n') + + def test_text_translate(self): + program, macros = self._compile( + '<span tal:content="string:BaR"/>') + self._check(program, '<span>BaR</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:content="string:BaR"/>') + self._check(program, '<span>BAR</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:replace="string:BaR"/>') + self._check(program, 'BAR\n') + + def test_structure_text_variable_translate(self): + program, macros = self._compile( + '<span tal:content="structure bar"/>') + self._check(program, '<span>BaRvAlUe</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:content="structure bar"/>') + self._check(program, '<span>BARVALUE</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:replace="structure bar"/>') + self._check(program, 'BARVALUE\n') + + # i18n messages defined in Python are translated automatically + # (no i18n:translate necessary) + program, macros = self._compile( + '<span tal:content="structure foo"/>') + self._check(program, '<span>FOOVALUE</span>\n') + + program, macros = self._compile( + '<span tal:replace="structure foo"/>') + self._check(program, 'FOOVALUE\n') + + def test_structure_text_translate(self): + program, macros = self._compile( + '<span tal:content="structure string:BaR"/>') + self._check(program, '<span>BaR</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:content="structure string:BaR"/>') + self._check(program, '<span>BAR</span>\n') + + program, macros = self._compile( + '<span i18n:translate="" tal:replace="structure string:BaR"/>') + self._check(program, 'BAR\n') + + def test_replace_with_messageid_and_i18nname(self): + program, macros = self._compile( + '<div i18n:translate="" >' + '<span i18n:translate="" tal:replace="foo" i18n:name="foo_name"/>' + '</div>') + self._check(program, '<div>FOOVALUE</div>\n') + + def test_pythonexpr_replace_with_messageid_and_i18nname(self): + program, macros = self._compile( + '<div i18n:translate="" >' + '<span i18n:translate="" tal:replace="python: foo"' + ' i18n:name="foo_name"/>' + '</div>') + self._check(program, '<div>FOOVALUE</div>\n') + + def test_structure_replace_with_messageid_and_i18nname(self): + program, macros = self._compile( + '<div i18n:translate="" >' + '<span i18n:translate="" tal:replace="structure foo"' + ' i18n:name="foo_name"/>' + '</div>') + self._check(program, '<div>FOOVALUE</div>\n') + + def test_complex_replace_with_messageid_and_i18nname(self): + program, macros = self._compile( + '<div i18n:translate="" >' + '<em tal:omit-tag="" i18n:name="foo_name">' + '<span i18n:translate="" tal:replace="foo"/>' + '</em>' + '</div>') + self._check(program, '<div>FOOVALUE</div>\n') + + def test_content_with_messageid_and_i18nname(self): + program, macros = self._compile( + '<div i18n:translate="" >' + '<span i18n:translate="" tal:content="foo" i18n:name="foo_name"/>' + '</div>') + self._check(program, '<div><span>FOOVALUE</span></div>\n') + + def test_content_with_messageid_and_i18nname_and_i18ntranslate(self): + # Let's tell the user this is incredibly silly! + self.assertRaises( + I18NError, self._compile, + '<span i18n:translate="" tal:content="foo" i18n:name="foo_name"/>') + + def test_content_with_explicit_messageid(self): + # Let's tell the user this is incredibly silly! + self.assertRaises( + I18NError, self._compile, + '<span i18n:translate="ID" tal:content="foo" />') + + def test_content_with_plaintext_and_i18nname_and_i18ntranslate(self): + # Let's tell the user this is incredibly silly! + self.assertRaises( + I18NError, self._compile, + '<span i18n:translate="" i18n:name="color_name">green</span>') + + def test_translate_static_text_as_dynamic(self): + program, macros = self._compile( + '<div i18n:translate="">This is text for ' + '<span tal:content="bar" i18n:name="bar_name"/>.' + '</div>') + self._check(program, + '<div>THIS IS TEXT FOR <span>BaRvAlUe</span>.</div>\n') + program, macros = self._compile( + '<div i18n:translate="">This is text for ' + '<span i18n:translate="" tal:content="bar" i18n:name="bar_name"/>.' + '</div>') + self._check(program, + '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n') + + def test_translate_static_text_as_dynamic_from_bytecode(self): + program = [('version', TAL_VERSION), + ('mode', 'html'), +('setPosition', (1, 0)), +('beginScope', {'i18n:translate': ''}), +('startTag', ('div', [('i18n:translate', '', 'i18n')])), +('insertTranslation', + ('', + [('rawtextOffset', ('This is text for ', 17)), + ('setPosition', (1, 40)), + ('beginScope', + {'tal:content': 'bar', 'i18n:name': 'bar_name', 'i18n:translate': ''}), + ('i18nVariable', + ('bar_name', + [('startTag', + ('span', + [('i18n:translate', '', 'i18n'), + ('tal:content', 'bar', 'tal'), + ('i18n:name', 'bar_name', 'i18n')])), + ('insertTranslation', + ('', + [('insertText', ('$bar$', []))])), + ('rawtextOffset', ('</span>', 7))], + None, + 0)), + ('endScope', ()), + ('rawtextOffset', ('.', 1))])), +('endScope', ()), +('rawtextOffset', ('</div>', 6)) +] + self._check(program, + '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n') + + def test_for_correct_msgids(self): + self.engine.translationDomain.clearMsgids() + result = StringIO() + #GChapelle: + #I have the feeling the i18n:translate with the i18n:name is wrong + # + #program, macros = self._compile( + # '<div i18n:translate="">This is text for ' + # '<span i18n:translate="" tal:content="bar" ' + # 'i18n:name="bar_name"/>.</div>') + program, macros = self._compile( + '<div i18n:translate="">This is text for ' + '<span tal:content="bar" ' + 'i18n:name="bar_name"/>.</div>') + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(1, len(msgids)) + self.assertEqual('This is text for ${bar_name}.', msgids[0][0]) + self.assertEqual({'bar_name': '<span>BaRvAlUe</span>'}, msgids[0][1]) + self.assertEqual( + '<div>THIS IS TEXT FOR <span>BaRvAlUe</span>.</div>\n', + result.getvalue()) + + def test_for_correct_msgids_translate_name(self): + self.engine.translationDomain.clearMsgids() + result = StringIO() + program, macros = self._compile( + '<div i18n:translate="">This is text for ' + '<span i18n:translate="" tal:content="bar" ' + 'i18n:name="bar_name"/>.</div>') + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(2, len(msgids)) + self.assertEqual('This is text for ${bar_name}.', msgids[1][0]) + self.assertEqual({'bar_name': '<span>BARVALUE</span>'}, msgids[1][1]) + self.assertEqual( + '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n', + result.getvalue()) + + def test_i18ntranslate_i18nname_and_attributes(self): + # Test for Issue 301: Bug with i18n:name and i18n:translate + # on the same element + self.engine.translationDomain.clearMsgids() + result = StringIO() + program, macros = self._compile( + '<p i18n:translate="">' + 'Some static text and a <a tal:attributes="href string:url"' + ' i18n:name="link" i18n:translate="">link text</a>.</p>') + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(2, len(msgids)) + self.assertEqual('Some static text and a ${link}.', msgids[0][0]) + self.assertEqual({'link': '<a href="url">LINK TEXT</a>'}, msgids[0][1]) + self.assertEqual('link text', msgids[1][0]) + self.assertEqual( + '<p>SOME STATIC TEXT AND A <a href="url">LINK TEXT</a>.</p>\n', + result.getvalue()) + + def test_for_raw_msgids(self): + # Test for Issue 314: i18n:translate removes line breaks from + # <pre>...</pre> contents + # HTML mode + self.engine.translationDomain.clearMsgids() + result = StringIO() + program, macros = self._compile( + '<div i18n:translate=""> This is text\n' + ' \tfor\n div. </div>' + '<pre i18n:translate=""> This is text\n' + ' <b>\tfor</b>\n pre. </pre>') + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(2, len(msgids)) + self.assertEqual(' This is text\n <b>\tfor</b>\n pre. ', msgids[0][0]) + self.assertEqual('This is text for div.', msgids[1][0]) + self.assertEqual( + '<div>THIS IS TEXT FOR DIV.</div>' + '<pre> THIS IS TEXT\n <B>\tFOR</B>\n PRE. </pre>\n', + result.getvalue()) + + # XML mode + self.engine.translationDomain.clearMsgids() + result = StringIO() + parser = TALParser() + parser.parseString( + '<?xml version="1.0"?>\n' + '<pre xmlns:i18n="http://xml.zope.org/namespaces/i18n"' + ' i18n:translate=""> This is text\n' + ' <b>\tfor</b>\n barvalue. </pre>') + program, macros = parser.getCode() + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(1, len(msgids)) + self.assertEqual('This is text <b> for</b> barvalue.', msgids[0][0]) + self.assertEqual( + '<?xml version="1.0"?>\n' + '<pre>THIS IS TEXT <B> FOR</B> BARVALUE.</pre>\n', + result.getvalue()) + + def test_raw_msgids_and_i18ntranslate_i18nname(self): + self.engine.translationDomain.clearMsgids() + result = StringIO() + program, macros = self._compile( + '<div i18n:translate=""> This is text\n \tfor\n' + '<pre i18n:name="bar" i18n:translate=""> \tbar\n </pre>.</div>') + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + msgids = self.engine.translationDomain.getMsgids('default') + msgids.sort() + self.assertEqual(2, len(msgids)) + self.assertEqual(' \tbar\n ', msgids[0][0]) + self.assertEqual('This is text for ${bar}.', msgids[1][0]) + self.assertEqual({'bar': '<pre> \tBAR\n </pre>'}, msgids[1][1]) + self.assertEqual( + u'<div>THIS IS TEXT FOR <pre> \tBAR\n </pre>.</div>\n', + result.getvalue()) + + def test_for_handling_unicode_vars(self): + # Make sure that non-ASCII Unicode is substituted correctly. + # http://collector.zope.org/Zope3-dev/264 + program, macros = self._compile( + "<div i18n:translate='' tal:define='bar python:unichr(0xC0)'>" + "Foo <span tal:replace='bar' i18n:name='bar' /></div>") + self._check(program, u"<div>FOO \u00C0</div>\n") + +class I18NCornerTestCaseMessage(I18NCornerTestCaseBase): + + def factory(self, msgid, default=None, mapping={}, domain=None): + return Message(msgid, domain=domain, default=default, mapping=mapping) + +class UnusedExplicitDomainTestCase(I18NCornerTestCaseMessage): + + def setUp(self): + # MultipleDomainsDummyEngine is a Engine + # where default domain transforms to uppercase + self.engine = MultipleDomainsDummyEngine() + self.engine.setLocal('foo', + self.factory('FoOvAlUe${empty}', 'default', {'empty': ''})) + self.engine.setLocal('bar', 'BaRvAlUe') + self.engine.setLocal('baz', + self.factory('BaZvAlUe', 'default', {})) + # Message ids with different domains + self.engine.setLocal('toupper', + self.factory('ToUpper', 'default', {})) + self.engine.setLocal('tolower', + self.factory('ToLower', 'default', {}, domain='lower')) + + def test_multiple_domains(self): + program, macros = self._compile( + '<div i18n:translate=""' + ' tal:content="toupper" />') + self._check(program, '<div>TOUPPER</div>\n') + program, macros = self._compile( + '<div i18n:translate=""' + ' tal:content="tolower" />') + self._check(program, '<div>tolower</div>\n') + program, macros = self._compile( + '<div i18n:translate=""' + ' tal:content="string:ToUpper" />') + self._check(program, '<div>TOUPPER</div>\n') + program, macros = self._compile( + '<div i18n:translate=""' + ' i18n:domain="lower"' + ' tal:content="string:ToLower" />') + self._check(program, '<div>tolower</div>\n') + program, macros = self._compile( + '<div i18n:translate=""' + ' tal:define="msgid string:ToUpper"' + ' tal:content="msgid" />') + self._check(program, '<div>TOUPPER</div>\n') + program, macros = self._compile( + '<div i18n:translate=""' + ' i18n:domain="lower"' + ' tal:define="msgid string:ToLower"' + ' tal:content="msgid" />') + self._check(program, '<div>tolower</div>\n') + + def test_unused_explicit_domain(self): + #a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine + #is a domain that transforms to lowercase + self.engine.setLocal('othertolower', + self.factory('OtherToLower', 'a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine', {}, domain='lower')) + program, macros = self._compile( + '<div i18n:translate=""' + ' tal:content="othertolower" />') + self._check(program, '<div>othertolower</div>\n') + #takes domain into account for strings + program, macros = self._compile( + '<div i18n:translate=""' + ' i18n:domain="a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine"' + ' tal:content="string:ToLower" />') + self._check(program, '<div>tolower</div>\n') + #but not for messageids + program, macros = self._compile( + '<div i18n:translate=""' + ' i18n:domain="a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine"' + ' tal:content="baz" />') + self._check(program, '<div>BAZVALUE</div>\n') + +class ScriptTestCase(TestCaseBase): + + def setUp(self): + self.engine = DummyEngine() + + def _check(self, program, expected): + result = StringIO() + self.interpreter = TALInterpreter(program, {}, self.engine, + stream=result) + self.interpreter() + self.assertEqual(expected, result.getvalue()) + + def test_simple(self): + program, macros = self._compile( + '<p tal:script="text/server-python">print "hello"</p>') + self._check(program, '<p>hello\n</p>\n') + + def test_script_and_tal_block(self): + program, macros = self._compile( + '<tal:block script="text/server-python">\n' + ' global x\n' + ' x = 1\n' + '</tal:block>\n' + '<span tal:replace="x" />') + self._check(program, '\n1\n') + self.assertEqual(self.engine.codeGlobals['x'], 1) + + def test_script_and_tal_block_having_inside_print(self): + program, macros = self._compile( + '<tal:block script="text/server-python">\n' + ' print "hello"' + '</tal:block>') + self._check(program, 'hello\n\n') + + def test_script_and_omittag(self): + program, macros = self._compile( + '<p tal:omit-tag="" tal:script="text/server-python">\n' + ' print "hello"' + '</p>') + self._check(program, 'hello\n\n') + + def test_script_and_inside_tags(self): + program, macros = self._compile( + '<p tal:omit-tag="" tal:script="text/server-python">\n' + ' print "<b>hello</b>"' + '</p>') + self._check(program, '<b>hello</b>\n\n') + + def test_script_and_inside_tags_with_tal(self): + program, macros = self._compile( + '<p tal:omit-tag="" tal:script="text/server-python"> <!--\n' + ' print """<b tal:replace="string:foo">hello</b>"""\n' + '--></p>') + self._check(program, '<b tal:replace="string:foo">hello</b>\n\n') + + def test_html_script(self): + program, macros = self._compile( + '<script type="text/server-python">\n' + ' print "Hello world!"\n' + '</script>') + self._check(program, 'Hello world!\n') + + def test_html_script_and_javascript(self): + program, macros = self._compile( + '<script type="text/javascript" src="somefile.js" />\n' + '<script type="text/server-python">\n' + ' print "Hello world!"\n' + '</script>') + self._check(program, + '<script type="text/javascript" src="somefile.js" />\n' + 'Hello world!\n') + + +class I18NErrorsTestCase(TestCaseBase): + + def _check(self, src, msg): + try: + self._compile(src) + except I18NError: + pass + else: + self.fail(msg) + + def test_id_with_replace(self): + self._check('<p i18n:id="foo" tal:replace="string:splat"></p>', + "expected i18n:id with tal:replace to be denied") + + def test_missing_values(self): + self._check('<p i18n:attributes=""></p>', + "missing i18n:attributes value not caught") + self._check('<p i18n:data=""></p>', + "missing i18n:data value not caught") + self._check('<p i18n:id=""></p>', + "missing i18n:id value not caught") + + def test_id_with_attributes(self): + self._check('''<input name="Delete" + tal:attributes="name string:delete_button" + i18n:attributes="name message-id">''', + "expected attribute being both part of tal:attributes" + + " and having a msgid in i18n:attributes to be denied") + +class OutputPresentationTestCase(TestCaseBase): + + def test_attribute_wrapping(self): + # To make sure the attribute-wrapping code is invoked, we have to + # include at least one TAL/METAL attribute to avoid having the start + # tag optimized into a rawtext instruction. + INPUT = r""" + <html this='element' has='a' lot='of' attributes=', so' the='output' + needs='to' be='line' wrapped='.' tal:define='foo nothing'> + </html>""" + EXPECTED = r''' + <html this="element" has="a" lot="of" + attributes=", so" the="output" needs="to" + be="line" wrapped="."> + </html>''' "\n" + self.compare(INPUT, EXPECTED) + + def test_unicode_content(self): + INPUT = """<p tal:content="python:u'déjà-vu'">para</p>""" + EXPECTED = u"""<p>déjà-vu</p>""" "\n" + self.compare(INPUT, EXPECTED) + + def test_unicode_structure(self): + INPUT = """<p tal:replace="structure python:u'déjà-vu'">para</p>""" + EXPECTED = u"""déjà-vu""" "\n" + self.compare(INPUT, EXPECTED) + + def test_i18n_replace_number(self): + INPUT = """ + <p i18n:translate="foo ${bar}"> + <span tal:replace="python:123" i18n:name="bar">para</span> + </p>""" + EXPECTED = u""" + <p>FOO 123</p>""" "\n" + self.compare(INPUT, EXPECTED) + + def test_entities(self): + INPUT = ('<img tal:define="foo nothing" ' + 'alt="&a;  
 &a - &; �a; <>" />') + EXPECTED = ('<img alt="&a;  
 ' + '&a &#45 &; &#0a; <>" />\n') + self.compare(INPUT, EXPECTED) + + def compare(self, INPUT, EXPECTED): + program, macros = self._compile(INPUT) + sio = StringIO() + interp = TALInterpreter(program, {}, DummyEngine(), sio, wrap=60) + interp() + self.assertEqual(sio.getvalue(), EXPECTED) + + +class TestSourceAnnotations(unittest.TestCase): + + # there are additional test files in input/ and output/ subdirs + # (test_sa*) + + def setUp(self): + program = [] + macros = {} + engine = DummyEngine() + self.interpreter = TALInterpreter(program, macros, engine) + self.sio = self.interpreter.stream = StringIO() + self.interpreter._pending_source_annotation = True + + def testFormatSourceAnnotation(self): + interpreter = self.interpreter + interpreter.sourceFile = '/path/to/source.pt' + interpreter.position = (123, 42) + self.assertEquals(interpreter.formatSourceAnnotation(), + "<!--\n" + + "=" * 78 + "\n" + + "/path/to/source.pt (line 123)\n" + + "=" * 78 + "\n" + + "-->") + + def testFormatSourceAnnotation_no_position(self): + interpreter = self.interpreter + interpreter.sourceFile = '/path/to/source.pt' + interpreter.position = (None, None) + self.assertEquals(interpreter.formatSourceAnnotation(), + "<!--\n" + + "=" * 78 + "\n" + + "/path/to/source.pt\n" + + "=" * 78 + "\n" + + "-->") + + def test_annotated_stream_write(self): + interpreter = self.interpreter + interpreter.formatSourceAnnotation = lambda: '@' + test_cases = [ + '@some text', + '\n', + '<?xml ...?>@some text', + ' <?xml ...?>@some text', + '\n<?xml ...?>@some text', + '<?xml ...', + '<?xml ...?>@\n<!DOCTYPE ...>some text', + ] + for output in test_cases: + input = output.replace('@', '') + self.sio.seek(0) + self.sio.truncate() + interpreter._pending_source_annotation = True + interpreter._annotated_stream_write(input) + self.assertEquals(self.sio.getvalue(), output) + if '@' in output: + self.assert_(not interpreter._pending_source_annotation) + else: + self.assert_(interpreter._pending_source_annotation) + + +class TestErrorTracebacks(TestCaseBase): + + # Regression test for http://www.zope.org/Collectors/Zope3-dev/697 + + def test_define_slot_does_not_clobber_source_file_on_exception(self): + m_program, m_macros = self._compile(""" + <div metal:define-macro="amacro"> + <div metal:define-slot="aslot"> + </div> + </div> + """, source_file='macros.pt') + p_program, p_macros = self._compile(""" + <div metal:use-macro="amacro"> + <div metal:fill-slot="aslot"> + <tal:x replace="no_such_thing" /> + </div> + </div> + """, source_file='page.pt') + engine = DummyEngine(macros=m_macros) + interp = TALInterpreter(p_program, {}, engine, StringIO()) + # Expect TALExpressionError: unknown variable: 'no_such_thing' + self.assertRaises(TALExpressionError, interp) + # Now the engine should know where the error occurred + self.assertEquals(engine.source_file, 'page.pt') + self.assertEquals(engine.position, (4, 16)) + + def test_define_slot_restores_source_file_if_no_exception(self): + m_program, m_macros = self._compile(""" + <div metal:define-macro="amacro"> + <div metal:define-slot="aslot"> + </div> + <tal:x replace="no_such_thing" /> + </div> + """, source_file='macros.pt') + p_program, p_macros = self._compile(""" + <div metal:use-macro="amacro"> + <div metal:fill-slot="aslot"> + </div> + </div> + """, source_file='page.pt') + engine = DummyEngine(macros=m_macros) + interp = TALInterpreter(p_program, {}, engine, StringIO()) + # Expect TALExpressionError: unknown variable: 'no_such_thing' + self.assertRaises(TALExpressionError, interp) + # Now the engine should know where the error occurred + self.assertEquals(engine.source_file, 'macros.pt') + self.assertEquals(engine.position, (5, 14)) + + + +def test_suite(): + suite = unittest.makeSuite(I18NErrorsTestCase) + suite.addTest(unittest.makeSuite(MacroErrorsTestCase)) + suite.addTest(unittest.makeSuite(MacroExtendTestCase)) + suite.addTest(unittest.makeSuite(OutputPresentationTestCase)) + suite.addTest(unittest.makeSuite(ScriptTestCase)) + suite.addTest(unittest.makeSuite(I18NCornerTestCaseMessage)) + suite.addTest(unittest.makeSuite(UnusedExplicitDomainTestCase)) + suite.addTest(unittest.makeSuite(TestSourceAnnotations)) + suite.addTest(unittest.makeSuite(TestErrorTracebacks)) + + # TODO: Deactivated test, since we have not found a solution for this and + # it is a deep and undocumented HTML parser issue. + # Fred is looking into this. + #suite.addTest(unittest.makeSuite(MacroFunkyErrorTest)) + + return suite + +if __name__ == "__main__": + errs = utils.run_suite(test_suite()) + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/test_talparser.py b/src/zope/tal/tests/test_talparser.py new file mode 100644 index 0000000..f159cc1 --- /dev/null +++ b/src/zope/tal/tests/test_talparser.py @@ -0,0 +1,39 @@ +############################################################################## +# +# Copyright (c) 2004 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for zope.tal.talparser. + +$Id$ +""" +import unittest + +from zope.tal import talparser + + +class TALParserTestCase(unittest.TestCase): + + def test_parser_returns_macros(self): + parser = talparser.TALParser() + parser.parseString( + "<?xml version='1.0'?>\n" + "<doc xmlns:metal='http://xml.zope.org/namespaces/metal'>\n" + " <m metal:define-macro='MACRO'>\n" + " <para>some text</para>\n" + " </m>\n" + "</doc>") + bytecode, macros = parser.getCode() + self.assertEqual(macros.keys(), ["MACRO"]) + + +def test_suite(): + return unittest.makeSuite(TALParserTestCase) diff --git a/src/zope/tal/tests/test_xmlparser.py b/src/zope/tal/tests/test_xmlparser.py new file mode 100644 index 0000000..02d5848 --- /dev/null +++ b/src/zope/tal/tests/test_xmlparser.py @@ -0,0 +1,268 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Tests for XMLParser.py. + +$Id$ +""" +import sys +import unittest + +from zope.tal import xmlparser +from zope.tal.tests import utils + + +class EventCollector(xmlparser.XMLParser): + + def __init__(self): + self.events = [] + self.append = self.events.append + xmlparser.XMLParser.__init__(self) + self.parser.ordered_attributes = 1 + + def get_events(self): + # Normalize the list of events so that buffer artefacts don't + # separate runs of contiguous characters. + L = [] + prevtype = None + for event in self.events: + type = event[0] + if type == prevtype == "data": + L[-1] = ("data", L[-1][1] + event[1]) + else: + L.append(event) + prevtype = type + self.events = L + return L + + # structure markup + + def StartElementHandler(self, tag, attrs): + self.append(("starttag", tag, attrs)) + + def EndElementHandler(self, tag): + self.append(("endtag", tag)) + + # all other markup + + def CommentHandler(self, data): + self.append(("comment", data)) + + def handle_charref(self, data): + self.append(("charref", data)) + + def CharacterDataHandler(self, data): + self.append(("data", data)) + + def StartDoctypeDeclHandler(self, rootelem, publicId, systemId, subset): + self.append(("doctype", rootelem, systemId, publicId, subset)) + + def XmlDeclHandler(self, version, encoding, standalone): + self.append(("decl", version, encoding, standalone)) + + def ExternalEntityRefHandler(self, data): + self.append(("entityref", data)) + + def ProcessingInstructionHandler(self, target, data): + self.append(("pi", target, data)) + + +class EventCollectorExtra(EventCollector): + + def handle_starttag(self, tag, attrs): + EventCollector.handle_starttag(self, tag, attrs) + self.append(("starttag_text", self.get_starttag_text())) + + +class SegmentedFile(object): + def __init__(self, parts): + self.parts = list(parts) + + def read(self, bytes): + if self.parts: + s = self.parts.pop(0) + else: + s = '' + return s + + +class XMLParserTestCase(unittest.TestCase): + + def _run_check(self, source, events, collector=EventCollector): + parser = collector() + if isinstance(source, list): + parser.parseStream(SegmentedFile(source)) + else: + parser.parseString(source) + self.assertEquals(parser.get_events(),events) + + def _run_check_extra(self, source, events): + self._run_check(source, events, EventCollectorExtra) + + def _parse_error(self, source): + def parse(source=source): + parser = xmlparser.XMLParser() + parser.parseString(source) + self.assertRaises(xmlparser.XMLParseError, parse) + + def test_processing_instruction_plus(self): + self._run_check("<?processing instruction?><a/>", [ + ("pi", "processing", "instruction"), + ("starttag", "a", []), + ("endtag", "a"), + ]) + + def _check_simple_html(self): + self._run_check("""\ +<?xml version='1.0' encoding='iso-8859-1'?> +<!DOCTYPE html PUBLIC 'foo' 'bar'> +<html>&entity;  +<!--comment1a +-></foo><bar><<?pi?></foo<bar +comment1b--> +<img src='Bar' ismap=''/>sample +text +<!--comment2a- -comment2b--> +</html> +""", [ + ("decl", "1.0", "iso-8859-1", -1), + ("doctype", "html", "foo", "bar", 0), + ("starttag", "html", []), +# ("entityref", "entity"), + ("data", " \n"), + ("comment", "comment1a\n-></foo><bar><<?pi?></foo<bar\ncomment1b"), + ("data", "\n"), + ("starttag", "img", ["src", "Bar", "ismap", ""]), + ("endtag", "img"), + ("data", "sample\ntext\n"), + ("comment", "comment2a- -comment2b"), + ("data", "\n"), + ("endtag", "html"), + ]) + + def test_bad_nesting(self): + try: + self._run_check("<a><b></a></b>", [ + ("starttag", "a", []), + ("starttag", "b", []), + ("endtag", "a"), + ("endtag", "b"), + ]) + except: + e = sys.exc_info()[1] + self.assert_(e.lineno == 1, + "did not receive correct position information") + else: + self.fail("expected parse error: bad nesting") + + def test_attr_syntax(self): + output = [ + ("starttag", "a", ["b", "v", "c", "v"]), + ("endtag", "a"), + ] + self._run_check("""<a b='v' c="v"/>""", output) + self._run_check("""<a b = 'v' c = "v"/>""", output) + self._run_check("""<a\nb\n=\n'v'\nc\n=\n"v"\n/>""", output) + self._run_check("""<a\tb\t=\t'v'\tc\t=\t"v"\t/>""", output) + + def test_attr_values(self): + self._run_check("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'/>""", + [("starttag", "a", ["b", "xxx xxx", + "c", "yyy yyy", + "d", " xyz "]), + ("endtag", "a"), + ]) + self._run_check("""<a b='' c="" d=''/>""", [ + ("starttag", "a", ["b", "", "c", "", "d", ""]), + ("endtag", "a"), + ]) + + def test_attr_entity_replacement(self): + self._run_check("""<a b='&><"''/>""", [ + ("starttag", "a", ["b", "&><\"'"]), + ("endtag", "a"), + ]) + + def test_attr_funky_names(self): + self._run_check("""<a a.b='v' e-f='v'/>""", [ + ("starttag", "a", ["a.b", "v", "e-f", "v"]), + ("endtag", "a"), + ]) + + def test_starttag_end_boundary(self): + self._run_check("""<a b='<'/>""", [ + ("starttag", "a", ["b", "<"]), + ("endtag", "a"), + ]) + self._run_check("""<a b='>'/>""", [ + ("starttag", "a", ["b", ">"]), + ("endtag", "a"), + ]) + + def test_buffer_artefacts(self): + output = [("starttag", "a", ["b", "<"]), ("endtag", "a")] + self._run_check(["<a b='<'/>"], output) + self._run_check(["<a ", "b='<'/>"], output) + self._run_check(["<a b", "='<'/>"], output) + self._run_check(["<a b=", "'<'/>"], output) + self._run_check(["<a b='<", "'/>"], output) + self._run_check(["<a b='<'", "/>"], output) + + output = [("starttag", "a", ["b", ">"]), ("endtag", "a")] + self._run_check(["<a b='>'/>"], output) + self._run_check(["<a ", "b='>'/>"], output) + self._run_check(["<a b", "='>'/>"], output) + self._run_check(["<a b=", "'>'/>"], output) + self._run_check(["<a b='>", "'/>"], output) + self._run_check(["<a b='>'", "/>"], output) + + def test_starttag_junk_chars(self): + self._parse_error("<") + self._parse_error("<>") + self._parse_error("</>") + self._parse_error("</$>") + self._parse_error("</") + self._parse_error("</a") + self._parse_error("</a") + self._parse_error("<a<a>") + self._parse_error("</a<a>") + self._parse_error("<$") + self._parse_error("<$>") + self._parse_error("<!") + self._parse_error("<a $>") + self._parse_error("<a") + self._parse_error("<a foo='bar'") + self._parse_error("<a foo='bar") + self._parse_error("<a foo='>'") + self._parse_error("<a foo='>") + + def test_declaration_junk_chars(self): + self._parse_error("<!DOCTYPE foo $ >") + + def test_unicode_string(self): + output = [('starttag', u'p', []), + ('data', u'\xe4\xf6\xfc\xdf'), + ('endtag', u'p')] + self._run_check(u'<p>\xe4\xf6\xfc\xdf</p>', output) + + +# Support for the Zope regression test framework: +def test_suite(skipxml=utils.skipxml): + if skipxml: + return unittest.TestSuite() + else: + return unittest.makeSuite(XMLParserTestCase) + +if __name__ == "__main__": + errs = utils.run_suite(test_suite(skipxml=0)) + sys.exit(errs and 1 or 0) diff --git a/src/zope/tal/tests/utils.py b/src/zope/tal/tests/utils.py new file mode 100644 index 0000000..03eba52 --- /dev/null +++ b/src/zope/tal/tests/utils.py @@ -0,0 +1,65 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Helper functions for the test suite. + +$Id$ +""" +import os +import sys + +mydir = os.path.abspath(os.path.dirname(__file__)) +codedir = os.path.dirname(os.path.dirname(os.path.dirname(mydir))) + +if codedir not in sys.path: + sys.path.append(codedir) + +import unittest + + +# Set skipxml to true if an XML parser could not be found. +skipxml = 0 +try: + import xml.parsers.expat +except ImportError: + skipxml = 1 + + +def run_suite(suite, outf=None, errf=None): + if outf is None: + outf = sys.stdout + runner = unittest.TextTestRunner(outf) + result = runner.run(suite) + +## print "\n\n" +## if result.errors: +## print "Errors (unexpected exceptions):" +## map(print_error, result.errors) +## print +## if result.failures: +## print "Failures (assertion failures):" +## map(print_error, result.failures) +## print + newerrs = len(result.errors) + len(result.failures) + if newerrs: + print "'Errors' indicate exceptions other than AssertionError." + print "'Failures' indicate AssertionError" + if errf is None: + errf = sys.stderr + errf.write("%d errors, %d failures\n" + % (len(result.errors), len(result.failures))) + return newerrs + + +def print_error(info): + testcase, (type, e, tb) = info |