Thursday, August 28, 2008

Unit Testing Saves the Day

I had a fantastic unit testing experience at work today. A couple of days ago I released a DLL to production that scans some text and transforms part of the text according to certain rules. An example of this would be the text that users enter into a forum post. Users would enter [b]some text[/b] and the text processor would transform that into <b>some text</b> before writing it out to a web page.

When writing the transform DLL I created several unit test that check every possibility that I could think of especially the edge cases. It was a great aid and tool to developing a robust and well tested DLL.

Inevitably as soon as it was release there an edge case came to light that I hadn't thought of and so I had to fix the "bug" in the DLL. Finding and fixing it was an absolute pleasure.

First off I took the block of text that demonstrated the bug and created a unit test that passed this block of text to the DLL and showed that the DLL was failing. At this point I haven't touched the errant transform code. I ran all the unit tests in the solution (takes about 5 seconds) and as expected they all passed the unit test except for the new one.

I then proceeded to fix the code and when done I reran all the unit tests again. This time the new test passed. This is called red/green testing. First you see the red light because it failed. You fix the code. Then you see the green light. I believe that Scott Hanselman says that it's called grey/grey testing if you're color blind.

This approach gave me an enormous amount of confidence to release the new DLL because I know that I haven't introduced any code that will break any of the previous standard and edge cases because I've tested them all again - and in only 5 seconds. Granted that it took me several hours to write all those tests but I would have probably spent at least 2 hours retesting this DLL after this fix had I not had the unit tests to do it for me.

I consider this a great victory for unit testing and test driven development and I am finally seeing my efforts in writing unit tests pay off in time saved and robust software.

Tuesday, August 26, 2008

Stack Overflow

I've been using the Beta version of Stack Overflow and I'm very impressed. Jeff Atwood and his team have done an excellent job with this site and it's already provided me with some answers to questions that I had and those answers were furiously fast and accurate. I hope the quality and speed continues when they go live.

I've just caught up with the Hansel Minutes podcasts so I've started listening to Stack Overflow's podcasts. I've listened to the first 3 so far. To start with I wasn't that excited by them but by the end of the 3rd podcast they've started to grow on me and I can see myself listening to them on a regular basis.

Talking of podcasts for programmers, my friend and co-worker Saul Mora has just published a list of techie podcasts that he listens to.

Stop Forum Spam

I'm impressed with a site that my friend Huw Reddick recently alerted me to called Stop Forum Spam. It's a database of IP's, user name's and emails that have been used to spam forums. If you run a forum or maintain forum software then it's a great resource to query when someone's registering on your forum to try and cut down on spammers joining your forum. You can also submit spammer information to their database (manually) at this link. If, however, you're like me and hate spammers but are also very lazy then you'll want to automate this process as much as possible. Here's some C# code that will submit the spammers info for you:

        public bool SubmitForumSpammer(string ip, string username, string email, string apikey)
        {
            WebRequest req = WebRequest.Create("http://www.stopforumspam.com/add");
            string postData = String.Format("username={0}&email={1}&ip_addr={2}&api_key={3}", username, email, ip, apikey);

            byte[] send = Encoding.Default.GetBytes(postData);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = send.Length;

            Stream sout = req.GetRequestStream();
            sout.Write(send, 0, send.Length);
            sout.Flush();
            sout.Close();

            WebResponse res = req.GetResponse();
            StreamReader sr = new StreamReader(res.GetResponseStream());
            string returnvalue = sr.ReadToEnd();

            return returnvalue.Contains("Data submitted successfully");
        }
 

Thursday, August 21, 2008

Unable to cast object of type 'System.Int32' to type 'System.String'

Came across an interesting situation today with the error message:  System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'

I couldn't work out how you couldn't cast an Int32 to a string? Seems impossible doesn't it?

Try this little snippet of code and you will be able to get that error:

            Hashtable groupList = new Hashtable();
            groupList.Add(11, new object());
            groupList.Add("12", new object());
            List<int> groups = groupList.Keys.Cast<string>().Select(a => Convert.ToInt32(a)).ToList();

The Hashtable accepts a string as a key in the second Add() call so it now has both int's and strings as keys. What I'm guessing though is that on a call to Add() the Hastable checks what data type for the key is. On the first call this data type is unset so it takes the data type of the first param and uses that as the data type for the key. On subsequent calls to Add() it sees that the data type for the key is set so just adds the item as an object for the key. This is just my guess and I'm sure if I took the time to look at this member function in Reflector I'd find out if I'm right or not.

Tuesday, August 19, 2008

Hashtable keys intersect with list of Int32

The problem: You have a classic Hashtable. Although the keys are strings they hold only ints. You also have a list of ints. You want to find out if any of the keys from the Hashtable are in the list of ints. How do you do this in one line of LINQ?

The solution, using LINQ, that I came up with is:

            // Setup the test data
            System.Collections.Hashtable ht = new System.Collections.Hashtable();
            ht.Add("1", new object());
            ht.Add("2", new object());

            List<int> second = new List<int>();
            second.Add(2);
            second.Add(3);

            // Query the data
            bool containsKey = ht.Keys.Cast<string>().Select(a => Convert.ToInt32(a)).ToList().Intersect(second).Count() > 0;

            // Print the result
            Console.Write("Contains Key: {0}", containsKey);
 

Monday, August 18, 2008

Startup Weekend Phoenix

Ever heard of Startup Weekend? I hadn't until just recently but there's one coming to Phoenix from 17-19 October 2008 and I've just ponied up my $40 to spend my entire weekend working on a startup. Should be interesting - I'm very excited:

http://phoenix.startupweekend.com/

Will take place at:

Gangplank HQ Offices
325 E Elliot Rd, Suite 34
Chandler, AZ 85225

Saturday, August 16, 2008

DOCX to HTML via XSLT

A friend just gave me a link to Creating a docx -> Html Preview Handler for SharePoint which has the modifications necessary for the XSLT that comes with Sharepoint to make the HTML web page show images as well as text from a Word 2007 document. I have a number of documents in .docx format that I want to make available as web pages but want to keep the originals in .docx format so that I can continue to edit and modify them. It is my idea that whenever I modify a Word 2007 (docx) document that I can just dump the new file into the App_Data folder and the site's pages will start showing the new or modified content. It should be too hard to do with this template. This is a soon-to-be-done project. I'll post a link to the site once I've got this done.