2008-05-06

Bug Discovered in Internet Explorer 7 JavaScript Regular Expression Engine

I enhanced my understanding about Regular Expressions' "look-ahead" concept that I hadn't fully comprehended before. The fact that (at least in the .NET framework and most JavaScript engines; I assume it also works in PERL and other popular RegEx engines...) you can use look-aheads to not only find a match but not include in the full-text match; but can look-ahead and not have the position of the start of the match matter either.

For some reason I always thought that the match would be made and the beginning of the next match would start at the position the other left off at. I wet my pants with glee when I found that wasn't the case...

That is, until I tried an expression in JavaScript in Internet Explorer 7.

To see an example of what I'm talking about, run my "Regular Expression Tests for Your Browser" on JavaScriptJedi.com in multiple browsers on your computer. You'll be running the "Pre Match Look Aheads (2008-05-05)" tests which are the only ones there at the time of this writing. I may add more in the future.

The scenario is this:
I had a set of password restriction requirements to enforce on a form when a user wanted to change their password. The requirements were that the password must be at least 8 characters long; contains at least one number and at least one "symbol". Due to a database constraint, I also added a max-length requirement of 50 characters, and I interpreted "symbol" to mean any non-alpha-numeric character.

That said, the regular expression ended up like this:
/^(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{8,50}$/

What's really cool about this is; when run in a properly working regular expression engine, it doesn't matter if the number or "symbol" come first, it will detect them both and then from the beginning of the string match any characters between the lengths 8 and 50. Genius. Whoever came up with Regular Expressions needs a Nobel prize or some equivalent; because, well, they just make a developer's world a better place to live. :)

So after getting uber-excited about my new found knowledge and greater love for Regular Expressions, my bubble was quickly burst when I found out it didn't work correctly in IE7 and I had to come up with a workaround.

So go see my page and try it for yourself; and I'd love to get your feedback on this one. I'll be submitting a bug report to Microsoft (if I can figure out how...) and if I hear anything back from them (which I'm sure I won't...) I'll post my findings here.

I'd especially like to hear from Mac users that can test on the major Mac browsers for me and tell me which work and which don't.

2008-05-04

MbUnit: Syntax Sugar for the Test-Driven Developer

I'm not going to profess to be the utlimate TDD guru; but I'm a firm believer and have been trying to continuosly better my skills in this development methodology.

I started my TDD experience about three years ago using CSUnit; but whas quickly moved to NUnit when we found that CSUnit wasn't totally meeting our needs. I've been with NUnit ever since and have heavily used it over the past year in NUnit GUI, NCover and MSBuild. It's easy to use and gets the job done well. The Unit Runner is a little lacking in some areas (mostly aesthetics... but we're not going for prize winning eye-candy... we're testing our code...) but it's functional and easy-to-use.

A friend of mine that works for LanDesk clued me in to one I hadn't heard before called MbUnit. I started searching around and realized that a lot of big names in the community seem to be excited about it. One blog post that really caught my eye and piqued my interest in checking it out was by
Scott Hanselman, entitled: 'MbUnit - Unit Testing on Crack'.

How wonderful it looked to write one short test for multiple scenarios rather than multiple test methods with basically the same repeated code over and over again with different test data.

So I took the simple phone number example I like to use when introducing someone to test-driven development and I made it my first experiment with MbUnit.

Without going into TOO much detail, I basically will have my phone number scenario be where we're going to write a utility class with a static method on it that will take a phone number string (in this case USA phone numbers) and return a boolean specifying its validity as a USA phone number format.

I make it a "red-green-refactor" scenario by first writing tests and implementing code that has pretty hard defined logic like string length tests, etc and then once I get some basic tests passing, I refactor the method's code to a regular expression and ensure the tests still pass. It's a fun little scenario and easy to help people pick up on the concept of Test-Driven Development.

In this scenario, the requirements were that the phone number had to be 10 digits and could only follow the formats (# representing a digit):
##########
###-###-####
###.###.####
(###) ###-####

Anyway, I was very pleased with the Test Fixture and Test code and how nicely the Icarus test runner still views them as separate tests.

The Test Code:


[TestFixture]
public class PhoneNumberIsValid_Tests
{
[RowTest]
// Success cases
[Row(PhoneNumberType.USA, "8888675309", true)]
[Row(PhoneNumberType.USA, "888-867-5309", true)]
[Row(PhoneNumberType.USA, "888.867.5309", true)]
[Row(PhoneNumberType.USA, "(888) 867-5309", true)]
// Failure cases
[Row(PhoneNumberType.USA, "(888.867-5309", false)]
[Row(PhoneNumberType.USA, "888.EYE.ROCK", false)]
[Row(PhoneNumberType.USA, "888EYEROCK", false)]
[Row(PhoneNumberType.USA, "888/867/5309", false)]
[Row(PhoneNumberType.USA, "123456", false)]
[Row(PhoneNumberType.USA, "123456789", false)]
[Row(PhoneNumberType.USA, "12345678901", false)]
public void USPhone_Tests( PhoneNumberType whichType, string testPhoneNumber, bool expectedResult )
{
bool result = PhoneNumberUtil.IsValid(whichType, testPhoneNumber);
Assert.AreEqual(expectedResult, result);
}
}


How cool is that to have your test method take parameters so the same test code can be used for multiple scenarios? Booya!

And you can see that I could easily add tests for non-USA phone number types by adding Row attributes that used a different value of the PhoneNumberType enum.

And here's how it looks inside Icarus:



Notice how it also shows the parameters being sent in to each test... makes it VERY easy to see what's going on with your tests. I love it!

Oh yes, MbUnit is Test-Driven Development evolved. I'm very excited about the potential of this framework.

Icarus Test Unit Runner is VERY alpha right now, but I'm excited at its potential. It's prettier than NUnit's GUI, though still showing its infancy. Icarus is very functional for being in alpha. Rumor is that ReSharper can also run MbUnit tests; so that will be awesome if that's true as well.

So, if you're a test-driven developer and you're looking for some new hotness in test-driven technology... I'd highly recommend looking into MbUnit.

To get hooked up with MbUnit and the Icarus test unit runner (and more) download the Gallio Automation Platform. Enjoy!