Re: Test driving a real world data parser
Phlip <[email protected]> Thu, 16 Nov 2006 11:27:58 -0800
| Newsgroups | gmane.comp.programming.test-driven-development,gmane.comp.programming.test-first-user-interfaces |
|---|---|
| Message-ID | <[email protected]> |
--c5c1hl7tHxYfUrOWQHnnCr4I1WfsTx-S4aSXXz-
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Tim Ottinger wrote:
> Personally I like the advice to clean it up with tidy. Tidy is awesome.
Then, XPath is a sledge-hammer to TDD raw HTML.
(Note - sometimes you just write the HTML, and sometimes you TDD at
another level. When you TDD at the HTML surface itself, use XPath.)
Here's a sample of my current project:
@xdoc = Document.new(updater.body)
assert_xpath "/span/input[@name = 'frob[id]' and @value = '#{frob.id}']"
assert_xpath "/span/script[@type = 'text/javascript']" do |node|
assert_equal "Form.Element.disable('frob_zone_mode_1');", node.text()
end
The first xpath asserts that we generated a span containing a (hidden)
input field with the given value.
The second xpath asserts this span also contains a script. Then a
nested assertion checks the script contains the right JavaScript.
My assert_xpath can nest calls to more assert_xpath, and they will
work on the selected node. So I could, for example, start at a form,
then drill down and inspect fields in the form.
The general principle here is one can TDD a scripting language by
driving a parser which reads that scripting language. And so this
leads to the ideal that we should only select scripts for which
parsers are available!
--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!
--c5c1hl7tHxYfUrOWQHnnCr4I1WfsTx-S4aSXXz-
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>
<!-- Network content -->
<body style="background-color: #ffffff;">
<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="width:655px; position:relative;">
<div id="ygrp-msg" style="width: 490px; padding: 0 15px 0 0; float:left; z-index:1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->
<div id="ygrp-text">
<p>Tim Ottinger wrote:<br>
<br>
> Personally I like the advice to clean it up with tidy. Tidy is awesome.<br>
<br>
Then, XPath is a sledge-hammer to TDD raw HTML.<br>
<br>
(Note - sometimes you just write the HTML, and sometimes you TDD at<br>
another level. When you TDD at the HTML surface itself, use XPath.)<br>
<br>
Here's a sample of my current project:<br>
<br>
@xdoc = Document.new(<wbr>updater.body)<br>
assert_xpath "/span/input[<wbr>@name = 'frob[id]' and @value = '#{frob.id}'<wbr>]"<br>
<br>
assert_xpath "/span/script[<wbr>@type = 'text/javascript'<wbr>]" do |node|<br>
assert_equal "Form.Element.<wbr>disable('<wbr>frob_zone_<wbr>mode_1');<wbr>", node.text()<br>
end<br>
<br>
The first xpath asserts that we generated a span containing a (hidden)<br>
input field with the given value.<br>
<br>
The second xpath asserts this span also contains a script. Then a<br>
nested assertion checks the script contains the right JavaScript.<br>
<br>
My assert_xpath can nest calls to more assert_xpath, and they will<br>
work on the selected node. So I could, for example, start at a form,<br>
then drill down and inspect fields in the form.<br>
<br>
The general principle here is one can TDD a scripting language by<br>
driving a parser which reads that scripting language. And so this<br>
leads to the ideal that we should only select scripts for which<br>
parsers are available!<br>
<br>
-- <br>
Phlip<br>
<a href="http://c2.com/cgi/wiki?ZeekLand">http://c2.com/<wbr>cgi/wiki?<wbr>ZeekLand</a> <-- NOT a blog!!<br>
</p>
</div>
<!--~-|**|PrettyHtmlStart|**|-~-->
<span width="1" style="color: white;">__._,_.___</span>
<!-- Start the section with Message In topic -->
<div id="ygrp-actbar">
<span class="left">
<a href="http://groups.yahoo.com/group/testdrivendevelopment/message/20784;_ylc=X3oDMTM2aG1pMWdhBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBG1zZ0lkAzIwODAyBHNlYwNmdHIEc2xrA3Z0cGMEc3RpbWUDMTE2MzcwNjA1OAR0cGNJZAMyMDc4NA--">
Messages in this topic </a> (<span class="bld">7</span>)
</span>
<a href="http://groups.yahoo.com/group/testdrivendevelopment/post;_ylc=X3oDMTJxNTVvYXQ5BF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBG1zZ0lkAzIwODAyBHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTE2MzcwNjA1OA--?act=reply&messageNum=20802">
<span class="bld">
Reply </span> (via web post)
</a> |
<a href="http://groups.yahoo.com/group/testdrivendevelopment/post;_ylc=X3oDMTJlb3VhNjZmBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTE2MzcwNjA1OA--" class="bld">
Start a new topic </a>
</div>
<!------- Start Nav Bar ------>
<!-- |**|begin egp html banner|**| -->
<div id="ygrp-vitnav">
<a href="http://groups.yahoo.com/group/testdrivendevelopment/messages;_ylc=X3oDMTJlaG9kNDZoBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA21zZ3MEc3RpbWUDMTE2MzcwNjA1OA--">Messages</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/files;_ylc=X3oDMTJmMzYyb25vBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2ZpbGVzBHN0aW1lAzExNjM3MDYwNTg-">Files</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/photos;_ylc=X3oDMTJldTAxcDY3BF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA3Bob3QEc3RpbWUDMTE2MzcwNjA1OA--">Photos</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/links;_ylc=X3oDMTJmbWs1bTYxBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2xpbmtzBHN0aW1lAzExNjM3MDYwNTg-">Links</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/database;_ylc=X3oDMTJjNWthOXRmBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2RiBHN0aW1lAzExNjM3MDYwNTg-">Database</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/polls;_ylc=X3oDMTJmcTY3ZGVvBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA3BvbGxzBHN0aW1lAzExNjM3MDYwNTg-">Polls</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/members;_ylc=X3oDMTJlODR1Y2ZjBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA21icnMEc3RpbWUDMTE2MzcwNjA1OA--">Members</a>
| <a href="http://groups.yahoo.com/group/testdrivendevelopment/calendar;_ylc=X3oDMTJkNW52dmZnBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2NhbARzdGltZQMxMTYzNzA2MDU4">Calendar</a>
</div>
<!-- |**|end egp html banner|**| -->
<!-- Do not have place to put it yet -->
<div id="ygrp-grft">
</div>
<!-- yahoo logo -->
<!-- |**|begin egp html banner|**| -->
<div id="ygrp-ft">
<a href="http://groups.yahoo.com/;_ylc=X3oDMTJkc25hNm1hBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2dmcARzdGltZQMxMTYzNzA2MDU4">
<img src="http://us.i1.yimg.com/us.yimg.com/i/yg/img/logo/ma_grp_160.gif" height="15" width="106" border="0" alt="Yahoo! Groups"></a> <br>
<a href="http://groups.yahoo.com/group/testdrivendevelopment/join;_ylc=X3oDMTJmcTkxM3RpBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA3N0bmdzBHN0aW1lAzExNjM3MDYwNTg-">Change settings via the Web</a> (Yahoo! ID required) <br>
Change settings via email: <a href="mailto:[email protected]?subject=Email Delivery: Digest">Switch delivery to Daily Digest</a> | <a href = "mailto:[email protected]?subject=Change Delivery Format: Traditional">Switch format to Traditional</a> <br>
<a href="http://groups.yahoo.com/group/testdrivendevelopment;_ylc=X3oDMTJkbTBhbm1oBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2hwZgRzdGltZQMxMTYzNzA2MDU4">
Visit Your Group
</a> |
<a href="http://docs.yahoo.com/info/terms/">
Yahoo! Groups Terms of Use </a> |
<a href="mailto:[email protected]?subject=">
Unsubscribe </a>
</div> <!-- |**|end egp html banner|**| -->
</div> <!-- ygrp-msg -->
<!-- Sponsor -->
<!-- |**|begin egp html banner|**| -->
<div id="ygrp-sponsor" style="width:140px;float: left; clear: none; margin-left: 5px; background:white; margin-bottom:25px ;position:absolute; top:0; right: 0;">
<!-- Network content -->
<!-- Start vitality -->
<div id="ygrp-vital">
<div id="vithd">Recent Activity</div>
<ul style="list-style-type:none; padding: 0; margin: 2px 0;">
<li style="clear: both;">
<div class="ct" style="float: right;"><span style="display:none"> </span>16</div>
<div class="cat"><a href="http://groups.yahoo.com/group/testdrivendevelopment/members;_ylc=X3oDMTJmbDNyYzB0BF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzExNjM3MDYwNTg-">New Members</a></div>
</li>
</ul>
<a href="http://groups.yahoo.com/group/testdrivendevelopment;_ylc=X3oDMTJlM3FqZ2VxBF9TAzk3MzU5NzE0BGdycElkAzUwMzEyNTUEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTE2MzcwNjA1OA--">
Visit Your Group </a>
</div>
<div id="hd">SPONSORED LINKS</div>
<div id="ov">
<ul>
<li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJja2ViZDluBF9TAzk3MzU5NzE0BF9wAzEEZ3JwSWQDNTAzMTI1NQRncnBzcElkAzE3MDUwMDcxODEEc2VjA3NsbW9kBHN0aW1lAzExNjM3MDYwNTg-?t=ms&k=Software+development&w1=Software+development&w2=Development+software&w3=Web+development+software&w4=Offshore+software+development&w5=Computer+software+program&c=5&s=148&g=2&.sig=8RohCAKPn6EHF5tMJs6UeA">Software development</a></li>
<li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjNmFrYjJjBF9TAzk3MzU5NzE0BF9wAzIEZ3JwSWQDNTAzMTI1NQRncnBzcElkAzE3MDUwMDcxODEEc2VjA3NsbW9kBHN0aW1lAzExNjM3MDYwNTg-?t=ms&k=Development+software&w1=Software+development&w2=Development+software&w3=Web+development+software&w4=Offshore+software+development&w5=Computer+software+program&c=5&s=148&g=2&.sig=iKVfDB4TO41_ODhHZC7ANA">Development software</a></li>
<li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjNjFxaTM3BF9TAzk3MzU5NzE0BF9wAzMEZ3JwSWQDNTAzMTI1NQRncnBzcElkAzE3MDUwMDcxODEEc2VjA3NsbW9kBHN0aW1lAzExNjM3MDYwNTg-?t=ms&k=Web+development+software&w1=Software+development&w2=Development+software&w3=Web+development+software&w4=Offshore+software+development&w5=Computer+software+program&c=5&s=148&g=2&.sig=n8EwBYg9OqfRm2phD8ie2A">Web development software</a></li>
<li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjOTg4dnRrBF9TAzk3MzU5NzE0BF9wAzQEZ3JwSWQDNTAzMTI1NQRncnBzcElkAzE3MDUwMDcxODEEc2VjA3NsbW9kBHN0aW1lAzExNjM3MDYwNTg-?t=ms&k=Offshore+software+development&w1=Software+development&w2=Development+software&w3=Web+development+software&w4=Offshore+software+development&w5=Computer+software+program&c=5&s=148&g=2&.sig=8ssmCGaT2iieOzkkr3_gwg">Offshore software development</a></li>
<li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjNGczNzVoBF9TAzk3MzU5NzE0BF9wAzUEZ3JwSWQDNTAzMTI1NQRncnBzcElkAzE3MDUwMDcxODEEc2VjA3NsbW9kBHN0aW1lAzExNjM3MDYwNTg-?t=ms&k=Computer+software+program&w1=Software+development&w2=Development+software&w3=Web+development+software&w4=Offshore+software+development&w5=Computer+software+program&c=5&s=148&g=2&.sig=OJMkUip5bZpmnP__xpwt5A">Computer software program</a></li>
</ul>
</div>
<!-- Network content -->
<div id="nc">
<div class="ad">
<div id="hd1">Yahoo! Mail</div>
<p><a href="http://us.ard.yahoo.com/SIG=12hpn4dpo/M=493064.8985657.9760727.8674578/D=groups/S=1705007181:NC/Y=YAHOO/EXP=1163713258/A=3848569/R=0/SIG=12jcbehhh/*http://us.rd.yahoo.com/evt=42410/*http://advision.webevents.yahoo.com/handraisers">You're invited!</a></p>
<p>Try the all-new</p>
<p>Yahoo! Mail Beta</p> </div>
<div class="ad">
<div id="hd1">Y! Messenger</div>
<p><a href="http://us.ard.yahoo.com/SIG=12h639nvj/M=493064.8985659.9760753.8674578/D=groups/S=1705007181:NC/Y=YAHOO/EXP=1163713258/A=3848584/R=0/SIG=12ceqob45/*http://us.rd.yahoo.com/evt=42403/*http://messenger.yahoo.com/feat_conf.php">Group get-together</a></p>
<p>Host a free online</p>
<p>conference on IM.</p> </div>
<div class="ad">
<div id="hd1">New web site?</div>
<p><a href="http://us.ard.yahoo.com/SIG=12h3cvuv1/M=493064.8985663.9760769.8674578/D=groups/S=1705007181:NC/Y=YAHOO/EXP=1163713258/A=3848642/R=0/SIG=131eshi2t/*http://searchmarketing.yahoo.com/arp/srchv2.php?o=US2004&cmp=Yahoo&ctv=Groups3&s=Y&s2=&s3=&b=50">Drive traffic now.</a></p>
<p>Get your business</p>
<p>on Yahoo! search.</p> </div>
</div>
</div> <!-- |**|end egp html banner|**| -->
<div style="clear:both; color: #FFF; font-size:1px;">.</div>
</div> <img src="http://geo.yahoo.com/serv?s=97359714/grpId=5031255/grpspId=1705007181/msgId=20802/stime=1163706058/nc1=3848569/nc2=3848584/nc3=3848642" width="1" height="1"> <br>
<span style="color: white;">__,_._,___</span>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</body>
<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
<style type="text/css">
<!--
#ygrp-mlmsg {font-size:13px; font-family: arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
#ygrp-mlmsg table {font-size:inherit;font:100%;}
#ygrp-mlmsg select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}
#ygrp-mlmsg pre, code {font:115% monospace;*font-size:100%;}
#ygrp-mlmsg * {line-height:1.22em;}
#ygrp-text{
font-family: Georgia;
}
#ygrp-text p{
margin: 0 0 1em 0;
}
#ygrp-tpmsgs{
font-family: Arial;
clear: both;
}
#ygrp-vitnav{
padding-top: 10px;
font-family: Verdana;
font-size: 77%;
margin: 0;
}
#ygrp-vitnav a{
padding: 0 1px;
}
#ygrp-actbar{
clear: both;
margin: 25px 0;
white-space:nowrap;
color: #666;
text-align: right;
}
#ygrp-actbar .left{
float: left;
white-space:nowrap;
}
.bld{font-weight:bold;}
#ygrp-grft{
font-family: Verdana;
font-size: 77%;
padding: 15px 0;
}
#ygrp-ft{
font-family: verdana;
font-size: 77%;
border-top: 1px solid #666;
padding: 5px 0;
}
#ygrp-mlmsg #logo{
padding-bottom: 10px;
}
#ygrp-vital{
background-color: #e0ecee;
margin-bottom: 20px;
padding: 2px 0 8px 8px;
}
#ygrp-vital #vithd{
font-size: 77%;
font-family: Verdana;
font-weight: bold;
color: #333;
text-transform: uppercase;
}
#ygrp-vital ul{
padding: 0;
margin: 2px 0;
}
#ygrp-vital ul li{
list-style-type: none;
clear: both;
border: 1px solid #e0ecee;
}
#ygrp-vital ul li .ct{
font-weight: bold;
color: #ff7900;
float: right;
width: 2em;
text-align:right;
padding-right: .5em;
}
#ygrp-vital ul li .cat{
font-weight: bold;
}
#ygrp-vital a {
text-decoration: none;
}
#ygrp-vital a:hover{
text-decoration: underline;
}
#ygrp-sponsor #hd{
color: #999;
font-size: 77%;
}
#ygrp-sponsor #ov{
padding: 6px 13px;
background-color: #e0ecee;
margin-bottom: 20px;
}
#ygrp-sponsor #ov ul{
padding: 0 0 0 8px;
margin: 0;
}
#ygrp-sponsor #ov li{
list-style-type: square;
padding: 6px 0;
font-size: 77%;
}
#ygrp-sponsor #ov li a{
text-decoration: none;
font-size: 130%;
}
#ygrp-sponsor #nc {
background-color: #eee;
margin-bottom: 20px;
padding: 0 8px;
}
#ygrp-sponsor .ad{
padding: 8px 0;
}
#ygrp-sponsor .ad #hd1{
font-family: Arial;
font-weight: bold;
color: #628c2a;
font-size: 100%;
line-height: 122%;
}
#ygrp-sponsor .ad a{
text-decoration: none;
}
#ygrp-sponsor .ad a:hover{
text-decoration: underline;
}
#ygrp-sponsor .ad p{
margin: 0;
}
o {font-size: 0; }
.MsoNormal {
margin: 0 0 0 0;
}
#ygrp-text tt{
font-size: 120%;
}
blockquote{margin: 0 0 0 4px;}
.replbq {margin:4}
-->
</style>
</head>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</html><!--End group email -->
--c5c1hl7tHxYfUrOWQHnnCr4I1WfsTx-S4aSXXz---