Wednesday, January 30, 2008 -
UPDATE: Refactored and tweaked the validation method below by popular request!
I know this might make some people groan - but that's OK - I'm used to it. As Eilon Lipton always tells me:
You're a PM dude - you're not supposed to code
Which is true! And to get the PM as Haack tradition alive, here is my latest attempt to completely devastate my reputation as a coder. Have at me, I love it.
Let's Put an X in Front Of HTML Too
The world's gone X-Crazy (XBox, OS X, ASPX pages, ActiveX...) and it seems that nothing's cool anymore unless there's an X associated with it. Maybe I can regain some of the rep I'm about to lose by changing my name to "RobX".
XRob?
Testing For Compliance
One of the main things that I get hammered for (with respect to the MVC Toolkit) is the lack of XHTML Compliance. I tried to pay as much attention as I could to it but... well some things just slip through. I read somewhere that my slip ups (particularly with respect to the method on the form tag not being in quotes was
...yet again evidence that Microsoft could care less [sic] about the HTML spec
On the contrary it was me, being lame.
I know what you're thinking - "can't you test for that somehow?" and up until now it meant copy/pasting a whole mess of HTML up to w3.org to run through the validator. But as of today I decided to let my Mr. Hack take over and created some code to ping w3.org automatically.
The Code
For my compliance Unit Tests (you wouldn't want to do this for every test, for obvious reasons) I'm creating a Select box, comme ci:
[TestMethod]
public void Select_BindToIntegerArray() {
int[] numbers = { 1, 2, 3 };
string select = SelectBuilder.Select("test", numbers,"","",0,false,null,null);
//validate it
Assert.IsTrue(XHTMLValidator.ValidateFragment(select));
}
UPDATE: Duncan Smart (?) refactored this function yet again - thanks!
And I'm calling on my new hacked up wunderclass- the XHTMLValidator. Here's the code - have at me and make it hurt:
public static bool IsValidXhtml(string htmlFragment) { NameValueCollection values = new NameValueCollection(); values["fragment"] = htmlFragment; values["prefill"] = "1"; values["prefill_doctype"] = "xhtml10"; WebClient webClient = new WebClient(); string postResult = Encoding.UTF8.GetString( webClient.UploadValues("http://validator.w3.org/check", values) ); //lame check - but it works bool isValid = postResult.Contains("Congratulations"); return isValid; }
Yes, I know. But you know what - it's an automatic way to make sure that my tags are compliant :).
If You're Still Here...
I'm also going to use the HTML Agility Pack that's up on CodePlex to make sure all the other bits that are supposed to be present in the generated HTML are indeed there. This is a really cool project for checking your HTML out - from there site:
This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don't HAVE to understand XPATH nor XSLT to use it, don't worry...). It is a .NET code library that allows you to parse "out of the web" HTML files. The parser is very tolerant with "real world" malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams).
Hope someone finds this helpful...
It's a shame that we can't use the XhtmlConformance Web.config setting, but it only applies to server control output (and not Literal- or Label-encoded HTML either).
I'm with Joe, those streams need to be disposed or be in a using statement, it's never the best idea to trust the garbage collector to clean up your resources for you (memory yes, streams and handles, no). You should update the code on this page with the revised goodness once you've made the small tweaks so it can live on glory for the cut-n-pasters.
This is cool.
@Lance Fisher - Would you use this as a "Unit Test" or a higher-level one? I would want this one pre-commit but not on every unit-test run I think.
- Mike
I am not sure that you should have a higher focus on standards (perhaps managers really do have bigger fish to fry), but at least have some XHTML-savvy sap validate your code before anybody else has the chance to give you shit about it.
Anyways, the real reason I commented was to point out that there is already an API for this:
http://blog.madskristensen.dk/post/Using-the-W3C-HTML-Validator-API.aspx
Best regards...
You are doing an excellent job with this blog, I am so glad you have joined the MS Team.
Keep up the great work!
The fact that PMs are writing unit tests to validate XHTML indicates to me that they do care about standards. This is really cool.
@Mike,
Ideally, I would like to be able to validate the output in my unit tests, but I would not want to hit the w3c server on every unit test. So with this solution, which I really like in a lot of ways, I would rather just use it on a pre-commit like you suggest.
However, there might be another way. I found this great article:
http://www.thejoyofcode.com/Validator_Module.aspx
They wrote up an HttpModule that validates the output of any aspx page and appends the results to the rendered page. The way they check the validation is by loading the DTD from the W3C and caching it. They use an XmlReader to read the document which will then throw errors if the page doesn't validate. So aside from using the whole HttpModule, I think it should be possible to validate the XHTML with a local DTD. Now whether this covers everything the W3C's validator covers, I don't know, but it would cover quite a bit and you wouldn't have to do a call over the network.
I don't believe standards-compliance is a religous priority for Microsoft yet, but it is definitely reassuring to see there is some transcendence.
Keep up the great work, guys!
I came across this about a month ago, so if you care to fix it, you can:
http://mattberseth.com/blog/2007/12/ie7_cleartype_dximagetransform.html
Thanks for the quick reply, it really is good to see you guys are thinking about this stuff. I'm pretty excited about it!
"PM as Haack tradition" - was that a Freudian Slip? ;-)
Which part of your linq query is "predictive"?