Sunday, December 7, 2008

Hot Dog

While my wife and I were on vacation, my parents were kind enough to take care of our Old English Sheepdog, Molly. They live out in the woods near Kenora, so this is a real treat for Molly because she can run free out there; plus, my parents are retired and home during the day, so she isn't alone as much.

Now, life with Molly is always a bit of an adventure, so when we got back from Hawaii we called to ask how things were going, and sure enough my parents had a lot of stories to tell. Most of them were pretty typical Molly stories (running directly at oncoming vehicles, licking one of my dad's leather slippers so thoroughly one night that it is now hard as a rock since it dried out, and general tales of her legendary clumsiness), but one story truly stood out.

As the story goes, one night shortly after we left, my parents were relaxing in the house watching TV. As with most dogs, Molly likes to be wherever the people are, so she was lying in the room with them, off near a wall. As they all sit there, my dad begins to pick up the scent of something unpleasant. Now, Molly is well known for her profound ability to light up a room, so to speak, so assuming Molly has just let loose, my dad continues to watch TV in hopes the smell will soon dissipate.

As the minutes pass, however, the smell not only remains, but it strengthens. And it doesn't smell quite like gas... it smells like burning. So my dad starts to look around for a fire. He wanders out to the kitchen, around the house, looking for the source of the smell. Nothing seems out of the ordinary, but the smell is still there. As he is doing this, Molly goes to the back door and waits to go outside, so my mom lets her out.

Over the next few minutes they continue to look around for the source of the smell, but nothing seems amiss. So they resume watching TV, and sure enough the smell starts to lessen.

Later, Molly barks to come inside. As my dad lets her in the door, he discovers the source of the smell: all down one side, Molly's fur is a nice burnt orange. It seems she was sleeping next to an electric baseboard heater, and her fur must have pushed up against the heater coils and caught fire. Luckily she didn't go up in flames, but rather the fur must have smoldered for awhile, causing the smell. It seems that she never even noticed, and most likely just went outside to either avoid the smell, or because she was feeling a bit on the warmish side... likely from being on fire!

Looking at her now, about 2 weeks after the incident, the burnt fur isn't very noticeable, although it does cover quite a large patch of her right side. My dad says that for the first few days it was very obvious, and that everyone who saw her immediately asked what she'd gotten into, or why her fur was discolored. So he would have to tell them the story of Molly catching on fire, and most listeners would respond by telling him that he'd better trim the fur off and pretend that nothing happened if he ever expects to be able to watch his soon-to-exist Grandchild.

All I can say is, he's going to have to try harder than that if he wants to get out of babysitting.

Friday, December 5, 2008

Lots to talk about, so little time

I can't believe all the stuff that's been going on that I haven't blogged about! Obama is on his way to the White House; our own politicians back home are acting like children at best, idiots at worst (and I mean all of them, Harper, Dion, Layton, the whole lot); I spent 10 days in Hawai'i; I did a presentation on WPF Data Binding at the Microsoft Tech Days conference here in Winnipeg; and many more little things that I've been itching to spew opinions on. Oh, and my wife is 7 months pregnant.

Unfortunately, life has been a bit of a maelstrom and I just haven't taken the time to nurture this web site. Hopefully this post will be the beginning of the renaissance here at Chez Code Baboon.

So, with all the amazing things happening right now, what am I going to talk about first? A petty annoyance with a technology, of course!

At Tech Days everyone received a free copy of DVDs containing videos of every presentation from Tech-Ed 2008. I was pumped, so this evening I plopped a DVD into my computer and got ready to see what all was on there. There is an absolute boat-load of content, so MS has provided a Silverlight app to allow you to search and discover the content and figure out what disc it will be on.

Sounds great, right?

Well, it would be if the app on the DVDs wasn't written in Silverlight 2 Beta 2. You see, I like to stay current, and Silverlight 2.0 RTW has been released so that's what I have installed. You'd think the final release would be able to handle running an app written in Beta 2 of itself, right?


That's right, the DVD tells me I need to install Silverlight (specifically Silverlight 2 Beta 2). It provides me with a link to the Silverlight download site, but that site kindly informs me that the page I was redirected from is running an old version of Silverlight and needs to be updated to the latest version. Seriously, check it out (you may need to click the image to see it in full size to read the hilarious text in green):

Kinda hard to update something burned onto a DVD.

I tried to uninstall Silverlight and follow the link again, but it just had me install the 2.0 release again (since it is the latest version, after all). In order to actually view the content on those discs, I ended up having to Google search for the Beta 2 bits where I eventually found them on some filehippo site. I downloaded and installed it anyways; I mean, if you can't trust filehippo, who can you trust? Of course, the upshot here is that I now can't view any Silverlight sites written for 2.0. Sweet!

I've noticed problems like this before with Silverlight apps. It seems like there are about 25 different versions of the Silverlight framework out there, and none of them can view apps written in older or newer versions than themselves.

MS needs to sort this crap out; this is not the path to becoming the Flash/Flex Killer they aim to be.

Friday, October 10, 2008

New And Improved

When I began this blog, the idea was, ostensibly, to create a little corner of the interweb where I could espouse my views on the various and sundry details of software development, hopefully providing some useful information with a dusting of humour to keep things moving. Sure, a handful of posts strayed from the premise, but for the most part I tried to stick to my guns and not litter the site with pages of unrelated fluff. In my head I always wanted to maintain a ratio of at least 1:1 between crunch and fluff, as it were.

Unfortunately, what I've discovered is that there are long periods of time when, for various reasons, I have nothing relevant to add in regards to crunch. So what happens is that I end up posting nothing at all, because I don't want the blog to become overly fluffy. But you know what's worse than a fluffy blog? A dead one

So from here on out, the shackles are coming off. I'm going to post about whatever I feel like; be it sports, politics, arts, or anything else. Hopefully we'll get the odd software post mixed in, if for no other reason than to keep the name at least borderline relevant. But there are no promises.

So let us all raise our cups to the new and improved Code Baboon Blog!

... By the way, I'm virtually clinking glasses with all of my imaginary readers right now, and it's totally awesome.

Thursday, September 18, 2008

The Phoenix Rises

Remember this post? That was one crazy night. Perhaps some day I will explain it. For now, just know that the baboon in question is fine. Also know that some things, once seen, cannot be unseen.

I'm back.

Wednesday, June 4, 2008

On Being Out-Babooned

I'm being out-babooned. A few months ago I decided it might be a good idea to snag the domain, only to realise that someone else (Mark Theunissen apparently) had registered it literally days earlier. A little frustrated by my lack of initiative, I figured it was no big deal, that this new baboon would probably just do nothing with it or put up some craptastic site that I could mock now and again.

Boy was I wrong. Not to pimp some stranger's site, but check it out. Pretty nice looking, eh? He's got a cool little baboon logo that kind of looks like him, and a very nice, clean style. He shows up first in the Google search for code baboon, and has far more comments on his posts (which means he has a few readers). And to top it all off the bastard even has a photo of himself and a baboon!

Looks like I need to step it up. My frequency of posts has been increasing lately, so that's a start. I'm not sure what more I can do to make Blogger look sexy, so maybe I need to look into registering or something. Most importantly, I'll be heading to the Zoo this weekend to steal a baboon for a night on the town. I'm going to get photos of us having a drink on a patio, playing flag football in a park, riding a tandem bike, and high-fiving after scoring the winning touchdown in a game of flag football. Eat that, Mark.

Monday, June 2, 2008

Oops, I Did It Again...

By 'it', I mean Assert. But lets step back.

Following a dry run for Ryan Weppler's upcoming webcast Testing Out the MVC Routing, a few guys got into a discussion about multiple Assert statements in a unit test. Steve 'asserted' (oh yeah, I just went there) that you should only ever have 1 Assert per unit test (edit: from Steve per the comments: "the one Assert per test thing is just best practice, not a written-in-stone sort of thing. As long as you have a good reason for doing it, then fill your boots. Just ask yourself why you're doing it."). I was attending remotely and didn't have a mic, so I could not respond, which turned out to be a good thing. You see, I wanted to say something like "I have a bunch of tests from my demo code that used multiple Asserts, and they all were necessary/made sense". Because I couldn't speak, I decided to send an email to that effect.

But the good thing about email is that it generally encourages you to back up your random statements with crazy things like facts and examples, so I popped open the Dice Hockey code and looked at my tests. Sure enough a bunch have more than one Assert. Yet as I gazed upon those 'perfect' tests with the intent to throw them in Steve's metrosexually attractive visage, I realised that I couldn't do it. In each case, Steve was right. Damn him and the Mac he rode in on!

Anyways, et's take a look for ourselves at a function from one of my tests:

private void EnsureAllDesiredPlayersWereRetrieved(
                IEnumerable<Guid> playerIds)
        playerIds.Count(), "Not all players retrieved!");
    IEnumerable<Guid> playersNotRetrieved = 
        (from ptr in playerIdsToRetrieve
         select ptr).Except(playerIds);
    Assert.IsTrue(playersNotRetrieved.Count() == 0, 
       "Not all players retrieved!");

