Archive for April, 2008

Ubuntu friendliness test

I’ve been rambling for awhile now to anyone who’ll listen – including some friends who work for Dell – that Linux, in particular things like Ubuntu, will start to give Windows a run for its money pretty soon. This article reminds me that there’s still some ways to go before just anyone can ditch Windows, but as a depction of the average user’s reaction to the latest incarnation of desktop Linux, it’s pretty encouraging.

The guy over at Content Consumer (who incidentally is less impressed than I am by the ease of Linux) got his girlfriend to go through 12 basic tasks — from setting the desktop picture to watching a YouTube video to downloading an album through Bittorrent — with no help at all. Just sit down in front of Ubuntu and do it.

Now, her experience isn’t perfect, but it’s hard to see things working this well for a non-techie on Linux just 5 or 10 years ago. The most surprising thing to me is that the biggest fail came on the system’s inability to gracefully handle upgrading the Firefox installation with the Flash plugin. Other than that, she was able to get quite a few things going on the first try. The main problems really seemed to be in the interface cues, which are very hard to get right even when you have a massive budget for such things, which I imagine the Ubuntu people do not.

What I’d like to see now is another post in which he gets her to set up a variety of popular accessories through Ubuntu. How good is it at recognizing the ancient HP InkJet you still haven’t replaced? Does it like your digital camera? How about your Flip? The non-techies probably grind more of their molars away on getting new peripherals to work than they do on any other common, vital task on Windows. How well does Ubuntu handle these compatibility issues?

More AASM rabbit hole

No joy yet. But I’ve gone deeper into the issue, and the puzzlement continues. It puzzles even friends of mine with far more RSpec experience than I, which is obscurely gratifying.

Not sure why it didn’t occur to me to try the ActiveRecord::Base#reload method before, but it hadn’t. I tried it here, but with the same result. #reload returns back the object you’re trying to reload (as opposed to a true or false for success/failure of reloading, so you can query the object directly. Check this out.

When this didn’t work:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>
it <span class="s"><span class="dl">&quot;</span><span class="k">should change state to 'dormant' with #dormantize!</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>  <span class="iv">@user_feed</span>.dormantize!<tt>
</tt>  <span class="iv">@user_feed</span> = <span class="iv">@user_feed</span>.reload<tt>
</tt>  <span class="iv">@user_feed</span>.state.should == <span class="s"><span class="dl">&quot;</span><span class="k">dormant</span><span class="dl">&quot;</span></span><tt>
</tt><span class="r">end</span>


I threw this in there to see what the output was like:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>
it <span class="s"><span class="dl">&quot;</span><span class="k">should change state to 'dormant' with #dormantize!</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>  <span class="iv">@user_feed</span>.dormantize!<tt>
</tt>  puts <span class="iv">@user_feed</span>.reload.state<tt>
</tt>  <span class="iv">@user_feed</span>.state.should == <span class="s"><span class="dl">&quot;</span><span class="k">dormant</span><span class="dl">&quot;</span></span><tt>
</tt><span class="r">end</span>



And I got (big surprise), “active.” Which isn’t what I get in the console. This leads me to believe that my original suspicion of not getting the RSpec object life cycle really is what’s happening here. I’m going to throw together a minor test app and put this on the RSpec mailing list to see if the gurus can get what’s going on. After that, I’m going to start setting breakpoints in AASM and do other random stuff to see if I can figure out where this is(n’t) happening.

Also, I don’t think I’m going to write a custom expectation matcher for this. Feels like overkill to me when you can just use a lower-level test that’s much faster to use and actually just queries the DB to make sure that the correct data persistence happened, which is after all, the entire point of AASM. I need to start trusting my instincts more on this kind of thing.

“Philip in 12 Parts”

Would love to check out this bio documentary on Philip Glass, but it doesn’t seem to be available in DC yet. NYTimes seems to think that maybe it’s a little too fawning, but I’m not sure I’d mind that much. I’ve loved Glass since I first saw Koyaanisqatsi, although he’s of course done the score for much more mainstream movies as well — most recently the excellent “Notes on a Scandal”.

Acts_as_state_machine puzzlement

Sometimes it’s fun to fall down a coding rabbit hole — means you’re learning something. Tonight I began seriously messing with acts_as_state_machine as part of a skunkworks project I’m hoping to roll to alpha in the next couple weeks, and I ran into an interesting pickle when attempting to write basic RSpec to test valid state change: either the AASM isn’t persisting to the db, or my understanding of the RSpec model lifecycle is not what I had thought. That’s the limited amount I’ve been able to glean since hitting the wall, and what I’m going to dive back into after taking a break writing this post.

