This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: Andale! Andale! Yeehaw!
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
A colleague refactored some code the other day. And our tests broke of course. So it was time to fix them. One of the harder scenarios to test is objects which move from state to state by some other process. Usually, I like test driven design for this, because it usually results in a design where the state changes are message sends and the process that actually triggers them is dumbed down to something simple like:
[self tick] repeat
And the rest is handily tested. In this case it wasn't so easy though. It used Delay's in between state changes. We tried, but it was just hard. One might use a mock object or add some more instance variables or things. Then I had this zany idea. I'm still not sure what I think of this long term. But it seemed cool at the time, and I like to experiment with new things (and reinforce my coworkers opinions that I'm crazy when armed with messages).
What if I could change time for the process? What if I could change my mind and tell it something like "I know you're waiting for something, but let's just skip that this time and get right down to business, OK?" What I really need, is a way to tell a process to un-delay itself. Can we do that? Sure, this is Smalltalk. :)
Basically this checks a process to see if it is suspended. It then determines by examining the message send history if it is waiting on a Semaphore, and if that Semaphore was put in place by a Delay. If so, it's just a simple matter of signalling the Semaphore. Cool, huh? Oh, the nifty things you can do with messages.
So this is handy for testing, but can we test it? Sure, why not. First of all, we have a simple test:
Fork a process that waits for a LONG time. Since we haven't yielded to the forked process, we check that an initial unDelay doesn't UHE or anything to begin with. Then we yield and give the process a chance to come alive and get to it's delay. When it does, we get back to our test which should be able to successfully unDelay now. We yield again to give it a chance to do the "touch" and then assert that. In retrospect, if proc had been run at a higher priority, we wouldn't have needed the yielding.
The first checks to make sure that our unDelay will only signal a semaphore blocking a thread, WHEN that semaphore came from a Delay. And the second makes sure that it's ok to hammer processes that aren't delayed at all with unDelay. In fact if you start explaining your code out load to your coworker, you might start chanting something like "...and then we take this process here and we just send unDelay unDelay unDelay Yeehaw and it just hurries right on through everything..." And then, they will think your crazy.
Sidenote: I was disappointed to learn that Speedy Gonzales has been banished from just about any mainstream TV in the US. Apparently, he was racist. I guess I can dump my childhood reinforced baggage that my south-of-the-border cousins are smarter than me and my fellow cats. Sigh.