In this first example, the first Assert is meaningless. It only has value because I know that during my data initialization at the start of the test I put more players into the database than I did in my list of ID's to retrieve. But really, the second Assert is the one that makes sure everyone got retrieved that should have been. If I want to test that no other players were retrieved (which is basically what that first Assert is doing), I should have another test.

And hey, speaking of that, I do have another test for that! Well, sort of. I have another function, as seen here:

private void EnsureNoPlayersWereRetrievedThatShouldNotHaveBeen(
            IEnumerable<Guid> playerIds)
    IEnumerable<Guid> playersThatShouldntHaveBeenRetrieved = 
       (from p in playerIds
        join ptnr in playerIdsToNotRetrieve on p equals ptnr
        select p);
playersThatShouldntHaveBeenRetrieved.Count() == 0,
          "Players were retrieved that should not have been!");

That looks nice, right? But check out where these functions get used:

public void Should_retrieve_only_specified_players_from_Players_table()
    var retrievedPlayers = 
    // Check that all desired players were retrieved
        (from rp in retrievedPlayers
         select rp.PlayerId));
    // Check that no players were retrieved that 
    // should not have been
        (from rp in retrievedPlayers
         select rp.PlayerId));

That's a pretty clear-cut case of bad test writing; those should be two seperate tests, one for each function. Combine that with the clean-up of the two Asserts in that first function and we'd have a much nicer solution.

UPDATE: Code is all visable now, sorry for the formatting issues.

Thursday, May 29, 2008

Time Machine's and White-Socked Ninja's

With 2 of my friends finally moving to Gmail accounts this week, I decided to click the "oldest" button in my "All Mail" section to see how long I'd been a member. Turns out my 4 year Gmail Anniversary will arrive on June 16th. In that time I've never deleted anything, leaving a little over 6000 e-mails essentially tracking the last 4 years of my life. Looking back at those early email threads is like having my own little time machine back into 2004, which feels like a lifetime ago now. A lot has changed for me since then. I've married, purchased a home, purchased a dog, changed jobs, and exited my 20's.

But my favorite part was seeing the first email I ever sent from the account. It is an email to my long-time friend Jeremy Maxom with an attachment describing the sacred teachings of the White-Socked Ninja Clan, a clan whose actions the two of us have been tracking since high school. This document was listed as highly-classified, but the time has come for the public to be aware. So, with little fanfare but much significance, I present...