AASM works by establishing some states, which are tied to instance methods, which support callbacks. So you can declare any given model to act as a finite state machine. Real-world examples of this include users of a web service (who might be “inactive”, “active”, “suspended”, “pending”, etc), and orders in an e-commerce system, (which might be “new”, “pending payment”, “shipped”, etc).

Any system with a finite number of states can be modeled, in theory, as a finite state machine. With Rails AASM, is the easiest way to do this — going by the theory that you should always download whatever you can.

Here are the events and the initial states for my object:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>
acts_as_state_machine <span class="sy">:initial</span> =&gt; <span class="sy">:active</span><tt>
</tt><tt>
</tt>  state <span class="sy">:active</span><tt>
</tt>  state <span class="sy">:dormant</span><tt>
</tt>  state <span class="sy">:dropped</span>, <span class="sy">:enter</span> =&gt; <span class="sy">:do_drop</span> <tt>
</tt>  <tt>
</tt>  <tt>
</tt>  event <span class="sy">:activate</span> <span class="r">do</span><tt>
</tt>    transitions <span class="sy">:from</span> =&gt; [<span class="sy">:dropped</span>, <span class="sy">:dormant</span>], <span class="sy">:to</span> =&gt; <span class="sy">:active</span> <tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  event <span class="sy">:dormantize</span> <span class="r">do</span><tt>
</tt>    transitions <span class="sy">:from</span> =&gt; <span class="sy">:active</span>, <span class="sy">:to</span> =&gt; <span class="sy">:dormant</span><tt>
</tt>  <span class="r">end</span> <tt>
</tt>  <tt>
</tt>  event <span class="sy">:drop</span> <span class="r">do</span><tt>
</tt>    transitions <span class="sy">:from</span> =&gt; [<span class="sy">:active</span>, <span class="sy">:dormant</span>], <span class="sy">:to</span> =&gt; <span class="sy">:dropped</span><tt>
</tt>  <span class="r">end</span>  <tt>
</tt>



The rabbit hole I fell down is trying to figure out why the state change is so hard to validate with RSpec. This test passes:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>
it <span class="s"><span class="dl">&quot;</span><span class="k">should default to state of 'active'</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>     <span class="iv">@user_feed</span>.state.should eql(<span class="s"><span class="dl">&quot;</span><span class="k">active</span><span class="dl">&quot;</span></span>)<tt>
</tt>  <span class="r">end</span><tt>
</tt>


As well it should, since @user_feed is made by an RSpec helper method that actually creates an object of class ActiveRecord::Base::UserFeed in the database, and I added a default value to the db schema. The AASM stuff works on the console with no problems, and it responds to the AASM-created instance methods in RSpec tests. But the state change itself isn’t testing correctly:

This works:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>
it <span class="s"><span class="dl">&quot;</span><span class="k">should respond to 'drop!</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    <span class="iv">@user_feed</span>.respond_to?(<span class="s"><span class="dl">&quot;</span><span class="k">drop!</span><span class="dl">&quot;</span></span>).should eql(<span class="pc">true</span>)<tt>
</tt>  <span class="r">end</span><tt>
</tt>



This doesn’t:

1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>
it <span class="s"><span class="dl">&quot;</span><span class="k">should change state to 'dropped' with #drop!</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    <span class="iv">@user_feed</span>.drop!<tt>
</tt>    <span class="iv">@user_feed</span>.state.should eql(<span class="s"><span class="dl">&quot;</span><span class="k">dropped</span><span class="dl">&quot;</span></span>)<tt>
</tt>  <span class="r">end</span><tt>
</tt>



Now I still consider myself an RSpec n00b, and in a lot of ways, a Rails n00b as well, but it seems to me that I should basically be able to replicate the same ActiveRecord lifecycle in RSpec that I can in the console. In fact, this is the first time I can remember w/ using RSpec that I can’t.

A clue to the post-predicament steps comes from this blog post, in which the author has written a custom matcher for the AASM transition. That was going to be my next step after writing a basic test that simply ensures the state is changing correctly in the DB column. But first, I want to understand what’s going on with the inability to duplicate my console success in RSpec. I’m sure it’s going to end up being something tiny or obvious or both — ever thus with programming.

I await the next iteration of my ongoing humbling.

Sadness in Pennsylvania

Great. Clinton wins Pennsylvania by 9 points, and so now we get to watch even more of the primary that never ends.

Tags: ,