Sacred Teachings of the White-Socked Ninja

Within this document are details of a clan, a clan which has existed, surprisingly, for ages, or at least 10 years. Few have knowledge of the White-Socked Ninja, but those who do are wise to respect and honor the fierce irony that members of the clan must face. For a White-Socked Ninja is as his name implies: a ninja, skillfully trained, deadly and swift, cunning and agile, heard of often, yet never seen… from the ankles up.

You see, a White-Socked Ninja, much like your run-of-the-mill, everyday ninja, is above all else a man of stealth. Clothed all in black, a ninja can stalk the night like no other. But a White-Socked Ninja must adhere to the number 1 rule of the clan: White tube-socks must be worn, and visible, at all times. Although quite comfortable and stylish, this requirement has been the undoing of more than 1 White-Socked Ninja. In fact, it has foiled 100% of all missions the clan has attempted.

The exact date of inception for the clan is unknown, and some members have been known to claim it has been around for centuries. However, historians and clan co-founders have narrowed the likely date to sometime in 1993. The clan was borne out of a growing distaste for the normal ninja clans of its time. Tired of the outrageousness of the Teenage Mutant Ninja Turtles, yet bored of the non-distinct look of most other ninja clans (often derided by WSN members as being “effective but boring”), clan founders decided that a subtle yet cool ninja clan was “where it’s at”.

A uniform was quickly decided upon. Not wanting to stray too far from tradition, black was chosen as the predominant color. It was also noted by one co-founder that “black is slimming”. To maximize effectiveness in the field, while maintaining cool-non-vanilla Flava, the trim color could not be above the waist. When one co-founder noted that white tube socks could be easily acquired for low prices at many convenient locations in the metro area, the decision was unanimous and the White-Socked Ninjas were born.


“Stealth Is Important, But So Are Style And Affordability.”

Rules & Regulations

  1. White Tube-socks must be worn, and visible, at all times. These replace the standard two-toed ninja booties most trainees are familiar with.
  2. All other Standard Ninja Rules, as dictated by the International Consortium of Ninjadom, apply unless in direct conflict with rule 1.

Methods of Sneakiness

  1. Missions should be attempted during night-time hours if at all possible.
  2. Approach targets from any angle that is not the front.
  3. No chewing gum.
  4. Know your surroundings. Grass and carpet are good. Hardwood floors and bubble-wrap are bad.
  5. When in doubt, do what a cat would do, unless the cat would purr.

The Mission That Almost Succeeded

The lights were low that fateful night,
When white-socked ninjas approached the site.
The clouds hung low and children shivered,
For soon the strike would be delivered.

The quarry lay so still and quiet,
This was the perfect night to try it!
So up the fence the members shimmied
And through the door that one guy jimmied.

The group that night it counted four:
The first guy stayed to guard the door.
The second one was stationed outside,
Because he’d borrowed his grannies’ ride.

If things went poorly, as they often did,
And if the members could not be hid,
Then slam the car into drive he would
And they’d peel out of this neighborhood.

The two that continued had their orders;
Divide the quarry into quarters.
So up the stairs they softly stepped
And down a corridor they quickly crept.

And through a door, and there they were:
Their target in sight, of that we’re sure.
But what came next is somewhat muddy,
Like a story from your drunk friend Buddy.

In most accounts, someone screamed,
The jig was up, or so it seemed.
“Honey, honey, there’s someone here!”
“Where?!? Oh where? Pray tell me dear!”

”I’m not quite certain, it’s oh so dark,
But I saw a flash, a white-ish spark.
It was low to the ground, say ankle high
Please dear believe me, I wouldn’t lie!”

Later that night in a secret place,
Where a secret leader secretly paced,
The group of four softly entered
And faced their leader front and center.

“We failed again sir” said one member
“Our fourth failure since December”
The leader shook his head and sighed
“What happened this time, that no one died?”

“Same as always, like hands on clocks,
Despite our skill they saw our socks”

Wednesday, May 28, 2008

Gateway Webcast: The Files

Things went ok on the webcast today, although I did forget a couple of things that I wanted to show in the demo. I will make a post later tonight highlighting the content that I missed in the webcast for anyone who is interested to read through.

During the webcast I mentioned that I would be putting up links to the various resources used in the webcast, so here they are:
Disclaimer: The code provided is not supported or guaranteed in any way: use at your own risk. In fact, it is not entirely complete (being that the intent is to build it out into a full project) and so you will see at least one failing test because the method it tests is not even implemented.

Related Posts: Oops, I did it again...

Monday, May 26, 2008

Webcast Dry Run

Well today was the dry run for my upcoming webcast. As I've mentioned before, this is a first for me, so it was interesting. Things went ok, but we had some audio issues which I need to resolve by Wednesday. I suspect Vista is the problem, which is nice and ironic.

The other things I learned by way of feedback as well as just things I noticed myself while speaking or listening to the recording afterwards:
  • I should explain that we won't be deep-diving into any specific areas.
  • I forgot to have SQL Server Management Studio open.
  • I didn't have server explorer connection set up (not sure why, I set it up yesterday. Guess VS forgot it, so I'll need to set it up right before the presentation on wednesday).
  • I skipped around and didn't follow my notes properly! I need to make my notes easier to follow (NOT handwritten!).
  • I forgot to explain the Lambda expressions properly.
  • I need to expand the references section a bit.
  • I should use tinyurl for long URL's.
  • I set up bookmarks in Visual Studio, and then proceeded to not use them at all.
  • I intended to use Full Screen view in Visual Studio but forgot. This resulted in lots of sideways scrolling because I had the Solution Explorer pinned. I didn't clue in on this AT ALL during the entire presentation.
The timing was pretty good, 29 minutes start to finish. I would have preferred about 25 minutes because this doesn't give me much wiggle room to stray from my notes, but I suppose this will keep things focused and moving.

Listening to the recording was interesting. I have always hated listening to my own voice, but I didn't sound quite as stupid as I thought I had, so that was positive. Of course, with the audio cutting out constantly perhaps the dumb portions were mercifully absent.

Finally, the one thing I really noticed was how I sort of 'went blank' as I spoke. I was in some kind of zombie trance, and the couple times that I tripped up because I wasn't following my notes properly left me totally dumbfounded for a few seconds. I think the audio issues hid this pretty well actually, but there were a couple times when I stared at my notes for like 5-10 seconds thinking "What the heck? Where was I? What am I doing next? OH NOES!". Hopefully this does not happen on Wednesday!

Monday, May 19, 2008

Well That Ended Quickly

The great Linux experiment of '08 is officially over. I will really miss the virtual workspaces and other nice features, but until there is a reliable Exchange mail client it just won't do the trick for me. Evolution is beyond buggy, and I can't have my email and calendering crashing constantly. Thunderbird/Lightning didn't seem any better. I couldn't get Outlook to work under Wine.

So I'm back to Windows, and I'm giving Vista a third spin. I'm going to try my darndest to keep the OS 'clean' and hopefully have something that performs reasonably well. Of course, on a fresh install with just Firefox running I'm currently using 675MB of RAM... ugh.

I'm still glad I tried, and I think I might try installing Kubuntu under Wubi and seeing how Kontact works, but I don't hold out much hope. Maybe someday I'll be able to switch back, but for now I'm stuck.


Wednesday, May 14, 2008

Made The Switch

As of last night I'm officially an Ubuntu user. Things have gone pretty well so far, although Evolution seems to have some kind of leak because towards the end of the day I noticed my system slowing down, and a quick check in the System Monitor showed Evolution using 780MB of RAM and 25% CPU! I watched the RAM usage slowly grow for a few megs, during which time Evolution did not appear to be doing anything. I re-started it and the memory usage dropped back to the normal 20MB or so and my system became snappy again. Definitely another impetus to find an alternative.

Now lets talk about some things I like. Performance is the first thing. Everything just seems faster. Perhaps it isn't fair because I don't have nearly the list of services running and I need to use XP VM's to do a lot of tasks, but for anything I do within Ubuntu itself I really feel like the speed is much faster. Apps load faster, things respond to my actions quicker, and the file system manager (Nautilus I think) seems quicker than Explorer.

The other big plus so far is the window management. I absolutely love the virtual workspaces, and using the keyboard shortcuts to switch between them is starting to feel natural. Moving between them is quick and seamless, and it just gives the feel that I 'have all of my stuff spread out on my desk'. That's the best analogy I can think of.

Finally, tonight I've been playing with the neat desktop effects. I tried the famous Cube but I couldn't get all the effects to work (not sure why) and I find the default Wall behaviour to be more natural and efficient anyways. The zoom feature is great, I should get some use out of that, and the Expose feature might be useful as well (if all those Mac zealots can be believed). Last but not least are the eye candy effects, like wobbly-windows and whatnot, which I assumed would hurt performance but don't seem to really have any effect at all (aside from being neat).

All in all the jury is still out on how functional this can be given my Microsoft-centric career, but I would not hesitate to use Ubuntu on a home PC. Not my Mom's home PC, mind you, because despite all the fervor around how user-friendly Ubuntu is, there is a LOOOONG way to go. I may be crazy, but I'm not THAT crazy.

Webcast Update

Couple of things. First off, Steve did a great job with the first Webcast today, check out that link for all of his materials. For anyone who missed the live presentation, the recording should be available soon, I'll post a link when it's up.

Second off, the official launch of the webcast series has been put up on the Imaginet website, you can check it out here.

Last off, my own presentation is now only 2 weeks away, and that officially has me feeling nervous. Guess I better start prepping a bit eh?

Monday, May 12, 2008

Imaginet Webcasts Revealed

A couple weeks ago I mentioned that Imaginet would be presenting a weekly series of Webcasts (I called 'em Webinars back then), but I didn't know many of the details. Well, the details have been released.

Make sure to check out the first one, presented by Steve Porter, this Wednesday!

Making The Switch Part 2

I didn't have time to do the full move to Ubuntu last night, but I did decide that I would try to work exclusively out of the Wubi installation today. Things went ok, although I did have to jump to Windows in order to view a Live Meeting with audio. This was kind of annoying because MS advertises that you can view Live Meetings via a Web Browser applet, but they neglect to mention that this doesn't include audio. But hey, who needs audio, right?

I guess I'll have to install Live Meeting into one of my VPC's, or make a Live Meeting Appliance or something. I expected to have to do this for actually presenting anyways, so not the end of the world, although it would be nice to be able to accept impromptu invites within the browser.

I also came across a pretty serious bug that I need to look into more; twice today I completely lost the ability to use my shift or caps lock keys. Yep, no capital letters, underscores, question marks, or exclamation marks. How can I _WORK_ without those?!

Anyways, I did a quick search and it appears to be related to VMWare, which kind of sucks considering how reliant I will be on virtual machines for much of my day to day activities. There is supposedly a command you can type into your terminal that will restore your proper keystokes, but whenever I brought up my terminal and started to type it would disappear (something not unique to me based on the comments I was reading relating to this bug). The only solution for me was to log out and log back in. Not good.

Again, I don't want to let this stop me from moving over, but it is a SERIOUS bug that will cause me to give up and go back to windows if I can't find a fix or work around in a reasonable amount of time. Maybe VirtualBox is the answer? I mean, if I'm going 'alternative', why stop at just the OS? Of course if I start dating men you'll know I've taken this too far.

Sunday, May 11, 2008

Making The Switch

I've been curious about Linux for years. I've dipped my toe in the water in the past (installed Ubuntu on my home PC (that I never really use) a year or so ago until I flipped it to a Media Center PC), but I've never gone whole hog. I've never taken a primary machine and removed Windows. I've talked about it, I've pondered it, but I've never taken the leap.

Well, I'm about to leap.

The last week or two I've been evaluating the logistics of moving my work PC to Ubuntu. With the new Wubi installation option, I've been able to flip back and forth without needing to deal with the whole partitioning/dual-boot mess that I hate. I've managed to prove out most of my usage scenarios, and despite some frustrations and a bit of the 'sheen' coming off, I think I'm going to dive in. I'm about 99% certain that I can wipe my drive and throw Ubuntu on and still do everything I need to do, with virtual machines being my main fall back scenario where things just don't work.

I'm currently un-DRMing my purchased iTunes content, after which I should be ready to go. I don't know if I'll do it tonight, but likely sometime this week. I'll post my issues as I uncover them, but going in here are the things I'm a little disappointed about:

  • Evolution: It's the Outlook replacement, and I'm not super impressed. Seems pretty slow, I had some crashes while it downloaded my emails from exchange, and it's not real pretty. I might see if I can get connected via IMAP using Thunderbird, but I'll give Evolution more of a chance.
  • Networking: The NetworkManager app seems a little quirky, and I've had to mess with settings to get first connected wirelessly, and then again when I wanted to VPN to my office network. Even worse though, once VPN'd I can mount a windows share from work, but the file list I see is incomplete. I'm hoping I can figure this issue out, as I don't want to have to use a virtual machine to browse Windows network shares. This one almost sunk my move plans, but I've decided that there _must_ be a fix and that I'm not letting it stop me. If I can't resolve it after a few weeks, this might cause me to go back to XP. We'll see.
  • iTunes: No Linux version, and it doesn't seem like it works using Wine (at least for connecting to the iTunes store and/or actually sync-ing to my iPod). This isn't 'mission critical', so I haven't exhausted my research, so I might find a workable solution. I might try creating a VMWare Virtual Appliance thing specifically for iTunes too, see what that's all about.
  • Installing Apps: The Package Manager thing is pretty wicked, but installing apps that aren't in repositories is pretty painful. Linux needs to get that issue resolved if they ever hope to convert anyone aside from nerds.

Everything else seems pretty positive. I'm looking forward to becoming familiar with the OS as I use it on a daily basis. The speed seems pretty nice, and it's also fun to just be outside of my familiar Windows world, get out of the comfort zone and force myself to grow.

Wish me luck!

Wednesday, May 7, 2008

[Fact] vs [Test]

I got into a great discussion with Jeremy this morning on xUnit's use of the attribute [Fact] instead of a more common term like [Test]. I cringed the moment I saw [Fact]; it just felt wrong. And the more I read about the author's justifications for it, the more I cringe.

In most unit test frameworks, the word Test is used to describe or annotate the methods you write to prove your behaviour. For example, MSTest uses the [TestMethod] attribute, while NUnit and MbUnit simply use [Test]. xUnit has decided to go against convention and use [Fact]. Their reasoning seems to stem from an earlier decision they had made, which was to use [Theory] to annotate what are essentially data-driven tests, or more appropriately tests that are run against a set of inputs (think 'for-each thing in this set, do this test').

Here is what James Newkirk had to say in explaining [Fact]:
...someone in the audience said that if you were going to call "for-all" tests "Theory" then you should call a single test "Fact". Since then I have had a number of conversations with people and Fact seems to fit.

That explanation didn't exactly blow me away, so here is another one, this time from James' partner Brad Wilson:
The primary motivation is that it changes the expectations that what you do with this framework is capital-T Testing (aka, quality assurance). In reality, Test Driven Development is not really about testing at all. It's an example-driven design methodology which uses code to express the intentions of the class that is under design. The fact that it increases quality is a secondary benefit, and should not be considered a replacement for the work done by capital-T Testers. In Brian Marick's four quadrants of exploration through example, TDD-style code really only represents one of those quadrants (the technology-facing programmer support quadrant).

Additionally, as a word, [Fact] has very good symmetry with [Theory]. The two kinds of tests are fundamentally different; a [Fact] is an invariant statement which is always true, and a [Theory] is a statement which is true for all the given input values.

Now here is where my feathers start to ruffle. Brad writes about the xUnit framwork that "it's an example-driven design methodology which uses code to express the intentions of the class that is under design." Say what? Isn't that a fancy description of a unit test framework? Reading that is like going into a restaurant and having the waiter describe the ravioli as "a splendid blend of finely aged cheeses, high-quality bovine, and succulent savoy spinach, hand-sealed between two layers of circular pasta dough before being boiled in freshly salted mineral waters".

The argument that TDD is not really about testing at all does not fly with me. Of course it is about testing. Are there ways of doing TDD that provide more benefits than others? Sure, but they ALL provide the benefit of added quality (unless you are writing completely useless tests I suppose).

The entire usage of "capital-T Testing" irks me. Capital-T Testing is not the only kind of testing in a project, nor should it be. Look at it this way: we have a development environment, a QA environment, and a production environment. They are all still environments. Similarly we have developer testing and quality assurance testing. They are both forms of testing, and I've never heard anyone argue that developer (or unit testing, which is just a more structured and accurate approach than old-school test harnesses) should take the place of quality assurance testing.

Next, Brad almost spells out the exact reason why [Fact] is a poor choice: "a [Fact] is an invariant statement which is always true". Ok, except when that "example-driven code expression" fails during a build, in which case your [Fact] is no longer a fact, it is something else.

Finally, lets just see how this would work in practice:

"Hey Joe, your facts are failing in the current build".

Here is the bottom-line: all of this smells like people changing things just to be different. I can be convinced to get behind [Theory] for the 'for-all' tests, but until I hear some better rationale, the decision to switch to [Fact] seems arbitrary, and, if I may be so bold, wrong.

Tuesday, April 29, 2008


As I made my previous post I noticed something while linking to the Imaginet (gratuitous link) web site. Once again Imaginet is supporting the Manitoba Marathon with our Hard Drive to the Finish Contest, and it reminded me that I haven't yet blogged about something I've been doing over the last several weeks: running.

My wife and I signed up for a Learn To Run class at our local Running Room, which began about 5 weeks ago. If you're wondering how you learn to run, it is not as simple as the instructor simply throwing us into a gymnasium with a polar bear and telling us to survive until time is up. No, running is a little more involved than that.

The course is 10 weeks long, with one day each week devoted to an instructional presentation. So far we have learned how to properly select shoes, what sort of clothing to wear, how to best incorporate cross-training into our exercise plans, and most recently about how heart rate monitoring can be used to both pace yourself and as an indicator for whether you are actually working as hard as you think are (the likely answer: you're not).

After the instructional portion we go out in a pack and run for 25 minutes or so. The first week started with "1 and 1's", which is to say that for every minute we ran, we then walked a minute. This has been boosted as we progressed to where some of us are currently on "6 and 1's" and others are on "4 and 1's". By the end of the 10 weeks we should all be able to do "10 and 1's" as well as run 5k in duration.

Beyond the once-a-week instruction/run class, students are expected to run two more times during the week. Many of us meet up on Wednesdays to run together, which is nice, and just leaves one run to do alone. My wife and I have taken to bringing our dog Molly along with us on many of our runs, although I'm starting to worry that it might be bad for her to try to run too much as we get running for longer times and distances. I intend to speak with the vet about it this week, at which point I will post their advice here.

The bottom line in all of this: I've discovered that running is actually really fun! I'm not sure I would ever want to give up all of the team sports that I enjoy so much (hooray for Ultimate starting soon!) to focus solely on running, but it certainly is something I intend to continue doing after the class ends. I can't recommend a program like the Learn To Run class highly enough, and I encourage anyone who is even remotely interested to go sign up for something similar. You won't regret it!

And to tie this all together, my wife and I will be running in the relay portion of the Manitoba Marathon this spring. I ran it two years ago without any training of any sort, and while I gutted it out and did ok, I had no idea how to pace myself and the last mile was excruciating. This year I intend to have a goal in terms of time, as well as a goal to pace myself better and not feel terrible by the end. Next year I want to run the half-marathon, so that is my longer term goal... but one thing at a time!


My employer, Imaginet Resources, will be starting a series of webinars this spring. Details are just being worked out, but we will be producing one per week on a variety of topics. Currently I am scheduled to host two 'episodes':
  • May 28 2008 - WCF Service Gateways with C# 3.0 and Linq-To-Sql; and
  • June 25 2008 - NHibernate: An Entry-Level Primer
I'll post links to the rest of the topics and further details as they come out over the next couple weeks.

While many of the other presenters are seasoned vets at this sort of thing, this will be my first externally facing presentation. I'll probably post a couple of different thoughts as I prepare, and I will certainly post with my thoughts after each presentation. Hopefully I will learn some things that can be passed on to whichever poor soul Google's the wrong combination of terms and finds themselves at this blog.

Saturday, April 19, 2008

Am I Becoming An Experienced Traveler?

I've now traveled twice since the last time I wrote about my usual misadventures. Once to Vancouver, and now again to New York. And both times, nothing really of note occurred.

For most people this is probably normal, but I am far from a normal traveler and so we should be expecting lots of good material whenever I get sent away from home. Sure I brought the wrong suit to Vancouver and through a quirk in how I unpacked my bag spent about 45 panicked seconds at 6:00am the first morning thinking I had brought no pants. Sure, I pack 2-3 times more stuff than anyone I travel with, including most recently 4 pairs of shoes for 3 days in New York. And sure, I'm still totally awkward in pretty much any situation that involves speaking with hotel staff.

But this stuff isn't really up to snuff; I seem to be getting too good at traveling. We can only hope that maybe next time I'll lose my passport and have to spend a few nights at the Canadian consulate or something.

Friday, April 18, 2008

Should I Become A Rangers Fan?

I was in New York this week for work, and was lucky enough to catch game 4 of the Rangers/Devils series at Madison Square Garden. This was the first NHL playoff game I've seen in person since the Jets left way back in '96, and it was everything I hoped it would be.

The Garden itself is pretty amazing, and the fans and energy of New York just add that much more. There are several cool little traditions that I had no idea existed before I went, which were a joy to discover. I won't detail them all (you can read about them here), but my favorite is the song they all sing after each Rangers goal, followed closely by the "Potvin Sucks!" chant that at the time seemed random. I just love that people are still pooping on a guy that has been retired for 20 years for an incident that happened 30 years ago. Great stuff.

Now, was it as glorious as the playoff games I watched the Jets play back at the Winnipeg Arena in the 90's? No, but it couldn't possibly be. First off, I was in my teens back then, and things like using up a deodorant stick seemed like monumental events. Second off, the white-outs were ridiculously awesome, and ridiculously loud. If you showed up at school the next day with anything resembling your normal voice it meant you weren't really at the game.

But mostly the games back then were better because I cared so much more about who won the game. I read every Jets article in the newspaper every day. I spent more time studying box scores and leader boards than I did doing homework. I watched almost every game that came on TV (the Jets didn't get on TV all that often), and listened to many more on the radio in my room as I pretended to sleep (called marvelously by Curt Keilback).

But once the Jets left, my interest in the NHL declined. I'm still a fan, but now I mostly scan the headlines in the Sports section. I don't even glance at box scores or leaderboards, and honestly don't really know who is in what place in their division until the last week or so of the season. I don't even follow the scoring leaders anymore, despite my annual hockey pool.

Now don't get me wrong: I still love NHL hockey. I watch a few games on TV throughout the year, and I probably watch about 50 games over the course of the playoffs. But with no rooting interest, the results and stats have lost a lot of meaning. After the Jets left I hated the Coyotes. I resented them for leaving, and wanted nothing more than for them to fail badly. Thankfully they did just that, sparing me the fate so many Nordiques fans have tortuously endured.

If I wanted to really feel involved, I needed a team of my own. I had a brief fling with Buffalo during their couple strong years at the end of the decade, but that didn't stick. I tried to like the Canadiens during my 6 month stint in Montreal, but that died out soon after I left. Burned twice by brief flings, I swore off false allegiances and have since simply rooted for teams that played a fun style or had players I liked.

Unfortunately the ramification of this hockey chastity is that I never really get swept up in the games or series' anymore. Sometimes I will really want a specific team to lose (like Devils because I will hate them forever for inventing the trap), but mostly I just watched passively and marveled at individual plays or displays of skill. The only games that remind me of the old days are international games involving Team Canada, but those are few and far between.

So with all of this said, after enjoying a great time at MSG and being quite impressed by the fans and their traditions, is it time to give another team a chance? Should I adopt the Rangers as my new favorite NHL team?

Friday, April 4, 2008

I've Only Been Into It For A Couple Hours Though, But I'm REALLY Into It

I decided that it might be fun to list the stuff I'm currently "into". Theoretically this type of list might inform or inspire a reader to check something out, but the reality is I'm the only one who will read this so it's more just for historical purposes. I think it might be fun to find this blog 5 years from now and remember all the stuff I thought was great back in '08.

As an aside, I really wish I'd made a list like this every year of my life. It would be hilarious to see what 12-year old Dave was all about. I can make an educated guess (G.I. Joe, Transformers, spandex bike shorts, and my brother's-friend's-sister) but I'm sure I'm forgetting lots of stuff and my time line for others might be way off (perhaps 12-year old Dave thinks G.I. Joe is lame now! That was 11-year old Dave, and he was a loser).

Anyways, onto the list. I'll break this into two categories: tech stuff, and other stuff.

Tech Stuff
  • LINQ - In the spirit of Brick Tamland, I love LINQ! I'm not sold on LINQ-to-SQL, but LINQ-to-Entities is the best thing since sliced bread.
  • Lambda - I'm finding some nice places to use Lambda expressions, and it's happening more often. I can even write them without referring to old ones for guidance now!
  • NHibernate - This is really recent, as in this week, but I've finally gotten around to looking into NHibernate and I really think it's cool. Nothing like being 3-4 years late to the party, but whatever.
  • Gateways - I stole a cool Service and DAL architecture from some DinnerNow samples and have used it in a couple of projects now. It uses 'the Gateway pattern' (if such a thing actually exists) and just seems clean to me. Again I'm probably late to this party (and likely butchering terms - terms are not my strong suit), but whatever.
  • Macs - I'm dying to own a Mac. Yes, I am a marketers dream. Yes I'm jealous of Steve and Juan, those handsome, Mac-toting, metro-sexual bastards.

Other Stuff
  • Call of Duty 4 - This is a surprise to me and everyone I know. I hate on games like CoD all the time. I'm not a big FPS fan in general. And to top it off, previous versions of CoD made me sick when I watched or played them. But I've fallen for this one, aided by the fact that 7 of my friends also own it. Private matches are the bees knees.
  • Super Mario Galaxy - No one should be surprised by this. SMG is right in my video game wheelhouse, and it hits a home run. Fun times.
  • Motion-sensing light switches - The bathroom at the office I'm currently in has one, and inspired me to install them all over my house. I will be posting about my experiences soon, I just need to find about 3 hours to type it all out.
  • D&D - My friends and I have been getting back into D&D after a long hiatus. Yes, 30-year old men playing D&D in my basement; we are the uber-nerds. I don't care though, it's been a blast, and soon version 4 will be out and I'll get to soak in a bunch of new rules etc (my personal favorite part of RPG's is reading the books and making characters. Actually playing is merely icing on the cake).
  • Running - My wife and I just started a 10-week class at the Running Room called Learn to Run. I don't think I'm going to become 'a runner' or anything, but the class looks to be enjoyable and will hopefully prepare us to run in the relay portion of the Manitoba Marathon this summer (the other time I ran it my 'training' consisted of using my elliptical machine twice in the week leading up to the race... I did ok, but the idea of pacing was foreign to me and that last mile was pathetic and excruciating).
  • Hockey - My spongee and ice hockey seasons have just ended, but I felt this needed to be listed. Despite my ineptitude, I love playing all forms of hockey. I wish I could get into a summer league of ice hockey. Oh well, maybe some year.

I think that's it for now. I can't wait to review this thing in 2013 and discover what a dork I was!

Monday, February 11, 2008

Guess Who Traveled Again?

My wife and I just got back from a week long vacation in California. We had a great time, spent two awesome days skiing on Bear Mountain, and another fun one at Disneyland, visited with my snow-bird parents, saw some sights, etc. But I was vexed, very vexed, with one particular task I attempted. It was a task that at first looked easy, perhaps even mundane, but as usual the devil is in the details. What was this seemingly easy, yet incredibly difficult (and ultimately failed) undertaking?

Filling my dad's car with gas.

Don't laugh (ok, laugh), but that simple, every day activity had me absolutely steaming. Why was it so hard? Because America is stupid, that's why! Well maybe not, but somehow my anger took me there, as you will see. Here's what went down:

My wife and I took my Dad's Dodge to Disneyland. On the way home, I thought it would be awful nice (or at least mildly courteous) of me to leave him with a full tank of gas. So a few miles away from home I pulled into a friendly-looking Chevron station. I approached the pump, which indicated I needed to insert my debit card before I could fill.

"Fair enough", says I, so I swipe it through. Then it asks for my 5 digit zip code. Umm, I'm like, not from here... I don't have a zip. So I use a California one, which it tells me is invalid. Apparently the pump is 'smart' enough to check the zip against the address of my credit card (at least, that's what I assume it did). A little annoyed, but still pretty positive about the chances of getting this car filled up, I head inside to speak with staff.

Now here's where it gets fun. I present you with the transcript of my chat with the semi-English speaking Chevron employee (SESCE):

SESCE: How much?
Me: Fill please. (I hand my credit card)
SESCE: How much?
Me: I'd like a full tank of gas.
SESCE: I need number.
Me: I don't know how much it will take, I just want to fill it up.
SESCE: You tell me number, that's how much you get.
Me: But what if I tell you $50 and it only takes $42?
SESCE: You tell me number, that's what you pay.
Me: But I want to fill up the car, and I don't know the exact dollar amount it will take!
SESCE: I need number.
Me: Fine $40!!

So he runs my card through and actually charges it for $40 before I've even received any gas! Outside at the pump I'm fuming.

Me: How can I tell him a number if I don't know how much I need! I just want a fill!
My wife: Calm down.
Me: No! This is stupid! Why is this so difficult?!?
Wife: Do you think it will stop automatically at $40 or do we need to slow down?
Me: Keep holding it to the max, if it goes over $40 we're taking everything we can get!
Wife: What?!
Me: It shouldn't be "pay me $40 and hope you get some gas" it should be "give me some gas and hope I pay you for it"!
Wife: Sssh! These pumps have microphones, he can hear you!
Me: Good! He should hear this! This is dumb! I've just about had enough of this stupid country!!

Once I'd slandered an entire country for the actions of one gas station, it went downhill from there (I think I muttered random swears until the pumped stopped automatically at $40, which of course hadn't totally filled the car).

Can someone please explain to me why it was essentially impossible for me to fill my Dad's car with gas? Why do I need a zip code to pay at the pump? What kind of insane system makes you pay for something you possibly aren't going to get? If the car had only taken $32 in gas, could I have received a refund? Was there some kind of communication breakdown between me and the semi-English speaking Chevron employee? WTF??

I demand answers, and until such time as this makes sense, I am declaring that America is stupid.

Thursday, January 31, 2008

JP Boodhoo, You Magnificent Bastard!

For a little while now, my co-workers and I have been watching videos from dnrTV over lunch once a week. Recently we have been watching JP Boodhoo's series on demystifying design patterns, which has been nothing short of excellent. But one of the neatest things I learned while watching was something he and the host mostly glossed over: A strongly typed Constants class.

In the past when I've done a Constants class, it has looked something like this:

22 public class MyConstants

23 {

24 public const string MyFirstValue = "VALUE1";

25 public const string MySecondValue = "VALUE2";

26 }

Then to use them it goes sort of like this:

17 public class MyClass

18 {

19 public string MyValue { get; set; }

20 }

8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue);

14 }

15 }

Which would print out "VALUE1".

This works out fine, but has an inherent flaw: you are still just passing around a string, and there is nothing stopping someone from forgetting there is a class of constants and simply assigning their own random string value. This is where JP comes in. In this episode, somewhere near the end, he whips up a quick strongly-typed Constants class, and it works really, really well. Here's what my example above would look like if I had a quarter of Mr. Boodhoo's intelligence:

22 public class MyConstants

23 {

24 public static readonly MyConstants MyFirstValue = new MyConstants();

25 public static readonly MyConstants MySecondValue = new MyConstants();


27 private MyConstants() { }

28 }

Now when you use it, it can be typed:

17 public class MyClass

18 {

19 public MyConstants MyValue { get; set; }

20 }

8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue);

14 }

15 }

Which would print out... ConsoleApplication1.MyConstants? Oh crap, we're only part way there. But JP didn't leave us much to do, we just need to find a way to get a string value out of that object. Here's what our class could look like now:

22 public class MyConstants

23 {

24 public static readonly MyConstants MyFirstValue =

25 new MyConstants("VALUE1");

26 public static readonly MyConstants MySecondValue =

27 new MyConstants("VALUE2");

28 private readonly string value;


30 private MyConstants(string value)

31 {

32 this.value = value;

33 }


35 public override string ToString()

36 {

37 return value;

38 }

39 }

Now let's use it again:

17 public class MyClass

18 {

19 public MyConstants MyValue { get; set; }

20 }

8 class Program

9 {

10 static void Main(string[] args)

11 {

12 MyClass myObj = new MyClass { MyValue = MyConstants.MyFirstValue };

13 Console.Write(myObj.MyValue.ToString());

14 }

15 }

Pretty sweet eh?

The Latest Christmas Post Evar

When last I wrote, I promised a picture of this year's Christmas tree, in all it's glory. Six weeks later, I've gotten around to it. Here it is, check out the girth of this thing:

I'm gonna miss that tree, what a monster. Compare it to last year's tree from my previous post they both have the same tree skirt!

Coming soon: A useful post!